feat: update usage recommendations across multiple workflow commands to require user confirmation and improve clarity

This commit is contained in:
catlog22
2026-02-01 22:04:26 +08:00
parent 5fb910610a
commit 7dcc0a1c05
70 changed files with 4420 additions and 1108 deletions

View File

@@ -837,15 +837,28 @@ Selected items call: `/issue:new "{issue summary} - {dimension}"`
---
## Usage Recommendations
## Usage Recommendations (Requires User Confirmation)
1. **First Time**: Use default mode (debug-first), observe workflow
2. **Quick Decision**: Use CLI Quick (--mode cli) for immediate recommendations
3. **Quick Fix**: Use `--hotfix --yes` for minimal diagnostics (debug mode)
4. **Learning**: Use debug-first, read `understanding.md`
5. **Complete Validation**: Use bidirectional for multi-dimensional insights
6. **Auto Repair**: Use test-first for automatic iteration
7. **Escalation**: Start with CLI Quick, escalate to other modes as needed
**Use `Skill(skill="ccw-debug", args="\"bug description\"")` when:**
- First time: Use default mode (debug-first), observe workflow
**Use `Skill(skill="ccw-debug", args="--mode cli \"issue\"")` when:**
- Quick Decision: Immediate recommendations without full workflow
**Use `Skill(skill="ccw-debug", args="--hotfix --yes \"issue\"")` when:**
- Quick Fix: Minimal diagnostics for production issues
**Use `Skill(skill="ccw-debug", args="--mode debug \"issue\"")` when:**
- Learning: Read `understanding.md` for debugging insights
**Use `Skill(skill="ccw-debug", args="--mode bidirectional \"issue\"")` when:**
- Complete Validation: Multi-dimensional insights from parallel workflows
**Use `Skill(skill="ccw-debug", args="--mode test \"issue\"")` when:**
- Auto Repair: Automatic iteration with test-first approach
**Use `Skill(skill="ccw-debug", args="--mode cli \"issue\"")` when:**
- Escalation: Start with CLI Quick, then escalate to other modes as needed
---

View File

@@ -515,29 +515,35 @@ User agrees with current direction, wants deeper code analysis
- Current design allows horizontal scaling without session affinity
```
## Usage Recommendations
## Usage Recommendations (Requires User Confirmation)
**Use `/workflow:analyze-with-file` when:**
**Use `Skill(skill="workflow:analyze-with-file", args="\"topic\"")` when:**
- Exploring a complex topic collaboratively
- Need documented discussion trail
- Decision-making requires multiple perspectives
- Want to iterate on understanding with user input
- Building shared understanding before implementation
**Use `/workflow:debug-with-file` when:**
**Use `Skill(skill="workflow:debug-with-file", args="\"bug description\"")` when:**
- Diagnosing specific bugs
- Need hypothesis-driven investigation
- Focus on evidence and verification
**Use `/workflow:brainstorm-with-file` when:**
**Use `Skill(skill="workflow:brainstorm-with-file", args="\"topic or question\"")` when:**
- Generating new ideas or solutions
- Need creative exploration
- Want divergent thinking before convergence
**Use `/workflow:lite-plan` when:**
**Use `Skill(skill="workflow:collaborative-plan-with-file", args="\"task description\"")` when:**
- Complex planning requiring multiple perspectives
- Large scope needing parallel sub-domain analysis
- Want shared collaborative planning document
- Need structured task breakdown with agent coordination
**Use `Skill(skill="workflow:lite-plan", args="\"task description\"")` when:**
- Ready to implement (past analysis phase)
- Need structured task breakdown
- Focus on execution planning
- Need simple task breakdown
- Focus on quick execution planning
---

View File

@@ -745,25 +745,31 @@ Dimensions matched against topic keywords to identify focus areas:
See full markdown template in original file (lines 955-1161).
## Usage Recommendations
## Usage Recommendations (Requires User Confirmation)
**Use `/workflow:brainstorm-with-file` when:**
**Use `Skill(skill="workflow:brainstorm-with-file", args="\"topic or question\"")` when:**
- Starting a new feature/product without clear direction
- Facing a complex problem with multiple possible solutions
- Need to explore alternatives before committing
- Want documented thinking process for team review
- Combining multiple stakeholder perspectives
**Use `/workflow:analyze-with-file` when:**
**Use `Skill(skill="workflow:analyze-with-file", args="\"topic\"")` when:**
- Investigating existing code/system
- Need factual analysis over ideation
- Debugging or troubleshooting
- Understanding current state
**Use `/workflow:plan` when:**
**Use `Skill(skill="workflow:collaborative-plan-with-file", args="\"task description\"")` when:**
- Complex planning requiring multiple perspectives
- Large scope needing parallel sub-domain analysis
- Want shared collaborative planning document
- Need structured task breakdown with agent coordination
**Use `Skill(skill="workflow:lite-plan", args="\"task description\"")` when:**
- Direction is already clear
- Ready to move from ideas to execution
- Need implementation breakdown
- Need simple implementation breakdown
---

View File

@@ -658,15 +658,15 @@ Why is config value None during update?
| Hypothesis history | ❌ | ✅ hypotheses.json |
| Gemini validation | ❌ | ✅ At key decision points |
## Usage Recommendations
## Usage Recommendations (Requires User Confirmation)
Use `/workflow:debug-with-file` when:
**Use `Skill(skill="workflow:debug-with-file", args="\"bug description\"")` when:**
- Complex bugs requiring multiple investigation rounds
- Learning from debugging process is valuable
- Team needs to understand debugging rationale
- Bug might recur, documentation helps prevention
Use `/workflow:debug` when:
**Use `Skill(skill="ccw-debug", args="--mode cli \"issue\"")` when:**
- Simple, quick bugs
- One-off issues
- Documentation overhead not needed

View File

@@ -0,0 +1,453 @@
# Claude Code Hooks - 当前实现 vs 官方标准对比报告
## 执行摘要
当前 CCW 代码库中的钩子实现**不符合 Claude Code 官方标准**。存在以下主要问题:
1.**钩子事件名称不符合官方标准** - 使用了错误的事件名称
2.**配置结构不同** - 自定义了配置格式,不符合官方规范
3.**使用了不存在的事件类型** - 某些事件在官方钩子系统中不存在
4.**文档与实现不一致** - 代码中的注释引用的是自定义实现,而非官方标准
---
## 详细对比
### 1. 钩子事件名称对比
#### ❌ 当前实现(错误)
```json
{
"hooks": {
"session-start": [], // ❌ 错误:应为 SessionStart
"session-end": [], // ❌ 错误:应为 SessionEnd
"file-modified": [], // ❌ 错误:官方不支持此事件
"context-request": [], // ❌ 错误:官方不支持此事件
"PostToolUse": [] // ✅ 正确
}
}
```
#### ✅ 官方标准(正确)
```json
{
"hooks": {
"SessionStart": [], // ✅ 当会话开始或恢复时触发
"UserPromptSubmit": [], // ✅ 当用户提交提示词时触发
"PreToolUse": [], // ✅ 工具调用前触发,可以阻止
"PermissionRequest": [], // ✅ 权限对话出现时触发
"PostToolUse": [], // ✅ 工具调用成功后触发
"PostToolUseFailure": [], // ✅ 工具调用失败时触发
"Notification": [], // ✅ 通知发送时触发
"SubagentStart": [], // ✅ 子代理生成时触发
"SubagentStop": [], // ✅ 子代理完成时触发
"Stop": [], // ✅ Claude 完成响应时触发
"PreCompact": [], // ✅ 上下文压缩前触发
"SessionEnd": [] // ✅ 会话终止时触发
}
}
```
### 2. 配置结构对比
#### ❌ 当前实现(自定义结构)
```json
{
"hooks": {
"session-start": [
{
"name": "Progressive Disclosure",
"description": "Injects progressive disclosure index",
"enabled": true,
"handler": "internal:context",
"timeout": 5000,
"failMode": "silent"
}
]
},
"hookSettings": {
"globalTimeout": 60000,
"defaultFailMode": "silent",
"allowAsync": true,
"enableLogging": true
}
}
```
**问题:**
- 使用了非标准字段:`name`, `description`, `enabled`, `handler`, `failMode`
- 使用了自定义的 `hookSettings` 配置
- 结构过度复杂化
#### ✅ 官方标准(简洁标准)
```json
{
"hooks": {
"SessionStart": [
{
"matcher": "startup|resume|clear|compact",
"hooks": [
{
"type": "command",
"command": "bash /path/to/script.sh",
"timeout": 600,
"async": false
}
]
}
]
}
}
```
**优点:**
- 简洁明了的三层结构:事件 → 匹配器 → 处理器
- 标准的字段集:`type`, `command`, `timeout`, `async`
- 支持三种处理器类型:`command`, `prompt`, `agent`
### 3. 官方支持的钩子事件及其触发时机
| 事件名称 | 触发时机 | 可阻止 | 匹配器支持 |
|---------|---------|--------|-----------|
| `SessionStart` | 会话开始或恢复 | ❌ | startup, resume, clear, compact |
| `UserPromptSubmit` | 用户提交提示词前 | ✅ | ❌ |
| `PreToolUse` | 工具调用前 | ✅ | 工具名称 |
| `PermissionRequest` | 权限对话出现时 | ✅ | 工具名称 |
| `PostToolUse` | 工具调用成功后 | ❌ | 工具名称 |
| `PostToolUseFailure` | 工具调用失败时 | ❌ | 工具名称 |
| `Notification` | 通知发送时 | ❌ | 通知类型 |
| `SubagentStart` | 子代理生成时 | ❌ | 代理类型 |
| `SubagentStop` | 子代理完成时 | ✅ | 代理类型 |
| `Stop` | Claude 完成响应时 | ✅ | ❌ |
| `PreCompact` | 上下文压缩前 | ❌ | manual, auto |
| `SessionEnd` | 会话终止时 | ❌ | 终止原因 |
**当前实现不支持的事件:**
-`file-modified` - 官方系统中不存在
-`context-request` - 官方系统中不存在
### 4. 处理器类型对比
#### ❌ 当前实现
仅支持一种:`handler: "internal:context"`(自定义内部处理器)
#### ✅ 官方标准
支持三种标准类型:
1. **Command hooks** (`type: "command"`)
```json
{
"type": "command",
"command": "bash /path/to/script.sh",
"timeout": 600,
"async": false
}
```
2. **Prompt hooks** (`type: "prompt"`)
```json
{
"type": "prompt",
"prompt": "Evaluate if this is safe to execute: $ARGUMENTS",
"model": "haiku",
"timeout": 30
}
```
3. **Agent hooks** (`type: "agent"`)
```json
{
"type": "agent",
"prompt": "Verify tests pass: $ARGUMENTS",
"model": "haiku",
"timeout": 60
}
```
### 5. 匹配器对比
#### ❌ 当前实现
没有明确的匹配器概念,而是使用:
- `handler: "internal:context"` - 内部处理
- 没有工具级别的过滤
#### ✅ 官方标准
完整的匹配器系统:
```json
{
"PreToolUse": [
{
"matcher": "Edit|Write", // 仅在 Edit 或 Write 工具时触发
"hooks": [ ... ]
}
]
}
```
**支持的匹配器:**
- **工具事件**`Bash`, `Edit`, `Write`, `Read`, `Glob`, `Grep`, `Task`, `WebFetch`, `WebSearch`
- **MCP工具**`mcp__memory__.*`, `mcp__.*__write.*`
- **会话事件**`startup`, `resume`, `clear`, `compact`
- **通知类型**`permission_prompt`, `idle_prompt`, `auth_success`
- **代理类型**`Bash`, `Explore`, `Plan`
### 6. 输入/输出机制对比
#### ❌ 当前实现
- 未定义标准的 stdin/stdout 通信协议
- 使用了自定义的环境变量:`$SESSION_ID`, `$FILE_PATH`, `$PROJECT_PATH`
#### ✅ 官方标准
**标准 JSON stdin 输入:**
```json
{
"session_id": "abc123",
"transcript_path": "/path/to/transcript.jsonl",
"cwd": "/current/dir",
"permission_mode": "default",
"hook_event_name": "PreToolUse",
"tool_name": "Bash",
"tool_input": {
"command": "npm test"
}
}
```
**标准 exit code 输出:**
- **exit 0**: 成功,解析 stdout 的 JSON 决策
- **exit 2**: 阻止性错误stderr 成为 Claude 的反馈
- **其他码**: 非阻止性错误stderr 显示在详细模式
**标准 JSON stdout 输出:**
```json
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "allow|deny|ask",
"permissionDecisionReason": "explanation"
}
}
```
### 7. 文件位置对比
#### 当前实现
示例配置文件位置:
- `ccw/src/templates/hooks-config-example.json`
#### ✅ 官方标准
标准配置位置(优先级顺序):
1. `~/.claude/settings.json` - 全局用户配置
2. `.claude/settings.json` - 项目配置(可提交)
3. `.claude/settings.local.json` - 项目本地配置gitignored
4. 插件 `hooks/hooks.json` - 插件内部
5. Skill/Agent frontmatter - 技能或代理
---
## 代码库中的具体问题位置
### 1. 错误的配置示例
**文件:** `ccw/src/templates/hooks-config-example.json`
```json
{
"hooks": {
"session-start": [ ... ], // ❌ 应为 SessionStart
"session-end": [ ... ], // ❌ 应为 SessionEnd
"file-modified": [ ... ], // ❌ 不存在的事件
"context-request": [ ... ] // ❌ 不存在的事件
}
}
```
**应改为:**
```json
{
"hooks": {
"SessionStart": [
{
"matcher": "startup|resume",
"hooks": [
{
"type": "command",
"command": "echo 'Session started'"
}
]
}
],
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "prettier --write $FILE_PATH"
}
]
}
],
"SessionEnd": [
{
"matcher": "clear",
"hooks": [
{
"type": "command",
"command": "echo 'Session ended'"
}
]
}
]
}
}
```
### 2. 错误的命令注释
**文件:** `ccw/src/commands/hook.ts`
当前代码引用了自定义的钩子处理逻辑,但不符合官方标准。
---
## 修复建议
### 优先级 1关键修复
- [ ] 更新 `hooks-config-example.json` 使用官方事件名称
- [ ] 更新配置结构以符合官方三层标准
- [ ] 移除不支持的事件类型:`file-modified`, `context-request`
- [ ] 文档化官方支持的事件列表
### 优先级 2功能对齐
- [ ] 实现官方的标准 JSON stdin/stdout 通信
- [ ] 实现标准的 exit code 处理
- [ ] 支持标准的匹配器系统
### 优先级 3增强
- [ ] 添加对 `prompt` 和 `agent` 处理器类型的支持
- [ ] 实现标准的异步钩子支持(`async: true`
- [ ] 添加对环境变量持久化的支持(`CLAUDE_ENV_FILE`
---
## 官方示例
### 例1格式化代码后自动执行
```json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "jq -r '.tool_input.file_path' | xargs npx prettier --write"
}
]
}
]
}
}
```
### 例2阻止编辑受保护文件
```json
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/protect-files.sh"
}
]
}
]
}
}
```
### 例3会话开始时重新注入上下文
```json
{
"hooks": {
"SessionStart": [
{
"matcher": "compact",
"hooks": [
{
"type": "command",
"command": "echo 'Use Bun, not npm. Run bun test before committing.'"
}
]
}
]
}
}
```
### 例4基于条件的权限决策
```json
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "prompt",
"prompt": "Is this a safe command to run? $ARGUMENTS"
}
]
}
]
}
}
```
---
## 参考资源
- 官方指南https://code.claude.com/docs/en/hooks-guide
- 官方参考https://code.claude.com/docs/en/hooks
- 官方示例https://github.com/anthropics/claude-code/tree/main/examples/hooks
---
## 总结
当前 CCW 的钩子实现是基于自定义规范的,**完全不兼容** Claude Code 官方钩子系统。为了与官方标准对齐,需要进行彻底的重构,包括:
1. ✅ 采用官方的事件名称(已在 `.claude/docs/` 文件中提供)
2. ✅ 采用官方的三层配置结构
3. ✅ 实现官方的 JSON stdin/stdout 通信协议
4. ✅ 移除不存在的自定义事件
5. ✅ 支持官方的三种处理器类型
这样才能确保当用户将 CCW 的配置迁移到真实的 Claude Code CLI 时,能够正常工作。

View File

@@ -0,0 +1,224 @@
# Claude Code Hooks - 文档索引
本目录包含 Claude Code 官方钩子系统的完整文档和分析报告。
---
## 📚 官方文档(已下载)
### 1. HOOKS_OFFICIAL_GUIDE.md
- **来源**: https://code.claude.com/docs/en/hooks-guide
- **内容**: 官方钩子指南,包含快速入门、常见用例、配置教程
- **适用**: 初次使用钩子系统的开发者
### 2. HOOKS_OFFICIAL_REFERENCE.md
- **来源**: https://code.claude.com/docs/en/hooks
- **内容**: 完整的技术参考,包含所有事件的 schema、输入输出格式、配置选项
- **适用**: 需要查阅具体事件参数和配置细节的开发者
### 3. HOOKS_QUICK_REFERENCE.md
- **内容**: 快速查阅指南,包含所有事件列表、配置模板、常见用例
- **适用**: 需要快速查找特定配置或事件信息的开发者
---
## 📊 分析报告
### 4. HOOKS_ANALYSIS_REPORT.md
- **内容**: 当前 CCW 钩子实现 vs 官方标准对比分析
- **包含**:
- 当前实现存在的问题
- 事件名称对比
- 配置结构对比
- 修复建议和优先级
- **适用**: 需要了解当前实现与官方标准差异的开发者
---
## 💻 示例代码
### 5. ../examples/hooks_bash_command_validator.py
- **来源**: https://github.com/anthropics/claude-code/blob/main/examples/hooks/bash_command_validator_example.py
- **内容**: 官方示例 - Bash 命令验证器
- **功能**: 拦截 Bash 命令,建议使用 ripgrep 替代 grep
- **适用**: 学习如何编写 PreToolUse 钩子的开发者
---
## 🎯 官方钩子事件列表
### 官方支持的 12 个钩子事件
| # | 事件名称 | 触发时机 | 可阻止 |
|---|---------|---------|--------|
| 1 | `SessionStart` | 会话开始或恢复 | ❌ |
| 2 | `UserPromptSubmit` | 用户提交提示词前 | ✅ |
| 3 | `PreToolUse` | 工具调用前 | ✅ |
| 4 | `PermissionRequest` | 权限对话出现时 | ✅ |
| 5 | `PostToolUse` | 工具调用成功后 | ❌ |
| 6 | `PostToolUseFailure` | 工具调用失败后 | ❌ |
| 7 | `Notification` | 通知发送时 | ❌ |
| 8 | `SubagentStart` | 子代理生成时 | ❌ |
| 9 | `SubagentStop` | 子代理完成时 | ✅ |
| 10 | `Stop` | Claude完成响应时 | ✅ |
| 11 | `PreCompact` | 上下文压缩前 | ❌ |
| 12 | `SessionEnd` | 会话终止时 | ❌ |
---
## ⚠️ 当前实现的主要问题
### 问题 1: 事件名称不符合官方标准
**当前使用(错误):**
```json
{
"hooks": {
"session-start": [], // 错误
"session-end": [], // 错误
"file-modified": [], // 不存在
"context-request": [] // 不存在
}
}
```
**官方标准(正确):**
```json
{
"hooks": {
"SessionStart": [], // 正确
"SessionEnd": [], // 正确
"PostToolUse": [], // 使用其他官方事件
"PreToolUse": [] // 替代自定义事件
}
}
```
### 问题 2: 配置结构不符合官方标准
**当前结构(自定义):**
```json
{
"hooks": {
"session-start": [
{
"name": "...",
"enabled": true,
"handler": "internal:context",
"failMode": "silent"
}
]
}
}
```
**官方结构(标准):**
```json
{
"hooks": {
"SessionStart": [
{
"matcher": "startup|resume",
"hooks": [
{
"type": "command",
"command": "bash script.sh",
"timeout": 600
}
]
}
]
}
}
```
---
## 🔗 外部资源
### 官方资源
- **官方指南**: https://code.claude.com/docs/en/hooks-guide
- **官方参考**: https://code.claude.com/docs/en/hooks
- **GitHub 示例**: https://github.com/anthropics/claude-code/tree/main/examples/hooks
- **配置博客**: https://claude.com/blog/how-to-configure-hooks
### 社区资源
- [Claude Code Hooks 从入门到实战 - 知乎](https://zhuanlan.zhihu.com/p/1969164730326324920)
- [GitHub: claude-code-best-practices](https://github.com/xiaobei930/claude-code-best-practices)
- [Claude Code power user customization](https://claude.com/blog/how-to-configure-hooks)
---
## 📖 推荐阅读顺序
### 对于初学者
1. `HOOKS_QUICK_REFERENCE.md` - 快速了解钩子概念
2. `HOOKS_OFFICIAL_GUIDE.md` - 学习如何配置和使用
3. `hooks_bash_command_validator.py` - 查看示例代码
### 对于开发者(修复当前实现)
1. `HOOKS_ANALYSIS_REPORT.md` - 了解问题和修复方案
2. `HOOKS_OFFICIAL_REFERENCE.md` - 查阅技术细节
3. `HOOKS_OFFICIAL_GUIDE.md` - 学习最佳实践
### 对于高级用户
1. `HOOKS_OFFICIAL_REFERENCE.md` - 完整技术参考
2. 官方 GitHub 仓库 - 更多示例
3. `HOOKS_QUICK_REFERENCE.md` - 快速查阅
---
## 🛠️ 快速开始
### 查看当前配置
```bash
# 在 Claude Code CLI 中
/hooks
```
### 创建第一个钩子(格式化代码)
`.claude/settings.json`:
```json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "jq -r '.tool_input.file_path' | xargs prettier --write"
}
]
}
]
}
}
```
### 调试钩子
```bash
claude --debug # 查看详细执行日志
```
在 CLI 中按 `Ctrl+O` 切换详细模式
---
## 📝 文档更新
- **创建时间**: 2026-02-01
- **官方文档版本**: 最新(截至 2026-02-01
- **下次更新建议**: 当 Claude Code 发布新版本时
---
## 🔍 搜索关键词
钩子、Hooks、事件、Events、SessionStart、PreToolUse、PostToolUse、配置、Configuration、命令、Command、Prompt、Agent、阻止、Block、通知、Notification
---
**需要帮助?**
参考 `HOOKS_QUICK_REFERENCE.md` 获取快速答案,或查阅 `HOOKS_OFFICIAL_REFERENCE.md` 获取完整技术细节。

View File

@@ -0,0 +1,124 @@
# Claude Code Hooks - Official Guide
> Complete official documentation from https://code.claude.com/docs/en/hooks-guide
## Automate workflows with hooks
Run shell commands automatically when Claude Code edits files, finishes tasks, or needs input. Format code, send notifications, validate commands, and enforce project rules.
### Hook lifecycle
Hooks fire at specific points during a Claude Code session. The official hook events are:
| Event | When it fires |
| :------------------- | :--------------------------------------------------- |
| `SessionStart` | When a session begins or resumes |
| `UserPromptSubmit` | When you submit a prompt, before Claude processes it |
| `PreToolUse` | Before a tool call executes. Can block it |
| `PermissionRequest` | When a permission dialog appears |
| `PostToolUse` | After a tool call succeeds |
| `PostToolUseFailure` | After a tool call fails |
| `Notification` | When Claude Code sends a notification |
| `SubagentStart` | When a subagent is spawned |
| `SubagentStop` | When a subagent finishes |
| `Stop` | When Claude finishes responding |
| `PreCompact` | Before context compaction |
| `SessionEnd` | When a session terminates |
### Hook handler types
There are three types of hook handlers:
1. **Command hooks** (`type: "command"`): Run a shell command
2. **Prompt hooks** (`type: "prompt"`): Use Claude model for single-turn evaluation
3. **Agent hooks** (`type: "agent"`): Spawn subagent with tool access
### Configuration structure
```json
{
"hooks": {
"EventName": [
{
"matcher": "ToolName|AnotherTool",
"hooks": [
{
"type": "command",
"command": "bash /path/to/script.sh",
"timeout": 600,
"async": false
}
]
}
]
}
}
```
### Hook input (stdin)
Common fields for all events:
- `session_id`: Current session ID
- `transcript_path`: Path to conversation JSON
- `cwd`: Current working directory
- `permission_mode`: Current permission mode
- `hook_event_name`: Name of the event that fired
Event-specific fields depend on the event type.
### Hook output (exit codes and stdout)
- **Exit 0**: Success. Parse stdout for JSON decision
- **Exit 2**: Blocking error. stderr text becomes Claude's feedback
- **Any other code**: Non-blocking error
### Tool matchers
Available for: `PreToolUse`, `PostToolUse`, `PostToolUseFailure`, `PermissionRequest`
Tool names:
- Built-in: `Bash`, `Edit`, `Write`, `Read`, `Glob`, `Grep`, `Task`, `WebFetch`, `WebSearch`
- MCP tools: `mcp__<server>__<tool>` (e.g., `mcp__github__search_repositories`)
### Event matchers
Different events match on different fields:
- `SessionStart`: `startup`, `resume`, `clear`, `compact`
- `SessionEnd`: `clear`, `logout`, `prompt_input_exit`, `bypass_permissions_disabled`, `other`
- `Notification`: `permission_prompt`, `idle_prompt`, `auth_success`, `elicitation_dialog`
- `SubagentStart`/`SubagentStop`: agent type (e.g., `Bash`, `Explore`, `Plan`)
- `PreCompact`: `manual`, `auto`
### Hook configuration locations
| Location | Scope |
|----------|-------|
| `~/.claude/settings.json` | All your projects |
| `.claude/settings.json` | Single project |
| `.claude/settings.local.json` | Single project (gitignored) |
| Plugin `hooks/hooks.json` | When plugin enabled |
| Skill/Agent frontmatter | While component active |
### Best practices
**DO:**
- Use command hooks for deterministic actions
- Use prompt hooks for judgment-based decisions
- Use agent hooks when verification requires file inspection
- Quote all shell variables: `"$VAR"`
- Use absolute paths with `$CLAUDE_PROJECT_DIR`
- Set appropriate timeouts
- Use async hooks for long-running operations
- Keep hooks fast (< 10 seconds by default)
**DON'T:**
- Trust input data blindly
- Use relative paths
- Put sensitive data in hook output
- Create infinite loops in Stop hooks
- Run blocking operations without async
---
See https://code.claude.com/docs/en/hooks-guide for complete guide
See https://code.claude.com/docs/en/hooks for reference documentation

View File

@@ -0,0 +1,268 @@
# Claude Code Hooks - Official Reference
> Complete official reference from https://code.claude.com/docs/en/hooks
## Hooks reference
This is the complete technical reference for Claude Code hooks.
### Hook events reference
#### SessionStart
**When it fires:** When a session begins or resumes
**Matchers:**
- `startup` - New session
- `resume` - `--resume`, `--continue`, or `/resume`
- `clear` - `/clear`
- `compact` - Auto or manual compaction
**Input schema:**
```json
{
"session_id": "abc123",
"transcript_path": "/path/to/transcript.jsonl",
"cwd": "/current/working/dir",
"permission_mode": "default",
"hook_event_name": "SessionStart",
"source": "startup|resume|clear|compact",
"model": "claude-sonnet-4-5-20250929"
}
```
**Output control:**
- Exit 0: Text written to stdout is added to Claude's context
- Can use `additionalContext` in JSON output
- Cannot block session start
**Special variables:**
- `CLAUDE_ENV_FILE`: Write `export` statements to persist environment variables
#### UserPromptSubmit
**When it fires:** When user submits a prompt, before Claude processes it
**Input schema:**
```json
{
"session_id": "abc123",
"hook_event_name": "UserPromptSubmit",
"prompt": "User's prompt text here"
}
```
**Output control:**
- Exit 0: Plain text stdout is added as context
- `decision: "block"` prevents prompt processing
- `additionalContext` adds context to Claude
#### PreToolUse
**When it fires:** Before a tool call executes
**Matchers:** Tool names (Bash, Edit, Write, Read, etc.)
**Tool input schemas:**
- `Bash`: `command`, `description`, `timeout`, `run_in_background`
- `Write`: `file_path`, `content`
- `Edit`: `file_path`, `old_string`, `new_string`, `replace_all`
- `Read`: `file_path`, `offset`, `limit`
- `Glob`: `pattern`, `path`
- `Grep`: `pattern`, `path`, `glob`, `output_mode`, `-i`, `multiline`
- `WebFetch`: `url`, `prompt`
- `WebSearch`: `query`, `allowed_domains`, `blocked_domains`
- `Task`: `prompt`, `description`, `subagent_type`, `model`
**Output control:**
- `permissionDecision`: `"allow"`, `"deny"`, `"ask"`
- `permissionDecisionReason`: Explanation
- `updatedInput`: Modify tool input before execution
- `additionalContext`: Add context to Claude
#### PermissionRequest
**When it fires:** When permission dialog appears
**Input schema:** Similar to PreToolUse but fires when permission needed
**Output control:**
- `decision.behavior`: `"allow"` or `"deny"`
- `decision.updatedInput`: Modify input before execution
- `decision.message`: For deny, tells Claude why
#### PostToolUse
**When it fires:** After a tool call succeeds
**Input schema:** Includes both `tool_input` and `tool_response`
**Output control:**
- `decision: "block"` to flag issue to Claude
- `additionalContext`: Add context
- `updatedMCPToolOutput`: For MCP tools, replace output
#### PostToolUseFailure
**When it fires:** After a tool call fails
**Input schema:** Includes `error` and `is_interrupt` fields
**Output control:**
- `additionalContext`: Provide context about the failure
#### Notification
**When it fires:** When Claude Code sends a notification
**Matchers:**
- `permission_prompt` - Permission needed
- `idle_prompt` - Claude idle
- `auth_success` - Auth successful
- `elicitation_dialog` - Dialog shown
**Input schema:**
```json
{
"hook_event_name": "Notification",
"message": "Notification text",
"title": "Title",
"notification_type": "permission_prompt|idle_prompt|..."
}
```
#### SubagentStart
**When it fires:** When subagent is spawned
**Matchers:** Agent types (Bash, Explore, Plan, or custom)
**Input schema:**
```json
{
"hook_event_name": "SubagentStart",
"agent_id": "agent-abc123",
"agent_type": "Explore"
}
```
**Output control:**
- `additionalContext`: Add context to subagent
#### SubagentStop
**When it fires:** When subagent finishes
**Input schema:** Similar to SubagentStart with `stop_hook_active` field
#### Stop
**When it fires:** When Claude finishes responding
**Input schema:**
```json
{
"hook_event_name": "Stop",
"stop_hook_active": false|true
}
```
**Output control:**
- `decision: "block"` prevents Claude from stopping
- `reason`: Required when blocking, tells Claude why to continue
- Check `stop_hook_active` to prevent infinite loops
#### PreCompact
**When it fires:** Before context compaction
**Matchers:**
- `manual` - `/compact`
- `auto` - Auto-compact when context full
**Input schema:**
```json
{
"hook_event_name": "PreCompact",
"trigger": "manual|auto",
"custom_instructions": ""
}
```
#### SessionEnd
**When it fires:** When session terminates
**Matchers:**
- `clear` - `/clear`
- `logout` - User logged out
- `prompt_input_exit` - User exited during prompt
- `bypass_permissions_disabled` - Bypass disabled
- `other` - Other reasons
**Input schema:**
```json
{
"hook_event_name": "SessionEnd",
"reason": "clear|logout|..."
}
```
### Prompt-based hooks
**Type:** `"prompt"`
**Configuration:**
```json
{
"type": "prompt",
"prompt": "Your prompt here. Use $ARGUMENTS for input JSON",
"model": "haiku",
"timeout": 30
}
```
**Response schema:**
```json
{
"ok": true|false,
"reason": "Explanation if ok is false"
}
```
### Agent-based hooks
**Type:** `"agent"`
**Configuration:**
```json
{
"type": "agent",
"prompt": "Your prompt here. Use $ARGUMENTS for input JSON",
"model": "haiku",
"timeout": 60
}
```
**Response schema:** Same as prompt hooks
### Async hooks
**For command hooks only:**
```json
{
"type": "command",
"command": "...",
"async": true,
"timeout": 300
}
```
- Doesn't block Claude's execution
- Cannot return decisions
- Output delivered on next conversation turn
- Max 50 turns per session
---
See https://code.claude.com/docs/en/hooks for full reference

View File

@@ -0,0 +1,390 @@
# Claude Code Hooks - 快速参考
## 12 个官方钩子事件
| # | 事件名称 | 触发时机 | 可阻止 | 匹配器 |
|---|---------|---------|--------|--------|
| 1 | `SessionStart` | 会话开始/恢复 | ❌ | startup, resume, clear, compact |
| 2 | `UserPromptSubmit` | 用户提交提示词前 | ✅ | ❌ 不支持 |
| 3 | `PreToolUse` | 工具调用前 | ✅ | 工具名称 |
| 4 | `PermissionRequest` | 权限对话时 | ✅ | 工具名称 |
| 5 | `PostToolUse` | 工具成功后 | ❌ | 工具名称 |
| 6 | `PostToolUseFailure` | 工具失败后 | ❌ | 工具名称 |
| 7 | `Notification` | 发送通知时 | ❌ | 通知类型 |
| 8 | `SubagentStart` | 子代理开始 | ❌ | 代理类型 |
| 9 | `SubagentStop` | 子代理完成 | ✅ | 代理类型 |
| 10 | `Stop` | Claude完成响应 | ✅ | ❌ 不支持 |
| 11 | `PreCompact` | 上下文压缩前 | ❌ | manual, auto |
| 12 | `SessionEnd` | 会话终止 | ❌ | 终止原因 |
---
## 配置模板
### 基础结构
```json
{
"hooks": {
"EventName": [
{
"matcher": "pattern",
"hooks": [
{
"type": "command|prompt|agent",
"command": "...",
"timeout": 600,
"async": false
}
]
}
]
}
}
```
---
## 工具名称(用于匹配器)
### 内置工具
```
Bash, Edit, Write, Read, Glob, Grep, Task, WebFetch, WebSearch
```
### MCP 工具
```
mcp__<server>__<tool>
mcp__memory__.*
mcp__.*__write.*
```
---
## Exit Codes
| Code | 含义 | Claude反馈 |
|------|------|-----------|
| 0 | 成功 | 解析 stdout JSON允许操作 |
| 2 | 阻止 | stderr 发送给 Claude阻止操作 |
| 其他 | 错误 | stderr 仅在详细模式显示 |
---
## 标准 JSON 输入stdin
```json
{
"session_id": "abc123",
"transcript_path": "/path/to/transcript.jsonl",
"cwd": "/current/dir",
"permission_mode": "default",
"hook_event_name": "PreToolUse",
"tool_name": "Bash",
"tool_input": {
"command": "npm test"
}
}
```
---
## 标准 JSON 输出stdout, exit 0
### PreToolUse
```json
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "allow|deny|ask",
"permissionDecisionReason": "explanation"
}
}
```
### UserPromptSubmit
```json
{
"decision": "block",
"reason": "explanation",
"hookSpecificOutput": {
"hookEventName": "UserPromptSubmit",
"additionalContext": "context string"
}
}
```
### Stop
```json
{
"decision": "block",
"reason": "Must complete tasks X, Y, Z"
}
```
---
## 处理器类型
### 1. Command Hook
```json
{
"type": "command",
"command": "bash /path/to/script.sh",
"timeout": 600,
"async": false
}
```
### 2. Prompt Hook
```json
{
"type": "prompt",
"prompt": "Evaluate: $ARGUMENTS",
"model": "haiku",
"timeout": 30
}
```
响应格式:
```json
{
"ok": true|false,
"reason": "explanation if ok is false"
}
```
### 3. Agent Hook
```json
{
"type": "agent",
"prompt": "Verify tests pass: $ARGUMENTS",
"model": "haiku",
"timeout": 60
}
```
响应格式:与 Prompt Hook 相同
---
## 环境变量
### 标准变量
```bash
$CLAUDE_PROJECT_DIR # 项目根目录
$CLAUDE_PLUGIN_ROOT # 插件根目录(插件内部使用)
$CLAUDE_CODE_REMOTE # "true" 在远程环境
```
### SessionStart 特殊变量
```bash
$CLAUDE_ENV_FILE # 持久化环境变量的文件路径
```
用法:
```bash
#!/bin/bash
if [ -n "$CLAUDE_ENV_FILE" ]; then
echo 'export NODE_ENV=production' >> "$CLAUDE_ENV_FILE"
fi
```
---
## 常见用例
### 1. 格式化代码
```json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "jq -r '.tool_input.file_path' | xargs prettier --write"
}
]
}
]
}
}
```
### 2. 阻止危险命令
```json
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/block-rm.sh"
}
]
}
]
}
}
```
脚本 `block-rm.sh`:
```bash
#!/bin/bash
COMMAND=$(jq -r '.tool_input.command')
if echo "$COMMAND" | grep -q 'rm -rf'; then
echo "Blocked: rm -rf is not allowed" >&2
exit 2
fi
exit 0
```
### 3. 通知用户
```json
{
"hooks": {
"Notification": [
{
"matcher": "permission_prompt",
"hooks": [
{
"type": "command",
"command": "osascript -e 'display notification \"Claude needs your attention\"'"
}
]
}
]
}
}
```
### 4. 确认任务完成
```json
{
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "prompt",
"prompt": "Check if all tasks complete: $ARGUMENTS"
}
]
}
]
}
}
```
### 5. 异步运行测试
```json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write",
"hooks": [
{
"type": "command",
"command": "/path/to/run-tests.sh",
"async": true,
"timeout": 120
}
]
}
]
}
}
```
### 6. 会话开始注入上下文
```json
{
"hooks": {
"SessionStart": [
{
"matcher": "compact",
"hooks": [
{
"type": "command",
"command": "echo 'Reminder: use Bun, not npm'"
}
]
}
]
}
}
```
---
## 配置位置
| 位置 | 作用域 | 可共享 |
|------|--------|--------|
| `~/.claude/settings.json` | 全局用户 | ❌ |
| `.claude/settings.json` | 单个项目 | ✅ |
| `.claude/settings.local.json` | 单个项目 | ❌ (gitignored) |
| 插件 `hooks/hooks.json` | 插件启用时 | ✅ |
| Skill/Agent frontmatter | 组件活动时 | ✅ |
---
## 调试技巧
### 1. 详细模式
```bash
claude --debug # 查看完整钩子执行细节
Ctrl+O # 切换详细模式(实时)
```
### 2. 测试钩子脚本
```bash
echo '{"tool_name":"Bash","tool_input":{"command":"ls"}}' | ./my-hook.sh
echo $? # 检查退出码
```
### 3. 检查钩子配置
```
/hooks # 交互式钩子管理器
```
---
## 最佳实践
**推荐:**
- 总是引用 shell 变量:`"$VAR"`
- 使用绝对路径:`"$CLAUDE_PROJECT_DIR"/script.sh`
- 设置合理的超时时间
- 验证和清理输入数据
- 在 Stop 钩子中检查 `stop_hook_active`
- 使用 async 进行长时间运行的操作
**避免:**
- 直接信任输入数据
- 使用相对路径
- 在钩子输出中暴露敏感数据
- 创建无限循环(尤其在 Stop 钩子)
- 没有设置超时的阻塞操作
---
## 官方资源
- **指南**: https://code.claude.com/docs/en/hooks-guide
- **参考**: https://code.claude.com/docs/en/hooks
- **示例**: https://github.com/anthropics/claude-code/tree/main/examples/hooks
---
## 本地文档
- `HOOKS_OFFICIAL_GUIDE.md` - 官方指南中文版
- `HOOKS_OFFICIAL_REFERENCE.md` - 官方参考中文版
- `HOOKS_ANALYSIS_REPORT.md` - 当前实现对比分析
- `hooks_bash_command_validator.py` - 官方示例脚本

View File

@@ -0,0 +1,85 @@
#!/usr/bin/env python3
"""
Claude Code Hook: Bash Command Validator
=========================================
This hook runs as a PreToolUse hook for the Bash tool.
It validates bash commands against a set of rules before execution.
In this case it changes grep calls to using rg.
Read more about hooks here: https://code.claude.com/docs/en/hooks
Make sure to change your path to your actual script.
Configuration for .claude/settings.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "python3 /path/to/bash_command_validator.py"
}
]
}
]
}
}
"""
import json
import re
import sys
# Define validation rules as a list of (regex pattern, message) tuples
_VALIDATION_RULES = [
(
r"^grep\b(?!.*\|)",
"Use 'rg' (ripgrep) instead of 'grep' for better performance and features",
),
(
r"^find\s+\S+\s+-name\b",
"Use 'rg --files | rg pattern' or 'rg --files -g pattern' instead of 'find -name' for better performance",
),
]
def _validate_command(command: str) -> list[str]:
issues = []
for pattern, message in _VALIDATION_RULES:
if re.search(pattern, command):
issues.append(message)
return issues
def main():
try:
input_data = json.load(sys.stdin)
except json.JSONDecodeError as e:
print(f"Error: Invalid JSON input: {e}", file=sys.stderr)
# Exit code 1 shows stderr to the user but not to Claude
sys.exit(1)
tool_name = input_data.get("tool_name", "")
if tool_name != "Bash":
sys.exit(0)
tool_input = input_data.get("tool_input", {})
command = tool_input.get("command", "")
if not command:
sys.exit(0)
issues = _validate_command(command)
if issues:
for message in issues:
print(f"{message}", file=sys.stderr)
# Exit code 2 blocks tool call and shows stderr to Claude
sys.exit(2)
if __name__ == "__main__":
main()