Claude Code Hooks 详解:围绕 Agent 的确定性层
什么是 Claude Code hooks? Hooks 是用户自定义的 shell 命令(外加 HTTP 端点、MCP 工具和模型提示词),由 Claude Code 在其生命周期的固定节点自动执行:工具调用之前、编辑之后、会话启动时、Claude 结束响应时。1 CLAUDE.md 给模型的是它大概率会遵循的指令,而 hooks 无论模型是否配合都会执行。在任意会话中输入 /hooks,即可查看每个生命周期事件以及挂载在其上的内容。
{.answer-block}
大多数开发者运行 Claude Code 时依赖两层控制:权限限定 agent 可以做什么,CLAUDE.md 描述它应该做什么。Hooks 是第三层,也是唯一能提供保证的一层。下文包括:心智模型、当前文档中的全部生命周期事件、精确的输入/输出契约、配置方式、五个可用的模式,以及一个决策框架。所有 API 细节均已对照官方 hooks 参考文档和指南核实(截至 2026 年 7 月 1 日)——这套系统迭代很快,如果本文与参考文档有出入,以参考文档为准。(刚接触 Claude Code?不妨从 5 分钟上手或 Claude Code 新手路径开始。)
TL;DR: Hooks 从 stdin 接收 JSON,并通过退出码或 stdout 上的 JSON 作出应答。退出码 0 表示放行,退出码 2 表示阻止(仅对支持阻止的事件有效),而退出码 1——Unix 惯例中的失败码——什么都不会阻止,这是 hooks 最大的一个坑。2 在 settings.json 中以 PreToolUse、Stop 等事件名进行配置,并用 matcher 过滤。凡是必须每次都发生的事情用 hooks;模型只需知道的事情用 CLAUDE.md。
心智模型:非确定性内核之外的确定性保证
编码 agent 是一个概率系统。让它每次编辑后运行 Prettier,它会照做——大多数时候。当改动看起来微不足道、上下文过长,或者您的措辞恰好换了个说法时,它可能就跳过这一步。CLAUDE.md、技能(skills)和提示词都只是建议:质量很高,通常会被遵循,但从无保证。
Hooks 就是包裹这个内核的确定性外壳。官方定义是:”用户自定义的 shell 命令、HTTP 端点或 LLM 提示词,在 Claude Code 生命周期的特定节点自动执行”,从而提供”对 Claude Code 行为的确定性控制,确保某些操作始终发生,而不是依赖 LLM 自己选择是否运行”。3 格式化器在每次编辑后触发。命令守卫评估每一次 Bash 调用。完成门控检查每一次收尾。
这种强制力是真实的,而非装饰性的:PreToolUse hooks 在任何权限模式检查之前触发,因此返回 permissionDecision: "deny" 的 hook 即使在 bypassPermissions 模式下或使用 --dangerously-skip-permissions 时也能阻止该工具。反过来则不成立——返回 "allow" 的 hook 无法放宽 settings 中的 deny 规则。Hooks 可以把策略收得比权限更紧,但永远不能放松它。4
生命周期:全部 hook 事件
截至 2026 年 7 月 1 日,参考文档共记录了 30 个 hook 事件。1 它们按三种节奏划分:每会话一次(SessionStart、SessionEnd)、每轮对话一次(UserPromptSubmit、Stop、StopFailure),以及 agentic 循环内的每次工具调用(PreToolUse、PostToolUse)。其余事件在特定条件下触发——配置变更、上下文压缩、子代理、MCP 交互。
| 事件 | 触发时机 | 一个实际用途 |
|---|---|---|
SessionStart |
会话开始或恢复 | 将 git 分支和未关闭的 issue 注入为上下文 |
Setup |
--init-only,或 -p 模式下的 --init/--maintenance |
在 agent 运行前于 CI 中安装依赖 |
UserPromptSubmit |
您提交提示词后、Claude 处理之前 | 附加当前日期;拒绝包含机密信息的提示词 |
UserPromptExpansion |
键入的命令展开为提示词时 | 审计或否决技能/命令的展开 |
PreToolUse |
工具调用执行之前 | 阻止破坏性 shell 命令 |
PermissionRequest |
权限对话框出现时 | 自动批准可信命令,免去人工确认 |
PermissionDenied |
自动模式分类器拒绝工具调用时 | 返回 retry: true,允许模型重试 |
PostToolUse |
工具调用成功之后 | 自动格式化每个被编辑的文件 |
PostToolUseFailure |
工具调用失败之后 | 记录失败命令以便排查 |
PostToolBatch |
一批并行工具调用结束后、下一次模型调用之前 | 为 agentic 循环设检查点或中止它 |
Notification |
Claude Code 发送通知时 | Claude 需要输入时弹出桌面提醒 |
MessageDisplay |
助手消息文本显示期间 | 屏幕显示脱敏(仅影响显示;会话记录不变) |
SubagentStart |
子代理被启动时 | 注入特定 agent 类型的上下文 |
SubagentStop |
子代理完成时 | 在子代理输出返回前进行校验 |
TaskCreated |
通过 TaskCreate 创建任务时 |
强制执行任务命名或范围规则 |
TaskCompleted |
任务被标记为完成时 | 在完成生效前核验验收标准 |
Stop |
Claude 结束响应时 | 完成门控:测试通过前阻止收尾 |
StopFailure |
对话轮因 API 错误而结束时 | 对 rate_limit 或 billing_error 发出警报(仅记录;输出被忽略) |
TeammateIdle |
agent 团队成员即将进入空闲时 | 让团队成员持续处理队列中的工作 |
InstructionsLoaded |
CLAUDE.md 或 .claude/rules/*.md 文件加载进上下文时 |
记录哪些指令进入了会话 |
ConfigChange |
会话中途配置文件发生变化时 | 阻止未经授权的设置修改 |
CwdChanged |
工作目录变化时 | 重新加载 direnv 风格的环境 |
FileChanged |
被监视的文件在磁盘上发生变化时 | .env 变化时刷新环境变量 |
WorktreeCreate |
通过 --worktree 或 isolation: "worktree" 创建 worktree 时 |
替换默认的 git worktree 供给流程 |
WorktreeRemove |
worktree 被移除时 | 在会话或子代理退出时执行自定义清理 |
PreCompact |
上下文压缩之前 | 保存不容丢失的状态 |
PostCompact |
压缩完成之后 | 重新注入关键上下文 |
Elicitation |
MCP 服务器请求用户输入时 | 在无头(headless)运行中自动填写表单 |
ElicitationResult |
您回应 MCP elicitation 之后 | 在响应返回前校验或覆盖它 |
SessionEnd |
会话终止时 | 归档日志、清理资源 |
其中大多数您都用不上。几乎所有生产环境的配置都由五个事件构成:PreToolUse、PostToolUse、UserPromptSubmit、SessionStart 和 Stop。其余的留待需要的那天再用。
契约:JSON 进,退出码或 JSON 出
命令型 hooks 从 stdin 接收 JSON,并通过退出码、stdout 和 stderr 作出应答。(HTTP 型 hooks 以 POST 请求体的形式接收同样的 JSON,通过响应体应答。)2
每个事件都会传递一个通用信封——session_id、transcript_path、cwd 和 hook_event_name,大多数事件还带有 permission_mode——外加事件特有的字段。针对 Bash 命令的 PreToolUse hook 会收到:
{
"session_id": "abc123",
"transcript_path": "/home/user/.claude/projects/.../transcript.jsonl",
"cwd": "/home/user/my-project",
"permission_mode": "default",
"hook_event_name": "PreToolUse",
"tool_name": "Bash",
"tool_input": { "command": "npm test" }
}
其他事件替换的是尾部字段:UserPromptSubmit 携带 prompt,SessionStart 携带 source(startup/resume/clear/compact),Stop 携带 stop_hook_active 和 last_assistant_message。在子代理内部触发的 hooks 还会额外收到 agent_id 和 agent_type。2
退出码
三种结果:2
- 退出码 0——成功。Claude Code 会解析 stdout 中的 JSON 输出字段。对大多数事件而言,stdout 只进入调试日志;而对
UserPromptSubmit、UserPromptExpansion和SessionStart,纯文本 stdout 会作为 Claude 可见的上下文加入。 - 退出码 2——阻止性错误。stdout(包括其中的任何 JSON)会被忽略;stderr 作为错误消息反馈给 Claude。”阻止”的具体含义取决于事件。
- 其他任何退出码——非阻止性错误。会话记录中会显示
<hook name> hook error提示,执行继续。
最后这一条值得加粗:退出码 1 不会阻止任何东西。 文档对此有直接警告——尽管 1 是 Unix 惯例中的失败码,Claude Code 仍将退出码 1 视为非阻止性错误并继续执行。策略类 hooks 必须 exit 2。2
退出码 2 在各事件上的效果:2
| 事件 | 退出码 2 的效果 |
|---|---|
PreToolUse |
阻止该工具调用 |
PermissionRequest |
拒绝该权限 |
UserPromptSubmit |
阻止处理并清除该提示词 |
UserPromptExpansion |
阻止展开 |
Stop / SubagentStop |
阻止停止;对话继续 |
TeammateIdle |
阻止该团队成员进入空闲 |
TaskCreated / TaskCompleted |
回滚创建/阻止完成 |
ConfigChange |
阻止配置变更(policy_settings 除外) |
PreCompact |
阻止压缩 |
PostToolBatch |
在下一次模型调用前停止 agentic 循环 |
Elicitation / ElicitationResult |
拒绝该 elicitation/将响应转为拒绝 |
WorktreeCreate |
任何非零退出码都会中止 worktree 创建 |
其余事件都无法阻止。PostToolUse 和 PostToolUseFailure 会把 stderr 展示给 Claude(工具已经运行过了);SessionStart、Notification、SessionEnd、CwdChanged、FileChanged、PostCompact、SubagentStart 和 Setup 只把 stderr 展示给用户;StopFailure、InstructionsLoaded、MessageDisplay 和 PermissionDenied 会忽略退出码——对 PermissionDenied 而言,唯一的控制手段是 JSON 的 retry: true。2
JSON 输出
如果需要比”阻止或沉默”更精细的控制,可以以退出码 0 结束并向 stdout 打印一个 JSON 对象。先记住一条规则:退出码和 JSON 二选一,绝不同时用——JSON 只在退出码为 0 时被处理,退出码 2 会将其丢弃。5
通用字段对每个事件都有效:continue: false 让 Claude 完全停止(stopReason 会展示给用户),suppressOutput 在会话记录中隐藏 stdout,systemMessage 向用户显示一条警告,terminalSequence 发出一个在允许列表内的终端转义序列(桌面通知、窗口标题、响铃)。决策字段则因事件而异:5
| 事件 | 决策模式 | 关键字段 |
|---|---|---|
UserPromptSubmit、UserPromptExpansion、PostToolUse、PostToolUseFailure、PostToolBatch、Stop、SubagentStop、ConfigChange、PreCompact |
顶层 decision |
decision: "block" + reason(展示给 Claude)。省略 decision 即为放行 |
PreToolUse |
hookSpecificOutput |
permissionDecision:"allow" | "deny" | "ask" | "defer",外加 permissionDecisionReason,以及在执行前重写工具参数的 updatedInput |
PermissionRequest |
hookSpecificOutput |
decision.behavior:"allow" | "deny",可选 decision.updatedInput |
PermissionDenied |
hookSpecificOutput |
retry: true 告知模型可以重试 |
PostToolUse |
hookSpecificOutput |
updatedToolOutput 替换工具结果 |
Stop / SubagentStop |
hookSpecificOutput |
additionalContext:非错误反馈,让对话继续而不计为 hook 错误 |
SessionStart、Setup、SubagentStart |
仅上下文 | additionalContext,外加 SessionStart 独有的 initialUserMessage、sessionTitle、watchPaths、reloadSkills。不可阻止 |
MessageDisplay |
hookSpecificOutput |
displayContent 仅替换屏幕上显示的文本 |
Elicitation / ElicitationResult |
hookSpecificOutput |
action:"accept" | "decline" | "cancel",外加 content |
WorktreeRemove、Notification、SessionEnd、PostCompact、InstructionsLoaded、StopFailure、CwdChanged、FileChanged |
无 | 仅用于副作用 |
有两个细节常让人栽跟头。第一,PreToolUse 是顶层 decision 模式的例外:它在历史上曾使用顶层 decision/reason,但这两个字段对此事件已被弃用("approve"/"block" 分别映射到 "allow"/"deny");请改用 hookSpecificOutput.permissionDecision。5 第二,当多个 PreToolUse hooks 意见不一致时,优先级为 deny > defer > ask > allow。5
配置:settings.json、matcher 与作用域
Hook 配置嵌套三层:选择一个事件,添加一个 matcher 组来过滤触发时机,再定义一个或多个要运行的 hook 处理器。6
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{ "type": "command", "command": "/path/to/lint-check.sh" }
]
}
]
}
}
放置位置决定作用域:~/.claude/settings.json 适用于您的所有项目,.claude/settings.json 为项目级且可提交到版本库,.claude/settings.local.json 为项目级且被 gitignore 忽略,同时适用标准的设置优先级——托管策略高于 local,local 高于项目,项目高于用户。9 Hooks 还可以随插件(hooks/hooks.json)以及技能或 agent 的 frontmatter 一起分发,企业管理员还能强制启用用户无法覆盖的托管 hooks。6
Matcher 按其字符内容求值:"*"、"" 或省略 matcher 会匹配一切;只包含字母、数字、_、-、空格、逗号和 | 的值是精确字符串或列表(Bash、Edit|Write);其他任何值都会成为未锚定的 JavaScript 正则表达式,因此 Edit.* 会同时匹配 Edit 和 NotebookEdit——如果只想精确匹配一个工具,请用 ^Edit$ 加锚。Matcher 区分大小写,且每个事件按自己的字段匹配:工具事件按工具名,SessionStart 按 source,SubagentStart 按 agent 类型,Notification 按通知类型。6 若要在工具事件上做更精细的过滤,每个处理器的 if 字段接受一条权限规则,例如 "Bash(git *)"——但它是尽力而为的(遇到无法解析的命令时会放行),所以硬性保证请使用权限规则而不是 if。6
处理器共有五种类型:command(shell)、http(POST 端点)、mcp_tool、prompt(单轮模型评估)和 agent(拥有 Read/Grep/Glob 访问权限的子代理;实验性)。默认超时:command/http/mcp_tool 为 600 秒(UserPromptSubmit 降至 30 秒、MessageDisplay 降至 10 秒),prompt 为 30 秒,agent 为 60 秒——可通过 timeout 按 hook 单独覆盖。6 所有匹配的 hooks 并行运行,完全相同的处理器会被去重,$CLAUDE_PROJECT_DIR 会把脚本指向项目根目录。
用 /hooks 验证:这是一个只读浏览器,显示每个事件、其已配置的 hooks,以及各自来自哪个设置文件。要修改任何内容,请编辑 JSON(或让 Claude 来改)。要临时关闭全部 hooks,设置 "disableAllHooks": true。6
五个模式
以下模式经过通用化处理,保持最小实现。hooks 教程为其中几个构建了更完整的生产版本,Hooks 在 Apple 开发中的应用则将它们应用到 iOS 工具链。
1. 编辑后自动格式化(PostToolUse)
直接取自官方指南——Claude 碰过的每个文件都会被格式化,无一例外:3
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{ "type": "command", "command": "jq -r '.tool_input.file_path' | xargs npx prettier --write" }
]
}
]
}
}
按技术栈需要,将命令换成 ruff format、gofmt 或 swiftformat。
2. 阻止危险命令(PreToolUse,退出码 2)
#!/bin/bash
# .claude/hooks/guard-bash.sh — register on PreToolUse, matcher "Bash"
command=$(jq -r '.tool_input.command // empty')
case "$command" in
*"rm -rf"* | *"git push --force"* | *"DROP TABLE"*)
echo "Blocked: matches a destructive pattern. Propose a safer alternative." >&2
exit 2 ;;
esac
exit 0
退出码 2 会阻止该调用并把 stderr 反馈给 Claude,Claude 由此调整方向,而不是盲目重试。等价的 JSON 写法——带原因的 permissionDecision: "deny"——效果相同,并留有升级空间:"ask"(上报给人类)或 updatedInput(重写命令)。5
3. 会话启动时注入上下文(SessionStart)
SessionStart hook 的纯文本 stdout 会成为 Claude 可见的上下文——无需 JSON:1
#!/bin/bash
# .claude/hooks/session-context.sh — register on SessionStart
echo "Current branch: $(git branch --show-current)"
echo "Recent commits:"
git log --oneline -5
echo "Uncommitted files: $(git status --porcelain | wc -l | tr -d ' ')"
exit 0
此模式用于动态状态。静态约定应放在 CLAUDE.md 中——官方文档本身也建议,不需要脚本的上下文放在那里。1
4. Stop 上的完成门控
Stop 在 Claude 结束响应时触发。阻止它会迫使 agent 持续工作,直到条件满足:
#!/bin/bash
# .claude/hooks/stop-gate.sh — register on Stop
input=$(cat)
if [ "$(echo "$input" | jq -r '.stop_hook_active')" = "true" ]; then
exit 0 # already continuing because of this hook; don't loop forever
fi
if ! npm test --silent > /tmp/stop-gate.log 2>&1; then
jq -n '{decision: "block", reason: "Tests are failing. Fix them before finishing. Log: /tmp/stop-gate.log"}'
fi
exit 0
stop_hook_active 检查很重要:Claude Code 对 Stop hook 设有连续 8 次阻止的硬上限,一个从不检查自己是否已触发续跑的门控会径直烧穿这个额度。7 若想要更温和的引导,可返回 hookSpecificOutput.additionalContext 而非 decision: "block"——续跑效果相同,但被标记为反馈而不是 hook 错误。对于一次性条件,内置的 /goal 命令就是一个会话级、基于提示词的 Stop hook,零配置。1
5. 调度器:一个入口,多个小 hooks
注册十个 hooks 意味着 settings.json 里有十个条目,会在不同机器和项目之间逐渐失去同步。替代方案:每个事件只注册一个调度器,按约定路由。
#!/bin/bash
# .claude/hooks/dispatch.sh — register once per event you care about
input=$(cat)
event=$(echo "$input" | jq -r '.hook_event_name')
dir="$CLAUDE_PROJECT_DIR/.claude/hooks/$event"
[ -d "$dir" ] || exit 0
for hook in "$dir"/*.sh; do
[ -x "$hook" ] || continue
echo "$input" | "$hook" || exit $?
done
exit 0
现在,新增一个守卫就是在 .claude/hooks/PreToolUse/ 下对新文件执行 chmod +x——settings.json 从不改动,每个脚本都小到可以独立测试,且第一个退出码 2 会向上传播。一点注意事项:调度器把 Claude Code 本会并行运行的内容串行化了,它最适合退出码型 hooks——输出 JSON 的 hook 应保持独立注册,因为 stdout 必须恰好包含一个 JSON 对象。5
Hook、CLAUDE.md、技能与记忆的取舍
四种机制,各司其职:
| 机制 | 职责 | 选择规则 |
|---|---|---|
| Hook | 强制执行 | 如果它必须不可能被跳过——格式化、安全、门控——那就是 hook |
| CLAUDE.md | 指导 | 如果它是模型每个会话都应知道的约定——技术栈、风格、命令——那就是 CLAUDE.md |
| 技能 | 能力 | 如果它是带有自身指令和脚本、在相关时才被调用的流程,那就是技能 |
| 记忆 | 回忆 | 如果它是在某次会话中学到、未来会话需要的事实,那就是记忆 |
失误在两个方向上都会发生。把约定编码成 hooks,换来的是一堆脆弱的脚本,去强制执行一句指导语就能搞定的事。把策略写成 CLAUDE.md 的散文,换来的是 agent 在最要命的那天把 main 分支强制推送掉。判断标准:模型忽略这条规则一次的代价是什么?恼人 → CLAUDE.md。事故 → hook。
Hooks 做不到的事
如实列出限制,全部来自官方文档:7
- Hooks 无法调用工具或斜杠命令。 命令型 hooks 只会通过 stdout、stderr 和退出码表达——仅此而已。通过
additionalContext返回的上下文会以纯文本形式注入。 PostToolUse无法撤销。 工具已经运行完了。预防要放在PreToolUse里。Stop在每次响应结束时都会触发,而不仅在”任务完成”时,且从不在用户打断时触发(API 错误触发的是StopFailure)。门控逻辑必须容忍任务中途的停止。PermissionRequest在无头(-p)模式下不会触发。 自动化权限决策请使用PreToolUse。PreToolUse看不到通过@引用的文件。 在提示词中用@拉入的文件不涉及工具调用;要防住这条路径,请用Readdeny 规则保护相关路径。1- 并行的
updatedInput是非确定性的。 当多个 PreToolUse hooks 重写同一个工具的参数时,最后完成的那个获胜。每类重写只让一个 hook 负责。 - 超时会取消该 hook。 命令型 hooks 默认 600 秒(
UserPromptSubmit为 30 秒,MessageDisplay为 10 秒);一个因超时被取消的慢门控,等于没有运行的门控。 - 输出上限为 10,000 个字符——超出部分会被写入文件,并以预览替代。
- Hooks 以您的完整用户权限运行。 参考文档自己的警告:它们”可以修改、删除或访问您的用户账户能访问的任何文件。在将 hook 命令加入配置之前,请审查并测试所有命令”。8 给变量加引号、使用绝对路径、避开敏感文件。
- 一个坏掉的 hook 会拖累每一个会话,直到被修复。调试可用会话记录视图(
Ctrl+O)、claude --debug-file /tmp/claude.log,或在会话中使用/debug;一个经典的坑是 shell 配置文件在启动时输出内容,污染了 hook 的 JSON 输出。7
常见问题
什么是 Claude Code hooks?
Hooks 是用户自定义的命令——shell 脚本、HTTP 端点、MCP 工具或模型提示词——由 Claude Code 在特定生命周期节点自动执行。3 它们从 stdin 接收事件 JSON,并以退出码或 JSON 应答:阻止工具调用、注入上下文、重写参数、让 agent 继续工作。与 CLAUDE.md 指令不同,它们每次都会执行,与模型行为无关。
PreToolUse hooks 与权限有什么区别?
权限规则是声明式的:静态的 allow/deny/ask 模式,由 Claude Code 自行求值。PreToolUse hooks 是可编程的:由您的代码检查完整的工具输入并做出决定。Hooks 在权限模式检查之前触发,因此 hook 的 "deny" 即使在 bypassPermissions 模式下也依然生效——但 hook 的 "allow" 无法覆盖 settings 中的 deny 规则。4 凡是模式匹配能表达的,用权限规则;当决策需要逻辑、外部状态或输入重写时,才动用 hook。
Hooks 在无头(-p)模式下能用吗?
能——只有一个文档中注明的例外:PermissionRequest hooks 在非交互模式下不会触发,因此自动化权限决策应放在 PreToolUse 中。7 无头模式还解锁了一个交互式会话会忽略的选项:permissionDecision: "defer",它会暂停工具调用,让外层包装进程(Agent SDK 应用、自定义 UI)收集输入后再恢复会话。5
为什么我的 hook 运行了却什么都没阻止?
几乎总是违反了契约。退出码 1 不会阻止——只有退出码 2 会,而且仅对支持阻止的事件有效。2 JSON 决策只在退出码为 0 时被解析——打印 {"decision": "block"} 之后又以退出码 2 退出的脚本,其 JSON 会被丢弃。此外 matcher 区分大小写——bash 永远匹配不到 Bash。先用 /hooks 确认注册情况,再把示例 JSON 通过管道传给脚本并检查 echo $? 进行测试。7
来源
已于 2026 年 7 月 1 日对照官方文档核实。Hooks API 在 Claude Code v2.1.x 各版本间发生过实质性变化(新事件、新字段、matcher 语义),因此对版本敏感的细节请以”截至本文日期”来理解。
本站相关内容: Claude Code 指南的 hooks 章节提供包含 prompt 型与 agent 型 hooks 在内的全系统视角,hooks 教程提供五个带完整配置的生产级构建,Hooks 在 Apple 开发中的应用展示应用于 iOS 的实战模式;如果您还没安装 Claude Code,请从快速上手开始。
-
Anthropic, “Hooks reference — Hook lifecycle and hook events.” code.claude.com/docs/en/hooks#hook-events ↩↩↩↩↩↩
-
Anthropic, “Hooks reference — Hook input and output; exit code output; exit code 2 behavior per event.” code.claude.com/docs/en/hooks#exit-code-output ↩↩↩↩↩↩↩↩
-
Anthropic, “Automate actions with hooks.” code.claude.com/docs/en/hooks-guide ↩↩↩
-
Anthropic, “Hooks guide — Hooks and permission modes.” code.claude.com/docs/en/hooks-guide#hooks-and-permission-modes ↩↩
-
Anthropic, “Hooks reference — JSON output and decision control.” code.claude.com/docs/en/hooks#json-output ↩↩↩↩↩↩↩
-
Anthropic, “Hooks reference — Configuration: hook locations, matcher patterns, hook handler fields, the /hooks menu.” code.claude.com/docs/en/hooks#configuration ↩↩↩↩↩↩
-
Anthropic, “Hooks guide — Limitations and troubleshooting.” code.claude.com/docs/en/hooks-guide#limitations-and-troubleshooting ↩↩↩↩↩
-
Anthropic, “Hooks reference — Security considerations.” code.claude.com/docs/en/hooks#security-considerations ↩
-
Anthropic, “Claude Code settings.” code.claude.com/docs/en/settings ↩