mcpField
H
hooks-development

hooks-development

github.com/terrylicaAgent 工作流2132 次安装1 天前更新
代码仓库

关于 hooks-development

hooks-development 是用于开发和调试 Claude Code hooks 的技能,重点说明输出可见性、安全处理输入、shell 与 Bun 的选择及验证步骤。

主要功能

  1. 01Hook 输出可见性规则
  2. 02安全处理 AskUserQuestion
  3. 03Shell 与 Bun 选型建议
  4. 04创建和调试检查清单

适用场景

  1. 01创建 PreToolUse 或 PostToolUse hook
  2. 02排查 Claude 看不到 hook 消息
  3. 03检查 hook 配置和输出

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/terrylica/cc-skills --skill hooks-development

安装后在 Claude Code 中输入/hooks-development确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
debugging-guide.md
evolution-log.md
hook-templates.md
lifecycle-reference.md
visibility-patterns.md

详细介绍

Hooks 开发

开发 Claude Code hooks 并正确设置输出可见性的指南。

自我演进的技能:此技能会在使用中不断改进。如果指令有误、参数发生偏移,或需要变通方案,请立即修复此文件,不要拖延。仅针对真实、可复现的问题进行更新。

何时使用此技能

  • 创建新的 PostToolUse 或 PreToolUse hook
  • Claude 看不到 hook 输出(最常见的问题)
  • 用户询问 decision: block 模式
  • 调试 hook 消息为何没有显示
  • 用户提到“Claude Code hooks”或“hook 可见性”

快速参考:可见性模式

关键结论:只有当 JSON 包含 "decision": "block" 时,Claude 才能看到 PostToolUse hook 的 stdout。

输出格式Claude 可见性
纯文本不可见
不含 decision: block 的 JSON不可见
含 decision: block 的 JSON可见

退出码行为:

退出码stdout 行为Claude 可见性
0解析 JSON,仅在详细模式下显示仅当包含 "decision": "block" 时
2忽略,改用 stderrstderr 会显示给 Claude
其他stderr 在详细模式下显示不会显示给 Claude

绝不重写 AskUserQuestion

PreToolUse hook 绝不能为 AskUserQuestion 返回 updatedInput,无论是直接返回还是通过 allowWithInput 返回。对于此工具,updatedInput 是对话框用于传递用户 answers 的通道,因此 hook 一旦返回该字段,就会被视为已经作答:菜单不会显示,工具会返回“The user did not answer the questions.”。在 2026-09-24 对所有会话记录的测量中,86 次被重写的调用有 86 次都未显示且未获回答;而普通的 allow 调用有 466 次中的 465 次正常显示并获得回答。

  • 普通的 allow 是安全的;对话框仍会显示。
  • 如需更改用户看到的内容,请使用 deny,并在原因中准确说明 Agent 应该重新询问什么;同时确保重新询问时内容不变,以便循环在一轮内结束(pretooluse-pr-premise-annotator.ts 是示例)。
  • 通过三种方式强制执行:allowWithInput 会在运行时拒绝该工具,TOOL_SCHEMAS 中没有该工具的条目,并且当覆盖 AskUserQuestion 的 hook 输出 updatedInput 或调用 allowWithInput 时,scripts/validate-plugins.mjs 会使检查失败。

最简可用模式

/usr/bin/env bash << 'SKILL_SCRIPT_EOF'
#!/usr/bin/env bash
set -euo pipefail

# Read hook payload from stdin
PAYLOAD=$(cat)
FILE_PATH=$(echo "$PAYLOAD" | jq -r '.tool_input.file_path // empty')

[[ -z "$FILE_PATH" ]] && exit 0

# Your condition here
if [[ condition_met ]]; then
    jq -n \
        --arg reason "[HOOK] Your message to Claude" \
        '{decision: "block", reason: $reason}'
fi

exit 0
SKILL_SCRIPT_EOF

要点:

  1. 使用 jq -n 生成有效的 JSON
  2. 包含 "decision": "block" 以确保可见
  3. 以代码 0 退出
  4. “阻塞错误”标签仅是表象——操作仍会继续

语言选择:shell 还是 Bun/TypeScript

hook 默认使用 shell(bash)。 hook 会在每个匹配事件上触发,而约 95% 会立即退出,因此进程启动延迟占主导地位,而非逻辑本身。在工作站上的测量结果:完整的 bash hook(关键词匹配 + 退出)约 7 ms;一个_什么都不做_的 Bun 脚本约 17 ms。bash 也无需运行时依赖,并符合现有 hook 约定。让热路径退出逻辑使用 bash 内置的 case(不调用 jq 或启动进程)——参见 devops-tools SCS hooks 中的 pre-jq-fastpath。

只有当 hook 执行的实际工作足以抵消约 10 ms 的启动开销时,才使用 Bun/TypeScript:解析/转换结构化数据、调用 API、在多个 hook 间共享类型化模块,或维护状态。对于简单的匹配并输出提醒,shell 在速度、可靠性和约定方面更胜一筹。(这正是语言准则中“现有约定 + SOTA 原生生态优先于 Bun 优先默认策略”条款的体现。)


TodoWrite 模板

创建 PostToolUse Hook
1. [pending] Create hook script with shebang and set -euo pipefail
2. [pending] Parse PAYLOAD from stdin with jq
3. [pending] Add condition check for when to trigger
4. [pending] Output JSON with decision:block pattern
5. [pending] Register hook in hooks.json with matcher
6. [pending] Test by editing a matching file
7. [pending] Verify Claude sees the message in system-reminder
调试不可见的 Hook 输出
1. [pending] Verify hook executes (add debug log to /tmp)
2. [pending] Check JSON format is valid (pipe to jq .)
3. [pending] Confirm decision:block is present in output
4. [pending] Verify exit code is 0
5. [pending] Check hooks.json matcher pattern
6. [pending] Restart Claude Code session

参考文档


更改后检查清单(自我演进)

更新此技能时:


相关资源


故障排除

问题原因解决方案
钩子输出不可见JSON 中缺少 decision:block在 JSON 输出中添加 "decision": "block"
钩子中的 JSON 解析错误JSON 语法无效使用 jq -n 生成有效的 JSON
钩子未执行匹配器模式错误检查 hooks.json 匹配器正则表达式是否匹配工具名称
纯文本输出被忽略仅解析 JSON将输出包装为包含 decision:block 的 JSON
退出代码 2 的行为使用了 stderr 而非 stdout使用 exit 0 并输出 JSON,或使用 exit 2 输出 stderr 消息
会话未看到更改钩子已缓存更改钩子后重启 Claude Code 会话
未显示详细模式默认已禁用在 Claude Code 设置中启用详细模式
找不到 jq 命令未安装 jqbrew install jq

执行后反思

此技能完成后,在结束前检查:

  1. 命令是否成功? — 如果没有,修复导致失败的说明或错误表。
  2. 参数或输出是否发生变化? — 如果底层工具的接口发生了变化,请更新 Usage 示例和 Parameters 表,使其保持一致。
  3. 是否需要变通方案? — 如果你不得不临时调整(使用不同的标志、增加步骤),请更新此 SKILL.md,以免下次调用时还需要采用相同的变通方案。

仅当问题真实且可复现时才进行更新,不要基于猜测更新。

评论

支持 Markdown