一、一句话摘要
二、为什么需要精细的输出控制
退出码 0 放行、退出码 2 阻断——对简单的"拦截/放行"场景足够。但自动批准安全操作、修改工具输入参数、权限请求时动态添加持久化规则,这些需求单靠退出码无法表达。
stdout JSON 输出是第二条通道,把 Hook 的输出从二元信号扩展为结构化指令——允许、拒绝、询问、修改输入、动态更新权限规则,都通过 JSON 字段实现。
stderr 是第三条通道。退出码 2 阻断操作时,stderr 的文本作为反馈发送给 Claude,告知阻止原因,Claude 据此调整方案。
三、核心内容
三通道输出行为
三个通道在不同退出码下的行为:
退出码 0 和其他非 2 退出码都让操作继续,但只有退出码 0 的 stdout 会被解析。退出码 1 等非零非 2 退出码表示 Hook 脚本自身出错,Claude Code 静默跳过。
退出码 2 + stderr 反馈是最常用的阻断模式:
Claude 收到 stderr 文本后会据此调整方案——比如改用更安全的删除方式。
stderr 的第二个用途是调试。退出码非 2 时 stderr 不影响 Claude,但会记录到 verbose 日志:
通过 Ctrl+O 切换 verbose 模式可以查看这些日志。
输出控制规则
permissionDecision 三种决策
PreToolUse 事件的 stdout JSON 通过 permissionDecision 字段表达三种决策: