เอเจนต์การแจ้งเตือน
เอเจนต์

การแจ้งเตือน

cmux รองรับการแจ้งเตือนเดสก์ท็อป ช่วยให้ AI agent และสคริปต์แจ้งเตือนคุณเมื่อต้องการความสนใจ

วงจรชีวิต

  1. ได้รับ: แจ้งเตือนปรากฏในแผง, แจ้งเตือนเดสก์ท็อปทำงาน (ถ้าไม่ถูกระงับ)
  2. ยังไม่ได้อ่าน: แสดง badge บนแท็บ workspace
  3. อ่านแล้ว: ล้างเมื่อคุณดู workspace นั้น
  4. ล้างแล้ว: ลบออกจากแผง

การระงับ

แจ้งเตือนเดสก์ท็อปจะถูกระงับเมื่อ:

  • หน้าต่าง cmux ถูกโฟกัส
  • workspace ที่ส่งแจ้งเตือนกำลังทำงานอยู่
  • แผงแจ้งเตือนเปิดอยู่

แผงแจ้งเตือน

กด ⌘⇧I เพื่อเปิดแผงแจ้งเตือน คลิกที่แจ้งเตือนเพื่อกระโดดไป workspace นั้น กด ⌘⇧U เพื่อกระโดดตรงไป workspace ที่มีแจ้งเตือนที่ยังไม่ได้อ่านล่าสุด

คำสั่งที่กำหนดเอง

รัน shell command ทุกครั้งที่มีการตั้งเวลาแจ้งเตือน ตั้งค่าใน Settings > App > Notification Command คำสั่งรันผ่าน /bin/sh -c พร้อมตัวแปรสภาพแวดล้อมเหล่านี้:

ตัวแปรคำอธิบาย
CMUX_NOTIFICATION_TITLEชื่อการแจ้งเตือน (ชื่อ workspace หรือชื่อแอป)
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

คำสั่งทำงานอิสระจากตัวเลือกเสียงระบบ ตั้งตัวเลือกเป็น "None" เพื่อใช้เฉพาะคำสั่งที่กำหนดเอง หรือใช้ทั้งสองสำหรับเสียงระบบพร้อมกับ action ที่กำหนดเอง

ฮุกการแจ้งเตือน

cmux.json สามารถกำหนดฮุกการแจ้งเตือนที่รับนโยบายการแจ้งเตือนทุกครั้งเป็น JSON ผ่าน stdin แต่ละฮุกส่ง JSON กลับผ่าน stdout ฮุกจะปิดอยู่ตามค่าเริ่มต้น; 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 และไฟล์โปรเจ็กต์ .cmux/cmux.json จากไดเรกทอรีแม่มายัง workspace ปัจจุบัน ฮุกของโปรเจ็กต์ใช้พรอมป์ความเชื่อถือเดียวกับคำสั่งโปรเจ็กต์อื่นใน 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 รองรับ subtitle และ notification 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 99OSC 777
ชื่อ + เนื้อหาใช่ใช่
ชื่อรองใช่ไม่
ID การแจ้งเตือนใช่ไม่
ความซับซ้อนสูงกว่าต่ำกว่า
ใช้ OSC 777 สำหรับแจ้งเตือนแบบง่าย ใช้ OSC 99 เมื่อต้องการ subtitle หรือ notification ID ใช้ CLI (cmux notify) สำหรับการรวมที่ง่ายที่สุด

Claude Code hooks

cmux รวมกับ Claude Code ผ่าน hooks เพื่อแจ้งเตือนคุณเมื่อ task เสร็จ

1. สร้าง hook script

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

รีสตาร์ท Claude Code เพื่อใช้ hooks

GitHub Copilot CLI

Copilot CLI รองรับhooks ที่รันคำสั่ง shell ในเหตุการณ์วงจรชีวิต เช่น การส่ง prompt, การหยุด agent และข้อผิดพลาด

~/.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 ระดับ repo ให้สร้างไฟล์ .github/hooks/notify.json ด้วยโครงสร้างเดียวกัน:

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

ตัวอย่าง integration

แจ้งเตือนหลังคำสั่งที่ใช้เวลานาน

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

ถ้าใช้ tmux ภายใน cmux ให้เปิด passthrough:

.tmux.conf
set -g allow-passthrough on
printf '\ePtmux;\e\e]777;notify;Title;Body\a\e\\'
หน้านี้มีประโยชน์หรือไม่?
แจ้งปัญหา