# Claude Code Setup Claude Code hook 事件建议映射: | Claude Code event | Signal | | --- | --- | | `ConfigChange` | `attention` | | `CwdChanged` | `attention` | | `Elicitation` | `attention` | | `ElicitationResult` | `working` | | `FileChanged` | `attention` | | `InstructionsLoaded` | `attention` | | `SessionStart` | `session_start` | | `TaskCreated` | `subagent_start` | | `TaskCompleted` | `subagent_stop` | | `TeammateIdle` | `idle` | | `UserPromptExpansion` | `thinking` | | `UserPromptSubmit` | `thinking` | | `PreToolUse` | `working` | | `PostToolBatch` | `tool_done` | | `PostToolUse` | `tool_done` | | `PostToolUseFailure` | `blocked` | | `PreCompact` | `working` | | `PostCompact` | `tool_done` | | `SubagentStart` | `subagent_start` | | `SubagentStop` | `subagent_stop` | | `PermissionRequest` | `permission_request` | | `PermissionDenied` | `blocked` | | `Notification` | `notification` | | `Stop` | `done` | | `StopFailure` | `blocked` | | `WorktreeCreate` | `working` | | `WorktreeRemove` | `attention` | | `SessionEnd` | `session_end` | 普通 `Stop` 表示成功完成,会进入短暂的绿色 completed。紧随其后的 `SessionEnd` 会保留 completed 和需要处理的提示,只清理普通 active session。若当前 session 已经是 `permission`、`blocked` 或 `attention`,这个完成事件只会写入最近事件,不会覆盖仍需处理的提示。如果 hook payload 中包含 `error`、`failure`、`exception`、非零 `exit_status` 等结构化失败字段,即使事件名不是 `PostToolUseFailure`,也会映射为 `blocked`。 事件名会做容错归一化,`PostToolUseFailure`、`post_tool_use_failure`、`post-tool-use-failure` 和 `post tool use failure` 都会映射到同一个 signal。 常见 payload 字段名也会容错归一化,例如 `session_id` / `sessionId`、`hook_event_name` / `hookEventName`、`exit_status` / `exitStatus`、`stop_reason` / `stopReason`。 `Stop` 的 `stop_reason` 也会做容错归一化:`max_tokens`、`max-tokens`、`max tokens` 都会映射为 `max_tokens` 阻塞;包含 `error` / `failure` / `exception` 的原因会映射为红色错误。 Claude Code 会把事件 JSON 传给 hook stdin,因此通常不需要把事件名作为命令参数。 ## Desktop App vs Claude Code Agent Signal Bar 的 `thinking` / `working` / `done` 状态来自 Claude Code hook 事件,例如 `UserPromptSubmit`、`PreToolUse` 和 `Stop`。Claude Desktop 的普通聊天窗口只表示 Claude.app 正在运行,不会把这些 Claude Code hook 事件发给 `~/.claude/settings.json`。 如果设置窗口显示 hook 已配置,但 Claude 仍然只显示“桌面版运行中”,先运行: ```bash ./script/doctor.sh ``` 重点看两项: - `Claude Code CLI not found in PATH`:当前终端环境没有可运行的 `claude` 命令,无法用 CLI 会话触发 hook。 - `Claude Desktop log says Claude Code requires a Pro or Max subscription`:Claude Desktop 没能启动 Claude Code/local-agent runtime;在这个状态下,普通 Claude 聊天不会产生 `thinking` / `working` hook 事件。 ## Recommended Install 先安装 release 版 CLI,避免 hook 第一次触发时临时编译: ```bash ./script/install_cli.sh ``` 预览并合并到现有 `~/.claude/settings.json`: ```bash ./script/install_hooks.py --target claude --dry-run ./script/install_hooks.py --target claude --install ``` 安装脚本会保留已有 JSON 字段,只追加缺失的 Agent Signal Bar hook block,并在写入已有文件前生成 `settings.json.bak-YYYYmmddHHMMSS` 备份。如果发现旧路径的 `claude-code-signal-hook`,会迁移到当前 checkout 或当前 app bundle 的 wrapper 路径,避免同一个事件重复触发多个 Agent Signal Bar hook。 ## Manual Shape 通常不需要手写 JSON。若要手动配置,command 中的 wrapper 路径必须 shell-safe;路径含空格时要用单引号包住: ```json { "hooks": { "PreToolUse": [ { "hooks": [ { "type": "command", "command": "'/path/to/AgentSignalLight/scripts/claude-code-signal-hook'", "timeout": 5 } ], "matcher": "" } ], "PermissionRequest": [ { "hooks": [ { "type": "command", "command": "'/path/to/AgentSignalLight/scripts/claude-code-signal-hook'", "timeout": 10 } ], "matcher": "" } ] } } ``` 完整事件列表以 `./script/install_hooks.py --target claude --dry-run` 输出为准。