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

@@ -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 时,能够正常工作。