# 알림

cmux는 데스크톱 알림을 지원하여 AI 에이전트와 스크립트가 주의가 필요할 때 알려줄 수 있습니다.

## 생명주기

1.  수신: 알림이 패널에 나타나고, 데스크톱 알림이 발생합니다 (억제되지 않은 경우)
2.  읽지 않음: 워크스페이스 탭에 배지 표시
3.  읽음: 해당 워크스페이스를 볼 때 지워짐
4.  지워짐: 패널에서 제거됨

### 억제

다음 경우에 데스크톱 알림이 억제됩니다:

-   cmux 창이 포커스된 경우
-   알림을 보내는 특정 워크스페이스가 활성 상태인 경우
-   알림 패널이 열려 있는 경우

### 알림 패널

`⌘⇧I`을 눌러 알림 패널을 엽니다. 알림을 클릭하면 해당 워크스페이스로 이동합니다. `⌘⇧U`을 눌러 가장 최근의 읽지 않은 알림이 있는 워크스페이스로 바로 이동합니다.

## 커스텀 명령

알림이 예약될 때마다 셸 명령을 실행합니다. 설정 > 앱 > 알림 명령에서 설정하세요. 명령은 /bin/sh -c를 통해 실행되며 다음 환경 변수가 제공됩니다:

| 변수 | 설명 |
| --- | --- |
| `CMUX_NOTIFICATION_TITLE` | 알림 제목 (워크스페이스 이름 또는 앱 이름) |
| `CMUX_NOTIFICATION_SUBTITLE` | 알림 부제목 |
| `CMUX_NOTIFICATION_BODY` | 알림 본문 텍스트 |

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

명령은 시스템 사운드 선택기와 독립적으로 실행됩니다. 커스텀 명령만 사용하려면 선택기를 "없음"으로 설정하고, 시스템 사운드와 커스텀 동작을 모두 사용하려면 둘 다 유지하세요.

## 알림 훅

`cmux.json`은 모든 알림 정책을 stdin의 JSON으로 받는 알림 훅을 정의할 수 있습니다. 각 훅은 stdout으로 JSON을 반환합니다. 훅은 기본적으로 꺼져 있으며, cmux는 `notifications.hooks`에 활성화된 훅이 하나 이상 있을 때만 실행합니다. cmux는 반환된 알림 텍스트와 효과를 적용하므로 훅은 배너를 필터링하고, 사이드바 기록을 유지하거나 건너뛰고, 소리를 실행하거나, 이후 훅을 중지할 수 있습니다.

cmux.json

```
{
  "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`과 현재 workspace까지의 부모 디렉터리에 있는 프로젝트 `.cmux/cmux.json` 파일에서 상속됩니다. 프로젝트 훅은 실행 전에 다른 프로젝트 `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:

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.

## 알림 보내기

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

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 (리치)

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 | 예 | 아니오 |
| 복잡도 | 높음 | 낮음 |

간단한 알림에는 OSC 777을 사용하세요. 부제목이나 알림 ID가 필요한 경우 OSC 99를 사용하세요. 가장 쉬운 통합을 위해 CLI(cmux notify)를 사용하세요.

## Claude Code hooks

cmux는 hooks를 통해 [Claude Code](https://docs.anthropic.com/en/docs/claude-code)와 통합하여 작업이 완료되면 알려줍니다.

### 1\. 훅 스크립트 생성

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

hooks를 적용하려면 Claude Code를 재시작하세요.

## GitHub Copilot CLI

Copilot CLI는 프롬프트 제출, 에이전트 중지, 오류 등 라이프사이클 이벤트에서 셸 명령을 실행하는 [hooks](https://docs.github.com/en/copilot/how-tos/use-copilot-agents/coding-agent/use-hooks)를 지원합니다.

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

저장소 수준 hooks의 경우, 같은 구조로 .github/hooks/notify.json 파일을 생성하세요:

.github/hooks/notify.json

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

## 통합 예시

### 긴 명령 후 알림

~/.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 패스스루

cmux 내에서 tmux를 사용하는 경우 패스스루를 활성화하세요:

.tmux.conf

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

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

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

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