AgenciPowiadomienia
Agenci

Powiadomienia

cmux obsługuje powiadomienia na pulpicie, pozwalając agentom AI i skryptom alarmować Cię gdy potrzebują uwagi.

Cykl życia

  1. Odebrane: powiadomienie pojawia się w panelu, alert na pulpicie się uruchamia (jeśli nie jest wytłumiony)
  2. Nieprzeczytane: odznaka wyświetlana na karcie workspace'a
  3. Przeczytane: usunięte gdy wyświetlisz ten workspace
  4. Wyczyszczone: usunięte z panelu

Wyciszanie

Alerty na pulpicie są wyciszane gdy:

  • Okno cmux jest sfokusowane
  • Konkretny workspace wysyłający powiadomienie jest aktywny
  • Panel powiadomień jest otwarty

Panel powiadomień

Naciśnij ⌘⇧I aby otworzyć panel powiadomień. Kliknij powiadomienie aby przejść do tego workspace'a. Naciśnij ⌘⇧U aby przejść bezpośrednio do workspace'a z najnowszym nieprzeczytanym powiadomieniem.

Niestandardowe polecenie

Uruchom polecenie powłoki za każdym razem gdy powiadomienie jest zaplanowane. Ustaw to w Ustawieniach > Aplikacja > Polecenie powiadomienia. Polecenie uruchamia się przez /bin/sh -c z tymi zmiennymi środowiskowymi:

ZmiennaOpis
CMUX_NOTIFICATION_TITLETytuł powiadomienia (nazwa workspace'a lub aplikacji)
CMUX_NOTIFICATION_SUBTITLEPodtytuł powiadomienia
CMUX_NOTIFICATION_BODYTreść powiadomienia
Examples
# 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

Polecenie działa niezależnie od wybieraka dźwięku systemowego. Ustaw wybierak na "Brak" aby używać tylko niestandardowego polecenia, lub zachowaj oba dla dźwięku systemowego plus niestandardowa akcja.

Hooki powiadomień

cmux.json może definiować hooki powiadomień, które otrzymują każdą politykę powiadomień jako JSON na stdin. Każdy hook zwraca JSON na stdout. Hooki są domyślnie wyłączone; cmux uruchamia je tylko wtedy, gdy notifications.hooks zawiera co najmniej jeden włączony hook. cmux stosuje zwrócony tekst i efekty, więc hooki mogą filtrować banery, zachowywać lub pomijać historię paska bocznego, uruchamiać dźwięki albo zatrzymywać kolejne hooki.

cmux.json
{
  "notifications": {
    "hooks": [
      {
        "id": "quiet-docs",
        "command": "sed 's/"desktop":true/"desktop":false/'",
        "timeoutSeconds": 20
      }
    ]
  }
}
Wejście i wyjście hooka
{
  "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
  }
}

Hooki są dziedziczone z globalnego pliku ~/.config/cmux/cmux.json oraz plików projektu .cmux/cmux.json, od katalogów nadrzędnych do bieżącego workspace. Hooki projektu przed uruchomieniem używają tego samego monitu zaufania co inne polecenia projektu cmux.json. Banery akceptacji Feed też przechodzą przez te hooki; wyłączenie desktop ukrywa natywny baner, ale zostawia element Feed dostępny w cmux. Ustaw notifications.hooksMode na replace w konfiguracji projektu, aby ignorować odziedziczone hooki. Jeśli hook zawiedzie, przekroczy limit czasu albo zwróci nieprawidłowy JSON, cmux użyje domyślnego zachowania powiadomień i pokaże alert błędu hooka.

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:

Silence subagent completions
{
  "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.

Wysyłanie powiadomień

CLI

cmux notify --title "Task Complete" --body "Your build finished"
cmux notify --title "Claude Code" --subtitle "Waiting" --body "Agent needs input"

OSC 777 (prosty)

Protokół RXVT używa stałego formatu z tytułem i treścią:

printf '\e]777;notify;My Title;Message body here\a'
Shell function
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 (zaawansowany)

Protokół Kitty obsługuje podtytuły i identyfikatory powiadomień:

# 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\\'
FunkcjaOSC 99OSC 777
Tytuł + treśćTakTak
PodtytułTakNie
ID powiadomieniaTakNie
ZłożonośćWyższaNiższa
Użyj OSC 777 do prostych powiadomień. Użyj OSC 99 gdy potrzebujesz podtytułów lub identyfikatorów powiadomień. Użyj CLI (cmux notify) dla najłatwiejszej integracji.

Hooki Claude Code

cmux integruje się z Claude Code przez hooki aby powiadamiać Cię gdy zadania się zakończą.

1. Utwórz skrypt hooka

~/.claude/hooks/cmux-notify.sh
#!/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"
fi
chmod +x ~/.claude/hooks/cmux-notify.sh

2. Skonfiguruj Claude Code

~/.claude/settings.json
{
  "hooks": {
    "SubagentStop": [
      {
        "hooks": [{ "type": "command", "command": "~/.claude/hooks/cmux-notify.sh" }]
      }
    ],
    "Stop": [
      {
        "hooks": [{ "type": "command", "command": "~/.claude/hooks/cmux-notify.sh" }]
      }
    ]
  }
}

Zrestartuj Claude Code aby zastosować hooki.

GitHub Copilot CLI

Copilot CLI obsługuje hooki, które uruchamiają polecenia shell przy zdarzeniach cyklu życia, takich jak wysłanie promptu, zatrzymanie agenta i błędy.

~/.copilot/config.json
{
  "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
      }
    ]
  }
}

Dla hooków na poziomie repozytorium utwórz plik .github/hooks/notify.json o tej samej strukturze:

.github/hooks/notify.json
{
  "version": 1,
  "hooks": {
    "userPromptSubmitted": [ ... ],
    "agentStop": [ ... ]
  }
}

Przykłady integracji

Powiadom po długim poleceniu

~/.zshrc
# 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

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

node
function notify(title, body) {
  process.stdout.write(`\x1b]777;notify;${title};${body}\x07`);
}

notify('Build Done', 'webpack finished');

tmux passthrough

Jeśli używasz tmux wewnątrz cmux, włącz passthrough:

.tmux.conf
set -g allow-passthrough on
printf '\ePtmux;\e\e]777;notify;Title;Body\a\e\\'