Hook 配置、重载与排障
检查定义来源、串并行、显式重载、开关与调试日志。
Hook 定义写在 settings 的 hooks 中,事件名区分大小写。下面示例在会话开始时增加一条上下文,命令只打印文本:
{
"hooks": {
"SessionStart": [
{
"matcher": "startup",
"hooks": [
{
"type": "command",
"command": "echo 'Use the repository verification commands before reporting completion.'",
"name": "verification-reminder",
"timeout": 5
}
]
}
]
}
}来源与执行顺序
定义可来自项目 .qwen/settings.json、用户、系统与扩展。System、SystemDefaults 都显示为 System 来源。项目 Hook 只在可信目录加载,用户和系统 Hook 无论项目是否可信都可加载。
默认并行执行;组内 sequential: true 用于依赖前一步输出的顺序链。顺序 Hook 可修改后续输入,同一事件来自设置和扩展的顺序是 Project → User → System → Extension。
需要运行时单独启停的 Hook 必须设置 name;无名 Hook 只要事件和 matcher 命中就执行。由 Skills 或 SDK 动态注册的项目在浏览器显示为 Session。
修改后如何生效
编辑完定义,显式打开交互式 /hooks。它会重读当前会话实际使用的用户、工作区和系统文件,包括 worktree 会话。保存文件、拉取仓库或切换分支本身不会启用新 Hook。
| 读取问题 | 处理 |
|---|---|
| 用户或工作区文件读不到、解析失败 | 保留原有两个设置快照与运行中 Hooks,显示错误,不改文件 |
| 系统文件失败 | 保留原系统 Hooks,其他成功的编辑仍可生效,并指出失败文件 |
交互终端中的 /hooks list 同样打开菜单;非交互 list 不重载。Skills/SDK 的运行时注册项不受这次设置重载影响。
以下控制仍需重启:disableAllHooks、stopHookBlockingCap、security.allowedHttpHookUrls、security.allowPrivateNetworkHooks。不能只打开浏览器就认为新网络限制生效。
Agent 与 Skill 作用域
Agent frontmatter Hook 只属于该次调用,包括它的 SubagentStart / SubagentStop,不观察父级、兄弟或嵌套子级。项目 agent 每次事件前重新核对来源工作区信任。需要全会话观察应移到 settings。
Skill Hook 的注册和恢复行为不同,见Skill Hooks;不能把一次 agent 调用的作用域套用到整个会话注册项。
排查顺序
- 检查事件名;未知事件会以
Invalid hook event name警告跳过。 - 检查事件是否支持 matcher,以及运行时工具 ID 是否匹配。
- 检查信任、
disableAllHooks、--safe-mode/QWEN_CODE_SAFE_MODE、--bare/QWEN_CODE_SIMPLE。 - 核对脚本路径、可执行权限、输出 JSON、shell 和超时单位。
- 打开交互
/hooks重载,涉及控制项则重启。
用 --debug 或 QWEN_DEBUG_LOG_FILE=1 查看 ~/.qwen/debug/latest,配置 runtime 根时位于 $QWEN_RUNTIME_DIR 下。注册、执行、匹配、超时分别可搜 [HOOK_REGISTRY]、[TRUSTED_HOOKS]、[HOOK_MATCHER]、[HOOK_TIMEOUT]。Prompt Hook 展开输入可能写入日志,安排相应访问与保留范围。