mcpField
H
hooks-builder

hooks-builder

github.com/mike-coulbournAgent 工作流4546 次安装4 周前更新
代码仓库

关于 hooks-builder

用于创建 Claude Code 钩子的指南技能,可响应工具调用、提示词和会话生命周期事件。内容涵盖事件选择、匹配器、实现方式、安全加固与测试。

主要功能

  1. 01十种钩子事件参考
  2. 02事件与匹配器选择指南
  3. 03命令、脚本和提示词模式
  4. 04安全与输入验证检查
  5. 05手动及集成测试步骤

适用场景

  1. 01阻止高风险工具操作
  2. 02编辑后格式化或验证代码
  3. 03审计工具活动
  4. 04配置会话环境

安装

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

$npx skills add https://github.com/mike-coulbourn/claude-vibes --skill hooks-builder

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

包含的文件

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

examples/
quality-hooks.md
security-hooks.md
workflow-hooks.md
reference/
best-practices.md
syntax-guide.md
troubleshooting.md
templates/
basic-hook.md
production-hooks.md
with-decisions.md
with-prompts.md
with-scripts.md

详细介绍

Hooks 构建器

创建 Claude Code hooks 的综合指南——一种用于监控和控制 Claude 操作的事件驱动自动化机制。

快速参考

10 个 Hook 事件
事件触发时机可以阻止?支持匹配器?
PreToolUse工具执行前是是(工具名称)
PermissionRequest显示权限对话框时是是(工具名称)
PostToolUse工具成功执行后否是(工具名称)
NotificationClaude 发送通知时否是
UserPromptSubmit用户提交提示词时是否
StopClaude 完成响应时可强制继续否
SubagentStop子 Agent 完成时可强制继续否
PreCompact上下文压缩前否是(手动/自动)
SessionStart会话开始时否是(启动/恢复/清除/压缩)
SessionEnd会话结束时否否
退出代码语义
退出代码含义效果
0成功将 stdout 解析为 JSON 以进行控制
2阻止性错误否决——将 stderr 显示给 Claude
其他非阻止性错误在调试模式下记录 stderr
配置位置
~/.claude/settings.json          → Personal hooks (all projects)
.claude/settings.json            → Project hooks (team, committed)
.claude/settings.local.json      → Local overrides (not committed)
必备环境变量
变量说明
$CLAUDE_PROJECT_DIR项目根目录
$CLAUDE_CODE_REMOTE远程/本地标识
$CLAUDE_ENV_FILE环境持久化路径(SessionStart)
$CLAUDE_PLUGIN_ROOT插件目录(插件 hooks)
关键命令
/hooks              # View active hooks
claude --debug      # Enable debug logging
chmod +x script.sh  # Make script executable

6 阶段工作流

阶段 1:收集需求

使用 AskUserQuestion 进行澄清:

  1. 应该由哪个事件触发此 hook?

    • 工具执行(Pre/Post/Permission)→ PreToolUse、PostToolUse、PermissionRequest
    • 用户输入 → UserPromptSubmit
    • 响应完成 → Stop、SubagentStop
    • 会话生命周期 → SessionStart、SessionEnd
    • 上下文管理 → PreCompact
    • 通知 → Notification
  2. 触发后应该执行什么操作?

    • 仅观察(日志记录、指标)
    • 根据条件阻止/允许
    • 执行前修改输入
    • 向提示词添加上下文
    • 强制继续
  3. 它应该阻止、修改,还是只进行观察?

    • 观察者:PostToolUse、Notification、SessionEnd(无法阻止)
    • 守卫者:PreToolUse、PermissionRequest、UserPromptSubmit(可以阻止)
    • 转换器:带有 updatedInput 的 PreToolUse(可以修改)
    • 控制器:Stop、SubagentStop(可以强制继续)
  4. 有哪些安全影响?

    • 是否会处理不可信输入?
    • 是否可能泄露敏感数据?
    • 是否需要访问外部系统?
阶段 2:选择事件

根据用例匹配事件:

用例最佳事件
阻止危险操作PreToolUse
写入后自动格式化代码PostToolUse
验证用户提示词UserPromptSubmit
设置环境SessionStart
确保任务完成Stop
记录所有工具使用情况带有 "*" 匹配器的 PostToolUse
保护敏感文件针对 Write/Edit 的 PreToolUse
添加项目上下文UserPromptSubmit

确定是否需要匹配器:

  • 指定工具?→ 使用匹配器:"Write|Edit"
  • 所有工具?→ 使用 "*" 或省略匹配器
  • MCP 工具?→ 使用 mcp__server__tool 模式
  • Bash 命令?→ 使用 Bash(git:*) 模式
阶段 3:设计匹配器

匹配器模式语法:

// Exact match (case-sensitive!)
"matcher": "Write"

// OR pattern
"matcher": "Write|Edit"

// Prefix match
"matcher": "Notebook.*"

// Contains match
"matcher": ".*Read.*"

// All tools
"matcher": "*"

// MCP tools
"matcher": "mcp__memory__.*"

// Bash sub-patterns
"matcher": "Bash(git:*)"

常见匹配器模式:

模式匹配对象
"Write"仅 Write 工具
"Write|Edit"Write 或 Edit
"Bash"所有 Bash 命令
"Bash(git:*)"仅 git 命令
"Bash(npm:*)"仅 npm 命令
"mcp__.*__.*"所有 MCP 工具
".*" 或 "*"所有内容
阶段 4:实施

选择实施方式:

  1. 内联命令(简单,无需外部文件):

    {
      "type": "command",
      "command": "echo \"$(date) | $tool_name\" >> ~/.claude/audit.log"
    }
    
  2. 外部脚本(逻辑复杂,可重复使用):

    {
      "type": "command",
      "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/validate.sh"
    }
    
  3. 基于提示词(大模型评估,智能决策):

    {
      "type": "prompt",
      "prompt": "Analyze if all tasks are complete: $ARGUMENTS",
      "timeout": 30
    }
    

脚本模板(Bash):

#!/bin/bash
set -euo pipefail

# Read JSON input from stdin
input=$(cat)

# Parse fields with jq
tool_name=$(echo "$input" | jq -r '.tool_name // empty')
file_path=$(echo "$input" | jq -r '.tool_input.file_path // empty')

# Your logic here
if [[ "$file_path" == *".env"* ]]; then
    echo "BLOCKED: Cannot modify .env files" >&2
    exit 2
fi

# Success - output decision
echo '{"decision": "approve"}'
exit 0

脚本模板(Python):

#!/usr/bin/env python3
import sys
import json

# Read JSON input from stdin
data = json.load(sys.stdin)

# Extract fields
tool_name = data.get('tool_name', '')
tool_input = data.get('tool_input', {})
file_path = tool_input.get('file_path', '')

# Your logic here
if '.env' in file_path:
    print("BLOCKED: Cannot modify .env files", file=sys.stderr)
    sys.exit(2)

# Success - output decision
output = {"decision": "approve"}
print(json.dumps(output))
sys.exit(0)
阶段 5:强化安全性

重要:钩子会以你的权限执行 shell 命令。

安全检查清单:

  • 为所有变量加引号:"$VAR",而不是 $VAR
  • 使用 jq 或 json.load 解析 JSON(而不是 grep/sed)
  • 验证路径(不含 ..,并进行规范化)
  • 日志/输出中不包含敏感数据
  • 不使用 sudo 或提升权限
  • 先手动测试脚本
  • 运行项目前审查钩子
  • 设置适当的超时时间
  • 为所有故障模式处理错误

安全模式:

# UNSAFE - injection risk
rm $file_path

# SAFE - quoted, prevents flag injection
rm -- "$file_path"

# UNSAFE - parsing risk
cat "$input" | grep "field"

# SAFE - proper JSON parsing
echo "$input" | jq -r '.field'

纵深防御:

  1. 输入验证(正确解析 JSON)
  2. 路径净化(规范化并检查边界)
  3. 输出净化(不包含敏感数据)
  4. 故障安全默认值(出错时阻止,而非允许)
  5. 超时保护(防止无限循环)
阶段 6:测试

步骤 1:手动测试脚本

# Create mock input
cat > /tmp/mock-input.json << 'EOF'
{
  "session_id": "test-123",
  "hook_event_name": "PreToolUse",
  "tool_name": "Write",
  "tool_input": {
    "file_path": "/path/to/file.txt",
    "content": "test content"
  }
}
EOF

# Test script
cat /tmp/mock-input.json | ./my-hook.sh
echo "Exit code: $?"

步骤 2:边缘情况测试

  • 空输入:{}
  • 缺少字段:{"tool_name": "Write"}
  • 恶意输入:{"tool_input": {"file_path": "; rm -rf /"}}
  • 大型输入:10KB 以上的内容
  • Unicode:包含特殊字符的路径

步骤 3:集成测试

# Start Claude with debug mode
claude --debug

# Trigger the tool your hook targets
# Watch debug output for hook execution

步骤 4:验证

# Check hooks are registered
/hooks

# Watch hook execution
claude --debug 2>&1 | grep -i hook

钩子模式

观察者模式

记录但不阻止——使用 PostToolUse 或 Notification。

{
  "hooks": {
    "PostToolUse": [{
      "matcher": "*",
      "hooks": [{
        "type": "command",
        "command": "echo \"$(date) | $tool_name\" >> ~/.claude/audit.log"
      }]
    }]
  }
}
守门员模式

阻止危险操作——使用 PreToolUse 或 PermissionRequest。

{
  "hooks": {
    "PreToolUse": [{
      "matcher": "Write|Edit",
      "hooks": [{
        "type": "command",
        "command": "python3 ~/.claude/hooks/file-protector.py"
      }]
    }]
  }
}
转换器模式

在执行前修改输入——使用带 updatedInput 的 PreToolUse。

# In script, output:
output = {
    "hookSpecificOutput": {
        "hookEventName": "PreToolUse",
        "permissionDecision": "allow",
        "updatedInput": {
            "content": add_license_header(original_content)
        }
    }
}
print(json.dumps(output))
编排器模式

协调多个事件——组合使用 SessionStart、PreToolUse 和 PostToolUse。

{
  "hooks": {
    "SessionStart": [{
      "matcher": "startup",
      "hooks": [{"type": "command", "command": "~/.claude/hooks/setup-env.sh"}]
    }],
    "PreToolUse": [{
      "matcher": "Write|Edit",
      "hooks": [{"type": "command", "command": "~/.claude/hooks/validate.sh"}]
    }],
    "PostToolUse": [{
      "matcher": "Write|Edit",
      "hooks": [{"type": "command", "command": "~/.claude/hooks/format.sh"}]
    }]
  }
}

常见问题

1. 忘记使用退出代码 2 来阻止操作
# WRONG - exit 1 doesn't block
echo "Error" >&2
exit 1

# RIGHT - exit 2 blocks Claude
echo "BLOCKED: reason" >&2
exit 2
2. 匹配器区分大小写
// WRONG - won't match "Write" tool
"matcher": "write"

// RIGHT - case-sensitive match
"matcher": "Write"
3. 变量未加引号(存在注入风险)
# WRONG - command injection vulnerability
rm $file_path

# RIGHT - properly quoted
rm -- "$file_path"
4. 脚本缺少 Shebang
# WRONG - no shebang, may fail
set -euo pipefail

# RIGHT - explicit interpreter
#!/bin/bash
set -euo pipefail
5. 未将脚本设为可执行
# Don't forget!
chmod +x ~/.claude/hooks/my-hook.sh
6. 忘记在 JSON 中为路径加引号
// WRONG - spaces in path will break
"command": "$CLAUDE_PROJECT_DIR/.claude/hooks/script.sh"

// RIGHT - quoted path
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/script.sh"
7. 没有错误处理
# WRONG - silent failures
input=$(cat)
tool=$(echo "$input" | jq -r '.tool_name')

# RIGHT - handle errors
input=$(cat) || { echo "Failed to read input" >&2; exit 1; }
tool=$(echo "$input" | jq -r '.tool_name') || { echo "Failed to parse JSON" >&2; exit 1; }
8. 记录敏感数据
# WRONG - may log secrets
echo "Processing: $input" >> /tmp/debug.log

# RIGHT - sanitize before logging
echo "Processing tool: $tool_name" >> /tmp/debug.log

何时使用钩子

适合使用钩子的场景:

  • 安全强制执行(阻止危险操作)
  • 代码质量自动化(保存时格式化、运行 lint)
  • 合规与审计(记录所有操作)
  • 环境设置(保持配置一致)
  • 工作流自动化(通知、集成)
  • 输入验证(检查提示词)
  • 任务完成验证

不适合使用钩子的场景:

  • 添加新功能(使用 Skills)
  • 委派复杂工作(使用 Agents)
  • 由用户调用的提示词(使用 Commands)
  • 简单的一次性任务(直接询问 Claude)

此技能中的文件

模板(由简到繁)
  • templates/basic-hook.md — 单个事件,内联命令
  • templates/with-scripts.md — 外部 shell 脚本
  • templates/with-decisions.md — 权限控制、输入修改
  • templates/with-prompts.md — 基于大模型的评估
  • templates/production-hooks.md — 完整的多事件系统
示例(18 个完整钩子)
  • examples/security-hooks.md — 保护、验证、审计
  • examples/quality-hooks.md — 格式化、lint、测试
  • examples/workflow-hooks.md — 设置、上下文、通知
参考资料
  • reference/syntax-guide.md — 完整的 JSON 架构、所有事件
  • reference/best-practices.md — 安全、设计、团队部署
  • reference/troubleshooting.md — 10 个常见问题、测试方法

评论

支持 Markdown