命令字典
Slash 命令、CLI 子命令、Hook 事件、启动参数的字典与演进史。
Slash 命令、CLI 子命令、Hook 事件、启动参数的字典与演进史。
查看和管理工具事件的Hook配置
/hooks 是 Claude Code 会话内的一条 Slash 命令,输入后打开一个只读交互式浏览器,用于查阅当前生效的所有 Hook 配置。
Hook 是用户定义的自动化处理程序——shell 命令、HTTP 端点、MCP 工具调用、LLM 提示词或子 agent——它们在 Claude Code agent 循环的固定生命周期事件点自动执行。/hooks 本身不新建、不修改任何 Hook,只负责展示。修改必须直接编辑 settings.json 文件。
在任意 Claude Code 会话中输入:
/hooks
无需参数,不接受参数。命令打开交互式浏览器,显示所有已配置的 Hook 事件及每个事件下的 Hook 数量,可向下钻取查看具体 matcher 和 handler 详情。
交互浏览器展示的信息:
User、Project、Local、Plugin、Session、Built-incommand、prompt、agent、http、mcp_tool/hooks 展示的内容来自多个层级的 settings.json,按优先级从低到高:
| 文件路径 | 作用范围 | 可提交到版本库 |
|---|---|---|
~/.claude/settings.json | 全局(所有项目) | 否 |
.claude/settings.json | 当前项目 | 是 |
.claude/settings.local.json | 当前项目(本地覆盖) | 否 |
Plugin hooks/hooks.json | 启用该 Plugin 时生效 | 是(随 Plugin 分发) |
| Skill / agent frontmatter | Skill/agent 激活期间生效 | 是 |
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/check.sh"
}
]
}
]
}
}
三层嵌套结构:顶层 hooks 对象 → 生命周期事件名(如 PreToolUse)→ matcher 分组 → handler 数组。
| 类型 | 关键字段 | 说明 |
|---|---|---|
command | command、args、async、asyncRewake、shell | 执行 shell 命令,stdin 接收 JSON |
http | url、headers、allowedEnvVars | POST 事件 JSON 到指定 URL |
mcp_tool | server、tool、input | 调用已连接 MCP server 上的工具 |
prompt | prompt、model | 向 Claude 模型发送 yes/no 判断请求 |
agent | prompt、model | 启动子 agent,可使用工具进行复杂验证 |
所有 handler 类型共有字段:type(必填)、if(权限规则过滤)、timeout(超时秒数)、statusMessage(自定义 spinner 提示文字)。
在 command 和 args 中可用:
${CLAUDE_PROJECT_DIR} — 项目根目录${CLAUDE_PLUGIN_ROOT} — Plugin 安装目录${CLAUDE_PLUGIN_DATA} — Plugin 的持久化数据目录会话级:SessionStart、Setup、SessionEnd
每轮次:UserPromptSubmit、UserPromptExpansion、Stop、StopFailure、TeammateIdle
工具调用:PreToolUse、PermissionRequest、PermissionDenied、PostToolUse、PostToolUseFailure、PostToolBatch
其他:Notification、MessageDisplay、SubagentStart/Stop、TaskCreated/Completed、ConfigChange、CwdChanged、FileChanged、PreCompact/PostCompact、WorktreeCreate/Remove、Elicitation/ElicitationResult、InstructionsLoaded
| 写法 | 匹配逻辑 |
|---|---|
"*"、""、或省略 | 匹配所有触发 |
| 纯字母/数字/下划线 | 精确匹配工具名,| 分隔表示 OR,如 Edit|Write |
| 含其他字符 | 作为 JavaScript 正则,如 ^Notebook 或 mcp__memory__.* |
MCP 工具命名格式为 mcp__<server>__<tool>,可用 mcp__memory__.* 匹配某 server 下所有工具。
连字符标识符现为精确匹配(v2.1.195):v2.1.195 修复了含连字符的标识符(如
code-reviewer、mcp__brave-search)此前被当成子串匹配的 bug——它们现在改为精确匹配。后果是:若想匹配某个 hyphenated MCP server 下的全部工具,不能再只写 server 名mcp__brave-search(它现在只精确匹配那个同名工具,匹配不到具体工具),必须显式写正则mcp__brave-search__.*。来源:Claude Code changelog v2.1.195 —— "Fixed hook matchers with hyphenated identifiers ... they now exact-match. Usemcp__brave-search__.*to match all tools from a hyphenated MCP server."
逗号不是 OR 分隔符(v2.1.191):matcher 里写逗号分隔(如
"Bash,PowerShell")在旧版本会静默失效——它既不报错也匹配不到任何工具。OR 必须用|(写成"Bash|PowerShell")。v2.1.191 起相关行为被修正/明确。把多个工具名用逗号连起来是高频实操陷阱,务必改用|。
| 约束 | 原因 |
|---|---|
/hooks 界面为只读 | 修改入口统一为 settings.json,避免 UI 与文件状态不一致 |
| exit code 2 才触发阻断 | 其他非零退出码仅记录为非阻断错误,不中止工具调用 |
| 阻断效果因事件而异 | PreToolUse 的 exit 2 阻止工具执行;PostToolUse 的 exit 2 不阻断(工具已执行完毕),stderr 显示在 transcript 首行 |
disableAllHooks: true 可全局禁用 | 设置项存在于 settings.json 顶层 |
command 类型)| exit code | 含义 |
|---|---|
0 | 成功;stdout 被解析为 JSON 输出 |
2 | 阻断错误;stderr 作为错误信息反馈给 Claude 或用户 |
| 其他非零值 | 非阻断错误;transcript 中仅显示 stderr 首行 |
| 字段 | 作用 |
|---|---|
continue: false | 配合 stopReason 立即终止 Claude |
suppressOutput | 隐藏 hook stdout,不显示到 transcript |
systemMessage | 向用户展示警告 |
hookSpecificOutput.additionalContext | 向 Claude 注入额外上下文(嵌套在 hookSpecificOutput 下) |
hookSpecificOutput.decision: "block" | 在 UserPromptSubmit、Stop 等事件上阻断(嵌套在 hookSpecificOutput 下) |
hookSpecificOutput.permissionDecision | 在 PreToolUse 上精细控制 "allow"/"deny"/"ask"/"defer" |
下表为官方 Hooks 文档收录的全部生命周期事件及触发时机(一句话用途)。官方仅 SessionStart、Setup、UserPromptSubmit、InstructionsLoaded 4 个事件带完整 input schema,其余带触发说明。注:Claude Code 详情页对各 hook-<event> 子路径统一重定向回本页,本表即其落点。
| 事件 | 触发时机 |
|---|---|
SessionStart | 会话开始或被恢复时(带完整 input schema) |
Setup | 以 --init-only 启动,或 -p 模式下带 --init / --maintenance 时(带完整 input schema) |
InstructionsLoaded | 某个 CLAUDE.md 或 .claude/rules/*.md 文件被载入上下文时(带完整 input schema) |
UserPromptSubmit | 你提交一条 prompt、Claude 处理之前(带完整 input schema) |
UserPromptExpansion | 用户输入的命令展开成 prompt、到达 Claude 之前 |
PreToolUse | 某次工具调用执行之前 |
PermissionRequest | 弹出权限确认对话框时 |
PermissionDenied | 工具调用被自动模式分类器拒绝时 |
PostToolUse | 某次工具调用成功之后 |
PostToolUseFailure | 某次工具调用失败之后 |
PostToolBatch | 一整批并行工具调用全部 resolve 之后 |
Notification | Claude Code 发出通知时 |
MessageDisplay | 助手消息文本正在展示期间 |
SubagentStart | 子 agent 被启动时 |
SubagentStop | 子 agent 结束时 |
TaskCreated | 通过 TaskCreate 创建任务时 |
TaskCompleted | 任务被标记为完成时 |
Stop | Claude 结束本轮回复时 |
StopFailure | 本轮因 API 错误而结束时 |
TeammateIdle | agent 团队的某个队友即将转入 idle 时 |
ConfigChange | 会话期间某个配置文件发生变化时 |
CwdChanged | 工作目录变化时 |
FileChanged | 被监视的文件在磁盘上变化时 |
WorktreeCreate | 通过 --worktree 或 isolation: "worktree" 创建 worktree 时 |
WorktreeRemove | worktree 被移除时 |
PreCompact | 上下文压缩之前 |
PostCompact | 上下文压缩完成之后 |
Elicitation | 某个 MCP server 在工具调用中请求用户输入时 |
ElicitationResult | 用户对 MCP elicitation 作出响应之后 |
SessionEnd | 会话终止时 |
| 命令 | 作用 | 可修改配置 |
|---|---|---|
/hooks | 只读查看所有 Hook 配置 | 否,须手动编辑 JSON |
/permissions | 查看并管理工具权限规则 | 是(交互式) |
/mcp | 查看 MCP server 连接状态及工具列表 | 否(连接配置在 settings.json) |
/config | 修改主题、模型等基础会话配置 | 是 |
/hooks,确认 PreToolUse 下的安全拦截脚本已从 .claude/settings.json 正确加载,来源标签应显示 Project/hooks 钻取对应事件,检查 matcher 模式是否与实际工具名匹配/hooks 确认其注入的 Built-in 标签 Hook 覆盖范围,评估是否与自有规则冲突User(全局)还是 Project(项目级),判断是否需要在 settings.local.json 覆盖/hooks 看到的是当前合并状态:多层 settings.json 叠加后的结果会一起展示,来源标签是唯一区分方式;若同名事件在多层都有配置,/hooks 会全部显示,但实际执行顺序取决于优先级。PostToolUse 无法回滚已执行的工具:工具调用完成后 Hook 才触发,exit 2 此时不阻断(工具已执行),stderr 仅显示在 transcript 首行,不能撤销操作。真正的拦截必须放在 PreToolUse。"Bash,PowerShell" 不是 OR(逗号会静默失效),OR 必须用 |;要匹配 mcp__brave-search 这种带连字符的 server 下全部工具,v2.1.195 后必须写 mcp__brave-search__.*,光写 mcp__brave-search 只精确匹配同名工具、匹配不到具体工具。详见上文 Matcher 匹配规则下的两条版本说明。git push --force下面是一个 PreToolUse(matcher Bash)的 command hook,用 jq 从 stdin 读取工具调用 JSON,命中 git push --force / -f 时以 exit 2 阻断:
#!/usr/bin/env bash
# .claude/hooks/block-force-push.sh
# 配在 PreToolUse / matcher "Bash";stdin 是该次工具调用的 JSON
cmd="$(jq -r '.tool_input.command // ""')"
if printf '%s' "$cmd" | grep -Eq 'git[[:space:]]+push.*(--force([[:space:]]|=|$)|[[:space:]]-f([[:space:]]|$))'; then
echo "blocked: force push is not allowed via Claude Code" >&2
exit 2 # PreToolUse 下 exit 2 = 阻止该工具执行,stderr 反馈给 Claude
fi
exit 0
对应 settings.json 片段:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{ "type": "command", "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/block-force-push.sh" }
]
}
]
}
}
记得 chmod +x。注意 exit 2 只在 PreToolUse 等"工具执行前"事件才有阻断力(见上文 exit code 语义表)。