はじめに
Codexに作業をお願いしたあと、「今どこまで進んでいるかな?」と気になることはありませんか?
特に知りたかったのが、承認待ちや入力待ちになったタイミングです。PCの前を離れていても、スマホで気づけるとうれしいですよね。
そこで今回は、Codexに相談しながら、Discordへ通知を送る codex-alert というツールを作ってみました。
最初は「通知が届けば便利そう」というところからのスタートでしたが、途中で「ほかのプロジェクトでも使いたい」とお願いして、共通で使えるコマンドラインツールになりました。
この記事では、実際にどんな指示を出して、どんなものができたのかを紹介します。
最初にCodexへ伝えたこと
最初に用意したのは、「Discord通知機能 実装指示書」というMarkdownファイルでした。
「こういうときに通知してほしい」という希望に加えて、Webhook URLの扱いや、通知に失敗したときの動作も書いておきました。
実際の指示書はもう少し長いので、要点をまとめるとこんな内容です。
Codexやローカル開発環境の重要イベントをDiscordへ通知し、
スマートフォンから把握できる仕組みを作ってください。
特に知りたい状態は、承認待ち、入力待ち、認証待ち、完了、エラーです。
実装前に、現在のCodex環境と利用可能なHook・Event機能を調査し、
どの状態を検知できるのか報告してください。
取得できないイベントは、推測で実装せず制約と代替案を説明してください。
ログやターミナル出力の文字列解析を無断で採用しないでください。
通知先にはDiscord Incoming Webhookを使ってください。
Webhook URLをコード、Git、ログ、通知へ出さないでください。
通知失敗でCodex本体の処理を止めないでください。
タイムアウト、必要最低限の再試行、重複通知の抑止を考慮してください。
Codexイベントとは独立して通知を試せるCLIと、READMEを用意してください。
ここで最初に確認したかったのは、「そもそもCodexの承認待ちを検知できるのかな?」ということでした。
Discordにメッセージを送れても、知りたいタイミングで呼び出せないと困ります。そのため、いきなりコードを書いてもらう前に、取得できるイベントを調べてもらうようにしました。
できあがったのは、こんなツール
codex-alert は、Python 3.11以上で動く通知ツールです。実行時に追加のPythonパッケージを入れる必要はありません。
Discordへの投稿にはIncoming Webhookを使っています。全体の流れはこんな感じです。
Codexのイベント
↓
プロジェクトの .codex/hooks.json
↓
codex-alert hook
↓
イベントを通知データへ変換
↓
Discord Incoming Webhook
↓
Discordの通知チャンネル
Hookは、特定のイベントが起きたときにプログラムを呼び出す仕組みです。今回はそのタイミングで通知プログラムが起動するので、監視用のサーバーを常駐させる必要はありません。
Discordには、通知の種類やプロジェクト名、タスク名などを、Embedというカード形式で送ります。承認待ちのときなどに、自分へメンションする設定も用意しました。
スマホで気づけるようにするには、DiscordアプリとOS側の通知設定も確認しておきます。チャンネルに投稿できることと、スマホにPush通知が届くことは、分けて確認するのがよさそうです。
どんなタイミングで通知できる?
今回のバージョンで対応したのは、次のイベントです。
| 通知したい状態 | 実装で使うイベント | 対応範囲 |
|---|---|---|
| 承認待ち | PermissionRequest |
イベントを受け取ると通知 |
| 入力待ち | PreToolUse |
request_user_input 使用時に通知 |
| ツール実行エラー | PostToolUse |
構造化レスポンスの失敗情報を判定 |
| ターン終了 | Stop |
ターン終了を通知 |
| ターン開始 | UserPromptSubmit |
設定で有効にした場合に通知 |
| 認証待ち | 専用の自動連携なし | CLIなどから明示的に通知 |
ただ、最初にお願いした状態を、すべて自動で検知できるようになったわけではありません。
たとえば、completed が表すのは「Codexのターンが終了した」ということです。依頼した作業がすべて完成したかどうかは、Codexの回答や実装内容を確認する必要があります。
入力待ちも、request_user_input を使う場面が対象です。Codexが普通の文章で「どうしますか?」と質問して終わるケースまでは、入力待ちとして判定していません。
認証待ちは、必要なタイミングでCLIなどから通知を送れるようにしています。自動検知については、今後の課題として残っています。
次に出てきた疑問:「他のプロジェクトでも使える?」
通知処理ができたところで、「これ、別のプロジェクトでも使いたいな」と思い、Codexに質問しました。
使い方的には、.codexに配置されているhooks.jsonを他のプロジェクトへコピペしたら他のプロジェクトでも使い回せますか?
それとも別の手法で他のプロジェクトで使用すべきでしょうか。
確認すると、最初の構成は、Hookからリポジトリ内の scripts/codex-hook を実行する形でした。
つまり、hooks.json だけをコピーしても動かず、通知プログラム本体も一緒に持っていく必要があったんですね。
それでも使えますが、プロジェクトが増えると、修正のたびにあちこちを更新することになりそうです。
そこで、もう少し簡単に使い回せるように、改修案を出してもらいました。
提案の中で採用したのが、本体を一度インストールして、使いたいプロジェクトで有効化する方式です。
方針が決まったので、次のようにお願いしました。
では、提案していただいた方針で開発をお願いしたいです。
開発前にRepositoryに修正がある場合はGitへコミットをお願いします。(Zipファイル以外)
こんなふうに、まず動くものを作ってもらってから、使い方を相談して改修していく流れになりました。最初から細かい完成形まで決めておかなくても、途中で相談しながら形にできるのは助かります。
使い方も、だいぶシンプルになった
改修後は、通知プログラムを次の場所にインストールして使います。
~/.local/bin/codex-alert
各プロジェクトには .codex/hooks.json を作成し、この共通実行ファイルを呼び出します。
Webhook URLもユーザー共通設定へ保存するため、同じ通知先を使うならプロジェクトごとに入力する必要はありません。
最初に一度だけセットアップ
作成した codex-alert のソースがあるディレクトリで、次のコマンドを実行する形にしました。
python3 scripts/install
~/.local/bin/codex-alert configure
configure でWebhook URLを入力すると、既定では以下へ保存されます。
~/.config/codex-alert/config.env
あとは使いたいプロジェクトで有効化
cd /path/to/project
~/.local/bin/codex-alert enable
~/.local/bin/codex-alert doctor
/path/to/project は、通知を使いたいGitプロジェクトのパスに置き換えます。enable でHook設定を追加し、doctor でインストールや設定の状態を確認できます。
同じコマンドを繰り返してもHookが増え続けないようにしたり、既存設定のバックアップを作ったりと、導入まわりも整えてもらいました。
設定したら、対象プロジェクトでCodexの新しいセッションを開始し、Hookの内容を確認します。開発時に使ったCLIでは、/hooks から定義を確認して信頼する流れでした。この操作は、利用するCodexのバージョンや環境に合わせて確認してください。
生成される呼び出しは次の形です。
/bin/sh -c 'exec "$HOME/.local/bin/codex-alert" hook'
通知だけを試す
# Discordへ送信せず、通知データを確認
~/.local/bin/codex-alert test --dry-run
# Discordへテスト通知を送る
~/.local/bin/codex-alert test
通知が届かないときも、まずこれを試せば「Discordへの送信設定かな? それともHook側かな?」と確認しやすくなります。
自動通知を止める
~/.local/bin/codex-alert disable
設定変更後は、Codexで新しいセッションを開始します。
普段使うことを考えて、こんなところも
せっかく作るなら、通知が多すぎたり、送信エラーで本来の作業が止まったりするのは避けたいところです。そこで、次のような処理も入れてもらいました。
- HTTPタイムアウトと、回数を制限した再試行
- HTTP 429の待機時間を考慮した送信処理
- SQLiteを使った重要イベントの重複抑止
- 意図しない
@everyoneやロールへのメンションの抑制 - 通知本文などに含まれるWebhook URLのマスキング
- Hook内の通知失敗がCodexの処理を妨げないエラー処理
自動通知では、Codexのプロンプト、ツール入力、ツール出力、最終回答をそのままDiscordへ転送しません。ツールエラーも、ツール名と固定の概要を通知する実装です。
タスク名や実行環境などをプロジェクトごとに変更したい場合は、.codex/codex-alert.env で共通設定を上書きできます。
CODEX_ALERT_TASK=My Project
CODEX_ALERT_NOTIFY_START=false
テストも用意してもらいました
開発完了時には、58件の自動テストが成功しました。
通知の内容に加えて、実際に使い始めるときの動きもテストしています。
- 既存Hookと追加Hookの共存
-
enable再実行時の重複防止 -
disable後に他のHookが残ること - 不正な既存JSONを変更しないこと
- 設定の優先順位と、共通設定ファイルの権限
- 設定表示にWebhook URLが出ないこと
- ビルド済み実行ファイルのHook入力処理
一時ディレクトリへのインストールから、別の一時Gitプロジェクトでの有効化、生成されたHookコマンドの実行まで通すテストも追加しました。
この自動テストでは、Discordへの実送信は行っていません。手元のDiscordやスマホまで通知が届くかどうかは、先ほどの test コマンドで別途確認する形です。
検証用コマンドはREADMEに残しています。
PYTHONPATH=src python3 -m unittest discover -s tests -v
python3 -m compileall -q src tests scripts
python3 scripts/build
python3 dist/codex-alert.pyz notify completed --dry-run
作ってみて感じたこと
今回、指示に入れてよかったなと思ったのは、「どう使いたいか」と「うまくいかなかったときにどうしてほしいか」です。
「承認待ちを知りたい」と伝えたことで、まずイベントを取得できるか調べるところから始められました。「通知に失敗しても作業は止めないでほしい」というお願いも、エラー処理に反映されています。
そして、途中で「ほかのプロジェクトでも使える?」と聞いたことで、インストールして enable するだけで使い回せる形まで進められました。
最初はDiscordに通知を送る仕組みが欲しかっただけでしたが、設定・有効化・無効化・診断までまとまった小さなツールになったのは、うれしいところです。
これからCodexで何か作ってみたい方も、まずは「こんな場面で、こんなことができたら便利なんだけど」という相談から始めてみると、作りたいものを整理しやすいかもしれません。
今回の開発の流れが、ちょっとした不便をツールにする際の参考になればうれしいです。
おまけ:それ、スマホアプリでよくない?
ここまで読んでくださった方に、最後にひとつ。
デスクトップ版のCodexとスマホアプリを連携させて、スマホから操作できる環境なら、今回の「PCから離れていても状況を知りたい」という目的は、そちらでかなり満たせます。
……あれ、この通知アプリ、出番がほぼないのでは?
58件のテストまで通して、なかなか立派な遠回りをしてしまいました。
でも、今回使いたかったのは Codex CLI なんです。
「デスクトップアプリが便利なのはわかる。でも、どうしてもターミナルで作業したい」
そんな人に向けたのが、この codex-alert です。CLIでの作業を続けながら、承認待ちやターン終了をDiscordで知りたいときには、ちゃんと出番があります。なお、Discordから承認や操作を返す機能はなく、あくまで「呼ばれたことに気づく」ためのツールです。
万人向けの便利アプリではありませんが、CLIを使いたい気持ちには寄り添えた気がします。
便利なアプリがある。それでもCLIを使いたい。そして、画面はずっと見ていたくない。
そんな、ちょっとわがままなターミナル派の方へどうぞ。