钩子
钩子是 Codex 的可扩展框架。借助钩子,你可以将自己的脚本注入智能体循环,从而实现以下功能:
- 将聊天发送到自定义日志记录或分析引擎
- 扫描团队的提示词,阻止意外粘贴 API 密钥
- 总结聊天内容,自动创建持久记忆
- 在聊天轮次停止时运行自定义验证检查,强制执行规范
- 在特定目录中自定义提示词
需要注意的运行时行为:
- 来自多个文件的匹配钩子都会运行。
- 同一事件的多个匹配命令钩子会并发启动,因此某个钩子无法阻止其他匹配钩子启动。
- 非托管命令钩子必须经过审查并获得信任后才能运行。
钩子会在对话中的不同时间点运行:
| 时间 | 钩子 |
|---|---|
| 在轮次期间 | PreToolUse、PermissionRequest、PostToolUse、PreCompact、PostCompact、UserPromptSubmit、SubagentStop、Stop |
| 会话或子智能体启动时 | SessionStart、SubagentStart |
| 主线程结束时 | SessionEnd(不会对子智能体运行) |
Codex 查找钩子的位置
Section titled “Codex 查找钩子的位置”Codex 会在以下任一形式的活动配置层旁查找钩子:
hooks.jsonconfig.toml中的内联[hooks]表
已安装的插件也可以通过其插件清单或默认的 hooks/hooks.json 文件捆绑生命周期配置。有关插件打包规则,请参阅构建插件。
实际使用中,最有用的四个位置是:
~/.codex/hooks.json~/.codex/config.toml<repo>/.codex/hooks.json<repo>/.codex/config.toml
如果存在多个钩子源,Codex 会加载所有匹配的钩子。优先级更高的配置层不会替换优先级更低的钩子。如果同一层同时包含 hooks.json 和内联 [hooks],Codex 会合并二者,并在启动时发出警告。建议每个配置层只使用一种表示形式。
Codex 还可以发现已启用插件中捆绑的钩子。插件捆绑的钩子会与其他钩子源一同加载,并使用与其他非托管钩子相同的信任审查流程。
只有在项目的 .codex/ 层受到信任时,项目本地钩子才会加载。在不受信任的项目中,Codex 仍会从各自活动配置层加载用户钩子和系统钩子。
审查并信任钩子
Section titled “审查并信任钩子”Codex 会在决定哪些钩子可以运行之前,列出已配置的钩子。非托管命令钩子运行前,Codex 要求你审查并信任确切的钩子定义。Codex 会根据钩子的当前哈希记录信任状态,因此新增或更改的钩子会被标记为待审查,并在获得信任前跳过。
在 CLI 中使用 /hooks 可以检查钩子源、审查新增或更改的钩子、信任钩子,或禁用单个非托管钩子。如果启动时有钩子需要审查,Codex 会打印警告,提示你打开 /hooks。
来自系统、MDM、云端或 requirements.toml 源的托管钩子会标记为托管,并根据策略自动获得信任,且无法从用户钩子浏览器中禁用。
对于已经在 Codex 外部审查过钩子源的一次性自动化任务,可以传递 --dangerously-bypass-hook-trust,使启用的钩子在此次调用中运行,而无需为本次调用持久化钩子信任状态。
钩子分为三个层级:
- 钩子事件,例如
PreToolUse、PostToolUse、PreCompact、SubagentStart或Stop - 决定事件何时匹配的匹配器组
- 在匹配器组匹配时运行的一个或多个钩子处理程序
{ "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" } ] } ], "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默认使用1秒,最多支持3秒。
statusMessage是可选的。commandWindows是仅限 Windows 的可选命令覆盖项。在 TOML 中,使用command_windows或commandWindows。async选项会被解析,但目前尚不支持异步命令钩子。- 目前只有
type: "command"处理程序会运行。prompt和agent处理程序会被解析但跳过。 - 命令以会话的
cwd作为工作目录运行。 - 对于仓库本地钩子,建议从 git 根目录解析路径,而不是使用
.codex/hooks/...之类的相对路径。Codex 可能从子目录启动,基于 git 根目录的路径可以保持钩子位置稳定。
config.toml 中等效的内联 TOML:
[[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 = 30statusMessage = "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 = 30statusMessage = "Reviewing Bash output"钩子默认处于启用状态。要在 config.toml 中关闭钩子,请设置:
[features]hooks = false使用 hooks 作为规范功能键。codex_hooks 仍可作为已弃用的别名使用。管理员也可以在 requirements.toml 中通过 [features].hooks = false 以相同方式强制关闭钩子。
来自 requirements.toml 的托管钩子
Section titled “来自 requirements.toml 的托管钩子”企业托管的要求也可以在 [hooks] 下内联定义钩子。当管理员希望强制执行钩子配置,同时通过 MDM 或其他设备管理系统提供实际脚本时,这种方式很有用。要让托管钩子对本地禁用了钩子的用户也强制生效,请在 requirements.toml 中与 [hooks] 一起固定设置 [features].hooks = true。如果要忽略用户、项目、会话和插件钩子,同时仍允许管理员托管的钩子,请设置 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 = 30statusMessage = "Checking managed Bash command"托管钩子的注意事项:
- macOS 和 Linux 使用
managed_dir。 - Windows 使用
windows_managed_dir。 - Codex 不会分发
managed_dir中的脚本;你的企业工具必须单独安装和更新这些脚本。 - 托管钩子命令应使用配置的托管目录下的绝对脚本路径。
allow_managed_hooks_only = true会跳过来自用户、项目、会话和插件源的钩子,但仍会从requirements.toml和其他托管配置层加载托管钩子。
插件捆绑的钩子
Section titled “插件捆绑的钩子”启用插件后,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 |
*对于 apply_patch,matcher 值还可以使用 Edit 或 Write。
示例:
Bash^apply_patch$Edit|Writemcp__filesystem__read_filemcp__filesystem__.*startup|resume|clear|compactmanual|auto
工具覆盖范围
Section titled “工具覆盖范围”PreToolUse 和 PostToolUse 可以观测的不仅是 shell 和 MCP 调用。大多数本地函数工具使用相同的钩子路径,因此你可以按工具名称进行匹配、检查其 JSON 参数,并且对于 PreToolUse,还可以阻止或重写调用。
| 工具路径 | PreToolUse |
PostToolUse |
备注 |
|---|---|---|---|
| Shell 命令 | 是 | 是 | 匹配为 Bash。 |
统一执行(exec_command) |
是 | 是 | 匹配为 Bash。后续的 write_stdin 轮询可以在该命令完成时传递原始命令的 PostToolUse。 |
apply_patch |
是 | 是 | 匹配为 apply_patch、Edit 或 Write。 |
| MCP 工具 | 是 | 是 | 匹配 MCP 工具名称,例如 mcp__filesystem__read_file。 |
| 其他本地函数工具 | 是 | 是 | 匹配函数工具名称,例如 update_plan。spawn_agent 也匹配 Agent。 |
托管工具,例如 WebSearch |
否 | 否 | 这些工具不使用本地函数工具钩子路径。 |
write_stdin 是现有统一执行会话的传输工具。当它向已经通过 PreToolUse 的命令发送输入或进行轮询时,不会再次运行 PreToolUse。
某些专用工具路径可以选择退出默认钩子路径。应将工具钩子视为有用的防护措施,而不是完整的强制执行边界。
通用输入字段
Section titled “通用输入字段”每个命令钩子都会从 stdin 接收一个 JSON 对象。
以下是你通常会使用的共享字段:
| 字段 | 类型 | 含义 |
|---|---|---|
session_id |
string |
当前 Codex 会话 ID。子智能体钩子使用父会话 ID。 |
transcript_path |
string | null |
会话 transcript 文件的路径(如果有) |
cwd |
string |
会话的工作目录 |
hook_event_name |
string |
当前钩子事件名称 |
model |
string |
Codex 特有的扩展。活动模型 slug |
轮次范围的钩子会在其事件专属表中将 turn_id 列为 Codex 特有的扩展。
SessionStart、PreToolUse、PermissionRequest、PostToolUse、UserPromptSubmit、SubagentStart、SubagentStop 和 Stop 还包含 permission_mode,用于描述当前权限模式:default、acceptEdits、plan、dontAsk 或 bypassPermissions。
transcript_path 为方便起见指向聊天 transcript,但 transcript 格式并不是钩子的稳定接口,未来可能会发生变化。
如果需要完整的线格式,请参阅架构。
通用输出字段
Section titled “通用输出字段”SessionStart、PreCompact、PostCompact、UserPromptSubmit、SubagentStop 和 Stop 支持以下共享 JSON 字段。SubagentStart 对 systemMessage 和钩子专属上下文接受相同的结构,但 continue: false 不会停止子智能体:
{ "continue": true, "stopReason": "optional", "systemMessage": "optional", "suppressOutput": false}| 字段 | 作用 |
|---|---|
continue |
如果为 false,则将该钩子运行标记为已停止 |
stopReason |
记录停止原因 |
systemMessage |
在界面或事件流中显示为警告 |
suppressOutput |
当前会被解析,但尚未实现 |
退出码为 0 且没有输出会被视为成功,Codex 会继续运行。
PreToolUse 和 PermissionRequest 支持 systemMessage,但目前不支持这些事件中的 continue、stopReason 和 suppressOutput。如果 PreToolUse 钩子返回其中任何不受支持的字段,Codex 会将该钩子运行标记为失败、报告错误,然后继续工具调用。
PostToolUse 支持 systemMessage、continue: false 和 stopReason。suppressOutput 会被解析,但目前不支持此事件。
较大的钩子输出
Section titled “较大的钩子输出”Codex 将每条对模型可见的钩子输出消息限制在大约 2,500 个 token。如果钩子返回更多内容,Codex 会将完整文本保存到 <temp_dir>/hook_outputs/<session_id>/<uuid>.txt,并向模型提供包含保存文件路径的头尾预览。如果无法写入文件,模型仍会收到截断后的预览。
这适用于来自 SessionStart、SubagentStart、PreToolUse、PostToolUse 和 UserPromptSubmit 的额外上下文、来自 PostToolUse 的反馈,以及来自 Stop 和 SubagentStop 的继续提示。该限制适用于每个额外上下文条目或继续提示。对于 PostToolUse 反馈,Codex 会合并所有匹配钩子的反馈,然后将限制应用于合并后的消息。
由于超大的输出可能会写入磁盘,请避免在钩子输出中返回机密或其他敏感数据。
SessionStart
Section titled “SessionStart”对于此事件,matcher 会应用于 source。
除通用输入字段之外的字段:
| 字段 | 类型 | 含义 |
|---|---|---|
source |
string |
会话的启动方式:startup、resume、clear 或 compact |
stdout 中的纯文本会作为额外的开发者上下文添加。
stdout 中的 JSON 支持通用输出字段以及以下钩子专属结构:
{ "hookSpecificOutput": { "hookEventName": "SessionStart", "additionalContext": "Load the workspace conventions before editing." }}该 additionalContext 文本会作为额外的开发者上下文添加。
SessionEnd
Section titled “SessionEnd”借助 SessionEnd,你可以在会话结束时运行命令,例如保存最终笔记或清理文件。当你归档或删除仍处于打开状态的对话、Codex 正常关闭,或者对话闲置且未在任何已连接客户端中打开达 30 分钟后,它会对主线程运行。它不会对子智能体运行。
切换离开对话或调用 thread/unsubscribe 不会立即结束会话,因此不会立即运行 SessionEnd。钩子运行时仍然可以读取会话 transcript。
对于此事件,matcher 会筛选 reason。目前 reason 始终为 other。你可以省略 matcher,或使用 other,以便在每个 SessionEnd 事件上运行。
除通用输入字段之外的字段:
| 字段 | 类型 | 含义 |
|---|---|---|
reason |
string |
会话结束的原因:other |
例如,SessionEnd 命令会接收:
{ "session_id": "thr_123", "transcript_path": "/workspace/.codex/rollout.jsonl", "cwd": "/workspace", "hook_event_name": "SessionEnd", "reason": "other"}SessionEnd 钩子仅提供建议。其输出不会引导 Codex,也不会使线程保持打开状态。如果命令超时或因错误退出,Codex 会将其报告为钩子失败。
SubagentStart
Section titled “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
Section titled “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." }}如需在不阻止操作的情况下重写受支持的工具调用,请返回 permissionDecision: "allow" 以及 updatedInput:
{ "hookSpecificOutput": { "hookEventName": "PreToolUse", "permissionDecision": "allow", "updatedInput": { "command": "echo rewritten" } }}对于 Bash 命令和 apply_patch,updatedInput 必须包含字符串类型的 command 字段。对于 MCP 和其他本地函数工具,updatedInput 是替换后的参数对象。仅在 permissionDecision: "allow" 时返回 updatedInput;其他形式的 updatedInput 都会被报告为错误。
permissionDecision: "ask"、旧版 decision: "approve"、continue: false、stopReason 和 suppressOutput 会被解析,但目前尚不支持。Codex 会将钩子运行标记为失败,报告错误,然后继续工具调用。
PermissionRequest
Section titled “PermissionRequest”当 Codex 即将请求批准时,PermissionRequest 会运行,例如需要提升 shell 权限或请求托管网络批准时。它可以允许请求、拒绝请求,或不作决定并让正常的批准提示继续显示。对于不需要批准的命令,它不会运行。
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 都优先。否则,allow 会让请求继续执行,而不会显示批准提示。如果没有匹配的钩子作出决定,Codex 会使用正常的批准流程。
不要为 PermissionRequest 返回 updatedInput、updatedPermissions 或 interrupt;这些字段为未来行为保留,目前会直接失败。
PostToolUse
Section titled “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 会将钩子运行标记为失败,报告错误,然后继续正常处理工具结果。
来自代码模式的工具调用
Section titled “来自代码模式的工具调用”当模型使用代码模式从 JavaScript 调用工具时,钩子决定会应用于该嵌套调用。PreToolUse 可以在工具运行前停止工具,或重写其输入。阻止性的 PostToolUse 无法撤销工具的副作用,但可以阻止原始结果传递给正在运行的脚本。
| 钩子结果 | 代码模式看到的结果 |
|---|---|
PreToolUse 阻止 |
工具运行前,工具 promise 被拒绝。 |
PreToolUse 返回 updatedInput |
工具使用重写后的输入运行,promise 解析为该结果。 |
PostToolUse 返回 decision: "block" 或以代码 2 退出 |
工具运行,然后 promise 因钩子原因被拒绝。 |
PostToolUse 返回 continue: false |
Codex 使用钩子反馈作为模型可见结果,但不会拒绝嵌套工具 promise。 |
PreCompact
Section titled “PreCompact”PreCompact 会在 Codex 压缩聊天内容之前运行。matcher 会应用于 trigger,其值为 manual 和 auto。
除通用输入字段之外的字段:
| 字段 | 类型 | 含义 |
|---|---|---|
turn_id |
string |
Codex 特有的扩展。当前 Codex 轮次 ID |
trigger |
string |
触发压缩的原因:manual 或 auto |
stdout 上的纯文本会被忽略。
stdout 上的 JSON 支持通用输出字段。如果匹配的 PreCompact 钩子返回 continue: false,Codex 会在压缩前停止。
PostCompact
Section titled “PostCompact”PostCompact 会在 Codex 压缩聊天内容后运行。matcher 会应用于 trigger,其值为 manual 和 auto。
除通用输入字段之外的字段:
| 字段 | 类型 | 含义 |
|---|---|---|
turn_id |
string |
Codex 特有的扩展。当前 Codex 轮次 ID |
trigger |
string |
触发压缩的原因:manual 或 auto |
stdout 上的纯文本会被忽略。
stdout 上的 JSON 支持通用输出字段。如果匹配的 PostCompact 钩子返回 continue: false,Codex 会在压缩后停止。
UserPromptSubmit
Section titled “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
Section titled “SubagentStop”对于此事件,matcher 会应用于 agent_type。
除通用输入字段之外的字段:
| 字段 | 类型 | 含义 |
|---|---|---|
turn_id |
string |
Codex 特有的扩展。当前 Codex 轮次 ID |
agent_id |
string |
子智能体的标识符 |
agent_type |
string |
子智能体类型或配置 |
agent_transcript_path |
string | null |
子智能体 transcript 文件的路径(如果有) |
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 钩子返回的继续决定。
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 钩子返回的继续决定。
链接的 main 分支模式可能包含当前版本中不存在的钩子字段。请以本页面作为当前版本行为的参考。
如需确切的当前线格式,请参阅 Codex GitHub repository 中生成的模式。