Hooks

Documentation Index

Fetch the complete documentation index at: https://docs.qoder.com/llms.txt
Use this file to discover all available pages before exploring further.

Hooks

Hooks 让你可以在 Qoder IDE 和 JetBrains 插件执行的关键节点插入自定义逻辑,而无需修改任何代码。你只需编辑 JSON 配置文件,就能实现诸如:

  • 在工具执行前拦截危险操作
  • 写文件后自动跑 lint,保持代码风格一致
  • Agent 完成任务时弹出桌面通知,不用一直盯着 IDE

与 Prompt 指令不同,Hooks 是确定性的——只要事件触发,脚本就一定执行,不受模型理解偏差的影响。

支持的事件

当前 IDE / JB 插件支持以下五种 Hook 事件:

事件名称 触发时机 可阻断
UserPromptSubmit 用户提交 Prompt 后、Agent 处理前
PreToolUse 工具调用执行前
PostToolUse 工具调用成功后
PostToolUseFailure 工具调用失败后
Stop Agent 完成响应时

快速开始

下面用一个例子,演示如何拦截 rm -rf 这类危险命令。



“`bash theme={null}
mkdir -p ~/.qoder/hooks
cat > ~/.qoder/hooks/block-rm.sh << ‘EOF’
#!/bin/bash
input=$(cat)
command=$(echo “$input” | jq -r ‘.tool_input.command’)

if echo "$command" | grep -q 'rm -rf'; then
  echo "危险命令已被阻止: $command" >&2
  exit 2
fi

exit 0
EOF
chmod +x ~/.qoder/hooks/block-rm.sh
```


~/.qoder/settings.json 中添加:

```json  theme={null}
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "~/.qoder/hooks/block-rm.sh"
          }
        ]
      }
    ]
  }
}
```


打开 IDE,在 Qoder 插件面板中让 Agent 执行包含 rm -rf 的命令。Hook 会阻止执行,并把错误信息反馈给 Agent。

适用场景

场景 对应事件 说明
拦截危险命令 PreToolUse 在 Agent 执行 rm -rfDROP TABLE 等命令前阻止
文件路径校验 PreToolUse 限制 Agent 只能在指定目录下创建 / 编辑文件
自动 Lint / 格式化 PostToolUse 每次写文件后自动执行 ESLint / Prettier
日志审计 PostToolUse 记录 Agent 的所有工具调用,用于安全审计
失败监控告警 PostToolUseFailure 工具调用失败时发送告警或记录错误日志
Prompt 内容审查 UserPromptSubmit 检测用户输入中是否包含敏感信息(密码、密钥等)
自动注入上下文 UserPromptSubmit 自动在 Prompt 末尾追加项目规范或编码约定
桌面通知 Stop Agent 完成后弹出系统通知提醒用户

工作原理

Hook 的使用流程可以概括为三步:编写脚本 → 注册配置 → 自动生效

当 Agent 执行到某个生命周期节点时(如工具调用前),插件会检查配置中是否有对应的 Hook:

  1. 插件在启动时加载所有 Hook 配置
  2. Agent 运行过程中,到达某个事件节点(如 PreToolUse
  3. 插件遍历该事件下所有 Hook 分组,用 matcher 匹配当前上下文
  4. 匹配成功的 Hook 按顺序执行对应的 shell 脚本
  5. 脚本通过 stdin 接收事件上下文(JSON),通过 exit codestdout 返回决策
  6. 插件根据返回结果决定后续行为(放行 / 阻断)

前置条件

  • jq:示例脚本依赖 jq 解析 JSON。macOS 下执行 brew install jq,Linux 下执行 apt install jq
  • 脚本权限:所有 Hook 脚本需要有可执行权限(chmod +x)。

创建 Hooks

1. 确定需求:选择事件和匹配范围

首先明确你要在哪个节点介入,以及匹配什么条件:

“`plaintext theme={null}
我想在「什么时候」拦截/处理「什么操作」?
↓ ↓
选择事件 编写 matcher


| 需求                     | 事件                 | matcher           |
| ---------------------- | ------------------ | ----------------- |
| Agent 执行任何 Shell 命令前检查 | PreToolUse         | `"Bash"`          |
| Agent 写入或编辑文件后做处理      | PostToolUse        | `"Write \| Edit"` |
| Agent 工具调用失败时记录        | PostToolUseFailure | `"Bash"` 或不填      |
| 用户提交的所有 Prompt 做审查     | UserPromptSubmit   | 不填(匹配所有)          |
| Agent 停止时触发通知          | Stop               | 不填(匹配所有)          |
| 只拦截 MCP 工具             | PreToolUse         | `"mcp__.*"`       |

### 2. 编写 Hook 脚本

Hook 脚本是一个标准的 shell 脚本,遵循以下协议:

**输入**:通过 `stdin` 接收 JSON 格式的事件上下文

**输出**:通过 `exit code` 控制行为

```plaintext  theme={null}
exit 0   →  放行(继续执行)
exit 2   →  阻断(停止操作,stderr 注入对话)
其他值   →  错误(继续执行,stderr 展示给用户)

脚本模板:

“`bash theme={null}

!/bin/bash

1. 读取 stdin 的 JSON 输入

input=$(cat)

2. 用 jq 提取你关心的字段

不同事件有不同的字段,具体见「事件参考」章节

tool_name=$(echo “$input” | jq -r ‘.tool_name’)
tool_input=$(echo “$input” | jq -r ‘.tool_input’)

3. 编写你的判断逻辑

if [ “$tool_name” = “Bash” ]; then
command=$(echo “$input” | jq -r ‘.tool_input.command’)

# 检查是否包含危险操作
if echo “$command” | grep -qE ‘rm\s+-rf|DROP\s+TABLE’; then
# 阻断:exit 2 + stderr 消息会反馈给 Agent
echo “操作被拒绝: $command” >&2
exit 2
fi
fi

4. 放行

exit 0


<Tip>
  除了 exit code,你还可以在 `exit 0` 时输出 JSON 来提供更精细的控制:

  ```bash  theme={null}
  #!/bin/bash
  input=$(cat)

  # 输出 JSON 实现精细控制(仅 exit 0 时生效)
  echo '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"该操作不被允许"}}'
  exit 0
  ```
</Tip>

### 3. 注册到配置文件

将脚本路径写入配置文件的对应事件下:

```json  theme={null}
{
  "hooks": {
    "事件名": [
      {
        "matcher": "匹配条件(可选)",
        "hooks": [
          {
            "type": "command",
            "command": "脚本路径"
          }
        ]
      }
    ]
  }
}

4. 测试与调试

可以直接在终端用管道模拟测试:

“`bash theme={null}

模拟 PreToolUse 事件

echo ‘{“tool_name”:”Bash”,”tool_input”:{“command”:”rm -rf /”},”hook_event_name”:”PreToolUse”}’ \
| ~/.qoder/hooks/block-rm.sh
echo “Exit code: $?”


检查 stderr 输出(阻断消息):

```bash  theme={null}
echo '{"tool_name":"Bash","tool_input":{"command":"rm -rf /"}}' \
  | ~/.qoder/hooks/block-rm.sh 2>&1

配置 Hooks

配置文件位置

Hook 配置从以下文件加载,多级配置会被合并执行(优先级从低到高):

位置 作用域 优先级 可共享 说明
~/.qoder/settings.json 全局用户级 1(最低) 用户个人配置,对所有项目生效
.qoder/settings.json 项目级 2 可提交到 Git,团队共享
.qoder/settings.local.json 项目本地 3 gitignore,个人开发配置


IDE / JB 插件与 CLI 共享同一套配置文件。当前版本暂不支持热加载,修改配置文件后需要重启 IDE 才能生效。

配置格式

“`json theme={null}
{
“hooks”: {
“事件名”: [
{
“matcher”: “匹配条件”,
“hooks”: [
{
“type”: “command”,
“command”: “要执行的命令”
}
]
}
]
}
}


| 字段        | 必填 | 说明                                |
| --------- | -- | --------------------------------- |
| `type`    | 是  | 固定为 `"command"`                   |
| `command` | 是  | 要执行的 shell 命令或脚本路径                |
| `timeout` | 否  | 超时时间(秒),默认 30。当前版本不支持自定义,下个版本开放配置 |
| `matcher` | 否  | 匹配条件,不填则匹配该事件的所有触发                |

一个事件下可以配置多个 matcher 分组,每个分组可以包含多个 Hook 命令。

### matcher 匹配规则

`matcher` 用于过滤 Hook 的触发范围,不同事件匹配不同的字段(见各事件说明)。

| 写法        | 含义    | 示例                                   |
| --------- | ----- | ------------------------------------ |
| 不填或 `"*"` | 匹配所有  | 所有工具都会触发                             |
| 精确值       | 精确匹配  | `"Bash"` 只在 Bash 工具时触发               |
| `\|` 分隔   | 匹配多个值 | `"Write \| Edit"` 在 Write 或 Edit 时触发 |
| 正则表达式     | 正则匹配  | `"mcp__.*"` 匹配所有 MCP 工具              |

### 工具名映射

Qoder 支持两套工具名——原生工具名与 Claude Code 兼容工具名。配置 Hook 时可使用任意一套,插件内部会统一映射后执行匹配。例如 `matcher: "Bash"` 和 `matcher: "run_in_terminal"` 等价。

| Qoder 原生名               | 兼容名         | 说明          |
| ----------------------- | ----------- | ----------- |
| `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`      | 启动子任务 / 子代理 |
| `Skill`                 | -           | 调用技能        |
| `search_web`            | `WebSearch` | 网页搜索        |
| `fetch_content`         | `WebFetch`  | 获取网页内容      |
| `todo_write`            | `TodoWrite` | 写入 TODO     |
| `ask_user_question`     | -           | 向用户提问       |
| `search_memory`         | -           | 搜索记忆        |
| `update_memory`         | -           | 更新记忆        |
| `switch_mode`           | -           | 切换模式        |
| `create_plan`           | -           | 创建计划        |
| `run_preview`           | -           | 预览 Web 应用   |
| `mcp__<server>__<tool>` | 同左          | MCP 工具      |

## 编写 Hook 脚本

Hook 脚本通过 stdin 接收 JSON 输入,通过 exit code 和 stdout 输出来控制行为。本节说明所有事件通用的输入输出格式,各事件的额外字段见 Hooks 事件。

### 输入

Hook 脚本通过 **stdin** 接收 JSON 数据。所有事件都包含以下通用字段:

| 字段                | 说明              |
| ----------------- | --------------- |
| `session_id`      | 当前会话 ID         |
| `cwd`             | 当前工作目录          |
| `hook_event_name` | 触发的事件名称         |
| `transcript_path` | 会话上下文 JSON 文件路径 |

不同事件会在此基础上附加额外字段(见各 Hooks 事件)。

用 `jq` 解析输入:

```bash  theme={null}
#!/bin/bash
input=$(cat)
tool_name=$(echo "$input" | jq -r '.tool_name')

输出

Hook 通过 exit code 和 stdout 控制行为。

exit code 决定基本行为:

Exit Code 含义 行为
0 成功 继续执行,尝试解析 stdout JSON
2 阻断 停止操作,stderr 内容注入对话(仅对支持阻断的事件生效)
其他 错误 非阻断错误,stderr 显示给用户,继续执行

stdout JSON(仅 exit 0 时解析)可为部分事件提供精细控制,具体支持的字段见各事件说明。exit 非 0 时 stdout 被忽略。

环境变量

Hook 脚本执行时,插件会注入部分环境变量供脚本使用。具体注入的环境变量列表待补充确认。

Hooks 事件

UserPromptSubmit

用户在 IDE 插件面板中提交 Prompt 后、Agent 开始处理前触发。可用于 Prompt 审查、内容过滤、自动补充上下文等场景。

matcher 匹配: 无匹配字段,该事件对所有用户输入统一触发。

额外输入字段:

“`json theme={null}
{
“session_id”: “abc-123”,
“cwd”: “/path/to/project”,
“hook_event_name”: “UserPromptSubmit”,
“prompt”: “帮我写一个排序函数”
}


**阻止 Prompt 提交:** exit code 2,stderr 内容作为错误信息反馈给用户,Agent 不会处理该 Prompt。

**stdout JSON 输出字段(exit 0 时):**

```json  theme={null}
{
  "hookSpecificOutput": {
    "hookEventName": "UserPromptSubmit",
    "additionalContext": "## 当前 Git 状态\n..."
  }
}
字段 类型 说明
hookSpecificOutput.hookEventName string 固定为 "UserPromptSubmit"
hookSpecificOutput.additionalContext string 附加上下文信息,会注入到 Agent 的对话中

示例:自动给 Prompt 补充项目规范

“`bash theme={null}

!/bin/bash

input=$(cat)
prompt=$(echo “$input” | jq -r ‘.prompt’)

自动追加编码规范提醒

echo ‘{“hookSpecificOutput”:{“hookEventName”:”UserPromptSubmit”,”additionalContext”:”请遵循项目 .editorconfig 中的编码规范。”}}’
exit 0


### PreToolUse

工具执行前触发。**可以阻止工具执行。** 这是最常用的 Hook 事件,适用于危险命令拦截、文件路径校验、权限检查等场景。

**matcher 匹配:** 工具名(如 `Bash`、`Write`、`Edit`、`Read`、`Glob`、`Grep`,MCP 工具名如 `mcp__server__tool`)

**额外输入字段:**

```json  theme={null}
{
  "session_id": "abc-123",
  "cwd": "/path/to/project",
  "hook_event_name": "PreToolUse",
  "tool_name": "Bash",
  "tool_input": { "command": "rm -rf /tmp/build" }
}

阻止工具执行: exit code 2,stderr 内容作为错误返回给 Agent。完整示例见快速开始

stdout JSON 输出字段(exit 0 时):

“`json theme={null}
{
“hookSpecificOutput”: {
“hookEventName”: “PreToolUse”,
“permissionDecision”: “allow”,
“permissionDecisionReason”: “Safe read operation”,
“updatedInput”: { “command”: “npm test –coverage” },
“additionalContext”: “Added coverage flag”
}
}


| 字段                                            | 类型     | 说明                                        |
| --------------------------------------------- | ------ | ----------------------------------------- |
| `hookSpecificOutput.hookEventName`            | string | 固定为 `"PreToolUse"`                        |
| `hookSpecificOutput.permissionDecision`       | string | `"allow"`(放行)、`"deny"`(拒绝)或 `"ask"`(询问用户) |
| `hookSpecificOutput.permissionDecisionReason` | string | 决策原因,`deny` 或 `ask` 时展示给 Agent / 用户       |
| `hookSpecificOutput.updatedInput`             | object | 修改后的工具输入参数(可选,用于改写工具调用)                   |
| `hookSpecificOutput.additionalContext`        | string | 附加上下文信息(可选)                               |

### PostToolUse

工具执行成功后触发。不可阻断。适用于自动 lint、日志记录、结果分析等场景。

**matcher 匹配:** 工具名

**额外输入字段:**

```json  theme={null}
{
  "session_id": "abc-123",
  "cwd": "/path/to/project",
  "hook_event_name": "PostToolUse",
  "tool_name": "Write",
  "tool_input": { "file_path": "/path/to/file.ts", "content": "..." },
  "tool_response": "File written successfully"
}

stdout JSON 输出字段(exit 0 时):

“`json theme={null}
{
“hookSpecificOutput”: {
“hookEventName”: “PostToolUse”,
“feedback”: “File formatted with Prettier. 3 issues auto-fixed.”
}
}


| 字段                                 | 类型     | 说明                       |
| ---------------------------------- | ------ | ------------------------ |
| `hookSpecificOutput.hookEventName` | string | 固定为 `"PostToolUse"`      |
| `hookSpecificOutput.feedback`      | string | 反馈信息,会展示给用户(如 lint 结果摘要) |

### PostToolUseFailure

工具调用失败后触发。不可阻断。适用于错误监控、失败重试提示、日志记录等场景。

**matcher 匹配:** 工具名

**额外输入字段:**

```json  theme={null}
{
  "session_id": "abc-123",
  "cwd": "/path/to/project",
  "hook_event_name": "PostToolUseFailure",
  "tool_name": "Bash",
  "tool_input": { "command": "npm test" },
  "error": "Command exited with non-zero status code 1"
}
字段 类型 说明
error string 工具执行的错误信息

Stop

Agent 完成响应后触发(主 Agent 无待执行的工具调用时)。不可阻断。适用于桌面通知、日志记录、任务状态汇报等场景。


当前版本 Stop 事件不支持阻断(即无法通过 exit 2 让 Agent 继续工作)。该能力计划在下个版本中支持。

matcher 匹配: 无匹配字段,该事件在 Agent 停止时统一触发。

额外输入字段:

“`json theme={null}
{
“session_id”: “abc-123”,
“cwd”: “/path/to/project”,
“hook_event_name”: “Stop”,
“stop_hook_active”: true,
“last_assistant_message”: “我已经完成了排序函数的编写。”
}


**stdout JSON 输出字段(exit 0 时,下个版本生效):**

```json  theme={null}
{
  "decision": "block",
  "reason": "Tests failing. Fix them before completing."
}
字段 类型 说明
decision string "block"(阻止停止,让 Agent 继续工作)
reason string 阻止的原因,会作为消息注入对话

场景示例

拦截危险命令

在 Agent 执行 shell 命令前检查是否包含危险操作,如 rm -rfDROP TABLE 等。

脚本 ~/.qoder/hooks/block-dangerous.sh

“`bash theme={null}

!/bin/bash

input=$(cat)
command=$(echo “$input” | jq -r ‘.tool_input.command’)

检查危险模式

if echo “$command” | grep -qE ‘rm\s+-rf|DROP\s+TABLE|mkfs|dd\s+if=’; then
echo “危险命令已被阻止: $command” >&2
exit 2
fi

exit 0


配置:事件 `PreToolUse`,matcher `Bash`,command `~/.qoder/hooks/block-dangerous.sh`。

### 写文件后自动 Lint

每次 Agent 写入或编辑文件后,自动执行 lint 检查。

脚本 `${project}/.qoder/hooks/auto-lint.sh`:

```bash  theme={null}
#!/bin/bash
input=$(cat)
file_path=$(echo "$input" | jq -r '.tool_input.file_path')

# 只检查 JS/TS 文件
case "$file_path" in
  *.js|*.ts|*.jsx|*.tsx)
    npx eslint "$file_path" --fix 2>/dev/null
    ;;
esac

exit 0

配置:事件 PostToolUse,matcher Write|Edit,command .qoder/hooks/auto-lint.sh

工具失败时记录日志

当 Agent 调用的工具执行失败时,自动记录到日志文件,便于排查问题。

脚本 ~/.qoder/hooks/log-failure.sh

“`bash theme={null}

!/bin/bash

input=$(cat)
tool_name=$(echo “$input” | jq -r ‘.tool_name’)
error=$(echo “$input” | jq -r ‘.error’)
timestamp=$(date ‘+%Y-%m-%d %H:%M:%S’)

echo “[$timestamp] $tool_name 执行失败: $error” >> ~/.qoder/hooks/failure.log

exit 0


配置:事件 `PostToolUseFailure`,无 matcher(匹配所有工具),command `~/.qoder/hooks/log-failure.sh`。

### Agent 完成后桌面通知

Agent 完成任务后弹出系统通知,适合长时间运行的任务。

脚本 `~/.qoder/hooks/notify-done.sh`(macOS):

```bash  theme={null}
#!/bin/bash
input=$(cat)
message=$(echo "$input" | jq -r '.last_assistant_message // "任务已完成"' | head -c 100)

osascript -e "display notification \"$message\" with title \"Qoder Agent\""

exit 0

配置:事件 Stop,无 matcher,command ~/.qoder/hooks/notify-done.sh

Prompt 内容审查

在用户提交 Prompt 时,检查是否包含敏感信息(如密码、密钥等),防止意外泄露。

脚本 ~/.qoder/hooks/check-prompt.sh

“`bash theme={null}

!/bin/bash

input=$(cat)
prompt=$(echo “$input” | jq -r ‘.prompt’)

检查是否包含疑似密钥

if echo “$prompt” | grep -qiE ‘(password|secret|api_key|token)\s[:=]\s\S+’; then
echo “检测到 Prompt 中可能包含敏感信息,请检查后重新提交” >&2
exit 2
fi

exit 0


配置:事件 `UserPromptSubmit`,无 matcher,command `~/.qoder/hooks/check-prompt.sh`。

### 完整配置示例

以下是一个包含所有五种事件的完整配置:

```json  theme={null}
{
  "hooks": {
    "UserPromptSubmit": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "~/.qoder/hooks/check-prompt.sh"
          }
        ]
      }
    ],
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "~/.qoder/hooks/block-dangerous.sh"
          }
        ]
      },
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": ".qoder/hooks/validate-file-path.sh"
          }
        ]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": ".qoder/hooks/auto-lint.sh"
          }
        ]
      }
    ],
    "PostToolUseFailure": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "~/.qoder/hooks/log-failure.sh"
          }
        ]
      }
    ],
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "~/.qoder/hooks/notify-done.sh"
          }
        ]
      }
    ]
  }
}

注意事项

  • 超时处理: Hook 脚本默认超时 30 秒。超时后脚本将被终止,按放行处理。自定义超时时间将在下个版本中支持。
  • 错误处理: 脚本异常退出(exit code 非 0 且非 2)时,错误信息显示给用户,Agent 流程不受影响继续执行。
  • 脚本权限: 确保脚本具有可执行权限(chmod +x)。
  • 配置合并: 多级配置文件中的同一事件 Hook 按优先级从低到高依次执行,任一 Hook 返回阻断(exit 2)则终止后续执行。
  • jq 依赖: 示例脚本依赖 jq 命令行工具来解析 JSON。请确保系统已安装 jq(macOS: brew install jq,Linux: apt install jq)。

暂无介绍....

延伸阅读:

自定义智能体

Documentation IndexFetch the complete documentation index at...

Allen
2026年4月3日
指令

Documentation IndexFetch the complete documentation index at...

Allen
2026年4月3日
规划智能体

Documentation IndexFetch the complete documentation index at...

Allen
2026年4月3日
浏览器智能体

Documentation IndexFetch the complete documentation index at...

Allen
2026年4月3日
Skills

Documentation IndexFetch the complete documentation index at...

Allen
2026年4月3日