跳到正文
FunCoding

搜索

搜索文档、Skill 和 MCP

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 调用的作用域套用到整个会话注册项。

排查顺序

  1. 检查事件名;未知事件会以 Invalid hook event name 警告跳过。
  2. 检查事件是否支持 matcher,以及运行时工具 ID 是否匹配。
  3. 检查信任、disableAllHooks、--safe-mode / QWEN_CODE_SAFE_MODE、--bare / QWEN_CODE_SIMPLE。
  4. 核对脚本路径、可执行权限、输出 JSON、shell 和超时单位。
  5. 打开交互 /hooks 重载,涉及控制项则重启。

用 --debug 或 QWEN_DEBUG_LOG_FILE=1 查看 ~/.qwen/debug/latest,配置 runtime 根时位于 $QWEN_RUNTIME_DIR 下。注册、执行、匹配、超时分别可搜 [HOOK_REGISTRY]、[TRUSTED_HOOKS]、[HOOK_MATCHER]、[HOOK_TIMEOUT]。Prompt Hook 展开输入可能写入日志,安排相应访问与保留范围。