fix(cli): derive bootstrap --help from shared option definitions - #8902
Conversation
The bare `qwen --help` fast-path rendered a hand-maintained list that drifted from the real parser, hiding --approval-mode, --auth-type, and ~30 other accepted flags (issue #8897). Extract all non-hidden option definitions into a single shared module (top-level-options.ts) that both the bootstrap help parser and the real config parser consume from, keeping options in sync going forward. Also expand VALUE_FLAGS in cli.ts with every value-consuming option registered in the shared definitions, so resolveBootstrapRoute skips past values for these flags when detecting --help / --version.
|
Re-run at Template looks good ✓ Problem: observed bug, well evidenced — unchanged. #8897 is still open: a downstream integrator reported Direction: aligned, unchanged — no new auth/sandbox/telemetry surface is exposed; these flags already exist and are validated, this only makes help report them. The default-command addition documents the positional form that Size: touches the core path Approach: right shape, unchanged — one shared definition map drives both help surfaces and the scanner vocabulary. The new commit Risk: no elevated risk signals — no high-risk path matches. Moving on to code review. 🔍 中文说明基于 模板完整 ✓ 问题:已观测到的 bug,证据充分——结论不变。#8897 仍然 open:下游集成方报告 方向:对齐,不变——没有引入新的 auth/沙箱/遥测面;这些参数本就存在且已被校验,本 PR 只是让 help 如实报告它们。default-command 的补充记录了 规模:触及核心路径 方案:形态正确,不变——一张共享定义表同时驱动两个 help 面与扫描器词表。新提交 风险:无升级风险信号——无高风险路径命中。 进入代码审查 🔍 — Qwen Code · qwen3.8-max Reviewed at |
Code reviewIndependent baseline (unchanged across runs): the hand-maintained bootstrap option list was the drift mechanism, so both help surfaces must consume one set of definitions, and the scanner's flag vocabulary should derive from that same source. This head still implements exactly that; the full diff was re-read at
Round-32's only Critical (R31-2) is resolved at this head — verified against the live PR body. The Chinese 风险与范围 bullet now carries the corrected My own full-diff pass found no new Critical. The load-bearing pieces check out: the route-order change keeps Recorded for follow-up, not blocking (round 32+, per the convergence posture and AGENTS.md's review-round guidance — this PR is far past the ~5-round mark, so only Critical fixes land here): the §6 note naming the still-hand-maintained Test evidence (PR's own CI at
|
| Check | Conclusion |
|---|---|
| Test (ubuntu-latest, Node 22.x) | ✅ success |
| Test (windows-latest, Node 22.x) | ⏭️ skipped (path filter) |
| Test (macos-latest, Node 22.x) | ⏭️ skipped (path filter) |
| Integration Tests (CLI, No Sandbox) | ⏭️ skipped (path filter) |
| Post Coverage Comment (ubuntu-latest, 22.x) | ✅ success |
| Desktop Shell (ubuntu-22.04) | ✅ success |
| Desktop Shell (windows-2022) | ✅ success |
| web-shell E2E Smoke (ubuntu-latest, Node 22.x) | ✅ success |
| Secret scan (TruffleHog) | ✅ success |
| Dependency CVE audit | ✅ success |
Sandboxed verification for the residual behavioural delta: @qwen-code /verify at this exact head would settle it — the delta since @wenshao's real-binary sweep at 1417741c1 is the sentinel-parity commit (unit-pinned, moves toward base), the §4/§5 net subtraction and locale pin (witness-tested), and two clean merges, so the unit suite pins all of it and this is belt-and-braces rather than an open gap. The maintainer's sweep verdict on the substance (fix works, extraction rendered-help-neutral, no destructive divergence across 283 shapes) stands unchallenged by anything landed since.
中文说明
代码审查
独立基线(历次运行不变):手工维护的 bootstrap 选项列表是漂移机制本身,因此两个 help 面必须消费同一组定义,扫描器的旗标词表也应从同一来源派生。当前 head 仍然正是这样实现的;已在 4ed60c3c1 上重新通读完整 diff,并对上次完整审查以来的两个提交做了全新审查:
a0b2f0399是一次向 base 对齐的恢复,方向安全。hasFlag与firstPositionalArg重新获得对BASE_VALUE_FLAGS(PR 前硬编码的 11 拼写集合)值槽的无条件跳过——base 即使下一个 token 是--哨兵也如此处理——因此qwen --model -- --help与 base 一致仍路由到 help。仅派生集合中的旗标(--worktree、--proxy、-e等)保留经由skipOptionValues的有条件跳过,因此--worktree -- --help降级到慢路径。两种情形均有测试钉住,且每个调用点的注释说明了两个集合为何刻意不同。4ed60c3c1是一次干净的main合并——经 compare API 验证:到达本 PR 六个文件的改动只有 main 侧gemini.js→llm.js重命名扫尾(import 目标与注释引用)。没有任何冲突解决触及本 PR 的逻辑。
第 32 轮唯一的 Critical(R31-2)在当前 head 已解决——已对照线上 PR 正文核实。 中文「风险与范围」条目现在写入了修正后的 --no-help 家族披露,与英文 Risk & Scope 部分一致:除该家族外无功能性回归;该家族下 headless 启动 agent 并以 exit 1 退出,真实 TTY 打开交互式 TUI(base 打印帮助),并明确这 3 个 shape 确实是行为变化。中文读者可能依赖的矛盾表述已经消除。
我自己的全 diff 审查未发现新的 Critical。承重部件均核实无误:路由顺序变化不会让 serve/mcp 误入 help 快路径(位置参数检测在 help 条件内运行);版本拦截是失败关闭的(打印版本从不执行子命令,而降级可能执行——@wenshao 的二进制扫描确认两臂上 mcp remove victim -v help 都不删除任何内容);隐藏选项在两个 help 面中都保持隐藏;allowed-tools 去重保留了最后注册的措辞;deprecateOption 迁移对渲染 help 中性(维护者实测完整 parser help 逐字节一致,sha256 相同);top-level-options.ts 保持"无运行时 core import"属性,由源码扫描测试加对照 core 真实 ApprovalMode/AuthType 值与描述的对齐测试钉住。
记录为后续跟进、不阻塞合并(第 32 轮起,按收敛姿态与 AGENTS.md 的审查轮次指引——本 PR 已远超 5 轮门槛,此处只落 Critical 修复):§6 关于 TOP_LEVEL_COMMANDS 仍手工维护、已漂移的备注始终未写入 PR 正文;第 32 轮延后的探针清单(TOP_LEVEL_COMMANDS 注册表漂移、TOP_LEVEL_DEPRECATED_OPTIONS 注册见证、泛化的 toContain('deprecated') 钉住、npm 包装器 --expose-gc 滞后、版本扫描孪生哨兵钉住)继续记录在案;此前延后的建议级条目(import 边界逃逸面、BASE_VALUE_FLAGS 钉住数量、mcp-add mock 保真度)无变化。这些在当前 head 均非正确性阻塞。
测试证据(4ed60c3c1 上 PR 自己的 CI,经 API 获取——本次运行不构建、不执行 PR 代码)
两个 pull_request 事件的工作流在当前 head 全部绿色结束:Qwen Code CI(success)与 Security Checks(success)。该提交上没有任何红色检查。Windows/macOS/集成测试因本 PR 的路径过滤被跳过,与 base 一致;集成测试套件在该路径过滤下依旧不被执行,与 base 相同——此处无需处理。第 32 轮披露的缺口(集成套件未运行、审查 worktree 中两个 vitest 块未执行)属于审查流程缺口,不是产品信号——产品信号是下面绿色的单元测试套件。
沙箱验证用于覆盖残余行为差异:在当前 head 上运行 @qwen-code /verify 可以闭合它——自 @wenshao 在 1417741c1 上做真实二进制扫描以来的差异是哨兵对齐提交(单元测试钉住、向 base 方向移动)、§4/§5 净减法与 locale 固定(有见证测试),加两次干净合并,单元测试已将其全部钉住,所以这是双保险而非未闭合的缺口。维护者对实质内容的结论(修复有效、抽取对 help 渲染中性、283 个形态无破坏性差异)在其后落下的所有内容中均未受挑战。
— Qwen Code · qwen3.8-max
Reviewed at 4ed60c3c11d62e9e835dd784712a69979c5c402d · re-run with @qwen-code /triage
|
Confidence: 4/5 — clean pass at Stepping back: what landed since the approved pass at Reservations, stated so the score is honest: the §6 note naming the still-hand-maintained Verdict: approve, pinned to the reviewed commit. This supersedes round 32's request-changes, whose single Critical was the body bullet now corrected. ✅ 中文说明置信度:4/5 —— 退一步看:自 保留意见,如实说明以保证分数诚实:§6 关于 裁决:批准,锚定到被审查的提交。此批准取代第 32 轮的 request-changes——那一轮唯一的 Critical 正是现已修正的正文条目。✅ — Qwen Code · qwen3.8-max Reviewed at |
⏸️ Deferring to @doudouOUC (most recent human reviewer) — re-run at ⏸️ 转交 @doudouOUC(最近的人类审查者)——在 — Qwen Code · qwen3.8-max Reviewed at |
|
Local UI verification: PASS
中文本地 UI 验证:PASS
|
Code Coverage Summary
CLI Package - Full Text ReportCore Package - Full Text ReportFor detailed HTML reports, please see the 'coverage-reports-22.x-ubuntu-latest' artifact from the main CI run. |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
Not reviewed: build-and-test — "Integration Tests (CLI, No Sandbox)" was skipped in CI and its suite did not run locally.
Not explored to full depth (tool budget reached): chunk 2: none — did not run repo-wide typecheck, but the redundancy finding is verified by direct comparison of the two definitions and does not depend on it..
中文说明
未审查:build-and-test — "Integration Tests (CLI, No Sandbox)" was skipped in CI and its suite did not run locally。
未探索到全部深度(达到工具调用预算):chunk 2:none — did not run repo-wide typecheck, but the redundancy finding is verified by direct comparison of the two definitions and does not depend on it.。
— qwen3.8-max via Qwen Code /review (v0.21.9)
|
Fixed the bootstrap help option parsing follow-ups in |
|
Fixed the exact-head CI failure on |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
Reviewed. Suggestions are inline.
Not reviewed: build-and-test — "Integration Tests (CLI, No Sandbox)" was skipped in CI and its suite did not run locally.
Not explored to full depth (tool budget reached): Context: PR 8902 derives the bootstrap qwen --help outp...: none — all checks above were completed within budget..
中文说明
已审查。 建议见行内评论。
未审查:build-and-test — "Integration Tests (CLI, No Sandbox)" was skipped in CI and its suite did not run locally。
未探索到全部深度(达到工具调用预算):Context: PR 8902 derives the bootstrap qwen --help outp...:none — all checks above were completed within budget.。
— qwen3.8-max via Qwen Code /review (v0.21.9)
|
No blocking code findings at The remaining merge gates are operational: the branch currently conflicts with |
|
Closeout from resolve-pr-comments automation: Changed: PR body now includes the repository template's Chinese details section. No code changes. Pending: existing review threads remain; no product code changed in this pass. |
|
Closed the remaining help-output Suggestions as intentionally not changed: the current head has no blocking help/parsing finding, and the remaining requests are parity/type/test hardening beyond this bounded bug fix. No code changed. |
|
Closeout from resolve-pr-comments automation: no code changes. Resolved seven outdated review threads and updated the PR body to include the full Chinese details section from the current template. Current head has no active threads and no non-skipped red or pending checks. |
|
@qwen-code /review --timeout=360 |
|
Qwen Code review request accepted. Review is queued in workflow run. |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
Partially reviewed — gaps disclosed.
Not reviewed: build-and-test — "Integration Tests (CLI, No Sandbox)" was skipped in CI and its suite did not run locally.
Not explored to full depth (tool budget reached): chunk 1: none — no checks left unfinished.; "You are review agent reverse-audit — Reverse audit agent…": none — all checks above completed within budget.; "You are review agent reverse-audit — Reverse audit agent…": none — all checks above completed within budget..
Not reviewed: reverse audit — did not converge within the reverse-audit round cap of 5.
— qwen3.8-max via Qwen Code /review (v0.21.11)
# Conflicts: # packages/cli/src/cli.ts
|
Status update from resolve-pr-comments: Changed: resolved the latest-base conflict in Verified: Prettier, Pending: CI and automatic review on head e24ba6f. |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
Partially reviewed — gaps disclosed. Suggestions are inline.
Not reviewed: build-and-test — "Integration Tests (CLI, No Sandbox)" was skipped in CI and its suite did not run locally.
Not explored to full depth (tool budget reached): "Context: PR #8902 (QwenLM/qwen-code) derives the bootstrap…": none — all checks above completed within budget. (Items deliberately not reported: hidden-option fast-path completeness and positional+ --help slow-path conser…; "Context: PR #8902 (QwenLM/qwen-code) derives the bootstrap…": none — all planned checks completed; no checks left unfinished..
Not reviewed: reverse audit — did not converge within the reverse-audit round cap of 5.
中文说明
仅完成部分审查,审查缺口已披露。 建议见行内评论。
未审查:build-and-test — "Integration Tests (CLI, No Sandbox)" was skipped in CI and its suite did not run locally。
未探索到全部深度(达到工具调用预算):"Context: PR #8902 (QwenLM/qwen-code) derives the bootstrap…":none — all checks above completed within budget. (Items deliberately not reported: hidden-option fast-path completeness and positional+ --help slow-path conser…;"Context: PR #8902 (QwenLM/qwen-code) derives the bootstrap…":none — all planned checks completed; no checks left unfinished.。
未审查:反向审计——在 5 轮的反审轮数上限内未收敛。
— qwen3.8-max via Qwen Code /review (v0.21.11)
- Consume values of value-taking options registered outside TOP_LEVEL_HELP_OPTIONS (the hidden --sandbox-session-id), so a later --help reaches the fast path instead of booting the full CLI graph. - Handle =-form values: --flag=value carries its value inside the token (the next token must not be consumed), while array flags keep consuming following value tokens. - Document the remaining direction-safe limitation: short-option clusters (-vh, -sm gpt-4) are matched as whole tokens and demote to the slow path; output stays correct there. Adds regression tests for all three shapes.
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
Partially reviewed — gaps disclosed.
Not reviewed: build-and-test — "Integration Tests (CLI, No Sandbox)" was skipped in CI and its suite did not run locally.
Not explored to full depth (tool budget reached): "You are review agent reverse-audit — Reverse audit agent…": none — all checks I started were completed within budget..
中文说明
仅完成部分审查,审查缺口已披露。
未审查:build-and-test — "Integration Tests (CLI, No Sandbox)" was skipped in CI and its suite did not run locally。
未探索到全部深度(达到工具调用预算):"You are review agent reverse-audit — Reverse audit agent…":none — all checks I started were completed within budget.。
— qwen3.8-max via Qwen Code /review (v0.21.11)
skipOptionValues' array branch greedily consumed every following non-dash token, modeling yargs' final-parse semantics — but yargs detects commands in an earlier pass where these default-command-builder options are still unknown and an unknown option takes at most one value; the --flag=value form consumes none. A command token sitting after array values was therefore swallowed, firstPositionalArg returned undefined, and the top-level help fast path misfired: 'qwen --extensions=a serve --help' printed the root help instead of the 'qwen serve' page (also '--extensions a serve', '-e a serve', '--include-directories x mcp', '--fallback-model m1 serve'). Consume at most one space-separated token for every value-taking flag, matching the command-detection pass (probe-verified against yargs on this repo); multi-value array invocations such as '--extensions a b --help' demote to the slow path, which prints the identical page via the full parser. Adds regression coverage for the swallowed-command shapes (R5-1).
|
🤖 Addressed the latest review feedback (round 2/100). What changed, and what I pushed back on: · 已处理最新评审反馈(第 2/100 轮)。改动内容与我反驳保留之处如下: Round summaryAddresses the maintainer verification report ([ic:5439725115]) and the sandboxed-verification build failure ([ic:5438847744]). One commit: §4 —
|
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
Partially reviewed — gaps disclosed.
3 Suggestion-level finding(s) this review confirmed are already reported on this PR and are not repeated:
- R7-1 .locale('en') pin on the fast-path help parser has no paired test (packages/cli/src/cli.ts:249) — already reported (comment 3787815805, round-7 R7-1)
- full-parser <-> TOP_LEVEL_HELP_OPTIONS help-parity test (packages/cli/src/cli.test.ts:771) — already reported (R2-1, comment 3757539808); author declined
- BASE-value-flag + -- sentinel corner unpinned and hasVersionToken comment overclaims (packages/cli/src/cli.ts:210-238) — already recorded in the round-22 (cli.ts:297), round-24 (cli.ts:232) and round-26 (cli.ts:237) deferred lists
Not reviewed: build-and-test — "Integration Tests (CLI, No Sandbox)" was skipped in CI and its suite did not run locally.
Not explored to full depth (tool budget reached): chunk 2: executing cli.test.ts under vitest to confirm the traced expectations pass at HEAD — the review worktree has no node_modules and no built packages/core di….
Not reviewed: reverse audit — did not converge within the reverse-audit round cap of 5.
中文说明
仅完成部分审查,审查缺口已披露。
本轮确认的 3 条建议级发现已在 PR 上报告过,不再重复发布(列表见上方英文部分)。
未审查:build-and-test — "Integration Tests (CLI, No Sandbox)" was skipped in CI and its suite did not run locally。
未探索到全部深度(达到工具调用预算):chunk 2:executing cli.test.ts under vitest to confirm the traced expectations pass at HEAD — the review worktree has no node_modules and no built packages/core di…。
未审查:反向审计——在 5 轮的反审轮数上限内未收敛。
— qwen3.8-max via Qwen Code /review (v0.22.2)
|
🤖 Addressed the latest review feedback (round 3/100). What changed, and what I pushed back on: · 已处理最新评审反馈(第 3/100 轮)。改动内容与我反驳保留之处如下: Round summaryAddresses the round-28 review [rv:5043407602]. That review posted zero new findings and confirmed three Suggestion-level findings as already reported on the PR. One of them was still open with neither a fix nor a recorded disposition; the other two were already handled in earlier rounds:
No failed checks and no new inline or issue-level feedback arrived this round; conflict resolution was not requested ( Reproduction and mutation probeReproduced the underlying behavior first with a direct yargs probe under
The suite therefore no longer stays green with the pin deleted, which is exactly the regression R7-1 named. Verification
中文说明轮次总结处理第 28 轮审查 [rv:5043407602]。该轮审查未发布任何新发现,仅确认了 3 条已在 PR 上报告过的建议级(Suggestion)发现。其中一条既无修复也无书面处置记录,仍处于未处理状态;另外两条已在早前的轮次中处理完毕:
本轮没有失败的检查,也没有新的行内或 issue 级反馈;未要求进行冲突解决( 复现与变异探测首先用直接的 yargs 探测在
因此,删除该固定后测试套件不再全绿——这正是 R7-1 所指出的回归。 验证
Base-conflict check · 基分支冲突检查: no conflict with main. · 与 main 无冲突。 Re-review when you have a moment. After round 100 this bot stops and leaves the PR for a human. · 有空请复审;第 100 轮后本 bot 停止并将 PR 交给人工。 🧠 Handled by Qwen Code · model/模型 |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
Partially reviewed — gaps disclosed.
2 Suggestion-level finding(s) this review confirmed are already reported on this PR and are not repeated:
- import-boundary guard misses runtime re-exports — already recorded in the round-26 deferred list (review 5020611515) and the round-27 deferred list (review 5038810142)
- BASE_VALUE_FLAGS base-set control pins 6 of 11 spellings — already recorded in the round-26 deferred list (review 5020611515) and re-confirmed as already reported in round 28 (review 5043407602)
Not reviewed: build-and-test — "Integration Tests (CLI, No Sandbox)" was skipped in CI and its suite did not run locally.
Not explored to full depth (tool budget reached): "agent 1a": executing packages/cli/src/cli.test.ts — the shared worktree had no usable node_modules, and three npm install attempts plus one npm run build each failed….
Deferred under the convergence posture (round 29, not a blocker) — recorded, not requested in this round:
packages/cli/src/cli.test.ts:166 — [probe] argvSafeForFastPath -- sentinel branch has no observable route pin (return-false mutant survives; qwen --help -- <data> demotes off the help fast path)
中文说明
仅完成部分审查,审查缺口已披露。
本轮确认的 2 条建议级发现已在 PR 上报告过,不再重复发布(列表见上方英文部分)。
未审查:build-and-test — "Integration Tests (CLI, No Sandbox)" was skipped in CI and its suite did not run locally。
未探索到全部深度(达到工具调用预算):"agent 1a":executing packages/cli/src/cli.test.ts — the shared worktree had no usable node_modules, and three npm install attempts plus one npm run build each failed…。
收敛姿态下延后(第 29 轮,非阻断)——已记录,本轮不要求修改:共 1 条(原文未翻译,列表见上方英文部分)。
— qwen3.8-max via Qwen Code /review (v0.22.2)
|
🔀 Base updated: red check(s) [Test (ubuntu-latest, Node 22.x), Post Coverage Comment (ubuntu-latest, 22.x)] pass on current main — merged current main via update-branch; CI will re-run. 中文说明🔀 已更新 base:红色检查 [Test (ubuntu-latest, Node 22.x), Post Coverage Comment (ubuntu-latest, 22.x)] 在当前 main 上通过 —— 已通过 update-branch 合入当前 main,CI 将重新运行。 |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
Partially reviewed — gaps disclosed.
3 Suggestion-level finding(s) this review confirmed are already reported on this PR and are not repeated:
- import-boundary guard escape surfaces (export-from re-exports and bare/compact import lines invisible to the ^import regex, cli.test.ts:1125) — already reported (round-26 deferred list: cli.test.ts:1076 'Import-boundary test only polices co…
- BASE_VALUE_FLAGS base-set control pins only 7 of the 11 spellings (cli.test.ts:313) — already reported (round-26 deferred list, cli.test.ts:313; re-confirmed as already reported in round 28, review 5043407602)
- Commands-section order/suffix/alias divergence between the fast-path help and the full parser (cli.ts:272) — already discussed: maintainer verification report §6 (comment 5439725115) verified it and deferred it to a follow-up
Not reviewed: build-and-test — "Integration Tests (CLI, No Sandbox)" was skipped in CI and its suite did not run locally.
Not reviewed: reverse audit — did not converge within the reverse-audit round cap of 5.
Deferred under the convergence posture (round 30, not a blocker) — recorded, not requested in this round:
packages/cli/src/config/top-level-options.ts:433 — [probe] TOP_LEVEL_HELP_OPTIONS union lacks a cross-map uniqueness guard (probe-verified last-wins clobber if a key ever appears in both source maps)
[Critical] R30-1: The PR body's Risk & Scope claim 'No functional regression in those 22: every one of them prints help on both paths' remains false for the --no-help family and is still uncorrected. qwen --help --no-help (also --help --no-h, -h -h=false) is one of the 22 routed shapes the body enumerates — one of the three it says 'move the other way' — but at this head it does not print help at all: resolveBootstrapRoute(['--help','--no-help']) returns 'default' (probe-verified at the reviewed commit 88679b2) because '--no-help' fails the KNOWN_FAST_PATH_FLAGS gate, so the full parser boots with help negated last-wins — headless exits 1, on a real TTY the interactive TUI opens — where base printed top-level help and exited 0. Maintainer @wenshao's verification report §3 (comment 5439725115) asked for exactly this sentence to be corrected before merge; §4 (membership-gate test + rule deletion) has since been implemented, but the body edit was never applied — the autofix round supplied verified drop-in replacement text (comment 5440448695) and noted it could not edit the body itself. Witness: probe at reviewed commit: resolveBootstrapRoute(['--help','--no-help']) => "default", ['--help'] => "help", ['--version'] => "version"; maintainer A/B at head 1417741 (real bundled binaries): base 'help + exit 0' → head 'agent boot + exit 1' headless, TUI on a real TTY. Fix: apply the verified replacement sentence from comment 5440448695 disclosing the --no-help family exception (full-parser parity: headless boots the agent and exits 1, a real TTY opens the TUI; base printed help).
中文说明
仅完成部分审查,审查缺口已披露。
本轮确认的 3 条建议级发现已在 PR 上报告过,不再重复发布(列表见上方英文部分)。
未审查:build-and-test — "Integration Tests (CLI, No Sandbox)" was skipped in CI and its suite did not run locally。
未审查:反向审计——在 5 轮的反审轮数上限内未收敛。
收敛姿态下延后(第 30 轮,非阻断)——已记录,本轮不要求修改:共 1 条(原文未翻译,列表见上方英文部分)。
[Critical] R30-1: The PR body's Risk & Scope claim 'No functional regression in those 22: every one of them prints help on both paths' remains false for the --no-help family and is still uncorrected. qwen --help --no-help (also --help --no-h, -h -h=false) is one of the 22 routed shapes the body enumerates — one of the three it says 'move the other way' — but at this head it does not print help at all: resolveBootstrapRoute(['--help','--no-help']) returns 'default' (probe-verified at the reviewed commit 88679b2) because '--no-help' fails the KNOWN_FAST_PATH_FLAGS gate, so the full parser boots with help negated last-wins — headless exits 1, on a real TTY the interactive TUI opens — where base printed top-level help and exited 0. Maintainer @wenshao's verification report §3 (comment 5439725115) asked for exactly this sentence to be corrected before merge; §4 (membership-gate test + rule deletion) has since been implemented, but the body edit was never applied — the autofix round supplied verified drop-in replacement text (comment 5440448695) and noted it could not edit the body itself. Witness: probe at reviewed commit: resolveBootstrapRoute(['--help','--no-help']) => "default", ['--help'] => "help", ['--version'] => "version"; maintainer A/B at head 1417741 (real bundled binaries): base 'help + exit 0' → head 'agent boot + exit 1' headless, TUI on a real TTY. Fix: apply the verified replacement sentence from comment 5440448695 disclosing the --no-help family exception (full-parser parity: headless boots the agent and exits 1, a real TTY opens the TUI; base printed help).
— qwen3.8-max via Qwen Code /review (v0.22.2)
|
@qwen-code /triage |
|
Sandboxed verification: The verification job did not complete (checkout, runner, or setup error) and produced no report. See the workflow run for details. 中文 — 判定:
|
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
LGTM, looks ready to ship. ✅
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
Partially reviewed — gaps disclosed.
4 Suggestion-level finding(s) this review confirmed are already reported on this PR and are not repeated:
- import-boundary guard export-from/dynamic-import escape surface (cli.test.ts:1119-1128) — already reported (round-26 deferred list cli.test.ts:1076, round-27 deferred list cli.test.ts:1084, round-30 already-reported list cli.test.ts:1125)
- VALUE_FLAGS number-type branch untested (cli.ts:86) — already reported as R11-3 (round-11 deferred list, review 4957427644; re-reported rounds 12/16)
- self-referential help-completeness parity loop (cli.test.ts:777) — already reported as R2-1 (comment 3757539808, round 2; re-reported rounds 14/17/21/22/27/28/30; author declined)
- mcp add mock partial mirror — omits production's argv['--']→args merge middleware and declared options (cli.test.ts:103-108) — already reported (round-20 deferred list cli.test.ts:111, round-27 deferred list cli.test.ts:98)
Not reviewed: build-and-test — "Integration Tests (CLI, No Sandbox)" was skipped in CI and its suite did not run locally.
Not explored to full depth (tool budget reached): chunk 2: executing packages/cli cli.test.ts (no node_modules in review worktree; install exceeds budget).
Deferred under the convergence posture (round 31, not a blocker) — recorded, not requested in this round:
packages/cli/src/cli.test.ts:217 — [probe] =-form pins' comments claim a guarantee the tests cannot observe (eq-branch mutant survives all 18 route tests)
Residual risk: this loop is persistently critical — Criticals stood in the previous round's work-list and stand again this round (2 Critical(s)), the rate of first-time findings is not falling (this round 1, previous 0), and the standing Critical backlog is not shrinking. The severity floor will not converge it. Recommendation: land-with-residual-risk — the exit is a maintainer risk-acceptance decision (merge, carrying the residual risk), not another review round. Residual-risk inventory for that decision (maintainer to complete):
| standing Critical | attack surface | attacker-dependency | blast radius |
|---|---|---|---|
| (each standing Critical) | … | … | … |
Advisory only — it does not block this review.
[Critical] R31-1: The round-30 body correction (R30-1) was applied to the English Risk & Scope section only. The Chinese 风险与范围 mirror still asserts "这 22 个没有功能性回归:两条路径都会打印 help" — the exact claim the maintainer's pre-merge ask (§3 of the verification report, comment 5439725115) required corrected before merge. The English section now reads "No functional regression in those 22 except the --no-help family … headless runs boot the agent and exit 1, and a real TTY opens the interactive TUI (base printed help)", so the two language sections of the same body directly contradict each other. A Chinese-reading reviewer relying on 风险与范围 is still told all 22 routing changes print help on both paths — false for --help --no-help / --help --no-h / -h -h=false, which route to 'default' at this head (pinned at cli.test.ts:647) and boot the agent instead of printing help. Witness: live PR body at head 88679b21 (EN discloses the exception; ZH does not) plus vitest src/cli.test.ts -t "KNOWN_FAST_PATH_FLAGS" → 1 passed, pinning resolveBootstrapRoute(['--help','--no-help']) === 'default'. Fix: translate the corrected disclosure into the Chinese 风险与范围 bullet — replace "这 22 个没有功能性回归:两条路径都会打印 help…" with the --no-help family exception (headless runs boot the agent and exit 1, a real TTY opens the TUI; base printed help). Fix witness: N/A — PR body edit; no test can pin it.
中文说明
[Critical] R31-1: 第 30 轮要求的正文更正(R30-1)只应用到了英文 Risk & Scope 部分。中文「风险与范围」镜像段落仍然写着"这 22 个没有功能性回归:两条路径都会打印 help"——正是维护者验证报告 §3(评论 5439725115)在合并前要求更正的那句话。英文部分现已写明"这 22 个 shape 中除--no-help 家族外没有功能性回归……headless 运行会启动 agent 并以 exit 1 退出,真实 TTY 会打开交互式 TUI(base 打印帮助)",同一正文的两个语言段落因此直接互相矛盾。依赖中文段落的评审者仍会被告知全部 22 个路由变更在两条路径下都会打印帮助——而 --help --no-help / --help --no-h / -h -h=false 在当前 head 下路由为 'default'(cli.test.ts:647 已固定),会启动 agent 而不是打印帮助。证据:head 88679b21 的线上 PR 正文(英文已披露例外、中文未披露);vitest src/cli.test.ts -t "KNOWN_FAST_PATH_FLAGS" 通过,固定了 resolveBootstrapRoute(['--help','--no-help']) === 'default'。修复:把更正后的披露翻译进中文「风险与范围」条目——用 --no-help 家族例外替换"这 22 个没有功能性回归:两条路径都会打印 help…"(headless 运行启动 agent 并 exit 1,真实 TTY 打开 TUI;base 打印帮助)。修复见证:N/A——PR 正文编辑,无测试可固定。 中文说明
仅完成部分审查,审查缺口已披露。
本轮确认的 4 条建议级发现已在 PR 上报告过,不再重复发布(列表见上方英文部分)。
未审查:build-and-test — "Integration Tests (CLI, No Sandbox)" was skipped in CI and its suite did not run locally。
未探索到全部深度(达到工具调用预算):chunk 2:executing packages/cli cli.test.ts (no node_modules in review worktree; install exceeds budget)。
收敛姿态下延后(第 31 轮,非阻断)——已记录,本轮不要求修改:共 1 条(原文未翻译,列表见上方英文部分)。
残余风险:本循环处于 persistently-critical 形态——上一轮工作清单中的 Critical 本轮依然存在(本轮 2 条 Critical),首次发现的速率没有下降(本轮 1,上一轮 0),且未决 Critical 积压没有减少。severity floor 无法使其收敛。建议:land-with-residual-risk——出口是 maintainer 的风险接受决定(合入并承担残余风险),而非再开一轮评审。供该决定使用的残余风险清单(maintainer 填写):按每条未决 Critical 列出「攻击面 · 攻击者依赖性 · 影响范围」三栏。仅为建议——不阻断本次评审。
[Critical] R31-1: The round-30 body correction (R30-1) was applied to the English Risk & Scope section only. The Chinese 风险与范围 mirror still asserts "这 22 个没有功能性回归:两条路径都会打印 help" — the exact claim the maintainer's pre-merge ask (§3 of the verification report, comment 5439725115) required corrected before merge. The English section now reads "No functional regression in those 22 except the --no-help family … headless runs boot the agent and exit 1, and a real TTY opens the interactive TUI (base printed help)", so the two language sections of the same body directly contradict each other. A Chinese-reading reviewer relying on 风险与范围 is still told all 22 routing changes print help on both paths — false for --help --no-help / --help --no-h / -h -h=false, which route to 'default' at this head (pinned at cli.test.ts:647) and boot the agent instead of printing help. Witness: live PR body at head 88679b21 (EN discloses the exception; ZH does not) plus vitest src/cli.test.ts -t "KNOWN_FAST_PATH_FLAGS" → 1 passed, pinning resolveBootstrapRoute(['--help','--no-help']) === 'default'. Fix: translate the corrected disclosure into the Chinese 风险与范围 bullet — replace "这 22 个没有功能性回归:两条路径都会打印 help…" with the --no-help family exception (headless runs boot the agent and exit 1, a real TTY opens the TUI; base printed help). Fix witness: N/A — PR body edit; no test can pin it.
中文说明
[Critical] R31-1: 第 30 轮要求的正文更正(R30-1)只应用到了英文 Risk & Scope 部分。中文「风险与范围」镜像段落仍然写着"这 22 个没有功能性回归:两条路径都会打印 help"——正是维护者验证报告 §3(评论 5439725115)在合并前要求更正的那句话。英文部分现已写明"这 22 个 shape 中除--no-help 家族外没有功能性回归……headless 运行会启动 agent 并以 exit 1 退出,真实 TTY 会打开交互式 TUI(base 打印帮助)",同一正文的两个语言段落因此直接互相矛盾。依赖中文段落的评审者仍会被告知全部 22 个路由变更在两条路径下都会打印帮助——而 --help --no-help / --help --no-h / -h -h=false 在当前 head 下路由为 'default'(cli.test.ts:647 已固定),会启动 agent 而不是打印帮助。证据:head 88679b21 的线上 PR 正文(英文已披露例外、中文未披露);vitest src/cli.test.ts -t "KNOWN_FAST_PATH_FLAGS" 通过,固定了 resolveBootstrapRoute(['--help','--no-help']) === 'default'。修复:把更正后的披露翻译进中文「风险与范围」条目——用 --no-help 家族例外替换"这 22 个没有功能性回归:两条路径都会打印 help…"(headless 运行启动 agent 并 exit 1,真实 TTY 打开 TUI;base 打印帮助)。修复见证:N/A——PR 正文编辑,无测试可固定。 — qwen3.8-max via Qwen Code /review (v0.22.2)
…tinel (#8902) The pre-PR hasFlag/firstPositionalArg scans skipped the value slot of the base's hardcoded value flags unconditionally, even when it held the -- sentinel, so 'qwen --model -- --help' routed to help and exited 0. The derived skipOptionValues refuses '--' as a value token, which flipped every long BASE value-flag spelling followed by '--' and --help/-h onto the default route, booting the agent on the literal prompt '--help'. Restore the unconditional BASE_VALUE_FLAGS skip in hasFlag and firstPositionalArg, mirroring hasVersionToken, and pin the route family. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
Partially reviewed — gaps disclosed.
4 Suggestion-level finding(s) this review confirmed are already reported on this PR and are not repeated:
- R32-1 option-set alignment loop is self-referential (cli.test.ts:794) — already reported as R2-1 (comment 3757539808; re-reported rounds 14/17/21/22/27/28/30; author declined)
- R32-5 mcp add mock partial mirror — omits production argv['--']→args merge middleware and declared options (cli.test.ts:98) — already reported (round-20 deferred list cli.test.ts:111, round-27 deferred list cli.test.ts:98)
- R32-6 import-boundary guard re-export escape surface (cli.test.ts:1141) — already reported (round-26/27/30 deferred lists, cli.test.ts:1119-1128)
- R32-10 BASE_VALUE_FLAGS base-set pin coverage — 4 spellings unpinned (cli.test.ts:268) — already reported (prior-round deferred item, named in triage comment 5248422469)
Not reviewed: build-and-test — "Integration Tests (CLI, No Sandbox)" was skipped in CI and its suite did not run locally.
Not explored to full depth (tool budget reached): chunk 7: execute packages/cli vitest run of src/config/top-level-options.test.ts (blocked by unbuilt workspace dist/ in the review worktree); chunk 2: did not execute packages/cli 's vitest suite for cli.test.ts — the review worktree has no node_modules and no built workspace dist/ , and a full npm ci ….
Deferred under the convergence posture (round 32, not a blocker) — recorded, not requested in this round:
packages/cli/src/cli.ts:40 — [probe] TOP_LEVEL_COMMANDS drifts from the real command registry (suffixes, order, [aliases: hook]); maintainer report §6 scoped the code fix to a follow-up — the PR body note naming it is still absentpackages/cli/src/config/config.ts:844 — [probe] TOP_LEVEL_DEPRECATED_OPTIONS keys have no registration witness; deprecateOption silently no-ops for unregistered keys (mutation-verified)packages/cli/src/cli.test.ts:807 — [probe] generic toContain('deprecated') leaves up to 8 of 9 deprecation annotations unpinned, including prompt (mutation-verified)packages/cli/src/cli.ts:172 — [probe] npm bin wrapper in-process/spawn decision lags the new demotion grammar — demoted help argv can boot the agent without --expose-gc (wrapper A/B verified)packages/cli/src/cli.test.ts:187 — [probe] no pin for the version-scan twin of the BASE-slot sentinel swallow (['--model','--','-v'] → 'version'); mutant flip caught by no existing test
中文说明
仅完成部分审查,审查缺口已披露。
本轮确认的 4 条建议级发现已在 PR 上报告过,不再重复发布(列表见上方英文部分)。
未审查:build-and-test — "Integration Tests (CLI, No Sandbox)" was skipped in CI and its suite did not run locally。
未探索到全部深度(达到工具调用预算):chunk 7:execute packages/cli vitest run of src/config/top-level-options.test.ts (blocked by unbuilt workspace dist/ in the review worktree);chunk 2:did not execute packages/cli 's vitest suite for cli.test.ts — the review worktree has no node_modules and no built workspace dist/ , and a full npm ci …。
收敛姿态下延后(第 32 轮,非阻断)——已记录,本轮不要求修改:共 5 条(原文未翻译,列表见上方英文部分)。
— qwen3.8-max via Qwen Code /review (v0.22.2)
|
@qwen-code /triage |
|
Sandboxed verification: ✅ passed — merge-ready (agent verdict) - workflow run Ran the PR in an isolated, token-free container: A/B against the base build, mock-free harness assertions, targeted gates. Advisory evidence for human reviewers — not a review, an approval, or a CI check. Scripted assertions: 600 passed · 0 failed · 600 total Flakiness gate: ✅ 3 changed test file(s) x 5 identical rounds, no divergence 中文 — 判定:✅ 通过 · 可合入(agent 判定)沙箱验证在隔离、无凭证的容器中执行了该 PR 的代码(与 base 构建 A/B 对照、无 mock harness 断言、定向门禁)。仅作为评审证据,不构成评审、批准或 CI 检查。 脚本断言:600 通过 · 0 失败 · 600 总计 抖动门:✅ 3 changed test file(s) x 5 identical rounds, no divergence Verification reportVerdict: 中文摘要
Previous-finding status (follow-up round)
Scope
Out of scope (listed under Not covered): per-commit attribution, lint, repo-wide suites, non-Linux platforms, internal route-name counts. Central claim — A/B tableOracle 1 (
Scripted results (29/29 pass):
Cell-selection note (methodology, not a finding): Cell-selection note 2: my first harness revision undercounted option rows (regex matched only Secondary claim 1 — routing corpus A/B (104/104)Oracle 2 (
The dangerous historical shapes from this PR's evolution ( Locale pin (oracle 3, witness Import-closure claim (indirect): head Secondary claim 2 — tests are load-bearing
CorrectionsNone — no earlier round described the code inaccurately (the previous round was a build-failure notice, re-measured above). FindingsNone. No new blocking or non-blocking problems were produced by the evidence. The one user-visible behavior change ( Not covered
MethodologyEnvironment: CI verify container ( Flakiness gate logEvidence imagesHarness scripts and raw logs are in the workflow run artifacts (7-day retention). — Qwen Code · sandboxed verification |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
LGTM, looks ready to ship. ✅
|
🤖 AutoFix updated a stale base — the fix did not pass verification, but this PR was behind What I found before stopping: Autofix address-review round — PR #8902 (head
|
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
Partially reviewed — gaps disclosed.
8 Suggestion-level finding(s) this review confirmed are already reported on this PR and are not repeated:
- R33-1 config.ts deprecation loop has no test witness — already reported as R2-5 (comment 3757539855); author declined; re-reported as R10-2
- R33-2 VALUE_FLAGS number-type branch untested — already reported as R11-3 (round-11 deferred list, review 4957427644; re-reported rounds 12/16)
- R33-3 BASE_VALUE_FLAGS base-set pin coverage (4 spellings unpinned) — already reported as R32-10 (triage comment 5248422469; round-26/28 deferred lists, cli.test.ts:313)
- R33-4 import-boundary guard re-export escape surface — already reported (round-26 deferred list cli.test.ts:1076, round-27 cli.test.ts:1084, round-30 cli.test.ts:1125, round-31 already-reported list)
- R33-5 option-set parity unwitnessed — already reported as R2-1 (comment 3757539808; author declined; re-reported rounds 14/17/21/22/27/28/30/32) and as R1-7 (comment 3755281208)
- R33-6 Commands-section order divergence — already discussed: maintainer verification report §6 (comment 5439725115) verified it and deferred it to a follow-up; round-32 deferred list (cli.ts:40)
- R33-7 TOP_LEVEL_DEPRECATED_OPTIONS keys unvalidated — already reported (round-32 deferred list, config.ts:844)
- R33-8 hasVersionToken docstring overclaims — already reported (round-28 already-reported list: 'hasVersionToken comment overclaims', cli.ts:210-238; round-22/24/26 deferred lists)
Not reviewed: build-and-test — "Integration Tests (CLI, No Sandbox)" was skipped in CI and its suite did not run locally.
Not reviewed: reverse audit — did not converge within the reverse-audit round cap of 5.
中文说明
仅完成部分审查,审查缺口已披露。
本轮确认的 8 条建议级发现已在 PR 上报告过,不再重复发布(列表见上方英文部分)。
未审查:build-and-test — "Integration Tests (CLI, No Sandbox)" was skipped in CI and its suite did not run locally。
未审查:反向审计——在 5 轮的反审轮数上限内未收敛。
— qwen3.8-max via Qwen Code /review (v0.22.2)
|
🤖 Reviewed the latest feedback — no changes needed. Why, point by point: · 已审阅最新反馈——无需改动。逐点说明原因如下: Autofix round report — PR #8902 (address-review, head
|
Local verification report (maintainer) — round 2, at the current headFollow-up to my 2026-08-25 and 2026-08-27 runs. I rebuilt both arms from source on Linux and put the real bundled binaries through the harness again, because the head has moved through five commits and a Verdict: every finding from my last two reports is now closed, and I could not reproduce a regression. Not blocking on anything. Five small non-blocking notes at the end, one of which is a leftover of the same dead-code class round 2 cleaned up.
1. The fix does what it claims — and now matches the real parser exactlyThe oracle is the same binary's own full parser: Base's fast path was missing 48 of the 59 options the real parser accepts. Head's fast-path option set is now exactly the real parser's — zero missing, zero extra, all nine The full-parser help is byte-identical across the two arms ( 2. Routing — 210 argv shapes on the real binariesNo exit-code divergence outside the The positive control fires: Worth noting how much this simplifies the surface: across its 158 help-printing shapes base emits 30 distinct help renderings; head emits 2 for 150 of its 155 — the fast-path help and the full-parser help, which now differ only by the hand-maintained 3. Round 2's "net subtraction" holds up — and one rule is still dominatedI re-ran every fix as a single-point mutation on the head source, re-bundled, and replayed the same 210 shapes plus the PR-adjacent suite. The important line is M3 ≡ M4: removing just the
4. The bootstrap-weight regression from my 2026-08-25 report is closedBefore The replacement is 5. The
|
| head | b085432868 |
| base | d6533785bd(与 main 的 merge-base) |
| 构建 | 两个隔离 worktree,按包链接依赖,node esbuild.config.js 产出 bundle |
| 环境 | Linux x86-64(Debian 13,内核 6.12)、Node v22.22.2 |
| 夹具 | 每次调用独立 HOME + QWEN_HOME + 空 cwd,settings.json 预置两个 MCP server(victim、keeper) |
1. 修复确实生效,且现在与真实 parser 完全一致
判据用的是同一个二进制自己的完整 parser:把 qwen --help(fast path)与 qwen zz --help(位置参数会让它降级到真实 yargs parser)做集合 diff。
base 的 fast path 缺了真实 parser 所接受的 59 个选项中的 48 个。head 的 fast-path 选项集现在与真实 parser 完全相同——零缺失、零多余,九个 [deprecated:] 标记全部带上,三个 hidden 选项在两条 help 路径上仍然隐藏。
完整 parser 的 help 在两臂上逐字节相同(sha256 cdac9a3183f2…),也就是说把约 350 行选项定义搬出 config.ts 之后渲染结果毫无变化。这是能给出的最强论据,说明本 PR 中 config.ts 那一半是纯重构。
2. 路由 —— 210 个 argv 形态跑真实二进制
除 --no-help 家族外没有退出码差异,任何地方都没有破坏性差异;27 个打印版本号的形态在两臂上逐字节相同。
正对照是会触发的:qwen mcp remove victim 在两臂上都真的删掉了那个 server,所以别处的"什么都没被删"是一次实测,而不是没测。
值得一提的是这对整个 help 面的收敛效果:base 的 158 个打印 help 的形态一共产生 30 种不同渲染;head 的 155 个里有 150 个只产生 2 种——fast-path help 与完整 parser help,而这两者如今只差一个手工维护的 Commands: 段(见 N4)。
3. 第 2 轮的"净减法"站得住脚 —— 但还有一条规则是冗余的
我把每一处修复都做成 head 源码上的单点变异,重新打包,再在同样的 210 个形态和 PR 相关测试套件上回放。
最关键的一行是 M3 ≡ M4:只删掉 KNOWN_FAST_PATH_FLAGS 成员检查,与把整个网关删掉,效果完全一样。这直接证明第 2 轮移除的那四条结构性规则确实是被支配的——网关现在是最小的,而且被测试钉住(删掉它会挂 2 条测试)。
BASE_VALUE_FLAGS 的对齐同样承重,只是我之前的语料看不见它:像 qwen --proxy -v 这样的形态,慢路径本来也会打印版本号。它只有在带命令尾巴时才暴露——qwen --proxy -v mcp remove victim 及其五个同类,在 M5 下从版本号、exit 0(base 对齐)变成报错、exit 1。head 在这十个形态上与 base 逐字节相同。
4. 我 2026-08-25 报告里的 bootstrap 权重回归已关闭
在 61f5bcfb8e 之前,共享模块在运行时 import 了 core barrel,把整个 agent 运行时拖进了 bootstrap 入口:97 个文件、10.6 MB,--help 从 40 ms 涨到 241 ms。在当前 head 上,静态 import 闭包是 10 个文件、51 KB(base 为 9 个文件、37.3 KB),而 qwen --help 的代价是 +6.2 ms,换来 4.4 倍的输出量。--version、mcp、mcp --version、mcp list 全部持平。
替代方案是 import type 加上由 satisfies / Record 见证守护的镜像字面量。我验证了这些见证在三个方向上都确实会报错:
5. .wrap() 修复,在真实 PTY 上验证
base 的 fast path 从不调用 .wrap(),所以无论终端多宽都停留在 yargs 默认的 80 列——这正是把标语切成 use -p/- / -prompt 的原因。head 与 config.ts 保持一致,变异 M2 确认有一条测试钉住了它。
6. 仓库检查
- ESLint 在全部六个改动文件上干净(
--max-warnings 0)。 npm run check:serve-fast-path-bundle—— 通过;共享模块没有把任何东西拖进启动闭包。- Typecheck:除了我自己 harness 里
audio-capturedist 未构建导致的 2 个TS6305之外干净——它在每次运行中都恒定出现,属于我的环境问题,与本 PR 无关。 - 与当前
main(5ae363e2f9)合并无冲突,config.ts自动合并。 - 两臂完整
packages/cli套件:base 25,452 通过 / 293 失败 / 33 个失败文件,head 25,476 通过 / 295 失败 / 35 个失败文件(多出的 24 条通过即本 PR 新增测试)。其中 33 个文件在两臂上完全一致地失败——ink/TUI 渲染套件,以及需要非 root 用户的serve套件。head 多出的那 2 个是 CPU 争抢下的抖动:单独运行时在 head 上 2/2 全绿,而serve/acp-http/transport.test.ts在同一组样本里在 base 上失败过一次。 - 合并安全性。
config.ts既是本 PR 掏空的文件,也是main持续往里加选项的文件,因此自动合并有可能悄悄丢掉一个新选项而不是把它注册进共享模块。我构建了真实的合并结果:它的真实 parser help 与当前main逐字节相同(两边都是 59 个选项),且它的 fast-path help 仍与自己的 parser 完全一致。没有任何东西丢失。
非阻塞说明
N1 —— argvSafeForFastPath 里还有一条规则是死代码。 if (!token.startsWith('-')) return false; 永远不可能成为某个 token 被拒的原因:KNOWN_FAST_PATH_FLAGS 完全由 --long / -x 拼写构成,因此任何过不了 startsWith('-') 的 token,在紧接着的下一行成员检查上同样过不了。删掉它在 210 个形态里 0 个发生变化,测试仍是 108/108 全绿——与第 2 轮删除另外四条规则用的是同一个论证。要么为了一致性把它也删掉,要么保留但在注释里写明它是文档而非生效规则。
N2 —— .locale('en') 这个钉子在发布产物里是空操作。 esbuild 不会打包 yargs 的 locales/*.json,因此 LC_ALL=de_DE.UTF-8 下 qwen --help 在两臂上、无论有没有这个钉子都渲染英文(已实测)。这个钉子和它新增的见证测试只在从源码运行时才起作用。无害且值得保留,但当前注释读起来像是发布版 CLI 依赖它。
N3 —— --no-help 家族现在会写 settings.json。 那三个行为发生变化的形态(--help --no-help、-h --no-h、-h --no-help)会启动 agent,而 agent 会盖上 "$version": 4 并重新缩进 settings 文件。没有任何数据丢失——两个预置 server 都还在——但 base 的 --help 压根不会碰这个文件。值得在风险章节补一句,因为"启动 agent 并以 exit 1 退出"稍微低估了它。
N4 —— TOP_LEVEL_COMMANDS 仍是手工维护的,而且它现在是 head 两条 help 路径之间唯一的差异。今天的实际漂移:
- qwen channel <command> (fast path) + qwen channel (真实 parser)
- qwen review <command> + qwen review
- qwen sessions <command> + qwen sessions
- qwen hooks + qwen hooks … [aliases: hook]外加排序不同。放到后续 PR 处理没问题——只是值得在正文里写一句,免得读者以为本 PR 为选项修掉的那类漂移在命令上也已经修好了。
N5 —— 有一处代码注释论断过头。 hasVersionToken 的注释用*"observed: mcp remove victim -v help deleted the server and its OAuth creds on the full parser"*来论证 fail-closed 拦截的必要性。在今天的构建上,这个 argv 在两臂都只打印版本号,所以该观察按字面表述无法复现。底层的担忧是真实的,我也用另一个 argv 复现了——qwen --proxy x mcp remove victim 确实会经由完整 parser 删除 server——所以我建议把例子换成仍然能演示该风险的那一个。
结论
Issue 已修复,config.ts 的抽取可证明对渲染中性,路由改写在逐 flag 穷举扫描下没有破坏性差异也没有退出码差异,而我上一轮提出的两点(给成员检查补测试、删掉被它支配的规则)是以真正的减法完成的。让我在 2026-08-25 犹豫的 bootstrap 权重回归已经消失。
没有阻塞项。 如果想在本 PR 里一并处理,N1 和 N5 都是两行的改动;N2–N4 属于注释/正文措辞。
🤖 Generated with Claude Code — Claude Opus 5 (1M context)













What this PR does
Derives bootstrap
qwen --helpoutput from the same top-level option definitions that the real parser accepts, so the fast help path no longer advertises a stale hand-maintained subset.Extracts all non-hidden CLI option definitions into a new shared module (
packages/cli/src/config/top-level-options.ts). Both the bootstrap help parser (cli.ts->buildTopLevelHelpParser) and the real config parser (config.ts) now consume from this single source of truth.Why it's needed
qwen --helplisted only 9 options while the real parser accepts around 50.--approval-modeand--auth-typewere both accepted and validated but invisible in help output, making headless integration confusing. The error messagePlease configure an auth type (e.g. via settings or \--auth-type`)pointed at a flag its own--help` never mentioned.Fixes #8897.
Reviewer Test Plan
How to verify
Before this PR: no output. After: both flags appear in the help text.
Unit test:
npx vitest run packages/cli/src/cli.test.ts -t "prints top-level help"asserts--approval-modeand--auth-typeare present.Evidence (Before & After)
Before:
--helpshows 9 options (model, fallback-model, prompt, prompt-interactive, safe-mode, sandbox, output-format, continue, resume).After:
--helpshows all around 50 non-hidden options registered in the real parser, including--approval-mode,--auth-type,--yolo,--debug,--mcp-config,--extensions,--channel,--worktree, telemetry flags, and more.Tested on
Environment (optional)
Not applicable.
Risk & Scope
resolveBootstrapRoutebehavior changed — this is not just additive help output. DerivingVALUE_FLAGSfrom the shared option definitions grew that set from 9 spellings to 47, which re-segments argv forhasFlag/firstPositionalArgand therefore shifts route detection. Measured over a 73-shape argv corpus (routing functions lifted verbatim fromcli.ts), 22 shapes route differently than base: 19 move from the full parser onto the help fast path (-p --help,--auth-type x --help,-e a --help,-m -h, …) and 3 move the other way (--help --no-help,--version=false --help,--unknown-flag --help— all three are fixes for pre-existing base bugs).--no-helpfamily (--help/-hfollowed by--no-help/--no-h): head follows the full parser's last-wins semantics there instead of printing help —--no-helpgenuinely negates--help, so headless runs boot the agent and exit 1, and a real TTY opens the interactive TUI (base printed help). The argv is exotic and the behavior is full-parser parity (fail-closed demotion to the slow path), but it is a behavior change for those 3 shapes. The remaining shapes print help on both paths (verified against a yargs parser withexitProcess(false); yargs short-circuits--helpbefore.strict()validation, so even the unknown-flag shape still exits 0). The only difference was help content — the fast-path help was missing theqwen [query..] … [default]row and thePositionals:block — which the default-command commit in this PR fixes.config.test.ts356/356 passing on this branch (the earlier "not validated / 19 pre-existing failures" note is obsolete — those failures were an environment artifact, not a real baseline).cli.test.ts+mcp/add.test.ts102/102. Type-check and ESLint clean; error sets diffed against the pristine branch to confirm no new type errors.CliArgsis byte-identical to base, everystring: true/coerceis retained at its call site, and relocatingdeprecateOptionout of the$0builder was verified to be a no-op for rendered help.argvSafeForFastPath,hasVersionToken,BASE_VALUE_FLAGS,KNOWN_FAST_PATH_FLAGS) is not required by --approval-mode and --auth-type are accepted but missing fromqwen --help#8897 — keepingVALUE_FLAGSat the base set would have fixed the issue with zero routing risk. It is retained here because it also fixes the three base bugs above, but it is a reasonable thing for a reviewer to ask to split out.Linked Issues
Fixes #8897.
中文说明
本 PR 做了什么
本 PR 让 bootstrap 阶段的
qwen --help输出从真实 parser 接受的同一组顶层选项定义派生,因此 fast help path 不再展示过时的手写子集。所有非 hidden 的 CLI 选项定义被抽到新的共享模块(
packages/cli/src/config/top-level-options.ts)中。bootstrap help parser(cli.ts->buildTopLevelHelpParser)和真实 config parser(config.ts)现在都消费同一个事实来源。为什么需要
qwen --help原来只列出 9 个选项,而真实 parser 接受约 50 个选项。--approval-mode和--auth-type都已经被接受并校验,但没有出现在 help 输出里,这会让 headless 集成很困惑。错误信息Please configure an auth type (e.g. via settings or \--auth-type`)指向了一个自己的--help` 都没有提到的参数。Fixes #8897。
Reviewer 测试计划
如何验证
本 PR 前:没有输出。本 PR 后:两个参数都会出现在 help 文本中。
单元测试:
npx vitest run packages/cli/src/cli.test.ts -t "prints top-level help"断言--approval-mode和--auth-type存在。证据(前后对比)
之前:
--help显示 9 个选项(model、fallback-model、prompt、prompt-interactive、safe-mode、sandbox、output-format、continue、resume)。之后:
--help显示真实 parser 中注册的约 50 个非 hidden 选项,包括--approval-mode、--auth-type、--yolo、--debug、--mcp-config、--extensions、--channel、--worktree、telemetry flags 等。测试平台
环境(可选)
不适用。
风险与范围
resolveBootstrapRoute的行为变了,不只是 help 输出的增量补充。从共享选项定义派生VALUE_FLAGS让这个集合从 9 个拼写涨到 47 个,从而改变了hasFlag/firstPositionalArg对 argv 的切分,进而影响 route detection。在 73 个 argv shape 的语料上实测(routing 函数从cli.ts原文抽取转译),22 个 shape 的路由与 base 不同:19 个从完整 parser 移到 help fast path(-p --help、--auth-type x --help、-e a --help、-m -h等),3 个反向移动(--help --no-help、--version=false --help、--unknown-flag --help——这三个都是 base 既有 bug 的修复)。--no-help家族(--help/-h后跟--no-help/--no-h)外,这 22 个没有功能性回归:在该家族下,head 遵循完整 parser 的 last-wins 语义而不再打印帮助——--no-help真正否定了--help,因此 headless 运行会启动 agent 并以 exit 1 退出,真实 TTY 则打开交互式 TUI(base 打印帮助)。这些 argv 很生僻,行为上属于完整 parser 对齐(fail-closed 降级到慢路径),但对这 3 个 shape 确实是行为变化。其余 shape 在两条路径下都会打印 help(用exitProcess(false)的 yargs parser 验证;yargs 会在.strict()校验之前短路处理--help,所以连未知 flag 的 shape 也仍然 exit 0)。唯一差别是 help 的内容——fast path 的 help 少了qwen [query..] … [default]行和Positionals:段——本 PR 的 default-command commit 已修复。config.test.ts356/356 通过(此前"未验证 / 19 个既有失败"的说法已作废,那些失败是环境问题而非真实基线)。cli.test.ts+mcp/add.test.ts102/102。Type-check 与 ESLint 干净;类型错误集合与未改动分支做过 diff,确认没有引入新错误。CliArgs与 base 逐字节相同,所有string: true/coerce都在调用点保留,把deprecateOption移出$0builder 也已验证对 help 渲染无影响。argvSafeForFastPath、hasVersionToken、BASE_VALUE_FLAGS、KNOWN_FAST_PATH_FLAGS)并非 --approval-mode and --auth-type are accepted but missing fromqwen --help#8897 所必需——把VALUE_FLAGS保持在 base 集合就能零路由风险地修好该 issue。这里保留它是因为它同时修掉了上面三个 base bug,但 reviewer 要求拆分是合理的。关联 Issue
Fixes #8897。