#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

  1. Recebida: notificação aparece no painel, alerta de desktop é disparado (se não suprimido)
  2. Não lida: badge exibido na aba do workspace
  3. Lida: limpa quando você visualiza aquele workspace
  4. 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ávelDescrição
CMUX_NOTIFICATION_TITLETítulo da notificação (nome do workspace ou do app)
CMUX_NOTIFICATION_SUBTITLESubtítulo da notificação
CMUX_NOTIFICATION_BODYCorpo da notificação
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

O 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.

cmux.json
{
  "notifications": {
    "hooks": [
      {
        "id": "quiet-docs",
        "command": "sed 's/"desktop":true/"desktop":false/'",
        "timeoutSeconds": 20
      }
    ]
  }
}
Entrada e saída do hook
{
  "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'
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 (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\\'
RecursoOSC 99OSC 777
Título + corpoSimSim
SubtítuloSimNão
ID da notificaçãoSimNão
ComplexidadeMaiorMenor
Use OSC 777 para notificações simples. Use OSC 99 quando precisar de subtítulos ou IDs de notificação. Use a CLI (cmux notify) para a integração mais fácil.

#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

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

#2. Configure o Claude Code

~/.claude/settings.json
{
  "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.

~/.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
      }
    ]
  }
}

Para hooks no nível do repositório, crie um arquivo .github/hooks/notify.json com a mesma estrutura:

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

#Exemplos de integração

#Notificar após comando longo

~/.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');

#Passthrough do tmux

Se estiver usando tmux dentro do cmux, ative o passthrough:

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