关于 claude-hook-writer
指导开发者设计、审查、调试和优化 Claude Code hooks 的 Skill,重点涵盖输入校验、安全错误处理、性能与测试,并附带参考资料。
主要功能
- 01选择 Hook 事件与匹配器
- 02输入校验和路径安全指导
- 03退出码与错误处理模式
- 04性能和依赖项检查
- 05附带模板、测试与发布参考资料
适用场景
- 01创建阻止修改敏感文件的 Hook
- 02调试因输入格式错误而失败的 Hook
- 03缩短同步 Hook 任务造成的等待
- 04准备将 Hook 发布到 PRPM
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ secondsky/ claude-skills --skill claude-hook-writer安装后在 Claude Code 中输入/claude-hook-writer确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/code-templates.mdpublishing-guide.mdquick-reference.mdreliability-performance.mdsecurity-requirements.mdtesting-debugging.md详细介绍
Claude Hook Writer
状态:生产就绪 版本:2.0.0(已通过渐进式披露优化) 最后更新:2025-12-17
概述
为编写安全、可靠且高性能的 Claude Code hooks 提供专业指导。此技能可验证设计决策、强制执行最佳实践,并避免常见陷阱。
何时使用此技能
- 设计新的 Claude Code hook
- 审查现有 hook 代码
- 调试 hook 故障
- 优化运行缓慢的 hook
- 保护处理敏感数据的 hook
- 将 hook 发布为 PRPM 包
核心原则
1. 安全不可妥协
Hook 会在用户权限下自动执行,并且可以读取、修改或删除用户有权访问的任何文件。
务必验证并清理所有输入。 Hook 通过 stdin 接收 JSON,切勿盲目信任。
完整的安全模式:实现输入验证或保护 hook 时,加载 references/security-requirements.md。
2. 可靠性优先于功能
一个有 99% 时间都能正常工作的 hook 仍然是有问题的 hook。边缘情况(Unicode 文件名、路径中的空格、缺失的工具)总会出现。
部署前请使用边缘情况进行测试。
可靠性模式:处理错误或边缘情况时,加载 references/reliability-performance.md。
3. 性能很重要
Hook 会阻塞操作。一个耗时 5 秒的 hook 会让 Claude 等待 5 秒才能继续。
让 hook 保持快速。将耗时操作放在后台运行。
性能优化:优化 hook 速度时,加载 references/reliability-performance.md。
4. 优雅地处理失败
依赖项缺失、输入格式错误和磁盘错误都会发生。
明确处理错误。记录失败情况。返回有意义的退出码。
Hook 设计检查清单
编写代码前,请回答以下问题:
此 hook 针对什么事件?
PreToolUse- 工具执行前(修改输入、验证、拦截)PostToolUse- 工具完成后(格式化、记录、清理)UserPromptSubmit- 用户输入处理前(验证、增强)SessionStart- Claude Code 启动时(设置、环境检查)SessionEnd- Claude Code 退出时(清理、持久化状态)Notification- 告警期间(桌面通知、记录)Stop/SubagentStop- 响应结束时(清理、摘要)PreCompact- 上下文压缩前(保存重要上下文)
常见错误: 使用 PostToolUse 进行验证(为时已晚——工具已经运行)。要拦截操作,请使用 PreToolUse。
哪些工具应触发此 hook?
请指定具体范围。matcher: "*" 会在每次工具调用时运行。
好的匹配器:
"Write"- 仅文件写入"Edit|Write"- 文件修改"Bash"- Shell 命令"mcp__github__*"- 所有 GitHub MCP 工具
不好的匹配器:
"*"- 所有内容(仅用于记录/指标)
此 hook 需要哪些输入?
不同工具提供的输入不同。请检查可用内容:
# PreToolUse / PostToolUse
{
"input": {
"file_path": "/path/to/file.ts", // Read, Write, Edit
"command": "npm test", // Bash
"old_string": "...", // Edit
"new_string": "..." // Edit
}
}
使用字段前,请验证字段是否存在:
FILE=$(echo "$INPUT" | jq -r '.input.file_path // empty')
if [[ -z "$FILE" ]]; then
echo "No file path provided" >&2
exit 1
fi
应使用命令 hook 还是提示词 hook?
命令 hook(type: "command"):
- 快速(毫秒级)
- 结果确定
- 适用于:格式化、记录、文件检查
提示词 hook(type: "prompt"):
- 较慢(2-10 秒)
- 感知上下文(使用大模型)
- 适用于:复杂验证、安全分析、意图检测
经验法则: 除非需要大模型推理,否则使用命令 hook。
用什么退出码表示成功或失败?
exit 0- 成功(继续操作)exit 2- 拦截操作(向 Claude 显示错误)exit 1或其他 - 非阻塞错误(记录错误但继续)
对于 PreToolUse hooks:
- 退出码 2 会阻止工具运行
- 退出码 0 允许工具运行(也可以选择修改输入)
对于 PostToolUse hooks:
- 退出码不会阻止操作(工具已经运行)
- 成功时使用退出码 0,记录错误时使用退出码 1
五大常见陷阱(必知)
陷阱 #1:未引用变量
错误:文件名包含空格或特殊字符时,钩子会出错
原因:未加引号的变量会按空白字符拆分
示例:
# ❌ WRONG - breaks on "my file.txt"
cat $FILE
prettier --write $FILE
rm $FILE
# ✅ RIGHT - handles spaces and special chars
cat "$FILE"
prettier --write "$FILE"
rm "$FILE"
这为何重要:文件名包含空格("my file.txt")、Unicode("文件.txt")或特殊字符("file (1).txt")的情况很常见。
有关引用的最佳实践:加载 references/security-requirements.md,了解全面的输入处理模式。
陷阱 #2:未经验证就信任输入
错误:钩子会针对恶意或格式错误的输入执行操作
原因:使用 JSON 字段前未进行验证
示例:
# ❌ DANGEROUS - no validation
FILE=$(jq -r '.input.file_path')
rm "$FILE" # Could delete ../../../etc/passwd
# ✅ SAFE - validate first
FILE=$(jq -r '.input.file_path // empty')
[[ -n "$FILE" ]] || exit 1
[[ "$FILE" == "$CLAUDE_PROJECT_DIR"* ]] || exit 2
[[ "$FILE" != *".."* ]] || exit 2
rm "$FILE"
这为何重要:可防止路径遍历攻击、保护项目外部的文件,并避免因输入格式错误而崩溃。
有关完整的安全模式:加载 references/security-requirements.md。
陷阱 #3:阻塞操作耗时过长
错误:钩子耗时 30 秒以上,导致 Claude 无法继续操作
原因:在钩子中同步运行耗时操作(测试、构建)
示例:
# ❌ BLOCKS Claude for 30 seconds
npm test
npm run build
# ✅ RUN IN BACKGROUND - returns immediately
(npm test > /tmp/test-results.log 2>&1 &)
(npm run build > /tmp/build.log 2>&1 &)
exit 0
这为何重要:缓慢的钩子会带来糟糕的用户体验。PreToolUse 的目标耗时应小于 100 毫秒,PostToolUse 应小于 500 毫秒。
有关性能优化:加载 references/reliability-performance.md。
陷阱 #4:用于阻止操作的退出码错误
错误:PreToolUse 钩子实际上没有阻止操作
原因:使用了 exit 1 而不是 exit 2
示例:
# ❌ WRONG - logs error but doesn't block
if [[ $FILE == ".env" ]]; then
echo "Don't edit .env" >&2
exit 1 # Tool still runs!
fi
# ✅ RIGHT - actually blocks
if [[ $FILE == ".env" ]]; then
echo "Blocked: .env is protected" >&2
exit 2 # Tool is blocked
fi
这为何重要:退出码 1 只会记录错误。PreToolUse 钩子必须使用退出码 2 才能阻止操作。
有关退出码模式:加载 references/hook-templates.md,了解完整的钩子响应模式。
陷阱 #5:假定工具已存在
错误:缺少依赖项时,钩子会崩溃
原因:使用工具前未检查其是否已安装
示例:
# ❌ BREAKS if prettier not installed
prettier --write "$FILE"
# ✅ SAFE - check first
if command -v prettier &>/dev/null; then
prettier --write "$FILE"
else
echo "prettier not installed, skipping" >&2
exit 0 # Success exit, just skip
fi
这为何重要:用户可能没有安装所有工具。钩子应能在依赖缺失时平稳降级。
有关可靠性模式:加载 references/reliability-performance.md。
关键规则
始终做到
✅ 使用 JSON 输入前先进行验证(jq -r '... // empty')
✅ 对所有包含路径或用户输入的变量加引号
✅ 为脚本使用绝对路径(${CLAUDE_PLUGIN_ROOT}/...)
✅ 阻止访问敏感文件(.env、*.key、凭据)
✅ 检查必需的工具是否存在(command -v toolname)
✅ 设置合理的超时时间(PreToolUse 小于 5 秒)
✅ 在后台运行耗时操作
✅ 使用边界情况进行测试(空格、Unicode、特殊字符)
✅ 在 PreToolUse 钩子中使用 exit 2 阻止操作
✅ 将错误记录到 stderr 或文件,而不是 stdout
绝不这样做
❌ 不经验证就信任 JSON 输入
❌ 使用未加引号的变量($FILE 而不是 "$FILE")
❌ 为脚本使用相对路径
❌ 跳过路径清理(检查是否包含 ..,并验证路径是否位于项目中)
❌ 假定工具已安装
❌ 在 PreToolUse 钩子中阻塞超过 1 秒
❌ 需要阻止操作时使用 exit 1(应使用 exit 2)
❌ 将敏感数据记录到 stdout 或文件
❌ 除非确有必要,否则不要使用 matcher: "*"
何时加载参考资料
针对特定的钩子方面开展工作时,请加载相应的参考文件:
安全要求(references/security-requirements.md)
在以下情况下加载:
- 实现输入验证和清理
- 保护处理敏感数据的钩子
- 阻止访问敏感文件(
.env、密钥、凭据) - 防止路径遍历攻击
- 了解安全漏洞和最佳实践
- 使用恶意输入进行安全测试
可靠性与性能(references/reliability-performance.md)
在以下情况下加载:
- 处理缺失的依赖项或工具
- 设置超时时间并处理耗时操作
- 优化钩子性能(目标小于 100 毫秒)
- 在后台运行耗时操作
- 缓存耗时操作的结果
- 使用边界情况进行测试(Unicode、空格、深层路径)
- 对耗时操作进行去重
代码模板(references/code-templates.md)
在以下情况下加载:
- 开始编写新的 hook,需要可用示例
- 实现保存时自动格式化功能
- 阻止修改敏感文件
- 记录命令或操作
- 使用基于提示词的安全分析
- 针对特定用例自定义模板
测试与调试(references/testing-debugging.md)
在以下情况下加载:
- 为 hook 编写测试用例
- 调试 hook 故障或意外行为
- 使用边缘情况进行测试(格式错误的 JSON、缺少字段)
- 在执行记录中检查 hook 的执行情况(Ctrl-R)
- 分析 hook 性能
- 创建自动化测试套件
发布指南(references/publishing-guide.md)
在以下情况下加载:
- 将 hook 发布到 PRPM 注册表
- 创建包清单(prpm.json)
- 使用高级选项配置 hook.json
- 使用
continue、stopReason、suppressOutput、systemMessage - 为用户编写 README.md
- 了解版本管理和发布命令
快速参考(references/quick-reference.md)
在以下情况下加载:
- 需要快速查阅语法(退出代码、jq 模式)
- 查询环境变量
- 查找常用 bash 模式(文件验证、后台执行)
- 检查 hook 事件和匹配器
- 需要查看性能技巧摘要
- 查询 JSON 输入结构
最终检查清单
发布 hook 前:
- 使用 jq 验证所有 stdin 输入
- 为所有变量加引号
- 为脚本使用绝对路径
- 阻止访问敏感文件(
.env、*.key等) - 在缺少工具时妥善处理
- 设置合理的超时时间(PreToolUse 不超过 5 秒)
- 将错误记录到 stderr 或文件,而不是 stdout
- 使用边缘情况进行测试(空格、Unicode、格式错误的 JSON)
- 在实际 Claude Code 会话中测试
- 在 README 中记录依赖项
- 使用语义化版本
- 提供清晰的描述和标签
使用捆绑资源
此 skill 包含 6 个可按需加载的参考文件:
安全与可靠性(2 个文件):
security-requirements.md- 输入验证、路径清理、阻止访问敏感文件reliability-performance.md- 错误处理、超时、性能优化
实现(2 个文件):
code-templates.md- 可用的 hook 示例(保存时自动格式化、阻止敏感操作、日志记录器等)quick-reference.md- 快速查阅语法(退出代码、jq 模式、环境变量)
测试与发布(2 个文件):
testing-debugging.md- 测试模式、边缘情况、调试技巧publishing-guide.md- PRPM 打包、高级配置、README 模板
需要特定知识时,按需加载参考文件。请参阅“何时加载参考文件”一节,了解触发条件。
资源
上次验证时间:2025-12-17 | 版本:2.0.0