#Notificações
O cmux suporta notificações de desktop, permitindo que agentes de IA e scripts alertem você quando precisam de atenção.
#Ciclo de vida
- Recebida: notificação aparece no painel, alerta de desktop é disparado (se não suprimido)
- Não lida: badge exibido na aba do workspace
- Lida: limpa quando você visualiza aquele workspace
- Limpa: removida do painel
#Supressão
Alertas de desktop são suprimidos quando:
- A janela do cmux está focada
- O workspace específico enviando a notificação está ativo
- O painel de notificações está aberto
#Painel de notificações
Pressione ⌘⇧I para abrir o painel de notificações. Clique em uma notificação para ir ao workspace. Pressione ⌘⇧U para ir diretamente ao workspace com a notificação não lida mais recente.
#Comando personalizado
Execute um comando shell toda vez que uma notificação for agendada. Defina em Configurações > App > Comando de Notificação. O comando é executado via /bin/sh -c com estas variáveis de ambiente:
| Variável | Descrição |
|---|---|
CMUX_NOTIFICATION_TITLE | Título da notificação (nome do workspace ou do app) |
CMUX_NOTIFICATION_SUBTITLE | Subtítulo da notificação |
CMUX_NOTIFICATION_BODY | Corpo da notificação |
# 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.logO comando é executado independentemente do seletor de som do sistema. Defina o seletor como "Nenhum" para usar apenas o comando personalizado, ou mantenha ambos para um som do sistema mais uma ação personalizada.
#Hooks de notificação
cmux.json pode definir hooks de notificação que recebem cada política de notificação como JSON no stdin. Cada hook retorna JSON no stdout. Os hooks ficam desativados por padrão; o cmux só os executa quando notifications.hooks contém pelo menos um hook habilitado. O cmux aplica o texto e os efeitos retornados, então os hooks podem filtrar banners, manter ou pular o histórico da barra lateral, tocar sons ou parar hooks posteriores.
{
"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
}
}Os hooks são herdados do arquivo global ~/.config/cmux/cmux.json e dos arquivos de projeto .cmux/cmux.json, dos diretórios pai até o workspace atual. Hooks de projeto usam o mesmo prompt de confiança de outros comandos de projeto em cmux.json antes de executar. Banners de aprovação do Feed também passam por esses hooks; desativar desktop suprime o banner nativo mantendo o item do Feed disponível no cmux. Defina notifications.hooksMode como replace em um projeto para ignorar hooks herdados. Se um hook falhar, expirar ou retornar JSON inválido, o cmux usa o comportamento padrão de notificação e mostra um alerta de falha do hook.
#Enviando notificações
#CLI
cmux notify --title "Task Complete" --body "Your build finished"
cmux notify --title "Claude Code" --subtitle "Waiting" --body "Agent needs input"#OSC 777 (simples)
O protocolo RXVT usa um formato fixo com título e corpo:
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 (rico)
O protocolo Kitty suporta subtítulos e IDs de notificação:
# 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\\'| Recurso | OSC 99 | OSC 777 |
|---|---|---|
| Título + corpo | Sim | Sim |
| Subtítulo | Sim | Não |
| ID da notificação | Sim | Não |
| Complexidade | Maior | Menor |
#Hooks do Claude Code
O cmux se integra com o Claude Code via hooks para notificá-lo quando tarefas são concluídas.
#1. Crie o script de 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. Configure o 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"
}
]
}
]
}
}Reinicie o Claude Code para aplicar os hooks.
#GitHub Copilot CLI
O Copilot CLI suporta hooks que executam comandos shell em eventos do ciclo de vida como envio de prompts, parada do agente e erros.
{
"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
}
]
}
}Para hooks no nível do repositório, crie um arquivo .github/hooks/notify.json com a mesma estrutura:
{
"version": 1,
"hooks": {
"userPromptSubmitted": [ ... ],
"agentStop": [ ... ]
}
}#Exemplos de integração
#Notificar após comando longo
# 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');#Passthrough do tmux
Se estiver usando tmux dentro do cmux, ative o passthrough:
set -g allow-passthrough onprintf '\ePtmux;\e\e]777;notify;Title;Body\a\e\\'