目次
TL;DR
- Codex には「under development」(開発中)ステータスの Hooks 機能があり、
codex features enable codex_hooksで有効化できる - 対応イベントは
SessionStart/UserPromptSubmit/Stopの3つ
はじめに
本記事の内容は Codex v0.115.0(2026年3月時点)で検証しています。開発中の機能のため、今後のバージョンで仕様が変更される可能性があります。
Codex には公式にはまだ Hooks 機能がありません。公式ドキュメントにも記載はなく、Changelog に「experimental hooks engine」という一行が載っている程度です。
ところが、実は「under development」ステータスで すでに動く Hooks が実装されています。codex features list を実行してみたところ codex_hooks というフィーチャーフラグが見つかり、有効化すると実際にフックが発火することを確認しました。
ただし設定の JSON 構造や対応イベントの詳細はどこにも書かれていないため、OSS として公開されている openai/codex リポジトリ(Apache License 2.0)の Rust ソースコード(codex-rs/hooks/)を読んで仕様を特定しました。本記事ではその調査結果をまとめます。
1. 発見と有効化
フィーチャーフラグの確認
Codex には codex features list というフィーチャーフラグの一覧を表示するコマンドがあります。Hooks の存在を知ったのもこのコマンドがきっかけで、実行してみたところ codex_hooks が「under development」として表示されました。
$ codex features list
codex_hooks under development false
デフォルトは無効です。
有効化
# config.toml に永続化される
codex features enable codex_hooks
有効化すると起動時に以下の警告が表示されます。
⚠ Under-development features enabled: codex_hooks. Under-development features are incomplete
and may behave unpredictably.
2. 設定ファイル
ファイルパスと形式
| 項目 | 値 |
|---|---|
| グローバル設定 | ~/.codex/hooks.json |
| プロジェクト設定 | <project>/.codex/hooks.json |
| 形式 | JSON |
Codex の一般設定は ~/.codex/config.toml(TOML 形式)ですが、Hooks 設定は hooks.json(JSON 形式) という別ファイルです。config.toml に hooks を書いても読まれません。
~/.codex/
├── config.toml ← 一般設定・feature flags
└── hooks.json ← hooks 設定(JSON)
JSON 構造
構造がやや独特で、イベント名の配列にハンドラを直接並べるのではなく、一段ラッパーを挟む必要があります。ソースコード(codex-rs/hooks/src/engine/config.rs)では MatcherGroup という構造体で定義されており、matcher(正規表現フィルタ)と hooks(ハンドラ配列)を持ちます。
hooks.<EventName>[].matcher → フィルタ条件(省略可)
hooks.<EventName>[].hooks[] → 実行するハンドラの配列
具体的な JSON は以下のようになります。
{
"hooks": {
"SessionStart": [
{
"hooks": [
{
"type": "command",
"command": "echo 'session started'",
"timeout": 10
}
]
}
],
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "echo 'session stopped'",
"timeout": 10
}
]
}
]
}
}
timeout はオプションで、デフォルトは600秒です。
動かない書き方
この入れ子構造を知らずに、イベント配列に直接ハンドラを並べる書き方をすると動きません。
{
"hooks": {
"SessionStart": [
{
"type": "command",
"command": "echo 'session started'"
}
]
}
}
実際にこの書き方で動かず、ソースコードを読んで入れ子が必要なことに気づきました。公式ドキュメントがないため、ソースコードが唯一の正確な情報源です。
3. 対応イベント
サポートされている3イベント
| イベント | 発火タイミング |
|---|---|
SessionStart | セッション開始・再開時 |
UserPromptSubmit | ユーザーがプロンプトを送信した時 |
Stop | エージェント応答完了時 |
ツール実行やサブエージェント関連のイベントは未実装です。
ハンドラタイプ
ハンドラタイプは「フックが発火したときに何を実行するか」の種類です。ソースコード(codex-rs/hooks/src/engine/config.rs)上は command・prompt・agent の3タイプが定義されていますが、現時点で実際に動作するのは command(シェルコマンド実行)のみです。
| タイプ | 内容 | 状態 |
|---|---|---|
command | シェルコマンドを実行する | 動作する |
prompt | エージェントのコンテキストにプロンプトを注入する | 未実装("skipping prompt hook" とログに表示される) |
agent | 別のエージェントを起動して処理させる | 未実装 |
async: true(非同期実行)も定義はありますが未実装です。prompt が使えるようになれば「プロンプト送信時に毎回追加の指示を注入する」、agent なら「応答完了後に別のエージェントでレビューを走らせる」といった使い方が考えられますが、現状は「イベント発火 → シェルコマンド実行」の一択です。
stdin に渡される JSON ペイロード
hook コマンドは $SHELL -l -c "<command>" で実行され、stdin に JSON ペイロード が渡されます。
{
"session_id": "019d07b0-...",
"cwd": "/Users/user/project",
"hook_event_name": "SessionStart",
"model": "o3-pro",
"permission_mode": "default",
"source": "startup",
"transcript_path": null
}
| フィールド | 説明 |
|---|---|
session_id | セッションID(UUID v7) |
cwd | 作業ディレクトリ |
hook_event_name | イベント名 |
model | 使用中のモデル |
permission_mode | 承認ポリシー |
source | 開始種別(SessionStart のみ) |
transcript_path | 会話履歴ファイルのパス(現状 null) |
イベントごとに追加されるフィールドがあります。
| フィールド | イベント | 説明 |
|---|---|---|
source | SessionStart | startup / resume / clear |
prompt | UserPromptSubmit | ユーザー入力テキスト |
turn_id | UserPromptSubmit / Stop | 会話ターンの識別子 |
last_assistant_message | Stop | 最後のアシスタント応答 |
stop_hook_active | Stop | Stop フックがアクティブか |
session_id、cwd、hook_event_name、model、permission_mode は全イベント共通です。
4. 活用事例: 複数エージェントセッションの一元管理
自作のデスクトップアプリで、AI コーディングエージェントの Hooks を利用して複数セッションの状態を一元管理しています。SessionStart / Stop イベントを受け取ってセッション一覧を更新する仕組みです。
Codex でもこの Hooks が使えることがわかったので、同じアプリで Codex のセッションも管理できるように拡張しました。
hooks.json で何を設定しているか
hooks.json にイベントとコマンドを書いておくと、そのイベントが発火したときにコマンドが実行されます。逆に言うと、hooks.json が空だったり存在しなければ、フィーチャーフラグを有効にしても何も起きません。
以下の設定例では、全イベントで同じことをしています。stdin に渡される JSON ペイロードを $(cat) で読み取り、curl で自作アプリの API にそのまま転送するだけです。
{
"hooks": {
"SessionStart": [
{
"hooks": [
{
"type": "command",
"command": "curl -s -X POST http://localhost:3000/api/hook -H 'Content-Type: application/json' -d \"$(cat)\"",
"timeout": 10
}
]
}
],
"UserPromptSubmit": [
{
"hooks": [
{
"type": "command",
"command": "curl -s -X POST http://localhost:3000/api/hook -H 'Content-Type: application/json' -d \"$(cat)\"",
"timeout": 10
}
]
}
],
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "curl -s -X POST http://localhost:3000/api/hook -H 'Content-Type: application/json' -d \"$(cat)\"",
"timeout": 10
}
]
}
]
}
}
受け取る側のアプリは、JSON 内の session_id と hook_event_name を見てセッションの状態を更新します。この仕組みは他のツールの Hooks とも共通なので、同じ API エンドポイントで複数のエージェントツールを一元管理できています。
5. 制限事項と今後の展望
現時点の制限
- 開発中ステータス: API が変更される可能性がある
- イベント粒度が粗い: ツール実行単位のフックがないため、作業中のリアルタイム進捗は取得できない
- command タイプのみ:
prompt、agent、asyncタイプのハンドラは未サポート - 公式ドキュメントがない: ソースコードを読まないと正確な仕様がわからない
OSS ならではの利点
制限が多い一方で、Codex は Apache License 2.0 の OSS であるため、Hooks の実装を直接ソースコードで確認できます。本記事の内容も codex-rs/hooks/src/ のソースを読んで特定したものです。仕様が不明な場合にソースコードが読めるのは大きな安心感があります。
今後の可能性
GitHub の Discussion #2150 では、Hooks 機能のリクエストスレッドに多数のコメントが寄せられており、コミュニティの関心の高さがうかがえます。今後ツールイベントの追加やハンドラタイプの拡充が期待されます。
まとめ
Codex の Hooks はまだ開発中で機能も限定的ですが、フィーチャーフラグを有効にすれば今すぐ使えます。セッションの開始・終了を検知してコマンドを実行する程度の用途であれば、十分活用できそうです。
参考
- Codex Changelog - hooks engine 追加のアナウンス
- openai/codex - GitHub - ソースコード(Apache License 2.0)
- Discussion #2150: Hook would be a great feature - コミュニティのリクエストスレッド