QwenLM / QwenLM/qwen-code

hooks: surface legacy millisecond command-hook timeouts at startup

Open
#11,675 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

category/core priority/P2 roadmap/hooks-events scope/cli scope/settings type/enhancement
Dominant language
TypeScript
Stars
28k
Forks
3.1k
Avg merge
1d 1h
Merged PRs (30d)
702

Description

Summary

#11615 changes command hook timeout to seconds and keeps values of 1000 or more working as legacy milliseconds. Today the only notice that a hook still uses the old form is a debug-log line written the first time that hook runs. A startup warning was prototyped in #11615 and removed from it during review, because doing it safely needs more design than that PR should carry. This issue records the requirements so it can land as its own change.

Requirements

  1. Never echo untrusted text raw. A repository-committed .qwen/settings.json is untrusted input. The warning must not print a hook's command. If it names the hook, run the label through stripAnsiAndControl, drop Unicode format characters (\p{Cf}: bidi overrides, zero-width characters, BOM), trim it, and cap it at the existing 64-character echo limit used for output-style names. Identifying the hook by position (hooks.<Event>[i]) plus the settings file path is an acceptable alternative. Startup warnings are written with a raw process.stderr.write before the UI renders, so escape sequences would reach the terminal and the clipboard.
  2. Cover every scope whose hooks run. System and SystemDefaults settings are merged as overrides and their hooks execute regardless of folder trust, so managed hooks need the warning too. Walk those scopes in a separate loop so admin-managed files do not also start producing legacy settings-key warnings.
  3. Only warn when there is something to do. A value of 1000000 or more cannot be rewritten in seconds while the legacy reading is supported, and the guide tells users to keep such values in milliseconds. Do not warn about them on every launch.
  4. Do not claim a reading for hooks that will not load. Workspace hooks in an untrusted folder, under --safe-mode, or with disableAllHooks are never loaded. Either skip them per scope (not with one trust check over all scopes, which would hide managed hooks) or word the message as "would be read as … when this hook runs". Safe mode is resolved from argv or the environment, so the early startup call site cannot read it from Config.
  5. Tests that can fail. Cover a workspace-scope file (the existing fixture only makes the user settings file exist), an HTTP hook that has a name so the command-only filter is actually exercised, a managed-scope file, the 1000000 band, and a label with escape and format characters. Prove each by mutation.
  6. Update the timeout paragraph in docs/users/features/hooks.md to describe the warning once it exists.

Related

  • #11610 (hooks alignment tracking issue)
  • #11615 (timeout unit change, where the prototype and review discussion live)
中文说明

概述

#11615 把命令 hook 的 timeout 改为按秒解释,同时让 1000 及以上的值继续按旧的毫秒含义生效。目前能提示用户"某个 hook 仍在用旧写法"的只有一条调试日志,在该 hook 第一次运行时写入。#11615 里做过一版启动警告,评审中被移出,原因是要做得安全需要的设计超出了那个 PR 应承担的范围。本 issue 记录需求,单独落地。

需求

  1. 不原样回显不可信文本。 仓库提交的 .qwen/settings.json 属于不可信输入。警告不得打印 hook 的 command。如果要点名 hook,label 需依次经过 stripAnsiAndControl、去掉 Unicode 格式字符(\p{Cf}:bidi 覆盖、零宽字符、BOM)、trim,并截断到输出风格名称已在用的 64 字符回显上限。也可以改用位置(hooks.<Event>[i])加设置文件路径来标识。启动警告在 UI 渲染前经裸 process.stderr.write 输出,转义序列会直接作用于终端和剪贴板。
  2. 覆盖所有 hook 会执行的作用域。 System 与 SystemDefaults 设置作为 override 合并,其中的 hook 不受目录信任限制也会执行,托管 hook 同样需要警告。请用独立的循环遍历这两个作用域,避免连带对管理员下发的文件报出旧设置键警告。
  3. 只在用户能做点什么时警告。 1000000 及以上的值在兼容期内无法改写成秒,指南也让用户保留毫秒写法,不应每次启动都警告。
  4. 不对不会加载的 hook 断言读取结果。 不受信任目录、--safe-modedisableAllHooks 下的工作区 hook 不会被加载。要么按作用域跳过(不能对所有作用域做一次信任检查,否则会把托管 hook 也藏掉),要么把文案写成"该 hook 运行时会按……读取"。safe mode 来自 argv 或环境变量,较早的启动调用点无法从 Config 读到它。
  5. 能失败的测试。 覆盖工作区作用域文件(现有 fixture 只让用户设置文件存在)、带 name 的 HTTP hook(使"只处理命令 hook"的过滤真正被执行)、托管作用域文件、1000000 区间,以及含转义和格式字符的 label。每条都用变异验证。
  6. 警告落地后,同步更新 docs/users/features/hooks.md 里关于超时的段落。

关联

  • #11610(hooks 对齐总 issue)
  • #11615(超时单位改动,原型与评审讨论所在)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reading #11615 and tracing the early startup hook-loading path, including stripAnsiAndControl and the safe-mode sources. Add mutation tests for workspace, managed, HTTP, large-timeout, and escaped-label cases, then update docs/users/features/hooks.md. Done means startup warnings are safe, scoped correctly, actionable only when conversion is possible, and all listed tests pass.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
cli, documentation, security, tooling
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
58/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.