Skip to content

Hook 参考指南

版本要求:本文档针对 CodeBuddy Code v1.16.0 及以上版本中提供的 Claude Code Hooks 兼容实现。 功能状态:Hook 功能当前处于 Beta 阶段,接口和行为可能在未来版本中调整。

Hook(钩子)允许你在 CodeBuddy Code 的会话生命周期内插入自定义脚本或命令,实现自动化校验、环境初始化、合规检查等高级能力。我们的实现完全兼容 Claude Code Hooks 规范,支持相同的事件类型、输入输出结构以及安全特性。


功能概览

  • 完整支持 Claude Code Hooks 九大事件:PreToolUsePostToolUseNotificationUserPromptSubmitStopSubagentStopPreCompactSessionStartSessionEnd
  • 支持基于正则表达式的 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|WriteWeb.*
    • 使用 * 匹配所有工具。也可以使用空字符串("")或留空匹配器。
  • hooks:当模式匹配时执行的 hooks 数组
    • type: Hook 执行类型 - "command" 用于 bash 命令,或 "prompt" 用于基于 LLM 的评估(暂未支持)
    • command: (对于 type: "command") 要执行的 bash 命令(可以使用 $CODEBUDDY_PROJECT_DIR 环境变量)
    • prompt: (对于 type: "prompt") 发送给 LLM 进行评估的提示词(暂未支持)
    • timeout: (可选) hook 运行多长时间(以秒为单位)后取消该特定 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 命令,而是:

  1. 将 hook 输入和你的提示词发送给快速 LLM
  2. LLM 使用包含决策的结构化 JSON 响应
  3. 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(工具已运行)
NotificationN/A,仅向用户显示 stderr
UserPromptSubmit阻止提示词处理,清除提示词,仅向用户显示 stderr
Stop阻止停止,向 CodeBuddy 显示 stderr
SubagentStop阻止停止,向 CodeBuddy 子代理显示 stderr
PreCompactN/A,仅向用户显示 stderr
SessionStartN/A,仅向用户显示 stderr
SessionEndN/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,然后再在生产环境中使用

安全最佳实践

  1. 验证和清理输入 - 永远不要盲目信任输入数据
  2. 始终引用 shell 变量 - 使用 "$VAR" 而不是 $VAR
  3. 阻止路径遍历 - 检查文件路径中的 ..
  4. 使用绝对路径 - 为脚本指定完整路径(对项目路径使用 "$CODEBUDDY_PROJECT_DIR")
  5. 跳过敏感文件 - 避免 .env.git/、密钥等

配置安全

直接编辑设置文件中的 hooks 不会立即生效。CodeBuddy Code:

  1. 在启动时捕获 hooks 的快照
  2. 在整个会话期间使用此快照
  3. 如果 hooks 在外部被修改,会发出警告
  4. 需要在 /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 不工作:

  1. 检查配置 - 运行 /hooks 查看你的 hook 是否已注册
  2. 验证语法 - 确保你的 JSON 设置有效
  3. 测试命令 - 首先手动运行 hook 命令
  4. 检查权限 - 确保脚本可执行
  5. 查看日志 - 使用 codebuddy --debug 查看 hook 执行详情

常见问题:

  • 引号未转义 - 在 JSON 字符串中使用 \"
  • 错误的匹配器 - 检查工具名称是否完全匹配(区分大小写)
  • 找不到命令 - 为脚本使用完整路径

高级调试

对于复杂的 hook 问题:

  1. 检查 hook 执行 - 使用 codebuddy --debug 查看详细的 hook 执行
  2. 验证 JSON 模式 - 使用外部工具测试 hook 输入/输出
  3. 检查环境变量 - 验证 CodeBuddy Code 的环境是否正确
  4. 测试边缘情况 - 尝试使用不寻常的文件路径或输入的 hooks
  5. 监控系统资源 - 检查 hook 执行期间的资源耗尽
  6. 使用结构化日志 - 在你的 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 入门指南