Skip to content
FunCoding

Search

Search docs, Skills and MCP

工具 Hooks 与审批决策

区分运行前阻断、审批请求决策、运行后反馈,以及 code mode 中 Promise 的结果。

This page has not been translated into English yet. The original Chinese version is shown below.

工具事件通过 matcher 正则匹配工具名。apply_patch 可匹配 Edit 或 Write,但载荷仍报告规范名 apply_patch。Bash 和 apply_patch 的输入使用 tool_input.command;其他本地工具和 MCP 使用自己的参数对象。

PreToolUse:执行前处理

输入包含 turn_id、tool_name、tool_use_id 与 tool_input。阻止已覆盖的工具调用可返回:

{
  "hookSpecificOutput": {
    "hookEventName": "PreToolUse",
    "permissionDecision": "deny",
    "permissionDecisionReason": "Destructive command blocked by hook."
  }
}

也支持旧式 decision: "block" 加 reason,或 exit 2 并把原因写入 stderr。增加上下文可使用 hookSpecificOutput.additionalContext。

需要重写参数时,只能将 updatedInput 与 permissionDecision: "allow" 一起返回。Bash/apply_patch 的新输入必须包含字符串 command,其他工具使用完整替代参数对象。

permissionDecision: "ask"、旧式 decision: "approve"、continue: false、stopReason、suppressOutput 当前不受支持。返回这些字段会使 Hook 失败并报告错误,随后继续工具调用;不能用它们建立拒绝策略。

PermissionRequest:审批前决策

只在 Codex 即将请求审批时运行,无需审批的调用不会触发。输入包括 turn_id、tool_name、tool_input;某些输入还提供 description,但不能假定总存在。

{
  "hookSpecificOutput": {
    "hookEventName": "PermissionRequest",
    "decision": {
      "behavior": "deny",
      "message": "Blocked by repository policy."
    }
  }
}

behavior: "allow" 可允许请求。多个处理器中任何 deny 优先;没有 deny 时,allow 允许继续且不显示审批提示;没人做决定时回到正常审批流程。updatedInput、updatedPermissions、interrupt 为保留字段,当前使用会 fail closed,应避免返回。

PostToolUse:处理已经发生的结果

输入在工具字段外增加 tool_response;Bash 非零退出也会触发。可以注入 additionalContext,或用 decision: "block" 加 reason(也可 exit 2 + stderr)替换反馈。但它不能撤销已经执行的命令或外部副作用。

continue: false 停止对原工具结果的正常处理,用 Hook 反馈继续模型流程。updatedMCPToolOutput 和 suppressOutput 尚不支持;Hook 会失败并继续正常结果处理。

Code mode 的嵌套调用

PreToolUse 阻断会在执行前让工具 Promise reject;重写则用新参数执行。PostToolUse block 或 exit 2 会在执行后让 Promise reject。PostToolUse 的 continue false 只替换模型可见反馈,不会让嵌套 Promise reject。

应分别测试拒绝、允许、无决定、超时和无效输出路径。一个 Hook 报错不等于对应动作已被成功拦截。