mcpField
C
claude-hook-writer

claude-hook-writer

github.com/secondskyAgent 工作流240401 次安装5 周前更新
代码仓库

关于 claude-hook-writer

指导开发者设计、审查、调试和优化 Claude Code hooks 的 Skill,重点涵盖输入校验、安全错误处理、性能与测试,并附带参考资料。

主要功能

  1. 01选择 Hook 事件与匹配器
  2. 02输入校验和路径安全指导
  3. 03退出码与错误处理模式
  4. 04性能和依赖项检查
  5. 05附带模板、测试与发布参考资料

适用场景

  1. 01创建阻止修改敏感文件的 Hook
  2. 02调试因输入格式错误而失败的 Hook
  3. 03缩短同步 Hook 任务造成的等待
  4. 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.md
publishing-guide.md
quick-reference.md
reliability-performance.md
security-requirements.md
testing-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

评论

支持 Markdown