# Notifications

cmux supporte les notifications bureau, permettant aux agents IA et aux scripts de vous alerter quand ils ont besoin d'attention.

## Cycle de vie

1.  Reçue : la notification apparaît dans le panneau, l'alerte bureau se déclenche (si non supprimée)
2.  Non lue : badge affiché sur l'onglet de l'espace de travail
3.  Lue : effacée quand vous consultez cet espace de travail
4.  Effacée : supprimée du panneau

### Suppression

Les alertes bureau sont supprimées quand :

-   La fenêtre cmux est active
-   L'espace de travail spécifique qui envoie la notification est actif
-   Le panneau de notifications est ouvert

### Panneau de notifications

Appuyez sur `⌘⇧I` pour ouvrir le panneau de notifications. Cliquez sur une notification pour aller à cet espace de travail. Appuyez sur `⌘⇧U` pour aller directement à l'espace de travail avec la notification non lue la plus récente.

## Commande personnalisée

Exécutez une commande shell à chaque fois qu'une notification est planifiée. Définissez-la dans Réglages > App > Commande de notification. La commande s'exécute via /bin/sh -c avec ces variables d'environnement :

| Variable | Description |
| --- | --- |
| `CMUX_NOTIFICATION_TITLE` | Titre de la notification (nom de l'espace de travail ou nom de l'app) |
| `CMUX_NOTIFICATION_SUBTITLE` | Sous-titre de la notification |
| `CMUX_NOTIFICATION_BODY` | Texte du corps de la notification |

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
```

La commande s'exécute indépendamment du sélecteur de son système. Définissez le sélecteur sur « Aucun » pour utiliser uniquement la commande personnalisée, ou gardez les deux pour un son système plus une action personnalisée.

## Hooks de notification

`cmux.json` peut définir des hooks de notification qui reçoivent chaque politique de notification en JSON sur stdin. Chaque hook renvoie du JSON sur stdout. Les hooks sont désactivés par défaut ; cmux ne les exécute que lorsque `notifications.hooks` contient au moins un hook activé. cmux applique le texte et les effets renvoyés, ce qui permet aux hooks de filtrer les bannières, conserver ou ignorer l’historique de la barre latérale, jouer des sons ou arrêter les hooks suivants.

cmux.json

```
{
  "notifications": {
    "hooks": [
      {
        "id": "quiet-docs",
        "command": "sed 's/"desktop":true/"desktop":false/'",
        "timeoutSeconds": 20
      }
    ]
  }
}
```

Entrée et sortie du 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
  },
  "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
  }
}
```

Les hooks sont hérités du fichier global `~/.config/cmux/cmux.json` et des fichiers de projet `.cmux/cmux.json`, des dossiers parents jusqu’à l’espace de travail courant. Les hooks de projet utilisent la même demande de confiance que les autres commandes de projet `cmux.json` avant de s’exécuter. Les bannières d’approbation Feed passent aussi par ces hooks ; désactiver `desktop` supprime la bannière native tout en gardant l’élément Feed disponible dans cmux. Définissez `notifications.hooksMode` sur `replace` dans un projet pour ignorer les hooks hérités. Si un hook échoue, expire ou renvoie un JSON invalide, cmux utilise le comportement de notification par défaut et affiche une alerte d’échec du hook.

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

## Envoyer des notifications

### CLI

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

### OSC 777 (simple)

Le protocole RXVT utilise un format fixe avec titre et corps :

```
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 (riche)

Le protocole Kitty supporte les sous-titres et les IDs de notification :

```
# 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\\'
```

| Fonctionnalité | OSC 99 | OSC 777 |
| --- | --- | --- |
| Titre + corps | Oui | Oui |
| Sous-titre | Oui | Non |
| ID de notification | Oui | Non |
| Complexité | Plus élevée | Plus basse |

Utilisez OSC 777 pour les notifications simples. Utilisez OSC 99 quand vous avez besoin de sous-titres ou d'IDs de notification. Utilisez le CLI (cmux notify) pour l'intégration la plus simple.

## Hooks Claude Code

cmux s'intègre avec [Claude Code](https://docs.anthropic.com/en/docs/claude-code) via des hooks pour vous notifier quand les tâches sont terminées.

### 1\. Créer le script de hook

~/.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\. Configurer 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" }]
      }
    ]
  }
}
```

Redémarrez Claude Code pour appliquer les hooks.

## GitHub Copilot CLI

Copilot CLI prend en charge les [hooks](https://docs.github.com/en/copilot/how-tos/use-copilot-agents/coding-agent/use-hooks) qui exécutent des commandes shell lors d'événements du cycle de vie comme la soumission de prompts, l'arrêt de l'agent et les erreurs.

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

Pour les hooks au niveau du dépôt, créez un fichier .github/hooks/notify.json avec la même structure :

.github/hooks/notify.json

```
{
  "version": 1,
  "hooks": {
    "userPromptSubmitted": [ ... ],
    "agentStop": [ ... ]
  }
}
```

## Exemples d'intégration

### Notifier après une longue commande

~/.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 tmux

Si vous utilisez tmux dans cmux, activez le passthrough :

.tmux.conf

```
set -g allow-passthrough on
```

```
printf '\ePtmux;\e\e]777;notify;Title;Body\a\e\\'
```

Canonical: https://cmux.com/fr/docs/notifications

Documentation index: https://cmux.com/llms.txt
