フック

Codex のライフサイクル中に決定論的なスクリプトを実行します

Hooks は Codex の拡張フレームワークです。エージェントループ中にスクリプトや MCP ツールを実行でき、次のような機能を実現できます。

  • チャットをカスタムのログ/分析エンジンへ送信する
  • チームのプロンプトをスキャンし、API key の誤貼り付けを防ぐ
  • チャットを要約し、永続的なメモリを自動作成する
  • チャットのターンが停止したときにカスタム検証を実行し、標準を適用する
  • 特定のディレクトリにいるときのプロンプトをカスタマイズする

フックの実行方法:

  • 複数のファイルで一致したフックはすべて実行されます。
  • 同じイベントに一致する複数のコマンドフックは同時に起動されるため、 あるフックが別の一致するフックの起動を阻止することはできません。
  • 管理対象外のフックは、実行前にレビューして信頼する必要があります。

フックは会話中のさまざまなタイミングで実行されます。

タイミング フック
ターン中 PreToolUse, PermissionRequest, PostToolUse, PreCompact, PostCompact, UserPromptSubmit, SubagentStop, Stop
アクティブなターンを中断したとき Interrupt(サブエージェントでは実行されません)
セッションまたはサブエージェントの開始時 SessionStart, SubagentStart
メインスレッドの終了時 SessionEnd(サブエージェントでは実行されません)

Codex がフックを検索する場所

Codex は、アクティブな設定レイヤーの隣にある次のいずれかの形式からフックを検出します。

  • hooks.json
  • config.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 server のツールを呼び出せます。構造化された引数をツールへ直接送信し、コマンドフックと同じ信頼レビューおよび出力契約を使用します。

MCP ツールフックを設定する

このフックは、Codex がファイルを書き込むか編集するたびに各パッチをスキャンするよう、 scanner MCP serverへ要求します。

{
  "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 serverの名前。必須です。
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 serverの準備が整う前に実行される場合があります。その場合、 セッションをブロックしません。
  • SessionEnd は MCP ツールフックをサポートしていません。

フックを無効にする

フックはデフォルトで有効です。config.toml で無効にするには、次のように設定します。

[features]
hooks = false

機能キーには hooks を使用してください。codex_hooks も引き続き非推奨のエイリアスとして機能します。管理者も同様に、 requirements.toml で [features].hooks = false を指定してフックを強制的に無効にできます。

requirements.toml からの管理対象フック

管理ポリシーとリモートフックが有効な場合、ローカルアクセスを有効にした Work Cloud と dots は、クラウドオーケストレーター上で管理者が管理するリモート MCP フックを使用します。グローバルの requirements.toml で mcp_tool ハンドラーを設定します。ローカルアクセスのない Work Cloud と個人アカウントでは、これらのエンタープライズ向けフックは使用されません。コマンド/シェル、プロンプト、エージェントのハンドラー、ローカル設定・プラグイン・ローカルディレクトリ由来のフック、環境をスコープとするフック、および SessionEnd MCP フックは、ツールがローカルで実行される場合でも、クラウドオーケストレーションではサポートされません。オーケストレーションと実行の両方がローカルで行われる場合、既存のサポート対象フックは、ローカルのみの Work および Codex スレッドで引き続き機能します。管理者は、これらのワークフローに対応する管理対象フックを引き続き Agent Security で設定できます。

これらのフックに依存する前に、コールバックの接続性、必要なイベント、失敗時の動作をテストしてください。サポートされている明示的な拒否はアクションをブロックできますが、PreToolUse コールバックのエラー、タイムアウト、不正な形式のレスポンスでは、ツールをブロックせずにフックが失敗する場合があります。MCP フックは、Compliance API の完全な監査証跡を提供するものではありません。

このセクションの Codex に関する手順は、サポート対象の Codex ワークフローに引き続き適用されます。Work Cloud でローカルコンピューターへのアクセスを有効にする前に、同期設定と Agent Security に表示される互換性の警告を確認してください。管理対象設定を参照してください。

Codex では、企業が管理する要件として、[hooks] の下にフックをインラインで定義できます。 以下のコマンドフックの例は Codex にのみ適用されます。 これは、管理者がフック設定を強制的に適用しながら、 実際のスクリプトを MDM やほかのデバイス管理システムで配布したい場合に役立ちます。 ローカルでフックを無効にしたユーザーにも管理対象フックを強制的に適用するには、 [features].hooks = true を requirements.toml 内で [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"

管理対象フックに関する注意事項:

  • 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、fork です
SubagentStart サブエージェントの種類 値は開始するサブエージェントによって異なります
SubagentStop サブエージェントの種類 値は停止するサブエージェントによって異なります
UserPromptSubmit サポート対象外 設定された matcher は、このイベントでは無視されます
Stop サポート対象外 設定された matcher は、このイベントでは無視されます
Interrupt サポート対象外 設定された matcher は、このイベントでは無視されます

*apply_patch では、matcher の値に Edit または Write も使用できます。

例:

  • Bash
  • ^apply_patch$
  • Edit|Write
  • mcp__filesystem__read_file
  • mcp__filesystem__.*
  • startup|resume|clear|compact|fork
  • manual|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、または fork

フォークされたスレッドでは source: "fork" を使用します。履歴を指定してスレッドを再開する場合も、 引き続き source: "resume" を使用します。

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