name: creating-hooks description: | 创建Claude Code钩子以实现自动化和工作流定制。 指导钩子事件选择、配置和脚本创建。 当用户想要创建钩子、自动化Claude Code或询问钩子事件时使用。
创建钩子
指导创建Claude Code钩子以实现自动化和工作流定制。
快速开始
- 选择钩子事件(何时触发?)
- 在settings.json中配置
- 创建钩子脚本
- 测试钩子
工作流:创建新钩子
进度:
- [ ] 选择钩子事件
- [ ] 添加到settings.json
- [ ] 创建钩子脚本
- [ ] 测试和验证
步骤1:选择钩子事件
| 事件 | 触发时机 | 常见用途 |
|---|---|---|
PreToolUse |
工具运行前 | 阻止/修改工具 |
PostToolUse |
工具成功后 | 验证、日志记录、反馈 |
UserPromptSubmit |
用户发送消息时 | 注入上下文、验证 |
SessionStart |
会话开始时 | 加载上下文、初始化状态 |
SessionEnd |
会话结束时 | 清理、保存状态 |
Stop |
代理完成时 | 决定是否继续 |
完整事件参考:reference.md
步骤2:配置settings.json
位置优先级(最高优先):
.claude/settings.local.json(本地,不提交).claude/settings.json(项目)~/.claude/settings.json(用户)
基本结构:
{
"hooks": {
"EventName": [
{
"matcher": "ToolPattern",
"hooks": [
{
"type": "command",
"command": "bash \"$CLAUDE_PROJECT_DIR/.claude/hooks/my-hook.sh\""
}
]
}
]
}
}
步骤3:创建钩子脚本
使用templates/目录中的模板。
关键要求:
- 从stdin读取JSON
- 使用退出代码进行控制(0=成功,2=阻止)
- 输出JSON用于决策
步骤4:测试
使用测试输入手动运行钩子:
echo '{"tool_name":"Write"}' | bash .claude/hooks/my-hook.sh
钩子配置
匹配器模式
"matcher": "Write" // 精确匹配
"matcher": "Edit|Write" // 多个工具
"matcher": "mcp__.*" // MCP工具(正则表达式)
"matcher": "*" // 所有工具
匹配器适用于:PreToolUse、PostToolUse、PermissionRequest
超时设置
{
"type": "command",
"command": "...",
"timeout": 120
}
默认:60秒。最大推荐:300秒。
退出代码
| 代码 | 含义 | 行为 |
|---|---|---|
| 0 | 成功 | 正常继续 |
| 2 | 阻止 | 停止操作,显示错误 |
| 其他 | 非阻止性错误 | 仅记录(详细模式) |
JSON输出
返回JSON到stdout用于决策:
{
"decision": "block",
"reason": "阻止原因",
"additionalContext": "给Claude的额外信息"
}
按事件的决策值:
PreToolUse:allow、deny、askPostToolUse:block(需提供原因)UserPromptSubmit:block(需提供原因)Stop:block(需提供原因)
安全最佳实践
- 引用所有变量:
"$VAR"而不是$VAR - 使用绝对路径:
"$CLAUDE_PROJECT_DIR/..." - 验证输入:处理前检查
- 阻止路径遍历:拒绝包含
..的路径 - 设置超时:防止脚本失控
环境变量
所有钩子中可用:
CLAUDE_PROJECT_DIR- 项目根路径CLAUDE_CODE_REMOTE- 如果是Web环境则为"true"
仅SessionStart:
CLAUDE_ENV_FILE- 持久化环境变量的路径
常见模式
会话开始时注入上下文
#!/bin/bash
# 输出上下文给Claude
echo '{"additionalContext": "项目使用TypeScript"}'
exit 0
阻止危险文件编辑
#!/bin/bash
INPUT=$(cat)
FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
if [[ "$FILE" == *".env"* ]]; then
echo "阻止编辑敏感文件" >&2
exit 2
fi
exit 0
记录所有工具使用
#!/bin/bash
INPUT=$(cat)
TOOL=$(echo "$INPUT" | jq -r '.tool_name')
echo "$(date -Iseconds) $TOOL" >> "$CLAUDE_PROJECT_DIR/.claude/tool.log"
exit 0
查看reference.md获取完整事件详情和更多示例。