第 7 章 · 01 事件与配置结构


文档摘要

第 7 章 · 01 事件与配置结构 本节摘要:Hooks 的骨架是"事件 → 配置 → handler"。31 个事件分四组:Tool(工具调用前后)、Session(会话启停与状态)、Task(任务/子代理/停止)、Lifecycle(工作树)。配置写在 settings 文件里,结构是 ;matcher 还能叠加 参数条件,精确到"哪个工具、哪类参数"。五种 handler 各有分工:command 跑脚本、http 发 webhook、prompt 让 LLM 评估、mcptool 直调 MCP 工具、agent 派子代理核查。 学习目标 阅读完本节,你应当能够: 说出 31 个事件四组分类,并指出哪些事件支持阻断。 说出 hooks 的五个配置位置与作用范围。

第 7 章 · 01 事件与配置结构

本节摘要:Hooks 的骨架是"事件 → 配置 → handler"。31 个事件分四组:Tool(工具调用前后)、Session(会话启停与状态)、Task(任务/子代理/停止)、Lifecycle(工作树)。配置写在 settings 文件里,结构是 事件名 → matcher(匹配工具) → hooks(处理器数组);matcher 还能叠加 if 参数条件,精确到"哪个工具、哪类参数"。五种 handler 各有分工:command 跑脚本、http 发 webhook、prompt 让 LLM 评估、mcp_tool 直调 MCP 工具、agent 派子代理核查。

学习目标

阅读完本节,你应当能够:

  1. 说出 31 个事件四组分类,并指出哪些事件支持阻断。
  2. 说出 hooks 的五个配置位置与作用范围。
  3. 写出含 matcher 与 if 条件的基本配置,并解释 matcher 与 if 的分工。
  4. 说出五种 handler 类型并各举一个适用场景。

一、31 个事件:四组分类

Hooks 由事件驱动。31 个事件按触发面分为四组:

Tool 组(12 个):工具调用的前后与交互

事件 触发时机 可阻断 典型用途
UserPromptSubmit 用户提交提示词 校验提示词
UserPromptExpansion 提示词展开(@引用/斜杠命令解析后) 检查展开后的内容
PreToolUse 工具执行前 ✅(allow/deny/ask) 校验/改写工具输入
PermissionRequest 权限弹窗出现时 自动批准/拒绝
PermissionDenied 用户拒绝权限 日志/策略执行
PostToolUse 工具成功后 ❌(可 block 反馈) 补充上下文/反馈
PostToolUseFailure 工具失败后 错误处理/日志
PostToolBatch 一批工具调用完成后 聚合报告/批量校验
Notification 发送通知时 自定义通知
MessageDisplay 助手消息显示时 转换/隐藏显示文本
Elicitation MCP 服务器请求用户输入时 输入校验
ElicitationResult 用户响应 Elicitation 后 响应处理

Session 组(10 个):会话生命周期

事件 触发时机 可阻断 典型用途
SessionStart 会话开始/恢复/清除/压缩/分支 环境初始化、持久化环境变量
Setup 每会话一次的环境设置 安装依赖、准备工具
InstructionsLoaded CLAUDE.md 等加载后 修改/过滤指令
ConfigChange 配置文件变化 ✅(策略除外) 响应配置更新
CwdChanged 工作目录变化 按目录初始化
DirectoryAdded 会话中途新增工作目录 为新目录准备工具链
FileChanged 被监听文件变化 文件监控/重建
PreCompact 上下文压缩前 压缩前动作
PostCompact 压缩完成后 压缩后动作
SessionEnd 会话终止 清理/最终日志

Task 组(7 个):任务与子代理

事件 触发时机 可阻断 典型用途
SubagentStart 子代理启动 子代理初始化
SubagentStop 子代理结束 子代理产出校验
Stop Claude 回复结束 任务完成检查
StopFailure API 错误终止回合 错误恢复/日志
TeammateIdle Agent 团队队员空闲 队员协调
TaskCompleted 任务标记完成 任务后动作
TaskCreated 任务创建 任务跟踪/日志

Lifecycle 组(2 个):工作树

事件 触发时机 可阻断 典型用途
WorktreeCreate 工作树创建中 ✅(返回路径) 工作树初始化
WorktreeRemove 工作树移除 工作树清理

记忆口诀:Tool 管"用工具",Session 管"会话生灭",Task 管"任务与代理",Lifecycle 管"工作树"。能阻断的事件集中在"事情发生之前或刚结束时"——拦截窗口一旦错过,就只剩反馈权。

二、配置位置:五个落点

位置 范围
~/.claude/settings.json 用户级,所有项目
.claude/settings.json 项目级,可提交共享
.claude/settings.local.json 本地项目级,不提交
受管策略(managed policy) 组织级
插件 hooks/hooks.json 插件作用域,用 ${CLAUDE_PLUGIN_ROOT} 引用插件目录
技能/代理 frontmatter 组件生命周期钩子,与组件代码同处存放

组件级钩子支持的事件只有三个:PreToolUse、PostToolUse、Stop——把钩子直接写进 SKILL.md、agent.md、command.md 的 frontmatter,相关代码聚在一起。特别注意:子代理 frontmatter 里的 Stop 钩子会被自动转换为 SubagentStop 并限定在该代理上,只在它完成时触发,不会连累主会话。

三、基本结构:事件 → matcher → hooks

{ "hooks": { "EventName": [ { "matcher": "ToolPattern", "hooks": [ { "type": "command", "command": "your-command-here", "timeout": 60 } ] } ] } }

关键字段:

字段 说明 示例
matcher 匹配工具名的模式(区分大小写) "Write""Edit|Write""*"
hooks 处理器数组,同一事件可挂多个 [{ "type": "command", ... }]
type handler 类型 "command"/"prompt"/"http"/"mcp_tool"/"agent"
command Shell 命令 "$CLAUDE_PROJECT_DIR/.claude/hooks/format.sh"
timeout 超时秒数(默认 60) 30
once 每会话只跑一次 true

matcher 模式

模式 说明 示例
精确串 匹配特定工具 "Write"
正则 匹配多个工具 "Edit|Write"
逗号分隔 命中任一工具(v2.1.191+) "Write,Edit"
通配 全部工具 "*"""
MCP 工具 服务器+工具模式 "mcp__memory__.*"

注意(v2.1.195+):matcher 是精确匹配,带连字符的 MCP 工具名不再误伤其他工具;逗号分隔写法在旧版本里是"静默永不触发"的 bug,升级后才生效。InstructionsLoaded 事件特殊,matcher 取 session_start/nested_traversal/path_glob_match 之一。

if 条件:从"哪个工具"精确到"哪次调用"

matcher 按工具名选钩子;要按工具参数过滤(比如只在编辑 src/ 下文件时触发,或拦截读密钥文件),在单个 handler 上加 if。matcher 决定"哪个工具",if 决定"哪次调用":

{ "hooks": { "PreToolUse": [ { "matcher": "Edit|Write", "hooks": [ { "type": "command", "if": "Edit(src/**)", "command": "./hooks/lint-src.sh" } ] }, { "matcher": "Read", "hooks": [ { "type": "command", "if": "Read(.env)", "command": "./hooks/block-secret-read.sh" } ] } ] } }

if 用权限规则语法(ToolName(pattern)),对工具名与参数一并求值;路径遵循 gitignore 语义,锚点与权限规则一致:裸名 .env 匹配任意深度、src/** 相对当前目录、/src/** 相对项目根、~/... 用户主目录、//... 绝对路径。常见写法:Edit(src/**)(编辑 src 下)、Read(~/.ssh/**)(读 SSH 密钥)、Bash(git push *)(仅 git push)。

四、五种 handler 类型

  1. command(默认):执行 Shell 命令,通过 JSON stdin/stdout 与退出码通信。覆盖绝大多数场景——校验、格式化、日志。
  2. http(v2.1.63+):POST JSON 到远端 Webhook,同样收到 JSON 响应。URL 里的环境变量插值必须显式 allowedEnvVars 白名单,防止敏感变量泄漏到远端。沙箱启用时 HTTP 钩子走沙箱路由。
  3. prompt:钩子内容是一段提示词,交给 LLM 评估,返回结构化决策。主要用于 Stop/SubagentStop 的"任务是否完成"智能检查。
  4. mcp_tool(v2.1.118+):直接调用已配置的 MCP 服务器上的工具,配置只写服务器名与工具名——校验逻辑本来就在 MCP 服务器里时最合适,钩子输入原样作为工具参数。
  5. agent:派一个专用子代理做多步核查。与 prompt 钩子(单回合 LLM 评估)不同,agent 钩子能用工具、能多步推理,适合需要查文档、对比代码的复杂验证。

五、环境变量速查

钩子脚本可用的环境变量:所有钩子都有 CLAUDE_PROJECT_DIR(项目根绝对路径);CLAUDE_ENV_FILE 只在 SessionStart/CwdChanged/FileChanged 有(用于持久化环境变量);CLAUDE_CODE_REMOTE 标识远端运行;插件钩子有 ${CLAUDE_PLUGIN_ROOT}${CLAUDE_PLUGIN_DATA};Bash 子进程还注入 CLAUDE_CODE_SESSION_ID(与钩子 JSON 的 session_id 对应)与 CLAUDE_EFFORT(当前 effort 等级)。

小结

Hooks 的骨架一句话:31 个事件按 Tool/Session/Task/Lifecycle 四组分布,配置按"事件 → matcher → handlers"组织,matcher 选工具、if 选调用,五种 handler 从跑脚本到派子代理各有分工。能阻断的事件集中在"执行前/刚结束时",组件级钩子只有 PreToolUse/PostToolUse/Stop 三件套。下一节精读 8 个官方示例脚本,看真实钩子怎么落地。

下一节预告:第 2 节精读示例脚本——命令校验、安全扫描、自动格式化、智能 Stop、上下文追踪。


发布者: 作者: 灏天文库 转发
评论区 (0)
U