#通知
cmux 支援桌面通知,讓 AI 代理和腳本在需要注意時提醒你。
#生命週期
- 已接收:通知出現在面板中,桌面提醒觸發(如果未被抑制)
- 未讀:在工作區分頁上顯示徽章
- 已讀:當你查看該工作區時清除
- 已清除:從面板中移除
#抑制
在以下情況下,桌面提醒會被抑制:
- cmux 視窗處於聚焦狀態
- 傳送通知的特定工作區處於活躍狀態
- 通知面板已開啟
#通知面板
按 ⌘⇧I 開啟通知面板。點擊通知以跳轉到該工作區。按 ⌘⇧U 直接跳轉到有最新未讀通知的工作區。
#自訂指令
每次排程通知時執行一個 shell 指令。在「設定 > 應用程式 > 通知指令」中設定。指令透過 /bin/sh -c 執行,並提供以下環境變數:
| 變數 | 說明 |
|---|---|
CMUX_NOTIFICATION_TITLE | 通知標題(工作區名稱或應用程式名稱) |
CMUX_NOTIFICATION_SUBTITLE | 通知副標題 |
CMUX_NOTIFICATION_BODY | 通知內文 |
# Text-to-speech
say "$CMUX_NOTIFICATION_TITLE"
# Custom sound file
afplay /path/to/sound.aiff
# Log to file
echo "$CMUX_NOTIFICATION_TITLE: $CMUX_NOTIFICATION_BODY" >> ~/notifications.log此指令獨立於系統聲音選擇器執行。將選擇器設為「無」以僅使用自訂指令,或兩者都保留以同時播放系統聲音和自訂動作。
#通知 Hook
cmux.json 可以定義通知 Hook,讓每個通知政策以 JSON 形式從 stdin 傳入。每個 Hook 會透過 stdout 回傳 JSON。Hook 預設為關閉;只有在 notifications.hooks 至少包含一個已啟用的 Hook 時,cmux 才會執行它們。cmux 會套用回傳的通知文字與效果,因此 Hook 可以篩選橫幅、保留或略過側邊欄歷史、播放聲音,或停止後續 Hook。
{
"notifications": {
"hooks": [
{
"id": "quiet-docs",
"command": "sed 's/"desktop":true/"desktop":false/'",
"timeoutSeconds": 20
}
]
}
}{
"version": 1,
"notification": {
"workspaceId": "3B3F0D83-...",
"surfaceId": "7E9C1A02-...",
"title": "Codex",
"subtitle": "Waiting",
"body": "Agent needs input"
},
"context": {
"cwd": "/path/to/project",
"configPath": "/path/to/project/.cmux/cmux.json",
"hookId": "quiet-docs",
"appFocused": false,
"focusedPanel": false
},
"effects": {
"record": true,
"markUnread": true,
"reorderWorkspace": true,
"desktop": true,
"sound": true,
"command": true,
"paneFlash": true
}
}Hook 會從全域 ~/.config/cmux/cmux.json 以及從父目錄到目前 workspace 的專案 .cmux/cmux.json 檔案繼承。專案 Hook 執行前會使用與其他專案 cmux.json 命令相同的信任提示。Feed 核准橫幅也會通過這些 Hook;停用 desktop 會抑制原生橫幅,同時讓 Feed 項目保留在 cmux 中。若要忽略繼承的 Hook,請在專案設定中將 notifications.hooksMode 設為 replace。如果 Hook 失敗、逾時或回傳無效 JSON,cmux 會使用預設通知行為並顯示 Hook 失敗提醒。
#傳送通知
#CLI
cmux notify --title "Task Complete" --body "Your build finished"
cmux notify --title "Claude Code" --subtitle "Waiting" --body "Agent needs input"#OSC 777(簡單)
RXVT 協定使用固定格式,包含標題和內文:
printf '\e]777;notify;My Title;Message body here\a'notify_osc777() {
local title="$1"
local body="$2"
printf '\e]777;notify;%s;%s\a' "$title" "$body"
}
notify_osc777 "Build Complete" "All tests passed"#OSC 99(豐富)
Kitty 協定支援副標題和通知 ID:
# Format: ESC ] 99 ; <params> ; <payload> ESC \
# Simple notification
printf '\e]99;i=1;e=1;d=0:Hello World\e\\'
# With title, subtitle, and body
printf '\e]99;i=1;e=1;d=0;p=title:Build Complete\e\\'
printf '\e]99;i=1;e=1;d=0;p=subtitle:Project X\e\\'
printf '\e]99;i=1;e=1;d=1;p=body:All tests passed\e\\'| 功能 | OSC 99 | OSC 777 |
|---|---|---|
| 標題 + 內文 | 是 | 是 |
| 副標題 | 是 | 否 |
| 通知 ID | 是 | 否 |
| 複雜度 | 較高 | 較低 |
#Claude Code hooks
cmux 透過 Claude Code 的 hooks 整合,在任務完成時通知你。
#1. 建立 hook 腳本
#!/bin/bash
# Skip if not in cmux
[ -S /tmp/cmux.sock ] || exit 0
EVENT=$(cat)
EVENT_TYPE=$(echo "$EVENT" | jq -r '.hook_event_name // "unknown"')
TOOL=$(echo "$EVENT" | jq -r '.tool_name // ""')
case "$EVENT_TYPE" in
"Stop")
cmux notify --title "Claude Code" --body "Session complete"
;;
"PostToolUse")
[ "$TOOL" = "Task" ] && cmux notify --title "Claude Code" --body "Agent finished"
;;
esacchmod +x ~/.claude/hooks/cmux-notify.sh#2. 設定 Claude Code
{
"hooks": {
"Stop": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "~/.claude/hooks/cmux-notify.sh"
}
]
}
],
"PostToolUse": [
{
"matcher": "Task",
"hooks": [
{
"type": "command",
"command": "~/.claude/hooks/cmux-notify.sh"
}
]
}
]
}
}重新啟動 Claude Code 以套用 hooks。
#GitHub Copilot CLI
Copilot CLI 支援hooks,可在提示提交、代理停止和錯誤等生命週期事件中執行 shell 命令。
{
"hooks": {
"userPromptSubmitted": [
{
"type": "command",
"bash": "if command -v cmux &>/dev/null; then cmux set-status copilot_cli Running; fi",
"timeoutSec": 3
}
],
"agentStop": [
{
"type": "command",
"bash": "if command -v cmux &>/dev/null; then cmux notify --title 'Copilot CLI' --body 'Done'; cmux set-status copilot_cli Idle; fi",
"timeoutSec": 5
}
],
"errorOccurred": [
{
"type": "command",
"bash": "if command -v cmux &>/dev/null; then cmux notify --title 'Copilot CLI' --subtitle 'Error' --body 'An error occurred'; cmux set-status copilot_cli Error; fi",
"timeoutSec": 5
}
],
"sessionEnd": [
{
"type": "command",
"bash": "if command -v cmux &>/dev/null; then cmux clear-status copilot_cli; fi",
"timeoutSec": 3
}
]
}
}對於儲存庫層級的 hooks,使用相同結構建立 .github/hooks/notify.json 檔案:
{
"version": 1,
"hooks": {
"userPromptSubmitted": [ ... ],
"agentStop": [ ... ]
}
}#整合範例
#長時間指令後通知
# Add to your shell config
notify-after() {
"$@"
local exit_code=$?
if [ $exit_code -eq 0 ]; then
cmux notify --title "✓ Command Complete" --body "$1"
else
cmux notify --title "✗ Command Failed" --body "$1 (exit $exit_code)"
fi
return $exit_code
}
# Usage: notify-after npm run build#Python
import sys
def notify(title: str, body: str):
"""Send OSC 777 notification."""
sys.stdout.write(f'\x1b]777;notify;{title};{body}\x07')
sys.stdout.flush()
notify("Script Complete", "Processing finished")#Node.js
function notify(title, body) {
process.stdout.write(`\x1b]777;notify;${title};${body}\x07`);
}
notify('Build Done', 'webpack finished');#tmux 透傳
如果在 cmux 內使用 tmux,請啟用透傳:
set -g allow-passthrough onprintf '\ePtmux;\e\e]777;notify;Title;Body\a\e\\'