フック
フック
Codex のライフサイクル中に決定論的なスクリプトを実行します
Hooks は Codex の拡張フレームワークです。エージェントループ中にスクリプトや MCP ツールを実行でき、次のような機能を実現できます。
- チャットをカスタムのログ/分析エンジンへ送信する
- チームのプロンプトをスキャンし、API key の誤貼り付けを防ぐ
- チャットを要約し、永続的なメモリを自動作成する
- チャットのターンが停止したときにカスタム検証を実行し、標準を適用する
- 特定のディレクトリにいるときのプロンプトをカスタマイズする
留意すべき実行時の動作は次のとおりです。
- 複数のファイルで一致したフックはすべて実行されます。
- 同じイベントに一致する複数のコマンドフックは同時に起動されるため、 あるフックが別の一致するフックの起動を阻止することはできません。
- 管理対象外のフックは、実行前にレビューして信頼する必要があります。
フックは会話中のさまざまなタイミングで実行されます。
| タイミング | フック |
|---|---|
| ターン中 | PreToolUse, PermissionRequest, PostToolUse, PreCompact, PostCompact, UserPromptSubmit, SubagentStop, Stop |
| アクティブなターンを中断したとき | Interrupt(サブエージェントでは実行されません) |
| セッションまたはサブエージェントの開始時 | SessionStart, SubagentStart |
| メインスレッドの終了時 | SessionEnd(サブエージェントでは実行されません) |
Codex がフックを検索する場所
Codex は、アクティブな設定レイヤーの隣にある次のいずれかの形式からフックを検出します。
hooks.jsonconfig.toml内のインライン[hooks]テーブル
インストール済みのプラグインも、プラグインのマニフェストまたはデフォルトの
hooks/hooks.json ファイルを通じてライフサイクル設定を同梱できます。プラグインの
パッケージ化ルールについては、プラグインを構築するを参照してください。
実際には、特に有用な場所は次の 4 つです。
~/.codex/hooks.json~/.codex/config.toml<repo>/.codex/hooks.json<repo>/.codex/config.toml
フックのソースが複数ある場合、Codex は一致するフックをすべて読み込みます。
優先順位の高い設定レイヤーが、優先順位の低いレイヤーのフックを置き換えることはありません。
1 つのレイヤーに hooks.json とインラインの [hooks] の両方が含まれる場合、Codex は
両者をマージし、起動時に警告します。レイヤーごとにいずれか一方の表現を使用してください。
Codex は、有効なプラグインに同梱されたフックも検出できます。プラグイン同梱の フックは、ほかのフックソースとともに読み込まれ、ほかの管理対象外フックと同じ 信頼レビューのフローを使用します。
プロジェクトローカルのフックは、プロジェクトの .codex/ レイヤーが信頼されている場合にのみ読み込まれます。
信頼されていないプロジェクトでも、Codex はユーザーおよびシステムのフックを、それぞれの
アクティブな設定レイヤーから引き続き読み込みます。
フックをレビューして信頼する
Codex は、実行可能なフックを決定する前に、設定済みのフックを一覧表示します。 管理対象外のフックを実行するには、正確なフック定義をレビューして信頼する必要があります。 Codex はフックの現在のハッシュに対して信頼を記録するため、新規または変更された フックはレビュー対象としてマークされ、信頼されるまでスキップされます。
CLI で /hooks を使用すると、フックのソースの確認、新規または変更されたフックのレビュー、
フックの信頼、管理対象外フックの個別無効化を行えます。起動時にレビューが必要な
フックがある場合、Codex は /hooks を開くよう促す警告を表示します。
システム、MDM、クラウド、または requirements.toml ソースからの管理対象フックは、
管理対象としてマークされ、ポリシーによって信頼されます。ユーザーのフックブラウザからは無効化できません。
Codex の外部ですでにフックソースを検証している一回限りの自動化では、
--dangerously-bypass-hook-trust を渡すと、その呼び出しに限り、保存済みのフック信頼を要求せずに
有効なフックを実行できます。
設定の構造
フックは次の 3 つのレベルで構成されます。
PreToolUse、PostToolUse、PreCompact、SubagentStart、Stopなどのフックイベント- そのイベントが一致する条件を決めるマッチャーグループ
- マッチャーグループが一致したときに実行される 1 つ以上のフックハンドラー
{
"description": "Optional lifecycle hooks for this workspace.",
"hooks": {
"SessionStart": [
{
"matcher": "startup|resume",
"hooks": [
{
"type": "command",
"command": "python3 ~/.codex/hooks/session_start.py",
"statusMessage": "Loading session notes",
"additionalContextLimit": 5000
}
]
}
],
"SessionEnd": [
{
"hooks": [
{
"type": "command",
"command": "python3 ~/.codex/hooks/session_end.py",
"timeout": 3
}
]
}
],
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "/usr/bin/python3 \"$(git rev-parse --show-toplevel)/.codex/hooks/pre_tool_use_policy.py\"",
"statusMessage": "Checking Bash command"
}
]
}
],
"PermissionRequest": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "/usr/bin/python3 \"$(git rev-parse --show-toplevel)/.codex/hooks/permission_request.py\"",
"statusMessage": "Checking approval request"
}
]
}
],
"PostToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "/usr/bin/python3 \"$(git rev-parse --show-toplevel)/.codex/hooks/post_tool_use_review.py\"",
"statusMessage": "Reviewing Bash output"
}
]
}
],
"UserPromptSubmit": [
{
"hooks": [
{
"type": "command",
"command": "/usr/bin/python3 \"$(git rev-parse --show-toplevel)/.codex/hooks/user_prompt_submit_data_flywheel.py\""
}
]
}
],
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "/usr/bin/python3 \"$(git rev-parse --show-toplevel)/.codex/hooks/stop_continue.py\"",
"timeout": 30
}
]
}
]
}
}注意事項:
descriptionは、hooks.jsonファイル用の省略可能なトップレベルメタデータです。 実行されるフックには影響しません。timeoutの単位は秒です。timeoutを省略すると、ほとんどのフックで Codex は600秒を使用します。SessionEndとInterruptのデフォルトは1秒で、最大3秒をサポートします。
statusMessageは省略可能です。additionalContextLimitは、Codex が全文をディスクへ保存して短いプレビューを 代わりに送信するまでに、コマンドフックがモデルへ送信できるadditionalContextの量を設定します。 大きなフック出力を参照してください。commandWindowsは、Windows 専用の省略可能なコマンドオーバーライドです。TOML ではcommand_windowsまたはcommandWindowsを使用します。asyncをtrueに設定すると、コマンドフックをバックグラウンドで 実行できます。commandおよびmcp_toolハンドラーがサポートされています。promptおよびagentハンドラーは解析されますが、スキップされます。- コマンドは、セッションの
cwdを作業ディレクトリとして実行されます。 - リポジトリローカルのフックでは、
.codex/hooks/...のような相対パスを使用せず、git ルートを 基準に解決することを推奨します。Codex はサブディレクトリから起動される場合があり、 git ルートを基準にしたパスならフックの場所が安定します。
config.toml で同等のインライン TOML:
[[hooks.SessionStart]]
matcher = "^compact$"
[[hooks.SessionStart.hooks]]
type = "command"
command = '/usr/bin/python3 "$(git rev-parse --show-toplevel)/.codex/hooks/session_start.py"'
additionalContextLimit = 5000
[[hooks.PreToolUse]]
matcher = "^Bash$"
[[hooks.PreToolUse.hooks]]
type = "command"
command = '/usr/bin/python3 "$(git rev-parse --show-toplevel)/.codex/hooks/pre_tool_use_policy.py"'
timeout = 30
statusMessage = "Checking Bash command"
[[hooks.PostToolUse]]
matcher = "^Bash$"
[[hooks.PostToolUse.hooks]]
type = "command"
command = '/usr/bin/python3 "$(git rev-parse --show-toplevel)/.codex/hooks/post_tool_use_review.py"'
timeout = 30
statusMessage = "Reviewing Bash output"MCP ツールフック
MCP ツールフックを使用すると、ライフサイクルイベントから、すでに接続されている MCP サーバーのツールを呼び出せます。構造化された引数をツールへ直接送信し、コマンドフックと 同じ信頼レビューおよび出力契約を使用します。
MCP ツールフックを設定する
このフックは、Codex がファイルを書き込むか編集するたびに各パッチをスキャンするよう、
scanner MCP サーバーへ要求します。
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "mcp_tool",
"server": "scanner",
"tool": "scan_patch",
"input": { "patch": "${tool_input.command}" },
"timeout": 30,
"statusMessage": "Scanning edited files"
}
]
}
]
}
}| フィールド | 意味 |
|---|---|
type |
mcp_tool である必要があります。 |
server |
すでに接続されている MCP サーバーの名前。必須です。 |
tool |
そのサーバーが公開するツールの名前。必須です。 |
input |
引数テンプレートの省略可能な JSON オブジェクト。デフォルトは {} です。 |
timeout |
アクティブな実行の省略可能なタイムアウト(秒)。デフォルトは 600 です。 |
statusMessage |
フックの実行中に表示される省略可能なメッセージ。 |
フックイベントから引数を展開する
${field.nested} を使用して、フックイベントからドット区切りのフィールドを読み取ります。値全体を
占めるプレースホルダーは JSON 型を保持します。より大きな文字列内のプレースホルダーは
テキストとしてレンダリングされます。Codex はオブジェクトと配列を再帰的に展開します。
{"tool_input":{"file_path":"src/main.rs","count":3}} を含むイベントでは、
次の引数テンプレート:
{
"path": "${tool_input.file_path}",
"count": "${tool_input.count}",
"message": "Scanning ${tool_input.file_path}"
}は次のようになります。
{
"path": "src/main.rs",
"count": 3,
"message": "Scanning src/main.rs"
}実行とライフサイクル
- フックは既存の MCP 接続を使用します。サーバーの起動や再接続は行いません。
- ツールがブロックの決定を返すと、フックは操作をブロックできます。 エラー、存在しないサーバー、利用できないツールは操作をブロックしません。
- MCP ツールフックは同期的に実行されます。ツールの承認を要求したり、 ほかのフックをトリガーしたりしません。
- フックとサーバーのうち短い方のタイムアウトが適用されます。MCP elicitation の応答を待つ時間はタイムアウトに含まれません。
SessionStartフックは、MCP サーバーの準備が整う前に実行される場合があります。その場合、 セッションをブロックしません。SessionEndは MCP ツールフックをサポートしていません。
フックを無効にする
フックはデフォルトで有効です。config.toml で無効にするには、次のように設定します。
[features]
hooks = false標準の機能キーとして hooks を使用してください。codex_hooks も非推奨の
別名として引き続き機能します。管理者は、requirements.toml で [features].hooks = false を使用し、
同じ方法でフックを強制的に無効化できます。
requirements.toml からの管理対象フック
企業が管理する要件では、[hooks] の下にインラインでフックを定義することもできます。
管理者がフック設定を適用しつつ、実際のスクリプトを MDM などの
デバイス管理システム経由で配布する場合に便利です。ユーザーがローカルでフックを
無効化していても管理対象フックを適用するには、[hooks] とともに
[features].hooks = true を requirements.toml に固定します。管理者が管理するフックを許可したまま、
ユーザー、プロジェクト、セッション、プラグインのフックを無視するには、allow_managed_hooks_only = true を設定します。
allow_managed_hooks_only = true
[features]
hooks = true
[hooks]
managed_dir = "/enterprise/hooks"
windows_managed_dir = 'C:\enterprise\hooks'
[[hooks.PreToolUse]]
matcher = "^Bash$"
[[hooks.PreToolUse.hooks]]
type = "command"
command = "python3 /enterprise/hooks/pre_tool_use_policy.py"
command_windows = 'py -3 C:\enterprise\hooks\pre_tool_use_policy.py'
timeout = 30
statusMessage = "Checking managed Bash command"管理対象フックに関する注意事項:
managed_dirは macOS と Linux で使用されます。windows_managed_dirは Windows で使用されます。- Codex は
managed_dir内のスクリプトを配布しません。企業の ツールを使用して、別途インストールおよび更新する必要があります。 - 管理対象フックのコマンドでは、設定済みの管理対象ディレクトリ以下にある スクリプトの絶対パスを使用してください。
allow_managed_hooks_only = trueは、ユーザー、プロジェクト、セッション、 プラグインのソースからのフックをスキップしますが、requirements.tomlおよび ほかの管理対象設定レイヤーからの管理対象フックは引き続き読み込みます。
プラグイン同梱のフック
プラグインが有効な場合、Codex はそのプラグインからライフサイクルフックを読み込み、 ユーザー、プロジェクト、管理対象のフックとともに使用できます。
デフォルトでは、Codex はプラグインルート内の hooks/hooks.json を検索します。プラグインの
マニフェストでは、.codex-plugin/plugin.json の hooks エントリを使用して、このデフォルトを
上書きできます。マニフェストのエントリには、./ 接頭辞付きパス、
./ 接頭辞付きパスの配列、インラインのフックオブジェクト、またはインラインの
フックオブジェクトの配列を指定できます。
{
"name": "repo-policy",
"hooks": "./hooks/hooks.json"
}マニフェストのフックパスはプラグインルートを基準に解決され、そのルート内に
収まる必要があります。マニフェストで hooks が定義されている場合、Codex はデフォルトの
hooks/hooks.json の代わりに、それらのマニフェストエントリを使用します。
プラグインのフックコマンドには、次の環境変数が渡されます。
PLUGIN_ROOTは Codex 固有の拡張で、インストール済みの プラグインルートを指します。PLUGIN_DATAは Codex 固有の拡張で、プラグインの 書き込み可能なデータディレクトリを指します。- Codex は、既存のプラグインフックとの互換性のために、
CLAUDE_PLUGIN_ROOTとCLAUDE_PLUGIN_DATAも設定します。
プラグインのフックは、ほかのフックと同じイベントスキーマを使用します。プラグインを インストールまたは有効化しても、そのフックは自動的には信頼されません。Codex は、現在の フック定義をレビューして信頼するまで、プラグイン同梱のフックをスキップします。
マッチャーパターン
matcher フィールドは、フックが発火するタイミングを絞り込む正規表現文字列です。サポート対象イベントの
すべての発生に一致させるには、"*"、"" を使用するか、matcher を完全に省略します。
現在の Codex イベントのうち、matcher を使用するのは一部だけです。
| イベント | matcher が絞り込む対象 |
注意事項 |
|---|---|---|
PermissionRequest |
ツール名 | Bash、apply_patch*、MCP ツール名をサポートします |
PostToolUse |
ツール名 | ツールの対象範囲を参照してください |
PostCompact |
コンパクションのトリガー | 値は manual または auto です |
PreCompact |
コンパクションのトリガー | 値は manual または auto です |
PreToolUse |
ツール名 | ツールの対象範囲を参照してください |
SessionEnd |
終了理由 | 現在は other のみです |
SessionStart |
開始元 | 値は startup、resume、clear、compact です |
SubagentStart |
サブエージェントの種類 | 値は開始するサブエージェントによって異なります |
SubagentStop |
サブエージェントの種類 | 値は停止するサブエージェントによって異なります |
UserPromptSubmit |
サポート対象外 | 設定された matcher は、このイベントでは無視されます |
Stop |
サポート対象外 | 設定された matcher は、このイベントでは無視されます |
Interrupt |
サポート対象外 | 設定された matcher は、このイベントでは無視されます |
*apply_patch では、matcher の値に Edit または Write も使用できます。
例:
Bash^apply_patch$Edit|Writemcp__filesystem__read_filemcp__filesystem__.*startup|resume|clear|compactmanual|auto
ツールの対象範囲
PreToolUse と PostToolUse は、シェルや MCP の呼び出し以外も監視できます。ほとんどの
ローカル関数ツールは同じフックパスを使用するため、ツール名との照合、JSON 引数の検査、
さらに PreToolUse では呼び出しのブロックや書き換えが可能です。
| ツールパス | PreToolUse |
PostToolUse |
注意事項 |
|---|---|---|---|
| シェルコマンド | 対応 | 対応 | Bash として照合します。 |
統合 exec(exec_command) |
対応 | 対応 | Bash として照合します。後続の write_stdin ポーリングでは、元のコマンドが完了したときにその PostToolUse を返せます。 |
apply_patch |
対応 | 対応 | apply_patch、Edit、Write として照合します。 |
| MCP ツール | 対応 | 対応 | mcp__filesystem__read_file などの MCP ツール名と照合します。 |
| その他のローカル関数ツール | 対応 | 対応 | update_plan などの関数ツール名と照合します。spawn_agent は Agent にも一致します。 |
WebSearch などのホステッドツール |
非対応 | 非対応 | これらはローカル関数ツールのフックパスを使用しません。 |
write_stdin は、既存の統合 exec セッション用のトランスポートです。すでに
PreToolUse を通過したコマンドへ入力を送信したり、ポーリングしたりするときに、
PreToolUse を再実行することはありません。
一部の特殊なツールパスは、デフォルトのフックパスを使用しない場合があります。ツール フックは有用なガードレールですが、完全な強制境界ではないものとして扱ってください。
共通の入力フィールド
すべてのコマンドフックは、stdin で 1 つの JSON オブジェクトを受け取ります。
通常使用する共有フィールドは次のとおりです。
| フィールド | 型 | 意味 |
|---|---|---|
session_id |
string |
現在の Codex セッション ID。サブエージェントのフックでは親セッション ID を使用します。 |
transcript_path |
string | null |
セッショントランスクリプトファイルのパス(存在する場合) |
cwd |
string |
セッションの作業ディレクトリ |
hook_event_name |
string |
現在のフックイベント名 |
model |
string |
Codex 固有の拡張。アクティブなモデルスラッグ |
ターンスコープのフックでは、イベント固有の表に Codex 固有の拡張として turn_id が記載されています。
SessionStart、PreToolUse、PermissionRequest、PostToolUse、
UserPromptSubmit、SubagentStart、SubagentStop、Stop、Interrupt には、
現在の権限モードを default、acceptEdits、plan、
dontAsk、bypassPermissions のいずれかとして記述する permission_mode も含まれます。
transcript_path は便宜上チャットのトランスクリプトを指しますが、
トランスクリプトの形式はフック用の安定したインターフェースではなく、今後変更される可能性があります。
完全なワイヤーフォーマットが必要な場合は、スキーマを参照してください。
共通の出力フィールド
SessionStart、PreCompact、PostCompact、UserPromptSubmit、
SubagentStop、Stop は、次の共有 JSON フィールドをサポートします。SubagentStart は
systemMessage とフック固有のコンテキストに同じ形式を受け付けますが、
continue: false はサブエージェントを停止しません。
{
"continue": true,
"stopReason": "optional",
"systemMessage": "optional",
"suppressOutput": false
}| フィールド | 効果 |
|---|---|
continue |
false の場合、そのフック実行を停止済みとしてマークします |
stopReason |
停止理由として記録されます |
systemMessage |
UI またはイベントストリームに警告として表示されます |
suppressOutput |
現在は解析されますが、まだ実装されていません |
出力なしで終了 0 になると成功として扱われ、Codex は続行します。
PreToolUse と PermissionRequest は systemMessage をサポートしますが、continue、
stopReason、suppressOutput は、現在これらのイベントではサポートされていません。
PreToolUse フックがこれらの未サポートフィールドのいずれかを返すと、Codex は
そのフック実行を失敗としてマークしてエラーを報告し、ツール呼び出しを続行します。
PostToolUse は systemMessage、continue: false、stopReason をサポートします。
suppressOutput は解析されますが、現在このイベントではサポートされていません。
大きなフック出力
デフォルトでは、Codex はモデルに表示される各フック出力メッセージを約
2,500 トークンに制限します。フックがそれを超える出力を返すと、Codex は全文を
<temp_dir>/hook_outputs/<session_id>/<uuid>.txt 以下へ保存し、保存先ファイルのパスを含む
先頭と末尾のプレビューをモデルへ渡します。この動作を spilling と呼びます。Codex は
大きすぎる出力をディスクへ保存し、モデルに表示される短いプレビューで置き換えます。
ファイルへ書き込めない場合でも、モデルは切り詰められたプレビューを受け取ります。
additionalContext を返すコマンドフックでは、ハンドラーに
additionalContextLimit を設定し、おおよそのトークンしきい値をカスタマイズします。
{
"type": "command",
"command": "python3 ~/.codex/hooks/session_start.py",
"additionalContextLimit": 5000
}デフォルトの 2500 トークンのしきい値を使用するには、additionalContextLimit を省略します。
別のしきい値を選択するには正の整数を、ハンドラーの追加コンテキスト全体をモデルへ直接渡すには
0 を使用します。Codex は一致する各ハンドラーを個別に評価します。追加コンテキストを
生成できないイベントでは、Codex は additionalContextLimit を無視し、設定警告を報告します。
この設定は additionalContext にのみ適用されます。ツールのフィードバックと継続
プロンプトにはデフォルトの上限が維持されます。
大きすぎる出力はディスクへ書き込まれる可能性があるため、フック出力にシークレットや その他の機密データを含めないでください。
フックをバックグラウンドで実行する
デフォルトでは、Codex はコマンドフックが完了するまで待ってから、そのフックを
トリガーした操作を続行します。async を true に設定すると、Codex が続行している間に
コマンドフックをバックグラウンドで実行できます。
バックグラウンドフックを設定する
hooks.json のコマンドハンドラーに "async": true を追加します。
{
"hooks": {
"PostToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "python3 ~/.codex/hooks/post_tool_use.py",
"async": true,
"timeout": 120
}
]
}
]
}
}config.toml のインラインフックでは、async = true を設定します。
[[hooks.PostToolUse]]
matcher = "Bash"
[[hooks.PostToolUse.hooks]]
type = "command"
command = "python3 ~/.codex/hooks/post_tool_use.py"
async = true
timeout = 120バックグラウンドフックは、同期コマンドフックと同じ入力、マッチャー、信頼レビュー、
タイムアウト、大きな出力の処理を使用します。ほかのコマンドフックと同様に、
timeout の単位は秒で、デフォルトは 600 です。Interrupt フックはバックグラウンド実行時もデフォルトが 1 秒、最大が 3 秒です。
バックグラウンドフックの実行方法
バックグラウンドフックが完了すると、Codex は会話内の次の安全なタイミングで、 サポートされている情報出力を渡します。
- ターンが進行中の場合、Codex は現在のモデルリクエストとツール呼び出しが 完了するまで待ち、そのターンの次のモデルリクエストで出力を利用可能にします。
- ターンが進行中でない場合、Codex は次のユーザーターンまで待ちます。 バックグラウンドフックが完了しても、新しいターンは開始されません。
同期フックと同じイベント固有の JSON 出力を使用します。Codex は
additionalContext をモデルのコンテキストへ追加し、systemMessage を警告として表示します。
制限事項
- Codex はセッションごとに最大 8 個のバックグラウンドフックを同時実行します。それを超える フックは、実行中のフックが完了するまで待機します。
- 一致する各呼び出しは独立して実行され、バックグラウンドフックは 開始時と異なる順序で完了する場合があります。
- セッションが終了すると、Codex は未完了のバックグラウンドフックをキャンセルし、 まだ渡されていない出力を破棄します。
SessionEndフックは常に同期的に実行されます。
フック
SessionStart
このイベントでは、matcher が source に適用されます。
共通の入力フィールドに加えて、次のフィールドがあります。
| フィールド | 型 | 意味 |
|---|---|---|
source |
string |
セッションの開始方法:startup、resume、clear、compact |
stdout のプレーンテキストは、追加の開発者コンテキストとして加えられます。
stdout の JSON は、共通の出力フィールドと、次の
フック固有の形式をサポートします。
{
"hookSpecificOutput": {
"hookEventName": "SessionStart",
"additionalContext": "Load the workspace conventions before editing."
}
}その additionalContext テキストは、追加の開発者コンテキストとして加えられます。
Codex がルートセッションをコンパクト化した後、source: "compact" に一致する
SessionStart フックは次のモデルリクエストより前に実行されます。これは、ターンの途中で
自動コンパクションが発生した場合にも適用されます。Codex はフックの追加コンテキストを、
後続のユーザーターンまで待たず、直後の継続処理へ渡します。フックが continue: false を返すと、
Codex は別のモデルリクエストを送信せずにターンを終了します。
SessionEnd
SessionEnd を使用すると、セッション終了時に、最終メモの保存やファイルの
クリーンアップなどのコマンドを実行できます。会話がまだ開いている状態でアーカイブまたは
削除したとき、Codex が正常終了したとき、または会話が 30 分間アイドル状態で、接続済みの
どのクライアントでも開かれていないときに、メインスレッドで実行されます。サブエージェントでは実行されません。
会話から切り替えたり、thread/unsubscribe を呼び出したりしても、セッションは
すぐには終了しないため、SessionEnd は直ちには実行されません。フックの実行中も、
セッションのトランスクリプトを読み取れます。
このイベントでは、matcher が reason を絞り込みます。現時点では、reason は常に other です。
すべての SessionEnd イベントで実行するには、matcher を省略するか、other を使用します。
共通の入力フィールドに加えて、次のフィールドがあります。
| フィールド | 型 | 意味 |
|---|---|---|
reason |
string |
セッションの終了理由:other |
たとえば、SessionEnd コマンドは次を受け取ります。
{
"session_id": "thr_123",
"transcript_path": "/workspace/.codex/rollout.jsonl",
"cwd": "/workspace",
"hook_event_name": "SessionEnd",
"reason": "other"
}SessionEnd フックは、async が true の場合でも常に同期的に実行されます。
これらは助言のみを行うため、その出力が Codex を誘導したり、スレッドを開いたままにしたりすることはありません。
コマンドがタイムアウトするか、エラーで終了した場合、Codex はフックの失敗として報告します。
SubagentStart
このイベントでは、matcher が agent_type に適用されます。
共通の入力フィールドに加えて、次のフィールドがあります。
| フィールド | 型 | 意味 |
|---|---|---|
turn_id |
string |
Codex 固有の拡張。アクティブな Codex ターン ID |
agent_id |
string |
サブエージェントの識別子 |
agent_type |
string |
サブエージェントの種類またはプロファイル |
permission_mode |
string |
現在の権限モード |
stdout のプレーンテキストは、サブエージェント用の追加の開発者コンテキストとして加えられます。
stdout の JSON は、systemMessage と次のフック固有の形式をサポートします。
{
"hookSpecificOutput": {
"hookEventName": "SubagentStart",
"additionalContext": "Review the repository test conventions first."
}
}その additionalContext テキストは、サブエージェント用の追加の開発者コンテキストとして
加えられます。continue: false は互換性のために解析されますが、サブエージェントの
開始を阻止しません。
PreToolUse
PreToolUse は、Bash、apply_patch を通じたファイル編集、
MCP ツール呼び出し、その他のローカル関数ツールに介入できます。サポートされるパスと例外については、
ツールの対象範囲を参照してください。
matcher は、tool_name とマッチャーの別名に適用されます。apply_patch を通じたファイル編集では、
matcher の値に apply_patch、Edit、Write を使用できますが、フック入力では
引き続き tool_name: "apply_patch" として報告されます。
共通の入力フィールドに加えて、次のフィールドがあります。
| フィールド | 型 | 意味 |
|---|---|---|
turn_id |
string |
Codex 固有の拡張。アクティブな Codex ターン ID |
tool_name |
string |
Bash、apply_patch、mcp__fs__read のような MCP 名など、標準のフックツール名 |
tool_use_id |
string |
この呼び出しのツール呼び出し ID |
tool_input |
JSON value |
ツール固有の入力。Bash と apply_patch は tool_input.command を使用します。MCP およびその他のローカル関数ツールは引数を送信します。 |
stdout のプレーンテキストは無視されます。
stdout の JSON では systemMessage を使用できます。サポート対象のツール呼び出しを拒否するには、
次のフック固有の形式を返します。
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "Destructive command blocked by hook."
}
}Codex は、次の以前のブロック形式も受け付けます。
{
"decision": "block",
"reason": "Destructive command blocked by hook."
}終了コード 2 を使用し、ブロック理由を stderr へ書き込むこともできます。
ブロックせずにモデルへ表示されるコンテキストを追加するには、
hookSpecificOutput.additionalContext を返します。
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"additionalContext": "The pending command touches generated files."
}
}サポート対象のツール呼び出しをブロックせずに書き換えるには、
updatedInput を含む permissionDecision: "allow" を返します。
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "allow",
"updatedInput": {
"command": "echo rewritten"
}
}
}Bash コマンドと apply_patch では、updatedInput に文字列の
command フィールドを含める必要があります。MCP およびその他のローカル関数ツールでは、updatedInput が
置換後の引数オブジェクトです。updatedInput は permissionDecision: "allow" と組み合わせた場合にのみ返してください。
それ以外の updatedInput 形式はエラーとして報告されます。
permissionDecision: "ask"、従来の decision: "approve"、continue: false、
stopReason、suppressOutput は解析されますが、まだサポートされていません。Codex は
フック実行を失敗としてマークしてエラーを報告し、ツール呼び出しを続行します。
PermissionRequest
PermissionRequest は、シェルの権限昇格や管理対象ネットワークの承認など、Codex が
承認を求めようとするときに実行されます。リクエストの許可、拒否、または判断を見送って
通常の承認プロンプトを続行できます。承認が不要なコマンドでは実行されません。
matcher は、tool_name とマッチャーの別名に適用されます。現在の標準値には、
Bash、apply_patch、mcp__server__tool のような MCP ツール名が含まれます。
apply_patch は Edit と Write にも一致します。
共通の入力フィールドに加えて、次のフィールドがあります。
| フィールド | 型 | 意味 |
|---|---|---|
turn_id |
string |
Codex 固有の拡張。アクティブな Codex ターン ID |
tool_name |
string |
Bash、apply_patch、mcp__fs__read のような MCP 名など、標準のフックツール名 |
tool_input |
JSON value |
ツール固有の入力。Bash と apply_patch は tool_input.command を使用し、MCP ツールはすべての引数を送信します。 |
tool_input.description |
string | null |
Codex が保持している場合、人間が読める承認理由 |
stdout のプレーンテキストは無視されます。
一部のツール入力には人間が読める説明が含まれる場合がありますが、すべてのツールに
tool_input.description フィールドがあるとは限らないため、依存しないでください。
リクエストを承認するには、次を返します。
{
"hookSpecificOutput": {
"hookEventName": "PermissionRequest",
"decision": {
"behavior": "allow"
}
}
}リクエストを拒否するには、次を返します。
{
"hookSpecificOutput": {
"hookEventName": "PermissionRequest",
"decision": {
"behavior": "deny",
"message": "Blocked by repository policy."
}
}
}一致する複数のフックが決定を返した場合、deny が 1 つでもあれば優先されます。それ以外の場合、
allow があれば、承認プロンプトを表示せずにリクエストを続行できます。一致する
どのフックも決定しなかった場合、Codex は通常の承認フローを使用します。
PermissionRequest では、updatedInput、updatedPermissions、interrupt を返さないでください。
これらのフィールドは将来の動作用に予約されており、現在はフェイルクローズになります。
PostToolUse
PostToolUse は、Bash、apply_patch、MCP ツール呼び出し、その他の
ローカル関数ツールなど、サポート対象ツールが出力を生成した後に実行されます。Bash では、
終了ステータスがゼロ以外のコマンドの後にも実行されます。すでに実行されたツールの副作用を
取り消すことはできません。サポートされるパスと例外については、ツールの対象範囲を参照してください。
matcher は、tool_name とマッチャーの別名に適用されます。apply_patch を通じたファイル編集では、
matcher の値に apply_patch、Edit、Write を使用できますが、フック入力では
引き続き tool_name: "apply_patch" として報告されます。
共通の入力フィールドに加えて、次のフィールドがあります。
| フィールド | 型 | 意味 |
|---|---|---|
turn_id |
string |
Codex 固有の拡張。アクティブな Codex ターン ID |
tool_name |
string |
Bash、apply_patch、mcp__fs__read のような MCP 名など、標準のフックツール名 |
tool_use_id |
string |
この呼び出しのツール呼び出し ID |
tool_input |
JSON value |
ツール固有の入力。Bash と apply_patch は tool_input.command を使用します。MCP およびその他のローカル関数ツールは引数を送信します。 |
tool_response |
JSON value |
ツール固有の出力。MCP ツールは MCP 呼び出し結果を送信します。その他のローカル関数ツールは通常、モデル向けの出力を送信します。 |
stdout のプレーンテキストは無視されます。
stdout の JSON では、systemMessage と次のフック固有の形式を使用できます。
{
"decision": "block",
"reason": "The Bash output needs review before continuing.",
"hookSpecificOutput": {
"hookEventName": "PostToolUse",
"additionalContext": "The command updated generated files."
}
}その additionalContext テキストは、追加の開発者コンテキストとして加えられます。
このイベントでは、decision: "block" は完了済みの Bash コマンドを取り消しません。
代わりに、Codex はフィードバックを記録し、ツールの結果をそのフィードバックで置き換え、
フックから提供されたメッセージを使用してモデルを続行します。
終了コード 2 を使用し、フィードバックの理由を stderr へ書き込むこともできます。
コマンドがすでに実行された後に、元のツール結果の通常処理を停止するには、
continue: false を返します。Codex はツール結果をフィードバックまたは停止テキストで
置き換え、そこから続行します。
updatedMCPToolOutput と suppressOutput は解析されますが、まだサポートされていません。
Codex はフック実行を失敗としてマークしてエラーを報告し、ツール結果の通常処理を続行します。
コードモードからのツール呼び出し
モデルがコードモードで JavaScript からツールを呼び出す場合、フックの決定は
そのネストされた呼び出しに適用されます。PreToolUse は、実行前にツールを停止したり、入力を
書き換えたりできます。ブロックする PostToolUse はツールの副作用を取り消せませんが、
元の結果が実行中のスクリプトへ到達するのを防げます。
| フックの結果 | コードモードから見える動作 |
|---|---|
PreToolUse がブロック |
ツールの実行前にツールの Promise が reject されます。 |
PreToolUse が updatedInput を返す |
書き換え後の入力でツールが実行され、Promise はその結果で resolve されます。 |
PostToolUse が decision: "block" を返すか、コード 2 で終了する |
ツールが実行された後、Promise がフックの理由で reject されます。 |
PostToolUse が continue: false を返す |
Codex はモデルに表示される結果としてフックのフィードバックを使用しますが、ネストされたツールの Promise は reject しません。 |
PreCompact
PreCompact は、Codex がチャットをコンパクト化する前に実行されます。matcher は、
値が manual または auto である trigger に適用されます。
共通の入力フィールドに加えて、次のフィールドがあります。
| フィールド | 型 | 意味 |
|---|---|---|
turn_id |
string |
Codex 固有の拡張。アクティブな Codex ターン ID |
trigger |
string |
コンパクションのトリガー:manual または auto |
stdout のプレーンテキストは無視されます。
stdout の JSON は、共通の出力フィールドをサポートします。一致する
PreCompact フックが continue: false を返すと、Codex はコンパクト化の前に停止します。
PostCompact
PostCompact は、Codex がチャットをコンパクト化した後に実行されます。matcher は、
値が manual または auto である trigger に適用されます。
共通の入力フィールドに加えて、次のフィールドがあります。
| フィールド | 型 | 意味 |
|---|---|---|
turn_id |
string |
Codex 固有の拡張。アクティブな Codex ターン ID |
trigger |
string |
コンパクションのトリガー:manual または auto |
stdout のプレーンテキストは無視されます。
stdout の JSON は、共通の出力フィールドをサポートします。一致する
PostCompact フックが continue: false を返すと、Codex はコンパクト化の後に停止します。
UserPromptSubmit
matcher は現在、このイベントでは使用されません。
共通の入力フィールドに加えて、次のフィールドがあります。
| フィールド | 型 | 意味 |
|---|---|---|
turn_id |
string |
Codex 固有の拡張。アクティブな Codex ターン ID |
prompt |
string |
これから送信されるユーザープロンプト |
stdout のプレーンテキストは、追加の開発者コンテキストとして加えられます。
stdout の JSON は、共通の出力フィールドと
次のフック固有の形式をサポートします。
{
"hookSpecificOutput": {
"hookEventName": "UserPromptSubmit",
"additionalContext": "Ask for a clearer reproduction before editing files."
}
}その additionalContext テキストは、追加の開発者コンテキストとして加えられます。
プロンプトをブロックするには、次を返します。
{
"decision": "block",
"reason": "Ask for confirmation before doing that."
}終了コード 2 を使用し、ブロック理由を stderr へ書き込むこともできます。
SubagentStop
このイベントでは、matcher が agent_type に適用されます。
共通の入力フィールドに加えて、次のフィールドがあります。
| フィールド | 型 | 意味 |
|---|---|---|
turn_id |
string |
Codex 固有の拡張。アクティブな Codex ターン ID |
agent_id |
string |
サブエージェントの識別子 |
agent_type |
string |
サブエージェントの種類またはプロファイル |
agent_transcript_path |
string | null |
サブエージェントのトランスクリプトファイルのパス(存在する場合) |
stop_hook_active |
boolean |
このサブエージェントがすでに継続されたかどうか |
last_assistant_message |
string | null |
利用可能な場合、サブエージェントの最新のアシスタントメッセージ |
SubagentStop は、0 で終了するときに stdout の JSON を想定します。プレーンテキスト出力は
このイベントでは無効です。
stdout の JSON は、共通の出力フィールドをサポートします。Codex に
サブエージェントのフローを継続するよう要求するには、次を返します。
{
"decision": "block",
"reason": "Run one more focused pass inside the subagent."
}終了コード 2 を使用し、継続理由を stderr へ書き込むこともできます。
一致する SubagentStop フックのいずれかが continue: false を返した場合、ほかの一致する
SubagentStop フックによる継続の決定よりも優先されます。
Stop
matcher は現在、このイベントでは使用されません。
共通の入力フィールドに加えて、次のフィールドがあります。
| フィールド | 型 | 意味 |
|---|---|---|
turn_id |
string |
Codex 固有の拡張。アクティブな Codex ターン ID |
stop_hook_active |
boolean |
このターンがすでに Stop によって継続されたかどうか |
last_assistant_message |
string | null |
利用可能な場合、最新のアシスタントメッセージのテキスト |
Stop は、0 で終了するときに stdout の JSON を想定します。プレーンテキスト出力は
このイベントでは無効です。
stdout の JSON は、共通の出力フィールドをサポートします。Codex を
続行させるには、次を返します。
{
"decision": "block",
"reason": "Run one more pass over the failing tests."
}終了コード 2 を使用し、継続理由を stderr へ書き込むこともできます。
このイベントでは、decision: "block" はターンを拒否しません。代わりに Codex へ
続行を指示し、reason をプロンプトテキストとして使用して、新しいユーザープロンプトとして
機能する継続プロンプトを自動作成します。
一致する Stop フックのいずれかが continue: false を返した場合、ほかの一致する
Stop フックによる継続の決定よりも優先されます。
Interrupt
Interrupt は、メインスレッドでアクティブなターンを中断したときに実行されます。フックによって開始された作業の中断を記録したり、クリーンアップしたりするために使用します。アイドル状態のスレッドやサブエージェントでは実行されず、設定された matcher はすべて無視されます。
共通の入力フィールドに加えて、このイベントには、中断されたターンの ID である turn_id と permission_mode が含まれます。
コマンドフックのデフォルトのタイムアウトは 1 秒です。設定できるタイムアウトは 1 秒から 3 秒までです。フックの出力で中断を阻止したり、ターンを再開したりすることはできません。出力なしで 0 で終了するか、警告を表示するための任意の systemMessage を含む JSON を返します。このイベントではプレーンテキストの出力は無効です。
{ "systemMessage": "Saved the interrupted turn to the local audit log." }スキーマ
現在の正確なワイヤーフォーマットが必要な場合は、 Codex GitHub リポジトリで生成されたスキーマを参照してください。
プレーンテキストの別名
- string | null