日本語

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.json
  • config.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 つのレベルで構成されます。

  • PreToolUsePostToolUsePreCompactSubagentStartStop などの 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
          }
        ]
      }
    ]
  }
}

注記:

  • descriptionhooks.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" ハンドラーだけです。promptagent ハンドラーは解析されますが、スキップされます。
  • コマンドはセッションの 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.jsonhooks エントリを使ってこのデフォルトを上書きできます。マニフェストのエントリには、./ で始まるパス、 ./ で始まるパスの配列、インライン 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_ROOTCLAUDE_PLUGIN_DATA も設定します。

プラグイン Hooks は、他の Hooks と同じイベントスキーマを使用します。プラグインをインストールまたは有効化しても、その Hooks が自動的に信頼されるわけではありません。現在の Hook 定義を確認して信頼するまで、Codex はプラグイン同梱の Hooks をスキップします。

Matcher パターン

matcher フィールドは、Hooks が発火するタイミングを絞り込む正規表現文字列です。サポート対象イベントのすべての発生に一致させるには、"*""" を使用するか、matcher を完全に省略します。

現在の Codex イベントのうち、matcher を使用するのは一部だけです。

イベント matcher が絞り込む対象 注記
PermissionRequest ツール名 Bashapply_patch*、MCP ツール名に対応します
PostToolUse ツール名 ツールの対応範囲を参照してください
PostCompact 圧縮トリガー 値は manual または auto です
PreCompact 圧縮トリガー 値は manual または auto です
PreToolUse ツール名 ツールの対応範囲を参照してください
SessionEnd 終了理由 現在は other のみです
SessionStart 開始元 値は startupresumeclearcompact です
SubagentStart サブエージェントの種類 値は開始されるサブエージェントによって異なります
SubagentStop サブエージェントの種類 値は停止するサブエージェントによって異なります
UserPromptSubmit 未対応 このイベントでは、設定された matcher は無視されます
Stop 未対応 このイベントでは、設定された matcher は無視されます

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

例:

  • Bash
  • ^apply_patch$
  • Edit|Write
  • mcp__filesystem__read_file
  • mcp__filesystem__.*
  • startup|resume|clear|compact
  • manual|auto

ツールの対応範囲

PreToolUsePostToolUse は、シェルおよび MCP 呼び出し以外も監視できます。ほとんどのローカル関数ツールは同じ Hook パスを使用するため、ツール名に一致させ、その JSON 引数を調査し、PreToolUse では呼び出しをブロックまたは書き換えられます。

ツールパス PreToolUse PostToolUse 注記
シェルコマンド はい はい Bash として一致させます。
統合 exec(exec_command はい はい Bash として一致させます。後続の write_stdin ポーリングでは、そのコマンドの完了時に元のコマンドの PostToolUse が配信される場合があります。
apply_patch はい はい apply_patchEdit、または Write として一致させます。
MCP ツール はい はい mcp__filesystem__read_file など、MCP ツール名に一致させます。
その他のローカル関数ツール はい はい update_plan など、関数ツール名に一致させます。spawn_agentAgent にも一致します。
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 が記載されています。

SessionStartPreToolUsePermissionRequestPostToolUseUserPromptSubmitSubagentStartSubagentStopStop には permission_mode も含まれます。これは現在の権限モードを defaultacceptEditsplandontAskbypassPermissions のいずれかで示します。

transcript_path は便宜上チャットのトランスクリプトを指しますが、トランスクリプト形式は Hooks 用の安定したインターフェースではなく、今後変更される可能性があります。

完全なワイヤー形式が必要な場合は、スキーマを参照してください。

共通の出力フィールド

SessionStartPreCompactPostCompactUserPromptSubmitSubagentStopStop は、次の共通 JSON フィールドに対応します。SubagentStartsystemMessage と Hook 固有のコンテキストについて同じ形式を受け付けますが、 continue: false でサブエージェントを停止することはできません。

{
  "continue": true,
  "stopReason": "optional",
  "systemMessage": "optional",
  "suppressOutput": false
}
フィールド 効果
continue false の場合、その Hook の実行を停止済みとしてマークします
stopReason 停止理由として記録されます
systemMessage UI またはイベントストリームに警告として表示されます
suppressOutput 現在は解析されますが、まだ実装されていません

出力せず終了コード 0 で終了した場合は成功とみなされ、Codex は続行します。

PreToolUsePermissionRequestsystemMessage に対応していますが、continuestopReasonsuppressOutput は現在これらのイベントではサポートされていません。 PreToolUse Hook がこれらの未対応フィールドのいずれかを返した場合、Codex はその Hook の実行を失敗としてマークし、エラーを報告してツール呼び出しを続行します。

PostToolUsesystemMessagecontinue: falsestopReason に対応しています。 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

このイベントでは、matchersource に適用されます。

共通の入力フィールドに加えて、次のフィールドがあります。

フィールド 意味
source string セッションの開始方法:startupresumeclear、または 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 の実行中も、セッションのトランスクリプトを読み取れます。

このイベントでは、matcherreason を絞り込みます。現時点で 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

このイベントでは、matcheragent_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 ツール呼び出し、その他のローカル関数ツールをインターセプトできます。対応するパスと例外については、 ツールの対応範囲を参照してください。

matchertool_name と matcher エイリアスに適用されます。apply_patch によるファイル編集では、matcher の値に apply_patchEditWrite を使用できますが、Hook 入力では引き続き tool_name: "apply_patch" と報告されます。

共通の入力フィールドに加えて、次のフィールドがあります。

フィールド 意味
turn_id string Codex 固有の拡張。アクティブな Codex ターン ID
tool_name string Bashapply_patch、または mcp__fs__read のような MCP 名など、正式な Hook ツール名
tool_use_id string この呼び出しのツール呼び出し ID
tool_input JSON value ツール固有の入力。Bashapply_patchtool_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 は置換後の引数オブジェクトです。updatedInputpermissionDecision: "allow" とともにのみ返してください。その他の updatedInput 形式はエラーとして報告されます。

permissionDecision: "ask"、従来の decision: "approve"continue: falsestopReasonsuppressOutput は解析されますが、まだサポートされていません。Codex は Hook の実行を失敗としてマークし、エラーを報告してツール呼び出しを続行します。

PermissionRequest

PermissionRequest は、シェルの権限昇格や管理対象ネットワークの承認など、Codex が承認を求めようとするときに実行されます。リクエストを許可または拒否するか、判断を保留して通常の承認プロンプトを続行できます。承認が不要なコマンドでは実行されません。

matchertool_name と matcher エイリアスに適用されます。現在の正式な値には Bashapply_patchmcp__server__tool などの MCP ツール名が含まれます。 apply_patchEditWrite にも一致します。

共通の入力フィールドに加えて、次のフィールドがあります。

フィールド 意味
turn_id string Codex 固有の拡張。アクティブな Codex ターン ID
tool_name string Bashapply_patch、または mcp__fs__read のような MCP 名など、正式な Hook ツール名
tool_input JSON value ツール固有の入力。Bashapply_patchtool_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 では updatedInputupdatedPermissionsinterrupt を返さないでください。これらのフィールドは将来の動作用に予約されており、現在は安全側に倒して失敗します。

PostToolUse

PostToolUse は、Bash、apply_patch、MCP ツール呼び出し、その他のローカル関数ツールなど、対応するツールが出力を生成した後に実行されます。Bash では、ゼロ以外のステータスで終了したコマンドの後にも実行されます。すでに実行されたツールの副作用を取り消すことはできません。対応するパスと例外については、ツールの対応範囲を参照してください。

matchertool_name と matcher エイリアスに適用されます。apply_patch によるファイル編集では、matcher の値に apply_patchEditWrite を使用できますが、Hook 入力では引き続き tool_name: "apply_patch" と報告されます。

共通の入力フィールドに加えて、次のフィールドがあります。

フィールド 意味
turn_id string Codex 固有の拡張。アクティブな Codex ターン ID
tool_name string Bashapply_patch、または mcp__fs__read のような MCP 名など、正式な Hook ツール名
tool_use_id string この呼び出しのツール呼び出し ID
tool_input JSON value ツール固有の入力。Bashapply_patchtool_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 はツール結果をフィードバックまたは停止テキストに置き換え、そこから続行します。

updatedMCPToolOutputsuppressOutput は解析されますが、まだサポートされていません。 Codex は Hook の実行を失敗としてマークし、エラーを報告してツール結果の通常処理を続行します。

コードモードからのツール呼び出し

モデルがコードモードで JavaScript からツールを呼び出す場合、Hook の判断はそのネストされた呼び出しに適用されます。PreToolUse は実行前にツールを停止したり、入力を書き換えたりできます。ブロックする PostToolUse はツールの副作用を取り消せませんが、元の結果が実行中のスクリプトへ到達するのを防止できます。

Hook の結果 コードモードから見える動作
PreToolUse がブロックする ツールの実行前にツールの Promise が reject されます。
PreToolUseupdatedInput を返す 書き換えられた入力でツールが実行され、その結果で Promise が resolve されます。
PostToolUsedecision: "block" を返すか、コード 2 で終了する ツール実行後、Hook の理由によって Promise が reject されます。
PostToolUsecontinue: false を返す Codex は Hook のフィードバックをモデル向けの結果に使用しますが、ネストされたツールの Promise は reject しません。

PreCompact

PreCompact は、Codex がチャットを圧縮する前に実行されます。matchertrigger に適用され、その値は manualauto です。

共通の入力フィールドに加えて、次のフィールドがあります。

フィールド 意味
turn_id string Codex 固有の拡張。アクティブな Codex ターン ID
trigger string 圧縮のトリガー:manual または auto

stdout のプレーンテキストは無視されます。

stdout の JSON は共通の出力フィールドに対応します。一致する PreCompact Hook が continue: false を返した場合、Codex は圧縮前に停止します。

PostCompact

PostCompact は、Codex がチャットを圧縮した後に実行されます。matchertrigger に適用され、その値は manualauto です。

共通の入力フィールドに加えて、次のフィールドがあります。

フィールド 意味
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

このイベントでは、matcheragent_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