## 経緯 [[cmux]]なら[[Claude Code]]の通知をいい感じにしてくれると思っていたが、そうでもなさそう & 安定性に不安がある......ので自分で仕組みをつくる。 基本的には[[フック (Claude Code)|フック]]を定義し、[[OSC 777 シーケンス]]を使って通知を行う。 <div class="link-card-v2"> <div class="link-card-v2-site"> <img class="link-card-v2-site-icon" src="https://publish-01.obsidian.md/access/35d05cd1bf5cc500e11cc8ba57daaf88/favicon-64.png" /> <span class="link-card-v2-site-name">Minerva</span> </div> <div class="link-card-v2-title"> 📜2026-02-24 copilot-plugin-notifyの初期開発記録 </div> <div class="link-card-v2-content">cmux notifyの不安定さとOSC 777シーケンスの/dev/tty出力問題に対処しつつ、Copilot CLI hooksの制約を調査した結果、自前通知実装を決定し、スクリプトや環境変数のリネームと許可コマンド用の通知抑制設定を行った記録である</div> <img class="link-card-v2-image" src="https://publish-01.obsidian.md/access/35d05cd1bf5cc500e11cc8ba57daaf88/Notes/attachments/activity.webp" /> <a data-href="📜2026-02-24 copilot-plugin-notifyの初期開発記録" class="internal-link"></a> </div> %%[[📜2026-02-24 copilot-plugin-notifyの初期開発記録]]%% > [!question] `cmux notify` を使わないのか? > `cmux` コマンドは[[cmux]]の状態によって発動しないこともあり不安定なので。 ## [[フック (Claude Code)|フック]]に組み込む `~/.claude/settings.json` に定義するのは変わってなさそう。 <div class="link-card-v2"> <div class="link-card-v2-site"> <img class="link-card-v2-site-icon" src="https://code.claude.com/docs/_mintlify/favicons/claude-code/pLsy-mRpNksna2sx/_generated/favicon/favicon-16x16.png" /> <span class="link-card-v2-site-name">code.claude.com</span> </div> <div class="link-card-v2-title"> Automate workflows with hooks - Claude Code Docs </div> <div class="link-card-v2-content"> Run shell commands automatically when Claude Code edits files, finishes tasks, or needs input. Format code, send ... </div> <img class="link-card-v2-image" src="https://claude-code.mintlify.app/_next/image?url=%2F_mintlify%2Fapi%2Fog%3Fdivision%3DBuild%2Bwith%2BClaude%2BCode%26appearance%3Dsystem%26title%3DAutomate%2Bworkflows%2Bwith%2Bhooks%26description%3DRun%2Bshell%2Bcommands%2Bautomatically%2Bwhen%2BClaude%2BCode%2Bedits%2Bfiles%252C%2Bfinishes%2Btasks%252C%2Bor%2Bneeds%2Binput.%2BFormat%2Bcode%252C%2Bsend%2Bnotifications%252C%2Bvalidate%2Bcommands%252C%2Band%2Benforce%2Bp%26logoLight%3Dhttps%253A%252F%252Fmintcdn.com%252Fclaude-code%252Fc5r9_6tjPMzFdDDT%252Flogo%252Flight.svg%253Ffit%253Dmax%2526auto%253Dformat%2526n%253Dc5r9_6tjPMzFdDDT%2526q%253D85%2526s%253D78fd01ff4f4340295a4f66e2ea54903c%26logoDark%3Dhttps%253A%252F%252Fmintcdn.com%252Fclaude-code%252Fc5r9_6tjPMzFdDDT%252Flogo%252Fdark.svg%253Ffit%253Dmax%2526auto%253Dformat%2526n%253Dc5r9_6tjPMzFdDDT%2526q%253D85%2526s%253D1298a0c3b3a1da603b190d0de0e31712%26primaryColor%3D%25230E0E0E%26lightColor%3D%2523D4A27F%26darkColor%3D%25230E0E0E%26backgroundLight%3D%2523FDFDF7%26backgroundDark%3D%252309090B&w=1200&q=100" /> <a href="https://code.claude.com/docs/en/hooks-guide"></a> </div> > Open `~/.claude/settings.json` and add a `Notification` hook. `setting.json` に `hooks` を追加。 ```json { "hooks": { "Notification": [ { "matcher": "idle_prompt", "hooks": [{ "type": "command", "command": "~/.claude/hooks/notify.sh" }] } ], "Stop": [ { "hooks": [{ "type": "command", "command": "~/.claude/hooks/notify.sh" }] } ] } } ``` `~/.claude/hooks/notify.sh` は以下のようにする。 ```bash #!/bin/bash notify() { local title="$1" local body="$2" # >dev/tty に出力しないとcopilotにインターセプトされて端末まで伝わらないので注意 printf '\e]777;notify;%s;%s\a' "$title" "$body" >/dev/tty } INPUT=$(cat) EVENT=$(echo "$INPUT" | jq -r '.hook_event_name // "unknown"') case "$EVENT" in "Notification") TYPE=$(echo "$INPUT" | jq -r '.notification_type // ""') MSG=$(echo "$INPUT" | jq -r '.message // ""') [ "$TYPE" = "idle_prompt" ] && notify "Claude Code" "入力待ち: $MSG" ;; "Stop") MSG=$(echo "$INPUT" | jq -r '.last_assistant_message // ""' | cut -c1-50) notify "Claude Code" "応答完了: $MSG" ;; esac ``` > [!question] `TaskCompleted` と `SubagentStop` を含めないのは? > バックグラウンドで[[Claude Code]]が管理しているケースがほとんどであり、ユーザーが通知を受け取るメリットはない (ノイズになる) ため。 ## 関連情報 > [!caution] > 古い情報なので参考程度に。 - [[📜2025-06-25 Claude Codeの作業や回答が終わり人間待ちになったとき通知を表示する]] - [[📜2025-07-02 Claude Codeで人間が確認待ちの状態になっている場合に通知させる]] -