Hooks
Codex のライフサイクル中に決定論的なスクリプトを実行します
Hooks は Codex の拡張フレームワークです。独自のスクリプトをエージェントループに組み込むことで、次のような機能を実現できます。
- チャットをカスタムのログ/分析エンジンへ送信する
- チームのプロンプトをスキャンし、API key の誤貼り付けを防止する
- チャットを要約し、永続的なメモリを自動作成する
- チャットのターンが停止したときにカスタム検証を実行し、標準を適用する
- 特定のディレクトリ内にいるときのプロンプトをカスタマイズする
実行時の動作について、次の点に注意してください。
- 複数のファイルにある一致した Hooks はすべて実行されます。
- 同じイベントに一致する複数のコマンド Hook は並行して起動されるため、ある Hook が別の一致する Hook の起動を阻止することはできません。
- 管理対象外のコマンド Hook は、実行前に確認して信頼する必要があります。
Hooks は会話中のさまざまな時点で実行されます。
| タイミング | Hooks |
|---|---|
| ターンの実行中 | PreToolUse, PermissionRequest, PostToolUse, PreCompact, PostCompact, UserPromptSubmit, SubagentStop, Stop |
| セッションまたはサブエージェントの開始時 | SessionStart, SubagentStart |
| メインスレッドの終了時 | SessionEnd(サブエージェントでは実行されません) |
Codex が Hooks を検索する場所
Codex は、アクティブな設定レイヤーの隣にある次のいずれかの形式から Hooks を検出します。
hooks.jsonconfig.toml内のインライン[hooks]テーブル
インストール済みのプラグインも、そのプラグインのマニフェストまたはデフォルトの hooks/hooks.json ファイルを通じてライフサイクル設定を同梱できます。プラグインのパッケージ化ルールについては、プラグインを構築するを参照してください。
実際には、次の 4 つの場所が特に便利です。
~/.codex/hooks.json~/.codex/config.toml<repo>/.codex/hooks.json<repo>/.codex/config.toml
Hook のソースが複数存在する場合、Codex は一致する Hooks をすべて読み込みます。優先順位の高い設定レイヤーが、優先順位の低い Hooks を置き換えることはありません。
1 つのレイヤーに hooks.json とインライン [hooks] の両方が含まれている場合、Codex はそれらをマージし、起動時に警告を表示します。レイヤーごとに 1 つの表現を使用することを推奨します。
Codex は、有効なプラグインに同梱された Hooks も検出できます。プラグイン同梱の Hooks は他の Hook ソースとともに読み込まれ、管理対象外の他の Hooks と同じ信頼確認フローを使用します。
プロジェクトローカルの Hooks は、プロジェクトの .codex/ レイヤーが信頼されている場合にのみ読み込まれます。信頼されていないプロジェクトでも、Codex はユーザーおよびシステムの Hooks を、それぞれのアクティブな設定レイヤーから引き続き読み込みます。
Hooks の確認と信頼
Codex は、実行可能な Hooks を決定する前に、設定済みの Hooks を一覧表示します。管理対象外のコマンド Hook を実行するには、正確な Hook 定義を確認して信頼する必要があります。 Codex は Hook の現在のハッシュに対して信頼を記録するため、新規または変更された Hooks は確認対象としてマークされ、信頼されるまでスキップされます。
CLI で /hooks を使用すると、Hook のソースを調査し、新規または変更された Hooks を確認し、
Hooks を信頼したり、管理対象外の Hooks を個別に無効化したりできます。起動時に確認が必要な Hooks がある場合、
Codex は /hooks を開くよう案内する警告を表示します。
システム、MDM、クラウド、または requirements.toml のソースにある管理対象の Hooks は管理対象としてマークされ、ポリシーによって信頼されます。ユーザー用 Hook ブラウザーから無効化することはできません。
Codex の外部ですでに Hook のソースを検証している一時的な自動化では、
--dangerously-bypass-hook-trust を渡すと、その呼び出しについて永続化された Hook の信頼を要求せずに有効な Hooks を実行できます。
設定の構造
Hooks は 3 つのレベルで構成されます。
PreToolUse、PostToolUse、PreCompact、SubagentStart、Stopなどの Hook イベント- そのイベントが一致する条件を決める matcher グループ
- matcher グループが一致したときに実行される 1 つ以上の Hook ハンドラー
{
"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ファイル用の省略可能なトップレベルメタデータです。どの Hooks が実行されるかには影響しません。timeoutの単位は秒です。timeoutを省略すると、Codex はほとんどの Hooks で600秒を使用します。SessionEndのデフォルトは1秒で、最大3秒まで指定できます。
statusMessageは省略可能です。additionalContextLimitは、コマンド Hook がモデルに送信できるadditionalContextの量を設定します。上限を超えると、Codex は全文をディスクに保存し、代わりに短いプレビューを送信します。 大きな Hook 出力を参照してください。commandWindowsは省略可能な Windows 専用のコマンド上書きです。TOML ではcommand_windowsまたはcommandWindowsを使用します。asyncオプションは解析されますが、非同期コマンド Hooks はまだサポートされていません。- 現在実行されるのは
type: "command"ハンドラーだけです。promptとagentハンドラーは解析されますが、スキップされます。 - コマンドはセッションの
cwdを作業ディレクトリとして実行されます。 - リポジトリローカルの Hooks では、
.codex/hooks/...のような相対パスではなく、 git ルートから解決することを推奨します。Codex はサブディレクトリから起動される場合があり、 git ルート基準のパスを使うことで Hook の場所を安定させられます。
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"Hooks を無効にする
Hooks はデフォルトで有効です。config.toml で無効にするには、次のように設定します。
[features]
hooks = false正式な機能キーには hooks を使用してください。codex_hooks も非推奨のエイリアスとして引き続き機能します。管理者は requirements.toml でも同様に
[features].hooks = false を指定して、Hooks を強制的に無効化できます。
requirements.toml の管理対象 Hooks
企業によって管理される要件では、[hooks] の下に Hooks をインラインで定義することもできます。これは、実際のスクリプトを MDM または別のデバイス管理システムから配布しつつ、管理者が Hook 設定を強制したい場合に便利です。Hooks をローカルで無効にしたユーザーにも管理対象 Hooks を適用するには、requirements.toml で [hooks] とともに
[features].hooks = true を固定します。管理者が管理する Hooks は許可しつつ、ユーザー、プロジェクト、セッション、プラグインの Hooks を無視するには、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"管理対象 Hooks に関する注記:
managed_dirは macOS と Linux で使用されます。windows_managed_dirは Windows で使用されます。- Codex は
managed_dir内のスクリプトを配布しません。企業側のツールで個別にインストールおよび更新する必要があります。 - 管理対象 Hook のコマンドでは、設定された管理対象ディレクトリ配下の絶対スクリプトパスを使用してください。
allow_managed_hooks_only = trueは、ユーザー、プロジェクト、セッション、プラグインのソースにある Hooks をスキップしますが、requirements.tomlおよびその他の管理対象設定レイヤーにある管理対象 Hooks は引き続き読み込みます。
プラグイン同梱の Hooks
プラグインを有効にすると、Codex はそのプラグインのライフサイクル Hooks を、ユーザー、プロジェクト、管理対象の Hooks とともに読み込めます。
デフォルトでは、Codex はプラグインルート内の hooks/hooks.json を検索します。プラグインのマニフェストでは、.codex-plugin/plugin.json の hooks エントリを使ってこのデフォルトを上書きできます。マニフェストのエントリには、./ で始まるパス、
./ で始まるパスの配列、インライン Hooks オブジェクト、またはインライン
Hooks オブジェクトの配列を指定できます。
{
"name": "repo-policy",
"hooks": "./hooks/hooks.json"
}マニフェストの Hook パスはプラグインルートからの相対パスとして解決され、そのルート内に収まる必要があります。マニフェストに hooks が定義されている場合、Codex はデフォルトの hooks/hooks.json の代わりに、そのマニフェストエントリを使用します。
プラグインの Hook コマンドには、次の環境変数が渡されます。
PLUGIN_ROOTは Codex 固有の拡張で、インストール済みのプラグインルートを指します。PLUGIN_DATAは Codex 固有の拡張で、プラグインの書き込み可能なデータディレクトリを指します。- Codex は、既存のプラグイン Hooks との互換性のために
CLAUDE_PLUGIN_ROOTとCLAUDE_PLUGIN_DATAも設定します。
プラグイン Hooks は、他の Hooks と同じイベントスキーマを使用します。プラグインをインストールまたは有効化しても、その Hooks が自動的に信頼されるわけではありません。現在の Hook 定義を確認して信頼するまで、Codex はプラグイン同梱の Hooks をスキップします。
Matcher パターン
matcher フィールドは、Hooks が発火するタイミングを絞り込む正規表現文字列です。サポート対象イベントのすべての発生に一致させるには、"*"、"" を使用するか、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 は無視されます |
*apply_patch では、matcher の値に Edit または Write も使用できます。
例:
Bash^apply_patch$Edit|Writemcp__filesystem__read_filemcp__filesystem__.*startup|resume|clear|compactmanual|auto
ツールの対応範囲
PreToolUse と PostToolUse は、シェルおよび MCP 呼び出し以外も監視できます。ほとんどのローカル関数ツールは同じ Hook パスを使用するため、ツール名に一致させ、その 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 などのホスト型ツール |
いいえ | いいえ | これらはローカル関数ツールの Hook パスを使用しません。 |
write_stdin は、既存の統合 exec セッション用のトランスポートです。すでに PreToolUse を通過したコマンドへ入力を送信したり、そのコマンドをポーリングしたりするときに、PreToolUse を再実行することはありません。
一部の特殊なツールパスでは、デフォルトの Hook パスを使用しないことがあります。ツール Hooks は便利なガードレールとして扱い、完全な適用境界とはみなさないでください。
共通の入力フィールド
すべてのコマンド Hook は、stdin で 1 つの JSON オブジェクトを受け取ります。
通常使用する共通フィールドは次のとおりです。
| フィールド | 型 | 意味 |
|---|---|---|
session_id |
string |
現在の Codex セッション ID。サブエージェント Hooks では親セッション ID を使用します。 |
transcript_path |
string | null |
セッションのトランスクリプトファイルへのパス(存在する場合) |
cwd |
string |
セッションの作業ディレクトリ |
hook_event_name |
string |
現在の Hook イベント名 |
model |
string |
Codex 固有の拡張。アクティブなモデルの slug |
ターン単位の Hooks では、イベント固有の表に Codex 固有の拡張として turn_id が記載されています。
SessionStart、PreToolUse、PermissionRequest、PostToolUse、
UserPromptSubmit、SubagentStart、SubagentStop、Stop には
permission_mode も含まれます。これは現在の権限モードを default、
acceptEdits、plan、dontAsk、bypassPermissions のいずれかで示します。
transcript_path は便宜上チャットのトランスクリプトを指しますが、トランスクリプト形式は Hooks 用の安定したインターフェースではなく、今後変更される可能性があります。
完全なワイヤー形式が必要な場合は、スキーマを参照してください。
共通の出力フィールド
SessionStart、PreCompact、PostCompact、UserPromptSubmit、
SubagentStop、Stop は、次の共通 JSON フィールドに対応します。SubagentStart は
systemMessage と Hook 固有のコンテキストについて同じ形式を受け付けますが、
continue: false でサブエージェントを停止することはできません。
{
"continue": true,
"stopReason": "optional",
"systemMessage": "optional",
"suppressOutput": false
}| フィールド | 効果 |
|---|---|
continue |
false の場合、その Hook の実行を停止済みとしてマークします |
stopReason |
停止理由として記録されます |
systemMessage |
UI またはイベントストリームに警告として表示されます |
suppressOutput |
現在は解析されますが、まだ実装されていません |
出力せず終了コード 0 で終了した場合は成功とみなされ、Codex は続行します。
PreToolUse と PermissionRequest は systemMessage に対応していますが、continue、
stopReason、suppressOutput は現在これらのイベントではサポートされていません。
PreToolUse Hook がこれらの未対応フィールドのいずれかを返した場合、Codex はその Hook の実行を失敗としてマークし、エラーを報告してツール呼び出しを続行します。
PostToolUse は systemMessage、continue: false、stopReason に対応しています。
suppressOutput は解析されますが、現在このイベントではサポートされていません。
大きな Hook 出力
デフォルトでは、Codex はモデルから見える各 Hook 出力メッセージをおよそ
2,500 トークンに制限します。Hook がそれを超える出力を返すと、Codex は全文を
<temp_dir>/hook_outputs/<session_id>/<uuid>.txt に保存し、保存先ファイルのパスを含む先頭と末尾のプレビューをモデルに渡します。この動作は spilling と呼ばれます。Codex は大きすぎる出力をディスクに保存し、モデルから見える短いプレビューに置き換えます。ファイルへ書き込めない場合でも、モデルは切り詰められたプレビューを受け取ります。
additionalContext を返すすべてのコマンド Hook では、ハンドラーに
additionalContextLimit を設定して、おおよそのトークンしきい値をカスタマイズします。
{
"type": "command",
"command": "python3 ~/.codex/hooks/session_start.py",
"additionalContextLimit": 5000
}additionalContextLimit を省略すると、デフォルトの 2500 トークンのしきい値が使用されます。別のしきい値を選ぶには正の整数を使用し、ハンドラーの追加コンテキスト全体をモデルへ直接渡すには 0 を使用します。Codex は一致する各ハンドラーを個別に評価します。追加コンテキストを生成できないイベントでは、Codex は additionalContextLimit を無視し、設定警告を報告します。
この設定は additionalContext にのみ適用されます。ツールのフィードバックと継続用のプロンプトには、デフォルトの上限が維持されます。
大きすぎる出力はディスクに書き込まれる可能性があるため、Hook 出力で秘密情報やその他の機密データを返さないでください。
Hooks
SessionStart
このイベントでは、matcher が source に適用されます。
共通の入力フィールドに加えて、次のフィールドがあります。
| フィールド | 型 | 意味 |
|---|---|---|
source |
string |
セッションの開始方法:startup、resume、clear、または compact |
stdout のプレーンテキストは、追加の開発者コンテキストとして追加されます。
stdout の JSON は、共通の出力フィールドと次の
Hook 固有の形式に対応します。
{
"hookSpecificOutput": {
"hookEventName": "SessionStart",
"additionalContext": "Load the workspace conventions before editing."
}
}この additionalContext テキストは、追加の開発者コンテキストとして追加されます。
Codex がルートセッションを圧縮した後、source: "compact" に一致する SessionStart Hooks は、次のモデルリクエストの前に実行されます。これは、ターンの途中で自動圧縮が発生した場合にも適用されます。
Codex は Hook の追加コンテキストを後続のユーザーターンまで待たず、直後の継続処理へ渡します。
Hook が continue: false を返した場合、Codex は別のモデルリクエストを送信せずにターンを終了します。
SessionEnd
SessionEnd を使用すると、最終メモの保存やファイルのクリーンアップなど、セッション終了時にコマンドを実行できます。開いている会話をアーカイブまたは削除したとき、Codex が正常終了したとき、あるいは会話が 30 分間アイドル状態で、接続中のどのクライアントでも開かれていないときに、メインスレッドで実行されます。サブエージェントでは実行されません。
別の会話へ切り替えたり、thread/unsubscribe を呼び出したりしても、セッションはすぐには終了しないため、SessionEnd も即座には実行されません。Hook の実行中も、セッションのトランスクリプトを読み取れます。
このイベントでは、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 Hooks は助言目的です。その出力で Codex の動作を制御したり、スレッドを開いたままにしたりすることはできません。コマンドがタイムアウトするかエラーで終了した場合、Codex は
Hook の失敗として報告します。
SubagentStart
このイベントでは、matcher が agent_type に適用されます。
共通の入力フィールドに加えて、次のフィールドがあります。
| フィールド | 型 | 意味 |
|---|---|---|
turn_id |
string |
Codex 固有の拡張。アクティブな Codex ターン ID |
agent_id |
string |
サブエージェントの識別子 |
agent_type |
string |
サブエージェントの種類またはプロファイル |
permission_mode |
string |
現在の権限モード |
stdout のプレーンテキストは、サブエージェント用の追加の開発者コンテキストとして追加されます。
stdout の JSON は、systemMessage と次の Hook 固有の形式に対応します。
{
"hookSpecificOutput": {
"hookEventName": "SubagentStart",
"additionalContext": "Review the repository test conventions first."
}
}この additionalContext テキストは、サブエージェント用の追加の開発者コンテキストとして追加されます。
continue: false は互換性のために解析されますが、サブエージェントの開始を阻止することはありません。
PreToolUse
PreToolUse は、Bash、apply_patch によるファイル編集、
MCP ツール呼び出し、その他のローカル関数ツールをインターセプトできます。対応するパスと例外については、
ツールの対応範囲を参照してください。
matcher は tool_name と matcher エイリアスに適用されます。apply_patch によるファイル編集では、matcher の値に apply_patch、Edit、Write を使用できますが、Hook 入力では引き続き tool_name: "apply_patch" と報告されます。
共通の入力フィールドに加えて、次のフィールドがあります。
| フィールド | 型 | 意味 |
|---|---|---|
turn_id |
string |
Codex 固有の拡張。アクティブな Codex ターン ID |
tool_name |
string |
Bash、apply_patch、または mcp__fs__read のような MCP 名など、正式な Hook ツール名 |
tool_use_id |
string |
この呼び出しのツール呼び出し ID |
tool_input |
JSON value |
ツール固有の入力。Bash と apply_patch は tool_input.command を使用し、MCP とその他のローカル関数ツールは引数を送信します。 |
stdout のプレーンテキストは無視されます。
stdout の JSON では systemMessage を使用できます。対応するツール呼び出しを拒否するには、次の Hook 固有の形式を返します。
{
"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."
}
}ブロックせずに対応するツール呼び出しを書き換えるには、
permissionDecision: "allow" とともに updatedInput を返します。
{
"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 は
Hook の実行を失敗としてマークし、エラーを報告してツール呼び出しを続行します。
PermissionRequest
PermissionRequest は、シェルの権限昇格や管理対象ネットワークの承認など、Codex が承認を求めようとするときに実行されます。リクエストを許可または拒否するか、判断を保留して通常の承認プロンプトを続行できます。承認が不要なコマンドでは実行されません。
matcher は tool_name と matcher エイリアスに適用されます。現在の正式な値には
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 名など、正式な Hook ツール名 |
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."
}
}
}一致する複数の Hooks が判断を返した場合、いずれか 1 つでも deny なら拒否されます。それ以外では、
allow により承認プロンプトを表示せずにリクエストが続行されます。一致する Hook が判断しなかった場合、Codex は通常の承認フローを使用します。
PermissionRequest では updatedInput、updatedPermissions、interrupt を返さないでください。これらのフィールドは将来の動作用に予約されており、現在は安全側に倒して失敗します。
PostToolUse
PostToolUse は、Bash、apply_patch、MCP ツール呼び出し、その他のローカル関数ツールなど、対応するツールが出力を生成した後に実行されます。Bash では、ゼロ以外のステータスで終了したコマンドの後にも実行されます。すでに実行されたツールの副作用を取り消すことはできません。対応するパスと例外については、ツールの対応範囲を参照してください。
matcher は tool_name と matcher エイリアスに適用されます。apply_patch によるファイル編集では、matcher の値に apply_patch、Edit、Write を使用できますが、Hook 入力では引き続き tool_name: "apply_patch" と報告されます。
共通の入力フィールドに加えて、次のフィールドがあります。
| フィールド | 型 | 意味 |
|---|---|---|
turn_id |
string |
Codex 固有の拡張。アクティブな Codex ターン ID |
tool_name |
string |
Bash、apply_patch、または mcp__fs__read のような MCP 名など、正式な Hook ツール名 |
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 と次の Hook 固有の形式を使用できます。
{
"decision": "block",
"reason": "The Bash output needs review before continuing.",
"hookSpecificOutput": {
"hookEventName": "PostToolUse",
"additionalContext": "The command updated generated files."
}
}この additionalContext テキストは、追加の開発者コンテキストとして追加されます。
このイベントでは、decision: "block" を返しても、完了済みの Bash コマンドは取り消されません。代わりに Codex はフィードバックを記録し、ツール結果をそのフィードバックで置き換え、
Hook から提供されたメッセージを基にモデルの処理を続行します。
終了コード 2 を使用し、フィードバックの理由を stderr に書き込むこともできます。
コマンド実行後に元のツール結果の通常処理を停止するには、continue: false を返します。
Codex はツール結果をフィードバックまたは停止テキストに置き換え、そこから続行します。
updatedMCPToolOutput と suppressOutput は解析されますが、まだサポートされていません。
Codex は Hook の実行を失敗としてマークし、エラーを報告してツール結果の通常処理を続行します。
コードモードからのツール呼び出し
モデルがコードモードで JavaScript からツールを呼び出す場合、Hook の判断はそのネストされた呼び出しに適用されます。PreToolUse は実行前にツールを停止したり、入力を書き換えたりできます。ブロックする PostToolUse はツールの副作用を取り消せませんが、元の結果が実行中のスクリプトへ到達するのを防止できます。
| Hook の結果 | コードモードから見える動作 |
|---|---|
PreToolUse がブロックする |
ツールの実行前にツールの Promise が reject されます。 |
PreToolUse が updatedInput を返す |
書き換えられた入力でツールが実行され、その結果で Promise が resolve されます。 |
PostToolUse が decision: "block" を返すか、コード 2 で終了する |
ツール実行後、Hook の理由によって Promise が reject されます。 |
PostToolUse が continue: false を返す |
Codex は Hook のフィードバックをモデル向けの結果に使用しますが、ネストされたツールの Promise は reject しません。 |
PreCompact
PreCompact は、Codex がチャットを圧縮する前に実行されます。matcher は
trigger に適用され、その値は manual と auto です。
共通の入力フィールドに加えて、次のフィールドがあります。
| フィールド | 型 | 意味 |
|---|---|---|
turn_id |
string |
Codex 固有の拡張。アクティブな Codex ターン ID |
trigger |
string |
圧縮のトリガー:manual または auto |
stdout のプレーンテキストは無視されます。
stdout の JSON は共通の出力フィールドに対応します。一致する
PreCompact Hook が continue: false を返した場合、Codex は圧縮前に停止します。
PostCompact
PostCompact は、Codex がチャットを圧縮した後に実行されます。matcher は
trigger に適用され、その値は manual と auto です。
共通の入力フィールドに加えて、次のフィールドがあります。
| フィールド | 型 | 意味 |
|---|---|---|
turn_id |
string |
Codex 固有の拡張。アクティブな Codex ターン ID |
trigger |
string |
圧縮のトリガー:manual または auto |
stdout のプレーンテキストは無視されます。
stdout の JSON は共通の出力フィールドに対応します。一致する
PostCompact Hook が continue: false を返した場合、Codex は圧縮後に停止します。
UserPromptSubmit
このイベントでは、現在 matcher は使用されません。
共通の入力フィールドに加えて、次のフィールドがあります。
| フィールド | 型 | 意味 |
|---|---|---|
turn_id |
string |
Codex 固有の拡張。アクティブな Codex ターン ID |
prompt |
string |
送信されようとしているユーザープロンプト |
stdout のプレーンテキストは、追加の開発者コンテキストとして追加されます。
stdout の JSON は、共通の出力フィールドと次の Hook 固有の形式に対応します。
{
"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 Hooks のいずれかが continue: false を返した場合、他の一致する SubagentStop Hooks からの継続判断より優先されます。
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" を返してもターンは reject されません。代わりに、
Codex に続行を指示し、reason をプロンプト本文として使用する新しい継続用プロンプトを新しいユーザープロンプトとして自動作成します。
一致する Stop Hooks のいずれかが continue: false を返した場合、他の一致する Stop Hooks からの継続判断より優先されます。
スキーマ
現在の正確なワイヤー形式が必要な場合は、 Codex GitHub リポジトリにある生成済みスキーマを参照してください。
プレーンテキストのエイリアス
- string | null