Claude Code の通知挙動と切り分け(スマホ純正プッシュ/tmux+iTerm2 のデスクトップ通知フォールバック)
開発環境
ツール設定
知識
判断
運用
ターミナル常駐型のコーディングエージェント(Claude Code 等)の通知は、スマホへの純正プッシュとデスクトップ通知で挙動が分かれ、それぞれハマりどころがある。設定が全部正しく見えても通知が来ない時の切り分けと、堅実な落とし所をまとめる。
スマホ純正プッシュ(Remote Control)
- 純正プッシュには2系統ある。権限・入力待ちの通知(inputNeeded 系設定)は比較的確実に飛ぶが、タスク完了通知(agentPush 系=「エージェントが判断して送る」)はベストエフォート。
- 「エージェントが判断して送る」の正体は、裏で動く自動送信エンジンではなく、モデルが通知ツール(PushNotification 相当)を呼ぶかどうかを毎回判断しているだけ。通知ツール自体が「不要な通知は送るな、短い完了や注視中は送るな、離席していそうな時だけ送れ」と保守的に設計されているため、短いタスクや端末フォーカス中に完了プッシュが出ないのは正常動作。
- 端末にフォーカスしている間はモバイルプッシュをスキップする(離席判定)。画面ロック状態を presence ファイル(新しめのバージョンの該当環境変数)で渡すと離席判定が安定する。
- 過去には「送信は成功応答を返すのに端末に届かない」配信不具合が報告されていたが、環境やバージョンによっては解消していることがある。実際に届くかは「長めのタスク+離席状態」で実機テストして判断する。毎回確実に届かせる決定論的な設定は無いので、毎回必要ならフック側(外部プッシュサービスへ送る等)で代替するしかない。
デスクトップ通知(特に tmux + iTerm2)
- 端末ネイティブのデスクトップ通知はエスケープシーケンス経由で実現され、tmux の中だと既定で外側端末に届かない。tmux のパススルー許可を有効化し、ホスト端末側でもエスケープシーケンス由来の通知を許可する必要がある。
- ただし tmux + iTerm2 では、tmux パススルー・iTerm2 のエスケープシーケンス通知許可・macOS のアプリ通知許可をすべて正しく有効にしても、純正デスクトップ通知が出ないことがある(環境依存でハマりやすい)。深追いせず、OS の通知 API を直接叩くローカル通知ツール(terminal-notifier 等)を完了/入力待ちフックに使ってフォールバックするのが堅実。
- 重要な切り分け: macOS の通知許可は「アプリ単位」。OS 直叩きのローカル通知ツールが通知を出せても、それは端末アプリ(iTerm2 等)自身の通知許可を保証しない。両者は別アプリとして別々に許可される。
- 端末アプリ側の通知設定は多くがプロファイル/セッション単位で、デフォルトプロファイルの変更は既に開いている既存セッションには効かない。今動いているセッションのプロファイルに設定が入っているかを確認する。
切り分け手順
- OS 直叩きツールで通知が出る → OS の通知系は生きている。端末ネイティブ通知だけ出ないなら、原因は端末アプリ側(プロファイル単位の通知設定、端末アプリの OS 許可、tmux パススルー)に絞れる。
- 「以前は出ていた」が「設定変更後に出ない」場合、以前の通知が OS 直叩きツール由来で端末アプリの通知経路を一切通っていなかった、というケースがある。動いていた経路と新しく使おうとしている経路が別物でないかを必ず確認する。
設計判断
- 通知は「デスクトップ=OS 直叩きフックで確実に出す」「スマホ=純正プッシュ(ベストエフォート、離席時の長タスク向け)」と分担させると、環境依存のハマりを避けつつ実用になる。デスクトップ純正通知に固執して環境設定を延々と詰めるより、確実なフォールバックに切り替える判断が早い。