Hook 参考指南
版本要求:本文档针对 CodeBuddy Code v1.16.0 及以上版本中提供的 Claude Code Hooks 兼容实现。 功能状态:Hook 功能当前处于 Beta 阶段,接口和行为可能在未来版本中调整。
Hook(钩子)允许你在 CodeBuddy Code 的会话生命周期内插入自定义脚本或命令,实现自动化校验、环境初始化、合规检查等高级能力。我们的实现完全兼容 Claude Code Hooks 规范,支持相同的事件类型、输入输出结构以及安全特性。
功能概览
- 完整支持 Claude Code Hooks 九大事件:
PreToolUse、PostToolUse、Notification、UserPromptSubmit、Stop、SubagentStop、PreCompact、SessionStart、SessionEnd。 - 支持基于正则表达式的 matcher,可按工具名称或事件上下文筛选执行。
- 自动注入
session_id、会话转录文件、当前工作目录等上下文信息。 - 支持退出码与 JSON 输出双模式,完全复刻 Claude Code 的决策语义。
- 支持 CLI
/hooks面板进行图形化配置,所有外部修改需在面板审核后生效,保障安全。 - 钩子脚本在 60 秒超时后自动终止,不影响其他 hook 执行。
配置
CodeBuddy Code hooks 存储在你的设置文件中:
| 作用域 | 文件路径 | 说明 |
|---|---|---|
| 用户级 | ~/.codebuddy/settings.json | 适用于所有项目 |
| 项目级 | <项目根>/.codebuddy/settings.json | 对项目成员共享的配置 |
| 项目本地 | <项目根>/.codebuddy/settings.local.json | 本地未提交配置 |
| 企业策略 | 集成发布的策略文件 | 受企业统一管理 |
结构
Hooks 按匹配器组织,每个匹配器可以有多个 hooks:
json
{
"hooks": {
"EventName": [
{
"matcher": "ToolPattern",
"hooks": [
{
"type": "command",
"command": "your-command-here"
}
]
}
]
}
}关键字段:
- matcher:用于匹配工具名称的模式,区分大小写(仅适用于 PreToolUse 和 PostToolUse)
- 简单字符串精确匹配:
Write仅匹配 Write 工具 - 支持正则表达式:
Edit|Write或Web.* - 使用
*匹配所有工具。也可以使用空字符串("")或留空匹配器。
- 简单字符串精确匹配:
- hooks:当模式匹配时执行的 hooks 数组
- type: Hook 执行类型 -
"command"用于 bash 命令,或"prompt"用于基于 LLM 的评估(暂未支持) - command: (对于 type:
"command") 要执行的 bash 命令(可以使用$CODEBUDDY_PROJECT_DIR环境变量) - prompt: (对于 type:
"prompt") 发送给 LLM 进行评估的提示词(暂未支持) - timeout: (可选) hook 运行多长时间(以秒为单位)后取消该特定 hook
- type: Hook 执行类型 -
对于不使用匹配器的事件(如 UserPromptSubmit、Stop 和 SubagentStop),你可以省略 matcher 字段:
json
{
"hooks": {
"UserPromptSubmit": [
{
"hooks": [
{
"type": "command",
"command": "/path/to/prompt-validator.py"
}
]
}
]
}
}项目特定的 Hook 脚本
你可以使用环境变量 CODEBUDDY_PROJECT_DIR(仅在 CodeBuddy Code 生成 hook 命令时可用)来引用存储在项目中的脚本:
json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "\"$CODEBUDDY_PROJECT_DIR\"/.codebuddy/hooks/check-style.sh"
}
]
}
]
}
}插件 Hooks
插件可以提供与用户和项目 hooks 无缝集成的 hooks。启用插件时,插件 hooks 会自动与你的配置合并。
插件 hooks 的工作方式:
- 插件 hooks 在插件的
hooks/hooks.json文件中定义,或在 hooks 字段提供的自定义路径的文件中定义 - 当插件启用时,其 hooks 会与用户和项目 hooks 合并
- 来自不同来源的多个 hooks 可以响应同一事件
- 插件 hooks 使用
${CODEBUDDY_PLUGIN_ROOT}环境变量来引用插件文件
插件 hook 配置示例:
json
{
"description": "Automatic code formatting",
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "${CODEBUDDY_PLUGIN_ROOT}/scripts/format.sh",
"timeout":30
}
]
}
]
}
}基于提示词的 Hooks
注:该功能暂未支持。
除了 bash 命令 hooks(type: "command"),CodeBuddy Code 还支持基于提示词的 hooks(type: "prompt"),使用 LLM 来评估是否允许或阻止某个操作。
基于提示词的 hooks 如何工作
基于提示词的 hooks 不是执行 bash 命令,而是:
- 将 hook 输入和你的提示词发送给快速 LLM
- LLM 使用包含决策的结构化 JSON 响应
- CodeBuddy Code 自动处理决策
配置
json
{
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "prompt",
"prompt": "Evaluate if CodeBuddy should stop: $ARGUMENTS. Check if all tasks are complete."
}
]
}
]
}
}字段:
- type:必须为
"prompt" - prompt:发送给 LLM 的提示词文本
- 使用
$ARGUMENTS作为 hook 输入 JSON 的占位符 - 如果不存在
$ARGUMENTS,输入 JSON 会附加到提示词后
- 使用
- timeout: (可选) 超时时间(秒)(默认: 30 秒)
响应模式
LLM 必须使用包含以下内容的 JSON 响应:
jsonc
{
"decision": "approve" | "block",
"reason": "Explanation for the decision",
"continue": false, // 可选: 完全停止 CodeBuddy
"stopReason": "Message shown to user", // 可选: 自定义停止消息
"systemMessage": "Warning or context" // 可选: 显示给用户
}Hook 事件
事件类型
| 事件 | 触发时机 | matcher 字段 | 典型场景 |
|---|---|---|---|
PreToolUse | 工具执行前 | 支持(工具名) | 校验命令、二次审批、日志记录 |
PostToolUse | 工具成功执行后 | 支持 | 自动格式化、补充上下文 |
Notification | 权限请求或 60 秒无输入提醒 | 部分支持 | 桌面提示、IM 通知 |
UserPromptSubmit | 用户提交消息时 注:不包括内部命令 | 不支持 | 内容审查、上下文注入 |
Stop | 主代理响应结束时 | 不支持 | 要求继续执行、追加提醒 |
SubagentStop | 子代理(TaskTool)结束时 | 不支持 | 子任务继续执行或补充说明 |
PreCompact | 执行上下文压缩前 | 支持(manual/auto) | 保留关键信息、防止压缩 |
SessionStart | 会话创建或恢复时 | 支持(startup/resume/clear/compact) | 环境初始化、变量注入 |
SessionEnd | 会话结束时 | 支持(clear/logout/prompt_input_exit/other) | 清理资源、持久化日志 |
PreToolUse
在 CodeBuddy 创建工具参数之后、处理工具调用之前运行。
常见匹配器:
Task- 子代理任务Bash- Shell 命令Glob- 文件模式匹配Grep- 内容搜索Read- 文件读取Edit- 文件编辑Write- 文件写入WebFetch,WebSearch- Web 操作
PostToolUse
在工具成功完成后立即运行。识别与 PreToolUse 相同的匹配器值。
Notification
在 CodeBuddy Code 发送通知时运行。支持匹配器以按通知类型过滤。
常见匹配器(部分支持):
permission_prompt- 来自 CodeBuddy Code 的权限请求idle_prompt- 当 CodeBuddy 等待用户输入时(空闲时间超过 60 秒后)auth_success- 身份验证成功通知elicitation_dialog- 当 CodeBuddy Code 需要 MCP 工具引导的输入时(暂未支持)
示例:
json
{
"hooks": {
"Notification": [
{
"matcher": "permission_prompt",
"hooks": [
{
"type": "command",
"command": "/path/to/permission-alert.sh"
}
]
},
{
"matcher": "idle_prompt",
"hooks": [
{
"type": "command",
"command": "/path/to/idle-notification.sh"
}
]
}
]
}
}UserPromptSubmit
在用户提交提示词后、CodeBuddy 处理之前运行。这允许你根据提示词/对话添加额外的上下文、验证提示词或阻止某些类型的提示词。
Stop
在主 CodeBuddy Code 代理完成响应时运行。如果停止是由于用户中断而发生的,则不会运行。
SubagentStop
在 CodeBuddy Code 子代理(Task 工具调用)完成响应时运行。
PreCompact
在 CodeBuddy Code 即将运行压缩操作之前运行。
匹配器:
manual- 从/compact调用auto- 从自动压缩调用(由于上下文窗口已满)
SessionStart
在 CodeBuddy Code 启动新会话或恢复现有会话时运行。
匹配器:
startup- 从启动调用resume- 从--resume、--continue或/resume调用clear- 从/clear调用compact- 从自动或手动压缩调用
SessionEnd
在 CodeBuddy Code 会话结束时运行。用于清理任务、记录会话统计信息或保存会话状态。
reason 字段将是以下之一:
clear- 使用/clear命令清除会话logout- 用户注销prompt_input_exit- 用户在提示词输入可见时退出other- 其他退出原因
Hook 输入
Hooks 通过 stdin 接收包含会话信息和事件特定数据的 JSON 数据:
jsonc
{
// 公共字段
"session_id": "string",
"transcript_path": "string", // 对话 JSON 的路径
"cwd": "string", // 调用 hook 时的当前工作目录
"permission_mode": "string", // 当前权限模式: "default"、"plan"、"acceptEdits" 或 "bypassPermissions"
// 事件特定字段
"hook_event_name": "string"
// ...
}PreToolUse 输入
json
{
"session_id": "abc123",
"transcript_path": "/Users/.../.codebuddy/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
"cwd": "/Users/...",
"permission_mode": "default",
"hook_event_name": "PreToolUse",
"tool_name": "Write",
"tool_input": {
"file_path": "/path/to/file.txt",
"content": "file content"
}
}PostToolUse 输入
json
{
"session_id": "abc123",
"transcript_path": "/Users/.../.codebuddy/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
"cwd": "/Users/...",
"permission_mode": "default",
"hook_event_name": "PostToolUse",
"tool_name": "Write",
"tool_input": {
"file_path": "/path/to/file.txt",
"content": "file content"
},
"tool_response": {
"filePath": "/path/to/file.txt",
"success": true
}
}Notification 输入
json
{
"session_id": "abc123",
"transcript_path": "/Users/.../.codebuddy/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
"cwd": "/Users/...",
"permission_mode": "default",
"hook_event_name": "Notification",
"message": "CodeBuddy needs your permission to use Bash",
"notification_type": "permission_prompt"
}UserPromptSubmit 输入
json
{
"session_id": "abc123",
"transcript_path": "/Users/.../.codebuddy/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
"cwd": "/Users/...",
"permission_mode": "default",
"hook_event_name": "UserPromptSubmit",
"prompt": "Write a function to calculate the factorial of a number"
}Stop 和 SubagentStop 输入
当 CodeBuddy Code 已经由于 stop hook 的结果而继续时,stop_hook_active 为 true。
json
{
"session_id": "abc123",
"transcript_path": "~/.codebuddy/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
"permission_mode": "default",
"hook_event_name": "Stop",
"stop_hook_active": true
}PreCompact 输入
对于手动触发,custom_instructions 来自用户传入 /compact 的内容。对于自动触发,custom_instructions 为空。
json
{
"session_id": "abc123",
"transcript_path": "~/.codebuddy/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
"permission_mode": "default",
"hook_event_name": "PreCompact",
"trigger": "manual",
"custom_instructions": ""
}SessionStart 输入
json
{
"session_id": "abc123",
"transcript_path": "~/.codebuddy/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
"permission_mode": "default",
"hook_event_name": "SessionStart",
"source": "startup"
}SessionEnd 输入
json
{
"session_id": "abc123",
"transcript_path": "~/.codebuddy/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
"cwd": "/Users/...",
"permission_mode": "default",
"hook_event_name": "SessionEnd",
"reason": "exit"
}Hook 输出
Hooks 有两种方式将输出返回给 CodeBuddy Code。
简单方式: 退出代码
Hooks 通过退出代码、stdout 和 stderr 传达状态:
- 退出代码 0:成功。stdout 在 transcript 模式(CTRL-R)中显示给用户,但 UserPromptSubmit 和 SessionStart 除外,其中 stdout 会添加到上下文中。
- 退出代码 2:阻塞错误。stderr 自动反馈给 CodeBuddy 处理。
- 其他退出代码:非阻塞错误。stderr 显示给用户,执行继续。
退出代码 2 的行为
| Hook 事件 | 行为 |
|---|---|
| PreToolUse | 阻止工具调用,向 CodeBuddy 显示 stderr |
| PostToolUse | 向 CodeBuddy 显示 stderr(工具已运行) |
| Notification | N/A,仅向用户显示 stderr |
| UserPromptSubmit | 阻止提示词处理,清除提示词,仅向用户显示 stderr |
| Stop | 阻止停止,向 CodeBuddy 显示 stderr |
| SubagentStop | 阻止停止,向 CodeBuddy 子代理显示 stderr |
| PreCompact | N/A,仅向用户显示 stderr |
| SessionStart | N/A,仅向用户显示 stderr |
| SessionEnd | N/A,仅向用户显示 stderr |
高级方式: JSON 输出
Hooks 可以在 stdout 中返回结构化 JSON 以实现更复杂的控制。
公共 JSON 字段
所有 hook 类型都可以包含这些可选字段:
jsonc
{
"continue": true, // CodeBuddy 在 hook 执行后是否继续(默认: true)
"stopReason": "string", // 当 continue 为 false 时显示的消息
"suppressOutput": true, // 在 transcript 模式中隐藏 stdout(默认: false)
"systemMessage": "string" // 显示给用户的可选警告消息
}PreToolUse 决策控制
PreToolUse hooks 可以控制工具调用是否继续。
jsonc
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "allow" | "deny" | "ask",
"permissionDecisionReason": "My reason here",
"updatedInput": {
"field_to_modify": "new value"
}
}
}"allow"绕过权限系统"deny"阻止工具调用执行"ask"要求用户在 UI 中确认工具调用updatedInput允许你在执行前修改工具的输入参数
PostToolUse 决策控制
jsonc
{
"decision": "block" | undefined,
"reason": "Explanation for decision",
"hookSpecificOutput": {
"hookEventName": "PostToolUse",
"additionalContext": "Additional information for CodeBuddy"
}
}UserPromptSubmit 决策控制
jsonc
{
"decision": "block" | undefined,
"reason": "Explanation for decision",
"hookSpecificOutput": {
"hookEventName": "UserPromptSubmit",
"additionalContext": "My additional context here"
}
}Stop/SubagentStop 决策控制
jsonc
{
"decision": "block" | undefined,
"reason": "Must be provided when CodeBuddy is blocked from stopping"
}SessionStart 决策控制
jsonc
{
"hookSpecificOutput": {
"hookEventName": "SessionStart",
"additionalContext": "My additional context here"
}
}使用 MCP 工具
CodeBuddy Code hooks 与模型上下文协议(MCP)工具无缝配合。
MCP 工具命名
MCP 工具遵循 mcp__<server>__<tool> 模式,例如:
mcp__memory__create_entities- Memory 服务器的创建实体工具mcp__filesystem__read_file- Filesystem 服务器的读取文件工具mcp__github__search_repositories- GitHub 服务器的搜索工具
为 MCP 工具配置 Hooks
你可以针对特定的 MCP 工具或整个 MCP 服务器:
json
{
"hooks": {
"PreToolUse": [
{
"matcher": "mcp__memory__.*",
"hooks": [
{
"type": "command",
"command": "echo 'Memory operation initiated' >> ~/mcp-operations.log"
}
]
},
{
"matcher": "mcp__.*__write.*",
"hooks": [
{
"type": "command",
"command": "/home/user/scripts/validate-mcp-write.py"
}
]
}
]
}
}安全注意事项
免责声明
使用风险自负: CodeBuddy Code hooks 会在你的系统上自动执行任意 shell 命令。通过使用 hooks,你承认:
- 你对所配置的命令负全部责任
- Hooks 可以修改、删除或访问你的用户账户可以访问的任何文件
- 恶意或编写不当的 hooks 可能导致数据丢失或系统损坏
- Tencent Cloud 不提供任何保证,并对因使用 hooks 而导致的任何损害不承担任何责任
- 你应该在安全环境中彻底测试 hooks,然后再在生产环境中使用
安全最佳实践
- 验证和清理输入 - 永远不要盲目信任输入数据
- 始终引用 shell 变量 - 使用
"$VAR"而不是$VAR - 阻止路径遍历 - 检查文件路径中的
.. - 使用绝对路径 - 为脚本指定完整路径(对项目路径使用
"$CODEBUDDY_PROJECT_DIR") - 跳过敏感文件 - 避免
.env、.git/、密钥等
配置安全
直接编辑设置文件中的 hooks 不会立即生效。CodeBuddy Code:
- 在启动时捕获 hooks 的快照
- 在整个会话期间使用此快照
- 如果 hooks 在外部被修改,会发出警告
- 需要在
/hooks菜单中审查才能应用更改
Hook 执行详情
- 超时:默认 60 秒执行限制,可按命令配置
- 并行化:所有匹配的 hooks 并行运行
- 去重:多个相同的 hook 命令会自动去重
- 环境:在当前目录中使用 CodeBuddy Code 的环境运行
CODEBUDDY_PROJECT_DIR环境变量包含项目根目录的绝对路径
- 输入:通过 stdin 的 JSON
- 输出:
- PreToolUse/PostToolUse/Stop/SubagentStop:在 transcript 中显示进度(Ctrl-R)
- Notification/SessionEnd:仅记录到调试(
--debug) - UserPromptSubmit/SessionStart: stdout 作为上下文添加给 CodeBuddy
调试
基本故障排除
如果你的 hooks 不工作:
- 检查配置 - 运行
/hooks查看你的 hook 是否已注册 - 验证语法 - 确保你的 JSON 设置有效
- 测试命令 - 首先手动运行 hook 命令
- 检查权限 - 确保脚本可执行
- 查看日志 - 使用
codebuddy --debug查看 hook 执行详情
常见问题:
- 引号未转义 - 在 JSON 字符串中使用
\" - 错误的匹配器 - 检查工具名称是否完全匹配(区分大小写)
- 找不到命令 - 为脚本使用完整路径
高级调试
对于复杂的 hook 问题:
- 检查 hook 执行 - 使用
codebuddy --debug查看详细的 hook 执行 - 验证 JSON 模式 - 使用外部工具测试 hook 输入/输出
- 检查环境变量 - 验证 CodeBuddy Code 的环境是否正确
- 测试边缘情况 - 尝试使用不寻常的文件路径或输入的 hooks
- 监控系统资源 - 检查 hook 执行期间的资源耗尽
- 使用结构化日志 - 在你的 hook 脚本中实现日志记录
调试输出示例
注:该功能暂未支持。
使用 codebuddy --debug 查看 hook 执行详情:
text
[DEBUG] Executing hooks for PostToolUse:Write
[DEBUG] Getting matching hook commands for PostToolUse with query: Write
[DEBUG] Found 1 hook matchers in settings
[DEBUG] Matched 1 hooks for query "Write"
[DEBUG] Found 1 hook commands to execute
[DEBUG] Executing hook command: <Your command> with timeout 60000ms
[DEBUG] Hook command completed with status 0: <Your stdout>进度消息出现在 transcript 模式 (Ctrl-R) 中,显示:
- 正在运行哪个 hook
- 正在执行的命令
- 成功/失败状态
- 输出或错误消息
通过本文档,你可以了解 CodeBuddy Code 中的 Hook 机制及其配置方式。若需快速实践示例,请继续阅读 Hook 入门指南。