一、一句话摘要
二、为什么需要多 Hook 协同
一个 SessionStart Hook 能初始化环境,一个 PreToolUse Hook 能拦截危险操作。但"初始化环境 → 基于环境信息拦截 → 记录操作 → 收尾统计"这条完整链路,单个 Hook 无法完成——每个事件只在特定时刻触发,Hook 之间默认不共享状态。
需要解决的问题:Hook 之间如何传递数据?多个 Hook 挂载同一事件时谁先执行?一个 Hook 失败是否影响其他 Hook?
三、核心内容
多 Hook 协同的可观察行为
同一事件挂载多个 Hook 时的执行行为:
同一事件下的多个 matcher 条目按 settings.json 中的声明顺序依次执行。同一 matcher 内的多个处理器也按声明顺序执行。
当 Claude 调用 Bash 工具时,check-a.sh 先执行,check-b.sh 后执行。如果 check-a.sh 返回退出码 2(阻断),check-b.sh 不再执行,工具调用被取消。
跨事件的数据传递行为:
不同事件的 Hook 之间没有直接通信通道。SessionStart 写入 $CLAUDE_ENV_FILE 的环境变量,在后续 PreToolUse/PostToolUse Hook 中可通过 $变量名 读取——这是 Hook 间传递数据的主要方式。
另一种方式是共享文件:一个 Hook 写入文件,另一个 Hook 读取该文件。
协同设计模式的规则
三种多 Hook 协同模式,每种有不同的触发条件和数据流方向。