安装 hook:转换事件
各 agent 如何命名 hook 事件
Section titled “各 agent 如何命名 hook 事件”Claude Code 在调用工具前运行 hook,使用的是 PreToolUse 事件。Gemini CLI 把同一时机称为 BeforeTool,Cursor 则称为 preToolUse。原样复制过去的 hook 永远不会触发。工具名称也不相同:Claude Code 的 shell 工具名为 Bash,Gemini CLI 的则是 run_shell_command。
HarnessKit 怎么做
Section titled “HarnessKit 怎么做”- 读取。HarnessKit 从来源 agent 读取 hook 的事件、matcher 和命令,其他内容(例如超时)都不会带过去。
- 转换事件。在一张以 Claude Code 事件名为键的表中查找该事件。若目标没有对应的事件,安装失败。详情面板只提示「安装到 Hermes 失败」;具体原因(例如「Hook event ‘Stop’ is not supported by hermes」)只能在批量安装的汇总中看到。
- 追加。在目标的 hook 文件中,把命令添加到转换后的事件下。已有的命令不会重复添加。
表中的几组实际对应关系:
| Claude Code 事件 | 目标 agent | 目标中的名称 |
|---|---|---|
PreToolUse | Gemini CLI | BeforeTool |
PreToolUse | Cursor | preToolUse |
PreToolUse | Hermes | pre_tool_call |
UserPromptSubmit | Gemini CLI | BeforeAgent |
Stop | Devin Desktop | post_cascade_response |
Stop | Hermes | 没有,安装失败 |
HarnessKit 支持 10 个 agent 的 hook:Claude Code、Codex、Gemini CLI、Cursor、Copilot、Devin Desktop、Hermes、Kiro、Grok Build 和 Qoder CN。其中 Codex、Copilot、Kiro、Grok Build 和 Qoder CN 与 Claude Code 共有的事件,使用的就是 Claude Code 的名称。
Devin Desktop 有 12 个 hook 事件,HarnessKit 有意只映射了其中 2 个。Devin Desktop 把工具调用拆分为读代码、写代码、运行命令和 MCP 调用。若把其中任何一类对应到 PreToolUse,都会改变 hook 触发的频率,因此 HarnessKit 不映射这几类。
下面是一个检查 shell 命令的 Claude Code hook:
{ "hooks": { "PreToolUse": [ { "matcher": "Bash", "hooks": [{ "type": "command", "command": "~/bin/check-command.sh" }] } ] }}安装到 Gemini CLI 后,Gemini CLI 的设置文件中会新增这一条:
{ "hooks": { "BeforeTool": [ { "hooks": [ { "command": "~/bin/check-command.sh", "type": "command" } ], "matcher": "Bash" } ] }}事件变为 BeforeTool。matcher 仍是 Bash,但 Gemini CLI 没有这个名称的工具。将其改为 run_shell_command 后,hook 才会触发。
Grok Build 有 disabled-hooks 文件,Kiro 的每个 hook 都有 enabled 标志,HarnessKit 直接使用这两种机制。在其他 agent 上,禁用会把 hook 从文件中删除,HarnessKit 在自己的数据库中保留一份快照(原样副本),与 MCP server 的做法相同。
crates/hk-core/src/adapter/hook_events.rs存放事件对应表,以 Claude Code 的事件名为键。crates/hk-core/src/service.rs在安装时转换事件,此外不转换任何内容。crates/hk-core/src/deployer.rs每种 hook 格式一个写入器,并决定哪些格式保留 matcher。crates/hk-core/src/manager.rs负责启用和禁用 hook。src/lib/agent-capabilities.ts按是否支持 hook、是否支持该范围,把安装到智能体下的 agent 按钮置灰,不看事件。