Codex のターン完了をデスクトップ通知や Slack に送る notify 設定と tui.notifications
Codex CLI が応答を終えたときに外部プログラムを起動する config.toml の notify と、ターミナル通知を制御する tui.notifications の書き方を解説します。渡される JSON の中身、通知の種類の絞り込み、macOS と Linux のスクリプト例をまとめます。
Codex に長めのタスクを任せて別の作業をしていると、終わったことに気づかず放置してしまいます。Codex CLI には、ターン完了時に 外部プログラムを起動する notify と、ターミナル自体の通知を制御する tui.notifications の 2 つの仕組みがあります。
結論として、notify = ["python3", "/path/to/notify.py"] のように argv 配列を書くと、ターン完了ごとに JSON を 1 引数として受け取るプログラムが起動します。デスクトップ通知でも Slack の Webhook でも、そのプログラムで好きな処理ができます。
KEY POINT
この記事で分かること
notifyの書き方と、プログラムに渡される JSON のフィールドtui.notificationsで通知の種類・条件・方式を絞る方法- macOS / Linux でデスクトップ通知を出すスクリプト例
notify:外部プログラムを起動する
~/.codex/config.toml に、起動するコマンドを配列で書きます。未設定なら無効です。
notify = ["python3", "/Users/you/.codex/notify.py"]
プログラムは JSON 文字列 1 つを引数として 受け取り、成功時は終了コード 0 を返します。渡される主なフィールドは次のとおりです。
| フィールド | 内容 |
|---|---|
type | イベント種別。現時点では agent-turn-complete |
thread-id | セッション(スレッド)の識別子 |
turn-id | ターンの識別子 |
cwd | 作業ディレクトリ |
input-messages | そのターンでユーザーが送ったメッセージ |
last-assistant-message | アシスタントの最後の出力テキスト |
用語解説
ターン: あなたが 1 回指示を送ってから、Codex が応答を返し終えるまでの単位です。途中でコマンド実行や承認が挟まっても 1 ターンです。notify はこの単位の終わりで発火します。
macOS の例
terminal-notifier を使った例です(Homebrew でインストールできます)。
#!/usr/bin/env python3
import json, subprocess, sys
payload = json.loads(sys.argv[1])
if payload.get("type") != "agent-turn-complete":
sys.exit(0)
title = "Codex: ターン完了"
body = (payload.get("last-assistant-message") or "")[:120]
subprocess.run(["terminal-notifier", "-title", title, "-message", body, "-group", payload.get("thread-id", "")])
Linux の例
notify-send を使う最小構成なら、スクリプトなしで直接指定もできます。サンプル設定にもこの形が示されています。
notify = ["notify-send", "Codex"]
この場合、JSON 文字列がそのまま通知本文として渡されます。本文を整えたい場合は上のようなスクリプトを挟んでください。
Slack に送る
Slack の Incoming Webhook に POST するなら、スクリプトの中で last-assistant-message を要約して送ります。Webhook URL は環境変数から読むようにし、config.toml に直接書かないでください。
last-assistant-message には作業内容が含まれる
通知本文に last-assistant-message をそのまま載せると、ファイル名やコードの断片が外部サービスに送られます。Slack などに送る場合は、先頭の数十文字に切り詰めるか、「完了」の一言だけにするのが安全です。
tui.notifications:ターミナル通知を制御する
ターミナル自体が出す通知は [tui] セクションで制御します。
[tui]
# true / false、または種類のリスト
notifications = ["agent-turn-complete", "approval-requested"]
# unfocused(既定)| always
notification_condition = "unfocused"
# auto(既定)| osc9 | bel
notification_method = "auto"
| キー | 値 | 意味 |
|---|---|---|
notifications | true / false / 種類のリスト | 既定は有効。agent-turn-complete と approval-requested で絞れる |
notification_condition | unfocused / always | 既定はターミナルが非アクティブのときだけ |
notification_method | auto / osc9 / bel | auto は端末が対応していれば OSC 9、そうでなければ BEL(\x07) |
notify と tui.notifications は独立しています。外部通知だけにしたいなら notifications = false にし、承認待ちにも気づきたいならリストに approval-requested を残します。
Codex の設定ファイル全体の構造は親記事の config.toml でモデル・推論の深さ・プロファイルを切り替える を参照してください。承認が必要になる条件は approval mode と sandbox 設定の違い で扱っています。
まとめ
notifyは argv 配列。ターン完了(agent-turn-complete)のたびに JSON 1 引数でプログラムを起動する- JSON には
type、thread-id、turn-id、cwd、input-messages、last-assistant-messageが入る - macOS は
terminal-notifier、Linux はnotify-sendを直接指定するだけでも動く - 外部サービスに送るときは本文を切り詰め、Webhook URL は環境変数に置く
- ターミナル通知は
[tui]のnotifications/notification_condition/notification_methodで別に制御する
よくある質問
- notify にはどんなイベントが渡されますか?
- 現時点で対応しているのは agent-turn-complete(ターン完了)です。type、thread-id、turn-id、cwd、input-messages、last-assistant-message を含む JSON が 1 つの引数として渡されます。
- ターミナルの通知だけ止めて notify は使えますか?
- はい。[tui] の notifications = false でターミナル通知を止め、notify は別に設定できます。
- IDE 拡張でも notify は使えますか?
- 公式の通知ページによると、接続先の Codex ホスト側で notify を設定します。
参考にした一次情報
この記事は公式ドキュメントを基に AI が下書きを作成し、運営者が内容を確認して公開しています。誤りを見つけた場合は お問い合わせからお知らせください。