Hook 执行器与返回协议
区分 command、prompt、function 和异步行为,正确使用超时、退出码与上下文输出。
选择执行器时同时决定输入发给谁、等待多久以及如何解释输出。JSON 对象与普通文本、同步与异步的行为不能混用。
四类执行器
| 类型 | 输入与输出 | 默认超时 |
|---|---|---|
| command | stdin 接收 JSON,stdout 返回结果 | 60 秒 |
| http | POST JSON,响应体返回结果 | 600 秒 |
| prompt | $ARGUMENTS 替换为事件输入,交给配置模型 | 30 秒 |
| function | 同进程 JavaScript 回调 | SDK 注册使用毫秒单位 |
Function 属于可信同进程代码,可修改接收的对象;不能假定输入不可变。官方目前不把它作为终端用户公共 API,常规配置优先选择 command 或 HTTP。
Command 超时与环境
必填 type: "command"、command;可配置 name、description、timeout、env、shell、statusMessage、async。shell 选项是 bash 或 powershell。
Command 的 timeout 小于 1000 时按秒,大于等于 1000 仍按旧毫秒兼容。例如旧 10000 应迁移成 10;需要 30 分钟时仍写 1800000,不能写 1800 并期待秒。非正数字或 "30s" 等无效值使用 60 秒默认,调试日志每会话报告相关 Hook 一次。
每个 command 环境提供 QWEN_PROJECT_DIR、CLAUDE_PROJECT_DIR、GEMINI_PROJECT_DIR。Bash 中双引号包住路径变量,例如 "$QWEN_PROJECT_DIR/.qwen/hooks/check.sh";单引号阻止展开,未引用会在含空格路径分词。
cmd,以及 PowerShell 中裸 $QWEN_PROJECT_DIR,会在执行前替换为带引号项目路径;PowerShell 也可用 $env:QWEN_PROJECT_DIR。旧版 Bash 的预替换已移除。
退出码与 stdout
| Command 退出码 | 解释 |
|---|---|
0 | stdout 为 JSON 对象时解析控制字段;其他内容按文本处理 |
2 | 阻止错误;忽略 stdout,把 stderr 反馈给模型 |
| 其他 | 非阻止故障,继续执行;stderr 只在调试中显示 |
普通文本只在 SessionStart、UserPromptSubmit、UserPromptExpansion 作为模型上下文,其他事件保留为 system message。42 这样的裸 JSON 值也按文本处理;看似 JSON 对象却解析失败的内容不会进入模型上下文。
控制对象可包含 continue、stopReason、suppressOutput、systemMessage,以及事件对应的 decision、reason、hookSpecificOutput。具体控制要按事件协议,不能把事前 deny 当成事后回滚。事件专用输出应写 hookEventName。
Prompt 判断
Prompt Hook 默认使用当前模型,也可写 model。提示中的 $ARGUMENTS 被事件 JSON 替换,模型需返回:
{
"ok": false,
"reason": "The requested completion condition has not been verified."
}ok: true 允许继续或停止,false 阻止并要求 reason;允许时可附 additionalContext。在 Stop 上 false 会要求继续工作。事件输入会发到该模型提供商,启用文件调试日志时完整展开请求也可能落盘。
异步不提供即时控制
只有 command 支持 async: true。事件在后台 Hook 启动后继续,不能通过它返回审批决定;当前异步 stdout、systemMessage、additionalContext 都不会显示或送给模型。需要留结果时写到可检查的文件。
最多十个异步 Hook 同时占槽,完成或超时释放;槽满时新 Hook 跳过。POSIX 退出会清理普通异步 Hook 进程树,明确保证退出后继续的事件另算。Windows 无法在根进程消失后重建后代树,完整回收依赖 Job Object 或后代跟踪,不能把平台行为看成完全等价。