# Claude Code Hooks 说明 ## 结构 ``` hooks/ ├── run-hook.ps1 # Windows dispatcher(读取 settings.local.json 后分发) ├── session-init.ps1 # SessionStart hook(PowerShell 版) ├── session-init.sh # SessionStart hook(bash 版) ├── check-changelog.ps1 # Stop hook(PowerShell 版) ├── check-changelog.sh # Stop hook(bash 版) └── README.md # 本文件 ``` ## 事件对应关系 Claude Code 的 hook 事件名与 Cursor 不同: | Cursor 事件 | Claude Code 事件 | 用途 | |-------------|------------------|------| | `sessionStart` | `SessionStart` | 会话启动时触发 | | `stop` | `Stop` | 会话停止或即将输出最终回复时触发 | 配置位置为 `.claude/settings.json` 的 `hooks` 字段,格式参考 [Claude Code 官方 hooks 文档](https://docs.claude.com/en/docs/claude-code/hooks)。 ## 跨平台适配 `settings.json` 中的 `command` 字段是**平台绑定的**——Windows 用 `powershell`,macOS/Linux 用 `bash`。 ### Windows(当前默认) settings.json 使用 `powershell ... run-hook.ps1` 作为入口,dispatcher 根据 `.claude/settings.local.json` 的 `shell` 字段决定执行 `.ps1` 还是 `.sh` 脚本。 ### 迁移到 macOS / Linux 将 settings.json 的 command 改为直接调用 `.sh` 脚本: ```json { "hooks": { "SessionStart": [ { "matcher": "", "hooks": [ { "type": "command", "command": "bash .claude/hooks/session-init.sh", "timeout": 5 } ] } ], "Stop": [ { "matcher": "", "hooks": [ { "type": "command", "command": "bash .claude/hooks/check-changelog.sh", "timeout": 10 } ] } ] } } ``` 同时把 `settings.local.example.json` 复制为 `settings.local.json`,将 `shell` 字段改为 `bash` 或 `zsh`。 ## 与 Cursor 版本的关键差异 1. **删除 `composer_mode` 检测** —— Claude Code 没有 IDE 模式概念,相关豁免逻辑已移除 2. **使用 `transcript_path` 做 edit evidence 检查** —— Stop hook 通过读取 Claude Code 传入的 transcript 文件,Grep `Write`/`Edit`/`NotebookEdit`/`MultiEdit` 工具调用判断本次会话是否实际修改过文件;没有则静默退出,避免跨会话残留 mtime 误触发 3. **无 `loop_limit` 字段** —— Claude Code hooks 配置中不存在此字段;`stop_hook_active` 由 Claude Code 通过 stdin 的 JSON 传入,避免死循环由 hook 脚本自行判断 4. **SessionStart Hook 双重职责** —— 除清除 ack 标记外,还会检查 `.claude/.init-done` sentinel:缺失时创建 `.claude/.pending-init` 标记文件,供 `claude-init-recall` 规则检测,确保首次会话确定性地触发 claude-init 流程。sentinel 存在时自动清理残留的 pending 标记。