Уведомления
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Команда работает независимо от системного выбора звуков. Установи выбор на "Нет" чтобы использовать только пользовательскую команду, или оставь оба для системного звука плюс пользовательского действия.
Хуки уведомлений
cmux.json может задавать хуки уведомлений, которые получают каждую политику уведомления как JSON через stdin. Каждый хук возвращает JSON через stdout. По умолчанию хуки отключены; cmux запускает их только когда notifications.hooks содержит хотя бы один включённый хук. cmux применяет возвращённый текст и эффекты, поэтому хуки могут фильтровать баннеры, сохранять или пропускать историю боковой панели, запускать звуки или останавливать последующие хуки.
{
"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
},
"agent": {
"kind": "claude",
"category": "turn-complete",
"pending": false,
"isSubagent": true
},
"effects": {
"record": true,
"markUnread": true,
"reorderWorkspace": true,
"desktop": true,
"sound": true,
"command": true,
"paneFlash": true
}
}Хуки наследуются из глобального файла ~/.config/cmux/cmux.json и проектных файлов .cmux/cmux.json от родительских каталогов до текущего workspace. Проектные хуки перед запуском используют тот же запрос доверия, что и другие проектные команды cmux.json. Баннеры подтверждения Feed тоже проходят через эти хуки; отключение desktop скрывает нативный баннер, но оставляет элемент Feed доступным в cmux. Установите notifications.hooksMode в replace в конфигурации проекта, чтобы игнорировать унаследованные хуки. Если хук завершается с ошибкой, истекает по тайм-ауту или возвращает неверный JSON, cmux использует поведение уведомлений по умолчанию и показывает предупреждение об ошибке хука.
Agent-event context
Notifications that originate from an agent completion signal carry a read-only agent object: kind is the stable lowercase agent slug (claude, codex, grok, …), category is turn-complete, needs-permission, or idle-reminder, pending is true when the turn ended with background work still running, and isSubagent is true for nested subagent sessions. The object is omitted for non-agent notifications, and the same values are exported to the hook process as CMUX_NOTIFICATION_AGENT_KIND, CMUX_NOTIFICATION_AGENT_CATEGORY, CMUX_NOTIFICATION_AGENT_PENDING, and CMUX_NOTIFICATION_AGENT_IS_SUBAGENT. For example, this hook silences the banner, sound, and pane flash for subagent completions while leaving everything else untouched:
{
"notifications": {
"hooks": [
{
"id": "mute-subagent-completions",
"command": "if [ \"${CMUX_NOTIFICATION_AGENT_IS_SUBAGENT-0}\" = \"1\" ] && [ \"$CMUX_NOTIFICATION_AGENT_CATEGORY\" = \"turn-complete\" ]; then printf '{\"effects\":{\"desktop\":false,\"sound\":false,\"paneFlash\":false}}'; fi"
}
]
}
}With no hooks configured, notification behavior is exactly cmux's built-in default — configuring a hook is the explicit opt-in that hands the delivery decision to your script. Note that cmux's built-in subagent suppression (automation.suppressSubagentNotifications, on by default) drops subagent completion events before they reach hooks; turn it off if your hook should see subagent events and make its own decision.
Отправка уведомлений
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. Создай скрипт хука
#!/bin/bash
# Outside cmux there is no socket to talk to, so do nothing.
[ -S /tmp/cmux.sock ] || exit 0
payload=$(cat)
field() { printf '%s' "$payload" | jq -r "$1 // empty"; }
event=$(field .hook_event_name)
if [ "$event" = "Stop" ]; then
cmux notify --title "Claude Code" --body "Session complete"
elif [ "$event" = "SubagentStop" ]; then
cmux notify --title "Claude Code" --body "Agent finished"
fichmod +x ~/.claude/hooks/cmux-notify.sh2. Настрой Claude Code
{
"hooks": {
"SubagentStop": [
{
"hooks": [{ "type": "command", "command": "~/.claude/hooks/cmux-notify.sh" }]
}
],
"Stop": [
{
"hooks": [{ "type": "command", "command": "~/.claude/hooks/cmux-notify.sh" }]
}
]
}
}Перезапусти Claude Code чтобы применить хуки.
GitHub Copilot CLI
Copilot CLI поддерживает хуки, которые выполняют 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
}
]
}
}Для хуков на уровне репозитория создайте файл .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 buildPython
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 passthrough
Если используешь tmux внутри cmux, включи passthrough:
set -g allow-passthrough onprintf '\ePtmux;\e\e]777;notify;Title;Body\a\e\\'