Hooks 让您可以在通义 Qoder CN IDE 执行的关键节点插入自定义逻辑,而无需修改任何代码。您只需编辑 JSON 配置文件,就能实现诸如:
当前通义 Qoder CN IDE 支持以下五种 Hook 事件:
下面以拦截 rm -rf 这类危险命令为例,演示 Hooks 的配置流程。
在 ~/.lingma/settings.json 中添加:
重启 IDE,在 Qoder CN 面板中让 Agent 执行包含 rm -rf 的命令。Hook 会阻止执行,并把错误信息反馈给 Agent。
Hook 的使用流程可以概括为三步:编写脚本 → 注册配置 → 自动生效。
当 Agent 执行到某个生命周期节点时(如工具调用前),插件会检查配置中是否有对应的 Hook:
首先明确您要在哪个节点介入,以及匹配什么条件:
Hook 脚本是一个标准的 shell 脚本,遵循以下协议:
脚本模板:
除了 exit code,您还可以在 exit 0时输出 JSON 来提供更精细的控制:
将脚本路径写入配置文件的对应事件下:
可以直接在终端用管道模拟测试:
检查 stderr 输出(阻断消息):
Hook 配置从以下文件加载,多级配置会被合并执行(优先级从低到高):
一个事件下可以配置多个 matcher 分组,每个分组可以包含多个 Hook 命令。
matcher 用于过滤 Hook 的触发范围,不同事件匹配不同的字段(见各事件说明)。
Qoder CN 支持两套工具名——原生工具名与兼容工具名。配置 Hook 时可使用任意一套,运行时会统一映射后执行匹配。例如 matcher: "Bash" 和 matcher: "run_in_terminal" 等价。
Hook 脚本通过 stdin 接收 JSON 输入,通过 exit code 和 stdout 输出来控制行为。本节说明所有事件通用的输入输出格式,各事件的额外字段见事件参考。
Hook 脚本通过 stdin 接收 JSON 数据。所有事件都包含以下通用字段:
不同事件会在此基础上附加额外字段(见下文事件参考)。用 jq 解析输入:
Hook 通过 exit code 和 stdout 控制行为。
exit code 决定基本行为:
stdout JSON(仅 exit 0 时生效,可选):
当前版本不支持热加载,修改 settings.json 后需要重启 IDE。
默认 30 秒超时,超时视为错误(继续执行,stderr 展示给用户)。
同一事件下按配置声明顺序执行;跨配置文件时,按「用户级 → 项目级 → 项目本地」优先级从低到高依次执行。
Hook 在当前项目根目录(cwd)下以当前用户身份执行,继承 IDE 进程的环境变量。
Hook 的 stderr 输出会反馈给 Agent 或用户;详细调用日志可在 Qoder CN 运行时日志中查找 [hook] 前缀的条目。
- 在工具执行前拦截危险操作
- 写文件后自动跑 lint,保持代码风格一致
- Agent 完成任务时弹出桌面通知,不用一直盯着 IDE
支持的事件
当前通义 Qoder CN IDE 支持以下五种 Hook 事件:
| 事件名称 | 触发时机 | 可阻断 |
|---|---|---|
| UserPromptSubmit | 用户提交 Prompt 后、Agent 处理前 | 是 |
| PreToolUse | 工具调用执行前 | 是 |
| PostToolUse | 工具调用成功后 | 否 |
| PostToolUseFailure | 工具调用失败后 | 否 |
| Stop | Agent 完成响应时 | 否 |
快速开始
下面以拦截 rm -rf 这类危险命令为例,演示 Hooks 的配置流程。
步骤一:创建脚本
步骤二:添加配置
在 ~/.lingma/settings.json 中添加:
步骤三:验证效果
重启 IDE,在 Qoder CN 面板中让 Agent 执行包含 rm -rf 的命令。Hook 会阻止执行,并把错误信息反馈给 Agent。
适用场景
| 场景 | 对应事件 | 说明 |
|---|---|---|
| 拦截危险命令 | PreToolUse | 在 Agent 执行 rm -rf、DROP TABLE 等命令前阻止 |
| 文件路径校验 | PreToolUse | 限制 Agent 只能在指定目录下创建或编辑文件 |
| 自动 Lint / 格式化 | PostToolUse | 每次写文件后自动执行 ESLint / Prettier |
| 日志审计 | PostToolUse | 记录 Agent 的所有工具调用,用于安全审计 |
| 失败监控告警 | PostToolUseFailure | 工具调用失败时发送告警或记录错误日志 |
| Prompt 内容审查 | UserPromptSubmit | 检测用户输入中是否包含敏感信息(密码、密钥等) |
| 自动注入上下文 | UserPromptSubmit | 自动在 Prompt 末尾追加项目规范或编码约定 |
| 桌面通知 | Stop | Agent 完成后弹出系统通知提醒用户 |
工作原理
Hook 的使用流程可以概括为三步:编写脚本 → 注册配置 → 自动生效。
当 Agent 执行到某个生命周期节点时(如工具调用前),插件会检查配置中是否有对应的 Hook:
- IDE 在启动时加载所有 Hook 配置。
- Agent 运行过程中,到达某个事件节点(如 PreToolUse)。
- 遍历该事件下所有 Hook 分组,用 matcher 匹配当前上下文。
- 匹配成功的 Hook 按顺序执行对应的 shell 脚本。
- 脚本通过 stdin 接收事件上下文(JSON),通过 exit code 和 stdout 返回决策。
- IDE 根据返回结果决定后续行为(放行或阻断)。
前置条件
- jq:示例脚本依赖 jq 解析 JSON。macOS 下执行 brew install jq,Linux 下执行 apt install jq。
- 脚本权限:所有 Hook 脚本需要有可执行权限(chmod +x)。
创建 Hooks
步骤一: 确定需求:选择事件和匹配范围
首先明确您要在哪个节点介入,以及匹配什么条件:
需求 | 事件 | matcher |
Agent 执行任何 Shell 命令前检查 | PreToolUse | "Bash" |
Agent 写入或编辑文件后做处理 | PostToolUse | "Write | Edit" |
Agent 工具调用失败时记录 | PostToolUseFailure | "Bash" 或不填 |
用户提交的所有 Prompt 做审查 | UserPromptSubmit | 不填(匹配所有) |
Agent 停止时触发通知 | Stop | 不填(匹配所有) |
只拦截 MCP 工具 | PreToolUse | "mcp__.*" |
步骤二:编写 Hook 脚本
Hook 脚本是一个标准的 shell 脚本,遵循以下协议:
- 输入:通过 stdin 接收 JSON 格式的事件上下文
- 输出:通过 exit code 控制行为
步骤三:注册到配置文件
将脚本路径写入配置文件的对应事件下:
步骤四:测试与调试
可以直接在终端用管道模拟测试:
配置 Hooks
配置文件位置
Hook 配置从以下文件加载,多级配置会被合并执行(优先级从低到高):
| 位置 | 作用域 | 优先级 | 可共享 | 说明 |
|---|---|---|---|---|
| ~/.lingma/settings.json | 用户级 | 1(最低) | 否 | 用户个人配置,对所有项目生效 |
| .lingma/settings.json | 项目级 | 2 | 是 | 可提交到 Git,团队共享 |
| .lingma/settings.local.json | 项目级(本地) | 3 | 否 | 建议加入 .gitignore,个人开发配置 |
当前版本暂不支持热加载,修改配置文件后需要重启 IDE 才能生效。
配置格式
| 字段 | 必填 | 说明 |
|---|---|---|
| type | 是 | 固定为 "command" |
| command | 是 | 要执行的 shell 命令或脚本路径 |
| timeout | 否 | 超时时间(秒),默认 30 |
| matcher | 否 | 匹配条件,不填则匹配该事件的所有触发 |
matcher 匹配规则
matcher 用于过滤 Hook 的触发范围,不同事件匹配不同的字段(见各事件说明)。
写法 | 含义 | 示例 |
不填或 "*" | 匹配所有 | 所有工具都会触发 |
精确值 | 精确匹配 | "Bash" 只在 Bash 工具时触发 |
| 分隔 | 匹配多个值 | "Write | Edit" 在 Write 或 Edit 时触发 |
正则表达式 | 正则匹配 | "mcp__.*" 匹配所有 MCP 工具 |
工具名映射
Qoder CN 支持两套工具名——原生工具名与兼容工具名。配置 Hook 时可使用任意一套,运行时会统一映射后执行匹配。例如 matcher: "Bash" 和 matcher: "run_in_terminal" 等价。
| 原生名 | 兼容名 | 说明 |
|---|---|---|
| run_in_terminal | Bash | 执行 shell 命令 |
| read_file | Read | 读取文件内容 |
| create_file | Write | 创建 / 写入文件 |
| search_replace | Edit | 编辑文件 |
| delete_file | - | 删除文件 |
| grep_code | Grep | 搜索文件内容 |
| search_file | Glob | 文件名匹配 |
| list_dir | LS | 列出目录 |
| task | Task | 启动子任务 / 子代理 |
| mcp__<server>__<tool> | 同左 | MCP 工具 |
编写 Hook 脚本
Hook 脚本通过 stdin 接收 JSON 输入,通过 exit code 和 stdout 输出来控制行为。本节说明所有事件通用的输入输出格式,各事件的额外字段见事件参考。
输入
Hook 脚本通过 stdin 接收 JSON 数据。所有事件都包含以下通用字段:
| 字段 | 说明 |
|---|---|
| session_id | 当前会话 ID |
| cwd | 当前工作目录 |
| hook_event_name | 触发的事件名称 |
| transcript_path | 会话上下文 JSON 文件路径 |
输出
Hook 通过 exit code 和 stdout 控制行为。
exit code 决定基本行为:
| Exit Code | 含义 | 行为 |
|---|---|---|
| 0 | 成功 | 继续执行,尝试解析 stdout JSON |
| 2 | 阻断 | 停止操作,stderr 内容注入对话(仅对支持阻断的事件) |
| 其他值 | 错误 | 继续执行,stderr 内容仅展示给用户 |
事件参考
UserPromptSubmit
- 触发:用户提交 Prompt 后、Agent 处理前
- 可阻断:是(exit 2 阻止本次请求)
- 额外字段:prompt(用户输入的原始文本)
PreToolUse
- 触发:工具调用执行前
- 可阻断:是(exit 2 拒绝本次工具调用)
- 匹配字段:tool_name
- 额外字段:tool_name、tool_input
PostToolUse
- 触发:工具调用成功后
- 可阻断:否
- 匹配字段:tool_name
- 额外字段:tool_name、tool_input、tool_response
PostToolUseFailure
- 触发:工具调用失败后
- 可阻断:否
- 匹配字段:tool_name
- 额外字段:tool_name、tool_input、error
Stop
- 触发:Agent 完成响应时
- 可阻断:否
- 额外字段:stop_hook_active、last_assistant_message