Skip to content

fix(ci): clean review worktrees after cancellation - #8474

Merged
yiliang114 merged 15 commits into
mainfrom
codex/cleanup-review-worktrees
Aug 5, 2026
Merged

fix(ci): clean review worktrees after cancellation#8474
yiliang114 merged 15 commits into
mainfrom
codex/cleanup-review-worktrees

Conversation

@yiliang114

Copy link
Copy Markdown
Collaborator

What this PR does

Adds an always-run cleanup step to the PR review job and extends the CI pre-checkout cleanup to remove stale Git worktree registrations and qwen-review branches on reused self-hosted runners.

Why it's needed

Cancelled or timed-out reviews can leave review worktrees and branch registrations behind. A later CI checkout then fails with "cannot delete branch ... used by worktree", blocking unrelated PRs on the same runner.

Reviewer Test Plan

How to verify

Confirm that the review job cleanup runs with always() after success, failure, cancellation, and the internal review timeout path. Confirm that the CI pre-checkout step prunes missing worktrees, removes review worktrees, and deletes only qwen-review/* branches before checkout.

Evidence (Before & After)

N/A — workflow-only change.

Tested on

OS Status
🍏 macOS N/A
🪟 Windows N/A
🐧 Linux ✅ tested

Environment (optional)

node scripts/lint.js --actionlint and node scripts/lint.js --yamllint passed.

Risk & Scope

  • Main risk or tradeoff: Cleanup is intentionally limited to .qwen/tmp/review-pr-* worktrees and qwen-review/* branches.
  • Not validated / out of scope: Hard runner termination still relies on the next job's pre-checkout cleanup because no process callback can run after SIGKILL.
  • Breaking changes / migration notes: None.

Linked Issues

No linked issue.

中文说明

本 PR 做了什么

为 PR review job 增加始终执行的最终清理步骤,并扩展 CI checkout 前的清理逻辑,处理复用 self-hosted runner 上残留的 Git worktree 注册和 qwen-review 分支。

为什么需要

review 被取消或超时后,可能会留下 review worktree 和分支注册。后续 CI checkout 会报“cannot delete branch ... used by worktree”,从而阻塞同一 runner 上的其他 PR。

Reviewer Test Plan

如何验证

确认 review 成功、失败、取消以及内部 review 超时后,清理步骤都会通过 always() 执行;确认 CI checkout 前会清理缺失的 worktree、移除 review worktree,并且只删除 qwen-review/* 分支。

证据(前后对比)

不适用——仅修改 workflow。

测试环境

Linux:已通过 node scripts/lint.js --actionlintnode scripts/lint.js --yamllint

风险与范围

  • 主要风险或取舍:清理范围严格限制为 .qwen/tmp/review-pr-* worktree 和 qwen-review/* 分支。
  • 未验证/不在范围内:runner 被强制终止后无法执行进程内回调,这种情况依赖下一次任务 checkout 前的兜底清理。
  • 破坏性变更/迁移说明:无。

关联 Issue

无。

@qwen-code-ci-bot

qwen-code-ci-bot commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator

⚠️ Deferred approval not posted — the PR head moved (or the PR closed) after the review of d1f976a; approving now would attest to unreviewed code. Re-run @qwen-code /triage on the new head. finalize run

⚠️ 延迟审批未提交 —— 审查 d1f976a 之后 PR head 已变更(或 PR 已关闭),此时审批会为未审查的代码背书。请在新 head 上重新运行 @qwen-code /triage查看 finalize 运行

@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Thanks for the PR!

Template looks good ✓

Problem: observed, not theoretical. Cancelled/timed-out reviews leaving .qwen/tmp/review-pr-* worktrees and qwen-review/* branches behind is already documented in this repo — the CLI has process-level lease cleanup for the errored path (Session.ts), and the review workflow carries a pre-run Clean stale agent state step for exactly these leftovers. The gaps this PR closes are real: there is no post-run cleanup on the cancellation/timeout path, and non-review jobs (ci.yml) that land on the same reused runner have no cleanup at all before checkout. No linked issue, but the failure mode is concrete and already codified in-repo.

Direction: aligned — CI reliability on reused self-hosted runners; a leaked worktree registration blocks unrelated PRs via "cannot delete branch ... used by worktree". Workflow-only change, no product surface. CHANGELOG not applicable.

Size: 2 workflow files, +48/-0 (ci.yml +16, qwen-code-pr-review.yml +32). No core paths, no production code.

Approach: scope feels right. Two layers matching the two failure modes: an always() final step on the review job (catches cancellation/failure when the CLI's process cleanup is unreachable) plus a pre-checkout fallback in ci.yml (catches hard kills where even always() never runs). Cleanup is tightly scoped — only /.qwen/tmp/review-pr-* worktrees, refs/heads/qwen-review/* branches, and the review lease files — so blast radius on unrelated state is nil. It mirrors the patterns already in the repo's existing cleanup steps rather than inventing new ones.

Risk: no elevated risk signals — workflow files only, nothing matches the high-risk paths from the revert history.

Moving on to code review. 🔍

中文说明

感谢贡献!

模板完整 ✓

问题:真实存在,不是理论问题。review 被取消/超时后会残留 .qwen/tmp/review-pr-* worktree 和 qwen-review/* 分支——这一点仓库里已有记录:CLI 有进程级的 lease 清理(Session.ts),review workflow 也有运行前清理步骤(Clean stale agent state)。本 PR 补的是两个真实缺口:取消/超时路径没有运行后清理;非 review 的 job(ci.yml)在复用的 runner 上 checkout 前完全没有清理。虽然没有关联 issue,但失败模式具体且已在仓库中多次体现。

方向:对齐——复用 self-hosted runner 上的 CI 可靠性问题,残留的 worktree 注册会以 "cannot delete branch ... used by worktree" 阻塞无关 PR。仅改 workflow,不涉及产品逻辑。

规模:2 个 workflow 文件,+48/-0(ci.yml +16,qwen-code-pr-review.yml +32)。不涉及核心路径和生产代码。

方案:范围合理。两层清理对应两种失败模式:review job 末尾的 always() 步骤(覆盖 CLI 进程清理不可达的取消/失败场景)+ ci.yml checkout 前的兜底(覆盖连 always() 都不会执行的强制 kill 场景)。清理范围严格限定在 /.qwen/tmp/review-pr-* worktree、refs/heads/qwen-review/* 分支和 review lease 文件,不会误伤其他状态。写法复用了仓库现有清理步骤的模式。

风险:无升级风险信号——仅 workflow 文件,未命中 revert 历史中的高风险路径。

进入代码审查 🔍

Qwen Code · qwen3.8-max

Reviewed at d1f976a5c20f18abf9662109af2f7fdc0fd139f1 · re-run with @qwen-code /triage

@qwen-code-ci-bot

qwen-code-ci-bot commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator

Code review

I'd have approached this the same way: there is no reliable way to run cleanup after a hard kill, so the answer is two independent layers — an always() step at the end of the review job, and an idempotent pre-checkout sweep in ci.yml. The diff does exactly that, and I verified the three artifact patterns against the code that produces them: fetch-pr.ts creates the qwen-review/pr-<n> branch and the .qwen/tmp/review-pr-<n> worktree, and review-worktree-lease.ts writes qwen-review-lease-pr-<n>.json. That is exactly what the two cleanup blocks target — and nothing else, so blast radius on unrelated state is nil.

Things I checked specifically:

  • Placement: the new step is the last step of the review-pr job, gated with if: always() and bounded by timeout-minutes: 5 — it runs on success, failure, and cancellation, and can't hang the runner.
  • Ordering in ci.yml: worktree prune first (drops registrations for directories already wiped by the step's rm -rf .qwen), then force-remove any live review-pr-* worktrees, prune again, then delete the branches. By the time branch -D runs, no worktree still holds the branch — precisely the ordering that makes "cannot delete branch ... used by worktree" impossible.
  • Best-effort semantics: every command carries || true or a warning fallback, set -uo pipefail without -e, and both blocks guard on .git existing — cleanup never fails the job, and fresh hosted runners with no prior checkout short-circuit.
  • The follow-up commit is an improvement over the first: it drops a redundant trailing prune in ci.yml and adds an rm -rf .qwen/tmp/review-pr-* fallback behind git worktree remove --force, mirroring the existing Clean stale agent state step's approach.

Nothing blocking. One truly trivial nit: the ci.yml block lives inside a step named Clean stale .qwen before checkout, which now covers slightly more than .qwen. Not worth a re-push on its own.

Test evidence

This is a workflow-only change; the unit/integration suites don't exercise it. Two signals instead. First, this PR's own CI run executes the new code: same-repo branches route Test (ubuntu-latest, Node 22.x) onto the reused self-hosted ECS pool (ci.yml's runner selection), so the new ci.yml pre-checkout block runs during this very run — a shell syntax or runtime error in it would fail that job. Second, the review-job step is not executed by this PR's CI (a review is a separate pull_request_target workflow, currently still in its delay stage); its always() gating settles under static review — see the not-verified line below. No failures on the reviewed commit so far.

Not verified: a live cancellation-path run of the new always() step — that requires cancelling a review run mid-flight on a reused runner, which no CI check and no sandbox lane (/verify, /tmux exercise the built product, not workflow YAML) can produce. Operational confirmation comes with the next cancelled /review run (or a deliberate cancellation by a maintainer).

Final CI results for d1f976a (auto-updated by the triage finalize job after CI completed):

Check Conclusion
Test (ubuntu-latest, Node 22.x) ❌ failure
Classify PR ✅ success
Desktop Shell (ubuntu-22.04) ✅ success
Post Coverage Comment (ubuntu-latest, 22.x) ✅ success
review-address (8474, codex/cleanup-review-worktrees, 8474, 0, 2026-08-03T16:10:27Z, 100, 2026-08... ✅ success
review-scan ✅ success
route ✅ success
takeover-ack ✅ success
web-shell E2E Smoke (ubuntu-latest, Node 22.x) ✅ success

One row per check name (latest run); skipped checks omitted; failures sort first. / 每个检查名一行(取最新一次运行),省略 skipped,失败项排在最前。

Remaining entries on the head SHA (label, Remind on force-push, delay-automatic-review) are bot orchestration jobs, not PR CI.

中文说明

代码审查:方案与我的独立判断一致——硬 kill 之后无法可靠清理,所以用两层独立机制:review job 末尾的 always() 步骤 + ci.yml checkout 前的幂等兜底。三个清理目标的模式都与产生它们的代码核对过(fetch-pr.ts 创建 qwen-review/pr-<n> 分支和 .qwen/tmp/review-pr-<n> worktree,review-worktree-lease.tsqwen-review-lease-pr-<n>.json),清理范围精确,不会误伤其他状态。

重点核对:新步骤是 review-pr job 的最后一步,if: always() + timeout-minutes: 5;ci.yml 中先 prune 再 remove 再删分支,保证 branch -D 执行时没有 worktree 还占用着分支,从顺序上杜绝 "cannot delete branch ... used by worktree";所有命令都是尽力而为(|| true/警告兜底),清理不会让 job 失败;后续 commit 去掉了多余的尾部 prune 并加了 rm -rf 兜底,比第一版更好。

无阻塞问题。一个极小的命名 nit:ci.yml 的新逻辑放在名为 Clean stale .qwen before checkout 的步骤里,覆盖范围略超出 .qwen,不值得为此重新推送。

测试证据:仅 workflow 改动,单元/集成套件不会覆盖它。两个信号:其一,本 PR 自己的 CI 就在执行新代码——same-repo 分支的 Test (ubuntu-latest) job 会被路由到复用的 self-hosted ECS runner 池,新的 ci.yml pre-checkout 清理块在本次运行中实际执行,语法或运行时错误会直接挂掉该 job;其二,review job 的新步骤不在本 PR 的 CI 中执行(review 是独立的 pull_request_target workflow,目前还在延迟阶段),其 always() 门控由静态审查确认。目前该 commit 无失败检查。未验证:取消路径下 always() 步骤的实际执行——需要在复用 runner 上中途取消一次 review 运行,CI 检查和沙箱通道(/verify/tmux 针对构建产物而非 workflow YAML)都无法产生该证据,实际验证留给下一次被取消的 /review 运行。表格中被跳过的三个平台 job 是仅 merge queue 触发的设计使然,与本 PR 改动范围无关。

Qwen Code · qwen3.8-max

Reviewed at d1f976a5c20f18abf9662109af2f7fdc0fd139f1 · re-run with @qwen-code /triage

@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Confidence: 4/5 — clean, minimal fix that mirrors the repo's existing cleanup conventions; only a non-blocking naming nit and the inherent "first real cancellation proves it" gap remain.

Stepping back: the two-layer design is exactly what this failure mode needs — a hard kill cannot run any cleanup, so an always() step (cancellation/failure) plus a pre-checkout sweep (hard kill) are the two independent nets, and that's precisely what I'd have proposed before reading the diff. I checked every artifact the cleanup targets against the code that creates it (fetch-pr.ts, review-worktree-lease.ts), and the scope is exact: review worktrees, review branches, review lease files, nothing else. The follow-up commit improved the first version rather than churning it. The problem itself is real — this repo already documents interrupted reviews leaking exactly this state in three places (the CLI lease cleanup comment, the review workflow's pre-run cleanup, and the PR description's concrete error).

Reservations, minor: the step-name nit from the review above, and the fact that the cancellation path can't be exercised by any automated check — the first real cancelled review on a reused runner is the live test. Neither blocks.

Approval deferred until CI lands green on d1f976a5c20f18abf9662109af2f7fdc0fd139f1 — the Linux unit-test job is still running, and it is literally executing the new ci.yml pre-checkout block on a reused self-hosted runner.

中文说明

综合判断:两层设计正是这个失败模式需要的——硬 kill 无法执行任何清理,所以 always() 步骤(覆盖取消/失败)+ checkout 前兜底(覆盖硬 kill)是两张独立的网,这也是我在看 diff 之前会给出的方案。清理目标逐一与产生它们的代码(fetch-pr.tsreview-worktree-lease.ts)核对过,范围精确:只动 review worktree、review 分支和 lease 文件。后续 commit 是在改进第一版而不是瞎折腾。问题本身真实存在——仓库里已有三处记录表明中断的 review 会泄漏这些状态。

保留意见(均不阻塞):上面提到的步骤命名 nit;以及取消路径无法被任何自动化检查覆盖——第一次在复用 runner 上真实取消 review 就是它的现场验证。

批准推迟到 CI 在 d1f976a5c20f18abf9662109af2f7fdc0fd139f1 上全绿之后——Linux 单元测试 job 仍在运行,且它正在复用的 self-hosted runner 上实际执行新的 ci.yml pre-checkout 清理块。

Qwen Code · qwen3.8-max

Reviewed at d1f976a5c20f18abf9662109af2f7fdc0fd139f1 · re-run with @qwen-code /triage

@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Summary

Package Lines Statements Functions Branches
CLI 83.39% 83.39% 89.34% 82.76%
Core 87.65% 87.65% 89.24% 86.22%
CLI Package - Full Text Report
-------------------|---------|----------|---------|---------|-------------------
File               | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-------------------|---------|----------|---------|---------|-------------------
All files          |   83.39 |    82.76 |   89.34 |   83.39 |                   
 src               |   84.71 |    80.73 |   88.39 |   84.71 |                   
  cli.ts           |   95.64 |     83.8 |     100 |   95.64 | ...52-553,557-558 
  gemini.tsx       |   72.21 |    76.81 |   80.76 |   72.21 | ...1253-1257,1378 
  ...ractiveCli.ts |   86.49 |    80.46 |   87.93 |   86.49 | ...2926,2932,2994 
  ...liCommands.ts |   89.11 |    85.15 |      90 |   89.11 | ...90,507,541,663 
  ...ActiveAuth.ts |     100 |     87.5 |     100 |     100 | 66-80             
 ...cp-integration |   69.97 |    72.73 |   89.81 |   69.97 |                   
  acpAgent.ts      |   69.64 |     72.6 |   89.84 |   69.64 | ...65,11370-11372 
  authMethods.ts   |      92 |       60 |     100 |      92 | 33-34             
  errorCodes.ts    |       0 |        0 |       0 |       0 | 1-22              
  ...ion-skills.ts |     100 |    88.23 |     100 |     100 | 17,32             
  generation.ts    |    97.1 |    81.25 |     100 |    97.1 | 109,112           
  ...DirContext.ts |     100 |      100 |     100 |     100 |                   
 ...ration/service |   97.04 |    95.71 |   93.33 |   97.04 |                   
  filesystem.ts    |   97.04 |    95.71 |   93.33 |   97.04 | ...21-122,238-239 
 ...ration/session |   90.66 |    86.17 |   95.91 |   90.66 |                   
  Session.ts       |   89.99 |    85.02 |   95.21 |   89.99 | ...9882,9909-9913 
  ...entTracker.ts |    96.8 |    89.36 |      90 |    96.8 | 137-143,221       
  ...stop-guard.ts |     100 |    98.07 |     100 |     100 | 37,127            
  ...eplay-page.ts |    93.1 |    90.72 |     100 |    93.1 | 71,82-85,111-121  
  ...y-replayer.ts |   98.53 |    95.52 |     100 |   98.53 | 238-240           
  index.ts         |       0 |        0 |       0 |       0 | 1-40              
  ...ssionUtils.ts |   89.76 |    87.32 |     100 |   89.76 | ...54-270,326-328 
  tasksSnapshot.ts |    94.3 |     87.5 |     100 |    94.3 | 65-71             
  ...on-tracker.ts |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...ssion/emitters |   95.79 |    93.52 |   96.66 |   95.79 |                   
  ...ageEmitter.ts |   95.34 |    94.28 |     100 |   95.34 | 52-59             
  PlanEmitter.ts   |     100 |       90 |     100 |     100 | 66                
  base-emitter.ts  |   78.26 |       75 |     100 |   78.26 | 23-24,26-28       
  index.ts         |       0 |        0 |       0 |       0 | 1-10              
  ...ll-emitter.ts |   99.18 |    96.47 |     100 |   99.18 | 355-356           
 ...ession/rewrite |    91.8 |    89.13 |   94.44 |    91.8 |                   
  LlmRewriter.ts   |    82.4 |     86.2 |     100 |    82.4 | ...,88-89,166-170 
  ...Middleware.ts |   96.96 |    88.09 |     100 |   96.96 | 144,152-154       
  TurnBuffer.ts    |     100 |      100 |     100 |     100 |                   
  config.ts        |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 src/agent-view    |   89.03 |    81.37 |   89.09 |   89.03 |                   
  ...t-cli-argv.ts |     100 |      100 |     100 |     100 |                   
  protocol.ts      |     100 |      100 |     100 |     100 |                   
  ...sor-client.ts |   80.38 |    72.54 |   76.66 |   80.38 | ...22-626,652-656 
  ...or-process.ts |   96.61 |    89.47 |   84.61 |   96.61 | 129-130,150-151   
  ...sor-runner.ts |    84.9 |     75.6 |      85 |    84.9 | ...44,468,471-481 
  ...sor-server.ts |   85.71 |    83.06 |   95.45 |   85.71 | ...67-468,471-488 
  ...isor-store.ts |   97.73 |    81.16 |     100 |   97.73 | ...92,594,607,643 
  ...nal-bridge.ts |   93.98 |     91.3 |   83.33 |   93.98 | 228-238           
 src/commands      |    89.1 |    72.41 |   64.51 |    89.1 |                   
  auth.ts          |     100 |    83.33 |     100 |     100 | 11,14             
  channel.ts       |   55.55 |      100 |       0 |   55.55 | 18-22,30-40       
  extensions.tsx   |   96.77 |      100 |      50 |   96.77 | 39                
  hooks.tsx        |   66.66 |      100 |       0 |   66.66 | 20-24             
  mcp.ts           |   95.45 |      100 |      50 |   95.45 | 31                
  review.ts        |   98.55 |      100 |      50 |   98.55 | 80                
  serve.ts         |   86.68 |    66.66 |     100 |   86.68 | ...70-673,687-691 
  sessions.ts      |     100 |      100 |      50 |     100 |                   
  update.ts        |   98.13 |    94.44 |   66.66 |   98.13 | 82-83             
 ...mmands/channel |   88.29 |    87.65 |    90.3 |   88.29 |                   
  channel-cwd.ts   |     100 |      100 |     100 |     100 |                   
  ...l-registry.ts |      80 |    84.61 |      80 |      80 | 37-40,49-52,63-66 
  ...entry-path.ts |      75 |       50 |     100 |      75 | 8-9               
  config-utils.ts  |   95.87 |    96.35 |     100 |   95.87 | ...08-213,271-274 
  configure.ts     |    14.7 |      100 |       0 |    14.7 | 18-21,23-84       
  daemon-worker.ts |   93.89 |    85.39 |   94.11 |   93.89 | ...1209,1216-1217 
  loop-runtime.ts  |   91.66 |      100 |      50 |   91.66 | 15,22             
  ...classifier.ts |   98.49 |    96.51 |     100 |   98.49 | 115-116,161       
  ...tact-store.ts |   93.51 |    87.65 |     100 |   93.51 | ...71,288-289,337 
  pairing.ts       |   72.85 |      100 |      50 |   72.85 | 22-28,57-68       
  pidfile.ts       |   95.55 |       90 |     100 |   95.55 | ...50-251,315-316 
  proxy.ts         |     100 |      100 |     100 |     100 |                   
  reload.ts        |    77.5 |    86.95 |      75 |    77.5 | 72-84,93-97       
  runtime.ts       |   82.43 |    86.44 |     100 |   82.43 | ...87-191,251-253 
  set.ts           |   75.72 |    85.71 |      50 |   75.72 | 65-83,111-116     
  start.ts         |    85.8 |    82.17 |      88 |    85.8 | ...85,591-594,606 
  ...ure-format.ts |   93.65 |    82.45 |     100 |   93.65 | ...42,48-49,74-75 
  status.ts        |   78.57 |    59.25 |   66.66 |   78.57 | ...36-137,150-161 
  stop.ts          |   57.83 |    82.35 |      50 |   57.83 | ...3,74-76,85-111 
 ...nds/extensions |   88.82 |    87.64 |   87.09 |   88.82 |                   
  consent.ts       |   72.53 |       90 |   42.85 |   72.53 | ...86-142,157-163 
  disable.ts       |     100 |       90 |     100 |     100 | 30                
  enable.ts        |     100 |    91.66 |     100 |     100 | 38                
  install.ts       |   82.95 |    81.57 |      75 |   82.95 | ...96-199,202-211 
  link.ts          |     100 |      100 |     100 |     100 |                   
  list.ts          |     100 |     87.5 |     100 |     100 | 18                
  new.ts           |     100 |      100 |     100 |     100 |                   
  settings.ts      |   99.15 |      100 |   83.33 |   99.15 | 151               
  sources.ts       |   93.42 |    87.09 |   92.85 |   93.42 | ...4-66,96-98,167 
  uninstall.ts     |   74.57 |       40 |   66.66 |   74.57 | 45-47,60-67,70-73 
  update.ts        |   96.71 |    97.05 |     100 |   96.71 | 114-118           
  utils.ts         |      75 |    53.84 |     100 |      75 | ...27-131,133-137 
 ...les/mcp-server |       0 |        0 |       0 |       0 |                   
  example.ts       |       0 |        0 |       0 |       0 | 1-60              
 ...amples/starter |       0 |        0 |       0 |       0 |                   
  example.ts       |       0 |        0 |       0 |       0 | 1-64              
 src/commands/mcp  |   90.17 |    84.39 |   83.33 |   90.17 |                   
  add.ts           |    99.3 |    96.07 |     100 |    99.3 | 154-155           
  approve.ts       |   76.19 |     87.5 |   66.66 |   76.19 | ...,89-99,114-124 
  list.ts          |   92.59 |    83.87 |      80 |   92.59 | ...62-164,180-181 
  reconnect.ts     |   78.85 |    66.66 |   85.71 |   78.85 | 42-55,169-191     
  remove.ts        |     100 |       80 |     100 |     100 | 21-25             
 ...ommands/review |   85.74 |    87.26 |   87.07 |   85.74 |                   
  agent-prompt.ts  |   90.89 |    92.78 |      96 |   90.89 | ...1311,1781-1850 
  base-tree.ts     |   74.87 |    79.16 |   77.77 |   74.87 | ...29-350,352-365 
  capture-local.ts |   68.57 |     90.9 |      75 |   68.57 | 107-111,158-189   
  ...k-coverage.ts |   46.92 |    13.33 |   66.66 |   46.92 | ...35-240,253-263 
  cleanup.ts       |   89.12 |    82.22 |   83.33 |   89.12 | ...99-504,506-507 
  ...ent-status.ts |   93.03 |    83.87 |   83.33 |   93.03 | 291,531-551       
  ...ose-review.ts |   95.77 |    91.19 |   95.65 |   95.77 | ...1615,1643-1665 
  drive.ts         |   72.22 |    88.88 |   72.72 |   72.22 | ...34-469,473-487 
  extract-step.ts  |   91.36 |    90.62 |   88.88 |   91.36 | ...90-707,714-729 
  fetch-pr.ts      |    76.7 |    68.75 |   63.63 |    76.7 | ...95,417,450-455 
  findings.ts      |   89.35 |    89.13 |   95.45 |   89.35 | ...15-918,927-928 
  load-rules.ts    |   26.41 |      100 |   16.66 |   26.41 | ...41-153,155-156 
  mock-provider.ts |   95.44 |    90.25 |   89.47 |   95.44 | 145,690-709       
  parse-args.ts    |   99.32 |    96.42 |     100 |   99.32 | 400,473           
  plan-diff.ts     |   64.04 |      100 |   66.66 |   64.04 | 127-163           
  pr-context.ts    |   81.77 |    80.86 |   92.85 |   81.77 | ...1043,1072-1074 
  presubmit.ts     |   83.75 |    92.72 |   88.88 |   83.75 | ...77-578,655-685 
  ...ish-assets.ts |   76.72 |    81.92 |   71.42 |   76.72 | ...76-522,524-535 
  ...ve-anchors.ts |   77.77 |    88.88 |      75 |   77.77 | ...77-182,194-211 
  run.ts           |   82.16 |    87.12 |   91.66 |   82.16 | ...52,468-516,529 
  save-artifact.ts |   79.13 |    79.68 |   88.23 |   79.13 | ...50-381,383-386 
  script-lint.ts   |   81.14 |    79.23 |   88.88 |   81.14 | ...59-773,775-797 
  submit.ts        |   80.82 |    81.96 |      80 |   80.82 | ...14-550,552-553 
  test-delta.ts    |   87.13 |    91.46 |      75 |   87.13 | 206-237,477-485   
  test-efficacy.ts |   88.01 |    84.12 |   95.45 |   88.01 | ...2598,2606-2626 
  test-plan.ts     |    90.9 |       92 |   89.47 |    90.9 | ...88-789,853-870 
 ...w/__fixtures__ |     100 |      100 |     100 |     100 |                   
  ...r-default.mjs |     100 |      100 |     100 |     100 |                   
  ...der-empty.mjs |     100 |      100 |     100 |     100 |                   
  ...der-named.mjs |     100 |      100 |     100 |     100 |                   
 ...nds/review/lib |   96.18 |    94.04 |   96.34 |   96.18 |                   
  agent-briefs.ts  |    98.8 |      100 |       0 |    98.8 | 653-654           
  anchors.ts       |     100 |    94.79 |     100 |     100 | ...33,169,178,225 
  assets.ts        |     100 |      100 |     100 |     100 |                   
  authorization.ts |    92.4 |    92.59 |     100 |    92.4 | 127-133           
  budget.ts        |     100 |      100 |     100 |     100 |                   
  coverage.ts      |    95.7 |    94.64 |   95.45 |    95.7 | ...12,349,458-475 
  diff-flags.ts    |     100 |        0 |     100 |     100 | 63                
  diff-plan.ts     |   98.73 |    93.01 |     100 |   98.73 | ...41,264,290-291 
  effort.ts        |     100 |      100 |     100 |     100 |                   
  gh.ts            |   85.92 |    91.11 |   73.33 |   85.92 | ...32,269-270,297 
  git.ts           |   97.64 |    95.65 |     100 |   97.64 | 180-181           
  heavy.ts         |     100 |      100 |     100 |     100 |                   
  inline-counts.ts |     100 |      100 |     100 |     100 |                   
  ledger.ts        |     100 |      100 |     100 |     100 |                   
  local-diff.ts    |    84.4 |    88.46 |     100 |    84.4 | ...63-473,475-483 
  merge-base.ts    |     100 |      100 |     100 |     100 |                   
  path-rules.ts    |     100 |      100 |     100 |     100 |                   
  paths.ts         |     100 |     87.5 |     100 |     100 | 92                
  prompt-record.ts |   94.73 |    88.23 |     100 |   94.73 | ...28,151-152,156 
  receipt.ts       |     100 |      100 |     100 |     100 |                   
  report.ts        |   94.68 |    93.75 |     100 |   94.68 | 187-191           
  roster.ts        |     100 |    94.23 |     100 |     100 | 143,161,206       
  shell-quote.ts   |     100 |      100 |     100 |     100 |                   
  test-utils.ts    |     100 |      100 |     100 |     100 |                   
  transcripts.ts   |   96.27 |    93.18 |     100 |   96.27 | ...83,269-270,294 
  workspaces.ts    |   98.88 |    92.39 |     100 |   98.88 | 212-213           
  worktree.ts      |     100 |      100 |     100 |     100 |                   
 ...mands/sessions |   91.56 |    86.95 |   83.33 |   91.56 |                   
  common.ts        |     100 |      100 |     100 |     100 |                   
  list.ts          |   90.96 |    86.66 |   81.81 |   90.96 | 208-219,221-222   
 src/config        |   94.38 |    88.94 |   95.63 |   94.38 |                   
  auth.ts          |   89.35 |    83.56 |     100 |   89.35 | ...97-298,314-315 
  ...eMcpImport.ts |   87.91 |    81.52 |     100 |   87.91 | ...63-371,453-454 
  compile-cache.ts |     100 |      100 |     100 |     100 |                   
  config.ts        |   88.92 |    88.73 |   83.78 |   88.92 | ...2446,2448-2456 
  ...cy-monitor.ts |   88.75 |    76.19 |     100 |   88.75 | ...3,90-92,98,101 
  ...ust-policy.ts |   83.04 |    88.28 |     100 |   83.04 | ...39,253,352-353 
  ...heme-names.ts |     100 |      100 |     100 |     100 |                   
  environment.ts   |   94.33 |    89.61 |   94.73 |   94.33 | ...35-639,655-656 
  ...le-watcher.ts |   90.86 |    83.65 |   95.83 |   90.86 | ...23-325,370,418 
  ...resh-state.ts |   90.57 |    97.29 |   93.75 |   90.57 | 137-142,146-152   
  ...ime-reload.ts |     100 |    69.69 |     100 |     100 | ...12-113,122-123 
  hot-reload.ts    |     100 |    89.13 |     100 |     100 | 47,172-178,238    
  keyBindings.ts   |   97.43 |       50 |     100 |   97.43 | 236-239           
  ...ngsAdapter.ts |     100 |    94.11 |     100 |     100 | 64                
  ...ig-watcher.ts |   95.17 |    83.05 |     100 |   95.17 | ...78,200,292-293 
  ...er-secrets.ts |   98.97 |    96.96 |     100 |   98.97 | 85                
  mcpApprovals.ts  |   96.55 |    95.55 |     100 |   96.55 | 223-224,229-231   
  mcpJson.ts       |     100 |      100 |     100 |     100 |                   
  mcpServers.ts    |   92.85 |     87.5 |     100 |   92.85 | 46-47             
  ...idersScope.ts |      95 |    94.73 |     100 |      95 | 11-12             
  ...abledTools.ts |     100 |      100 |     100 |     100 |                   
  ...comparison.ts |     100 |      100 |     100 |     100 |                   
  ...n-settings.ts |   99.15 |    93.75 |     100 |   99.15 | 63                
  sandboxConfig.ts |   61.64 |    71.87 |   66.66 |   61.64 | ...54-68,73,77-89 
  ...ings-cache.ts |   98.26 |    97.14 |     100 |   98.26 | 201-202           
  settings.ts      |   90.99 |     92.3 |      90 |   90.99 | ...1006,1008-1009 
  ...ingsSchema.ts |     100 |      100 |     100 |     100 |                   
  ...ngsWatcher.ts |   95.54 |    88.34 |     100 |   95.54 | ...28,277-278,293 
  ...d-env-keys.ts |     100 |      100 |     100 |     100 |                   
  ...l-settings.ts |     100 |      100 |     100 |     100 |                   
  ...paths-lite.ts |   89.47 |       88 |     100 |   89.47 | 43-44,53-54,56-57 
  ...tedFolders.ts |   93.35 |    94.11 |     100 |   93.35 | ...90-391,427-438 
 ...nfig/migration |   95.23 |    77.77 |   83.33 |   95.23 |                   
  index.ts         |   95.65 |     87.5 |     100 |   95.65 | 117-118           
  scheduler.ts     |   96.55 |    77.77 |     100 |   96.55 | 19-20             
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 ...ation/versions |   94.91 |      100 |     100 |   94.91 |                   
  ...-v2-shared.ts |     100 |      100 |     100 |     100 |                   
  v1-to-v2.ts      |   81.75 |      100 |     100 |   81.75 | ...28-229,231-247 
  v2-to-v3.ts      |     100 |      100 |     100 |     100 |                   
  v3-to-v4.ts      |     100 |      100 |     100 |     100 |                   
  v5-to-v4.ts      |      96 |      100 |     100 |      96 | 94-95,99          
 src/core          |     100 |      100 |     100 |     100 |                   
  auth.ts          |     100 |      100 |     100 |     100 |                   
  initializer.ts   |     100 |      100 |     100 |     100 |                   
  theme.ts         |     100 |      100 |     100 |     100 |                   
 src/dualOutput    |    71.8 |    70.31 |   66.66 |    71.8 |                   
  ...tputBridge.ts |   71.95 |    70.96 |   68.42 |   71.95 | ...08-409,417-420 
  ...utContext.tsx |     100 |      100 |     100 |     100 |                   
  index.ts         |       0 |        0 |       0 |       0 | 1-8               
 src/export        |       0 |        0 |       0 |       0 |                   
  index.ts         |       0 |        0 |       0 |       0 | 1-7               
 src/generated     |     100 |      100 |     100 |     100 |                   
  git-commit.ts    |     100 |      100 |     100 |     100 |                   
 src/hooks         |     100 |      100 |     100 |     100 |                   
  ...elete-hook.ts |     100 |      100 |     100 |     100 |                   
 src/i18n          |   85.98 |    81.92 |   89.65 |   85.98 |                   
  index.ts         |   73.45 |    77.77 |      90 |   73.45 | ...70-271,294-299 
  languages.ts     |   93.07 |     92.3 |   85.71 |   93.07 | ...35,164-169,184 
  ...nslateKeys.ts |     100 |      100 |     100 |     100 |                   
  ...lationDict.ts |   93.33 |    66.66 |     100 |   93.33 | 15                
 src/i18n/locales  |     100 |      100 |     100 |     100 |                   
  ca.js            |     100 |      100 |     100 |     100 |                   
  de.js            |     100 |      100 |     100 |     100 |                   
  en.js            |     100 |      100 |     100 |     100 |                   
  fr.js            |     100 |      100 |     100 |     100 |                   
  ja.js            |     100 |      100 |     100 |     100 |                   
  pt.js            |     100 |      100 |     100 |     100 |                   
  ru.js            |     100 |      100 |     100 |     100 |                   
  zh-TW.js         |     100 |      100 |     100 |     100 |                   
  zh.js            |     100 |      100 |     100 |     100 |                   
 ...nonInteractive |      80 |    76.31 |   81.35 |      80 |                   
  session.ts       |   84.08 |    75.27 |   93.61 |   84.08 | ...1007,1016-1026 
  types.ts         |    42.5 |      100 |   33.33 |    42.5 | ...31-632,635-636 
 ...active/control |   75.63 |    89.09 |      80 |   75.63 |                   
  ...rolContext.ts |    6.45 |        0 |       0 |    6.45 | 56-95             
  ...Dispatcher.ts |   91.79 |    92.45 |   88.88 |   91.79 | ...49-367,387,390 
  ...rolService.ts |    6.89 |        0 |       0 |    6.89 | 46-188            
 ...ol/controllers |   42.27 |    64.66 |   48.64 |   42.27 |                   
  ...Controller.ts |   39.49 |      100 |      80 |   39.49 | 88-92,127-210     
  ...Controller.ts |       0 |        0 |       0 |       0 | 1-56              
  ...Controller.ts |   53.96 |    65.71 |   58.33 |   53.96 | ...37-642,644-649 
  ...Controller.ts |   14.06 |      100 |       0 |   14.06 | ...82-117,130-133 
  ...Controller.ts |   37.92 |    60.71 |   46.66 |   37.92 | ...41-653,662-691 
 .../control/types |       0 |        0 |       0 |       0 |                   
  serviceAPIs.ts   |       0 |        0 |       0 |       0 | 1                 
 ...Interactive/io |    98.1 |    94.13 |   95.23 |    98.1 |                   
  ...putAdapter.ts |   97.98 |     93.2 |   98.07 |   97.98 | ...1415,1431-1432 
  ...putAdapter.ts |      96 |    91.66 |   85.71 |      96 | 51-52             
  ...nputReader.ts |     100 |    94.73 |     100 |     100 | 67                
  ...putAdapter.ts |   98.49 |      100 |   90.47 |   98.49 | 85-86,126-127     
  index.ts         |     100 |      100 |     100 |     100 |                   
 src/patches       |       0 |        0 |       0 |       0 |                   
  is-in-ci.ts      |       0 |        0 |       0 |       0 | 1-17              
 src/remoteInput   |   87.31 |    75.32 |   88.23 |   87.31 |                   
  ...utContext.tsx |     100 |      100 |     100 |     100 |                   
  ...putWatcher.ts |   88.01 |       76 |   93.33 |   88.01 | ...49-350,361-364 
  index.ts         |       0 |        0 |       0 |       0 | 1-8               
 src/runtime       |   99.61 |    95.04 |     100 |   99.61 |                   
  ...livery-ipc.ts |     100 |     90.9 |     100 |     100 | 94,106,134        
  ...l-delivery.ts |     100 |      100 |     100 |     100 |                   
  cpu-percent.ts   |     100 |      100 |     100 |     100 |                   
  ...erver-name.ts |     100 |      100 |     100 |     100 |                   
  ...-constants.ts |     100 |      100 |     100 |     100 |                   
  ...-summaries.ts |   86.66 |       50 |     100 |   86.66 | 11,19             
  ...ber-errors.ts |     100 |    95.32 |     100 |     100 | 53,93-94,172,192  
  ...ls-mapping.ts |     100 |      100 |     100 |     100 |                   
 src/serve         |   87.13 |     83.4 |   90.83 |   87.13 |                   
  ...tp-enabled.ts |     100 |      100 |     100 |     100 |                   
  ...ion-bridge.ts |     100 |      100 |     100 |     100 |                   
  auth.ts          |    93.4 |    92.95 |     100 |    93.4 | ...19-320,323-325 
  ...em-adapter.ts |     100 |      100 |     100 |     100 |                   
  capabilities.ts  |     100 |    97.95 |     100 |     100 | 650               
  ...cp-command.ts |     100 |      100 |     100 |     100 |                   
  ...horization.ts |   92.79 |    93.33 |    87.5 |   92.79 | 75-80,135-136     
  ...op-mcp-ipc.ts |   81.06 |    73.68 |   94.11 |   81.06 | ...37-242,267,289 
  ...nt-service.ts |   93.89 |    86.61 |     100 |   93.89 | ...66-468,475,477 
  ...-selection.ts |     100 |      100 |     100 |     100 |                   
  ...ings-store.ts |   86.06 |     92.2 |   95.83 |   86.06 | ...94-206,372-375 
  ...ebhook-ipc.ts |    98.5 |    86.66 |     100 |    98.5 | 47                
  ...iagnostics.ts |     100 |      100 |     100 |     100 |                   
  ...worker-env.ts |     100 |      100 |     100 |     100 |                   
  ...rker-group.ts |   87.27 |     85.2 |     100 |   87.27 | ...10,816-820,838 
  ...er-manager.ts |   89.39 |    83.88 |   93.33 |   89.39 | ...98,711,722-724 
  ...tartup-ipc.ts |   97.72 |    96.66 |     100 |   97.72 | 88-89             
  ...supervisor.ts |   92.41 |    84.44 |    97.1 |   92.41 | ...1460,1514-1518 
  ...e-grouping.ts |     100 |    94.11 |     100 |     100 | 69,132            
  core-runtime.ts  |     100 |      100 |     100 |     100 |                   
  ...ub-session.ts |   92.19 |    78.31 |     100 |   92.19 | ...60-469,494,532 
  daemon-logger.ts |    82.2 |    77.26 |   91.76 |    82.2 | ...1720,1747-1753 
  ...trics-ring.ts |     100 |      100 |     100 |     100 |                   
  ...s-provider.ts |   68.04 |    52.77 |     100 |   68.04 | ...44-249,282-290 
  daemon-status.ts |   98.47 |    90.59 |     100 |   98.47 | ...1197,1199-1200 
  debug-mode.ts    |     100 |      100 |     100 |     100 |                   
  demo.ts          |     100 |      100 |     100 |     100 |                   
  env-snapshot.ts  |   93.37 |    85.18 |     100 |   93.37 | 114-117,195-202   
  ...-scheduler.ts |   87.34 |    83.87 |     100 |   87.34 | 33-36,48-50,79-81 
  ...-path-argv.ts |     100 |      100 |     100 |     100 |                   
  ...h-settings.ts |   94.41 |    88.75 |     100 |   94.41 | ...24,702,718,728 
  fast-path.ts     |   90.61 |    81.25 |   95.45 |   90.61 | ...02-511,577-578 
  ...ration-sse.ts |   42.55 |    33.33 |     100 |   42.55 | 23-24,30,33-56    
  health-query.ts  |     100 |      100 |     100 |     100 |                   
  index.ts         |       0 |        0 |       0 |       0 | 1-143             
  ...e-observer.ts |   89.89 |    83.24 |      96 |   89.89 | ...11-512,541-543 
  ...back-binds.ts |     100 |    88.88 |     100 |     100 | 32                
  ...-workspace.ts |    90.9 |    85.71 |     100 |    90.9 | ...27-128,139-140 
  ...iders-edit.ts |     100 |    82.14 |     100 |     100 | 58-60,65,81       
  ...ory-picker.ts |     100 |    86.95 |     100 |     100 | 36,66,92          
  ...sion-audit.ts |     100 |      100 |   93.33 |     100 |                   
  rate-limit.ts    |   92.77 |    88.42 |     100 |   92.77 | ...93-295,307-309 
  ...qwen-serve.ts |   82.84 |    79.62 |   74.25 |   82.84 | ...6821,6826-6827 
  ...tup-errors.ts |     100 |      100 |     100 |     100 |                   
  ...-keepalive.ts |   94.19 |    88.57 |     100 |   94.19 | ...26,530-531,571 
  ...-lifecycle.ts |     100 |      100 |     100 |     100 |                   
  server.ts        |   93.57 |    93.29 |   74.02 |   93.57 | ...2148,2169-2173 
  ...on-helpers.ts |     100 |      100 |     100 |     100 |                   
  ...t-event-id.ts |     100 |    95.23 |     100 |     100 | 12                
  ...-admission.ts |   98.71 |    89.65 |     100 |   98.71 | 68                
  types.ts         |     100 |      100 |     100 |     100 |                   
  ...ion-limits.ts |     100 |      100 |     100 |     100 |                   
  ...t-sessions.ts |    93.3 |    76.83 |     100 |    93.3 | ...13,816,829-831 
  ...l-resolver.ts |   90.32 |    66.66 |     100 |   90.32 | 16,45-46          
  ...ell-static.ts |   91.07 |    86.66 |     100 |   91.07 | ...79-182,216-219 
  ...ace-agents.ts |   66.13 |    70.57 |   92.68 |   66.13 | ...2246,2256-2266 
  ...generation.ts |    95.4 |    82.35 |   66.66 |    95.4 | 55-56,78,92       
  ...-git-state.ts |     100 |    91.93 |    90.9 |     100 | 161,172,202,265   
  ...ace-inputs.ts |     100 |      100 |     100 |     100 |                   
  ...ace-memory.ts |      83 |    74.54 |     100 |      83 | ...30-537,597-604 
  ...ers-status.ts |   98.58 |       79 |     100 |   98.58 | 106,134,174,177   
  ...tion-store.ts |   89.67 |    88.27 |   92.59 |   89.67 | ...91-400,411-414 
  ...e-registry.ts |   93.89 |     87.5 |     100 |   93.89 | ...18-519,525-526 
  ...e-remember.ts |   98.23 |    92.51 |     100 |   98.23 | ...36,340-345,386 
  ...te-runtime.ts |   83.98 |    90.29 |     100 |   83.98 | ...48-156,216-237 
  ...me-storage.ts |     100 |      100 |     100 |     100 |                   
  ...management.ts |   72.63 |    72.72 |      96 |   72.63 | ...88-889,896-900 
  ...lls-status.ts |     100 |    95.45 |     100 |     100 | 152               
  ...reconciler.ts |    91.6 |     83.9 |     100 |    91.6 | ...70-272,305-306 
 ...serve/acp-http |   77.04 |    78.33 |   93.26 |   77.04 |                   
  ...r-registry.ts |   96.92 |    94.87 |     100 |   96.92 | 184-187           
  client-mcp-ws.ts |   54.85 |    58.62 |   72.72 |   54.85 | ...99-300,304-305 
  ...n-registry.ts |    98.2 |    88.62 |     100 |    98.2 | 1015,1041-1052    
  dispatch.ts      |   71.44 |    73.89 |   95.34 |   71.44 | ...4733,4781-4787 
  index.ts         |   81.93 |    79.92 |    90.9 |   81.93 | ...2291,2375-2376 
  json-rpc.ts      |     100 |    96.96 |     100 |     100 | 92                
  safe-ws-send.ts  |   52.94 |    71.42 |     100 |   52.94 | 33-42,47-55       
  sse-stream.ts    |   93.96 |    88.57 |   84.61 |   93.96 | ...57-159,161-163 
  ...ort-stream.ts |       0 |        0 |       0 |       0 | 1                 
  ws-stream.ts     |   91.86 |       80 |     100 |   91.86 | 45,50,96,100-103  
 src/serve/auth    |   86.86 |     79.7 |   93.87 |   86.86 |                   
  device-flow.ts   |   96.35 |    80.57 |   97.61 |   96.35 | ...1358,1453,1519 
  ...w-provider.ts |   44.24 |    74.07 |   71.42 |   44.24 | ...23-284,297,301 
 ...rve/cdp-tunnel |   87.73 |    76.21 |    97.5 |   87.73 |                   
  ...r-emulator.ts |   93.27 |    77.77 |     100 |   93.27 | ...53-256,282-283 
  ...verse-link.ts |      88 |    76.19 |     100 |      88 | ...28-329,420-423 
  ...l-registry.ts |     100 |      100 |     100 |     100 |                   
  cdp-ws.ts        |   76.28 |    61.29 |    87.5 |   76.28 | ...13-217,223-228 
 ...nel/acceptance |    6.12 |    57.89 |   46.15 |    6.12 |                   
  ...helpers.d.mts |       0 |        0 |       0 |       0 | 1                 
  ...e-helpers.mjs |   97.64 |    70.96 |     100 |   97.64 | 22-23             
  ...mcp-smoke.mjs |       0 |        0 |       0 |       0 | 1-124             
  ...cceptance.mjs |       0 |        0 |       0 |       0 | 1-473             
  ...re-server.mjs |       0 |        0 |       0 |       0 | 1-59              
  ...ols-smoke.mjs |       0 |        0 |       0 |       0 | 1-268             
  real-tab.mjs     |       0 |        0 |       0 |       0 | 1-218             
  ...al-chrome.mjs |       0 |        0 |       0 |       0 | 1-223             
 src/serve/fs      |    86.4 |    80.74 |     100 |    86.4 |                   
  audit.ts         |     100 |    96.15 |     100 |     100 | 204               
  errors.ts        |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...x-registry.ts |     100 |      100 |     100 |     100 |                   
  paths.ts         |   77.64 |     73.8 |     100 |   77.64 | ...65,594-598,611 
  policy.ts        |   90.42 |    89.18 |     100 |   90.42 | 161-169           
  text-cursor.ts   |   88.23 |       90 |     100 |   88.23 | 74-77,92-95       
  ...ile-system.ts |   86.17 |    79.55 |     100 |   86.17 | ...2506,2516-2517 
 src/serve/routes  |   85.54 |    79.53 |   95.47 |   85.54 |                   
  a2ui-action.ts   |   96.84 |     88.5 |    87.5 |   96.84 | ...70-272,309-311 
  capabilities.ts  |     100 |      100 |     100 |     100 |                   
  ...nel-notify.ts |   85.22 |       88 |     100 |   85.22 | ...,83-87,103-104 
  ...l-webhooks.ts |   93.56 |    84.09 |     100 |   93.56 | ...42,292,332,334 
  daemon-status.ts |   85.45 |    83.33 |     100 |   85.45 | 98-105            
  goals.ts         |   98.92 |     90.9 |     100 |   98.92 | 146               
  health-demo.ts   |   94.73 |     86.2 |     100 |   94.73 | 62-66,154         
  permission.ts    |     100 |     92.3 |     100 |     100 | 50,98             
  ...uled-tasks.ts |   87.12 |    82.73 |   92.59 |   87.12 | ...1263,1306-1307 
  ...on-runtime.ts |     100 |    90.47 |     100 |     100 | 58,94             
  session.ts       |   85.17 |     81.7 |   95.16 |   85.17 | ...4633,4635-4636 
  sse-events.ts    |   84.45 |     87.5 |   77.77 |   84.45 | ...36,453-456,485 
  usage-stats.ts   |     100 |    95.45 |     100 |     100 | 118               
  ...space-auth.ts |   85.55 |    75.64 |     100 |   85.55 | ...21-326,331,345 
  ...el-control.ts |   86.26 |    78.94 |     100 |   86.26 | ...17-318,339-347 
  ...management.ts |   90.19 |    77.68 |     100 |   90.19 | ...47-448,467-468 
  ...d-contacts.ts |     100 |      100 |     100 |     100 |                   
  ...controller.ts |   83.09 |       79 |      90 |   83.09 | ...1032,1038,1041 
  ...extensions.ts |   87.23 |    72.76 |   94.11 |   87.23 | ...1826,1871-1872 
  ...-file-read.ts |      91 |    80.91 |     100 |      91 | ...20-621,624-625 
  ...file-write.ts |   84.44 |    64.51 |     100 |   84.44 | ...73-275,355-357 
  ...t-branches.ts |   75.43 |    66.66 |     100 |   75.43 | ...13-618,627-634 
  ...e-git-diff.ts |   97.32 |    90.56 |     100 |   97.32 | 161-162,189-191   
  ...ce-git-log.ts |     100 |    93.18 |     100 |     100 | 52,77,188         
  workspace-git.ts |   77.08 |    89.65 |     100 |   77.08 | 97-118            
  ...github-prs.ts |   88.26 |    63.46 |     100 |   88.26 | ...38-239,264-265 
  ...-lifecycle.ts |   95.23 |    75.75 |     100 |   95.23 | ...50-151,186-187 
  ...management.ts |   88.22 |    85.29 |     100 |   88.22 | ...1546,1566-1571 
  ...cp-control.ts |    73.2 |    67.54 |   85.71 |    73.2 | ...27-633,644-645 
  ...ace-models.ts |   95.53 |    89.74 |     100 |   95.53 | ...52-157,296-297 
  ...ermissions.ts |    77.9 |    72.41 |     100 |    77.9 | ...69-277,298-316 
  ...e-settings.ts |    74.9 |    70.31 |     100 |    74.9 | ...49-660,666-667 
  ...tup-github.ts |   77.97 |    70.58 |   84.21 |   77.97 | ...46-352,397-398 
  ...ace-skills.ts |   69.87 |    78.12 |     100 |   69.87 | ...59-284,290-324 
  ...ace-status.ts |   82.94 |     74.5 |     100 |   82.94 | ...84-486,490-491 
  ...pace-tools.ts |   75.94 |    69.69 |   66.66 |   75.94 | ...59-164,193-194 
  ...pace-trust.ts |   78.42 |    64.78 |      80 |   78.42 | ...31-336,344-345 
  ...pace-voice.ts |   91.33 |    80.92 |     100 |   91.33 | ...70-673,676-678 
 src/serve/server  |   90.71 |    89.17 |   96.55 |   90.71 |                   
  access-log.ts    |   98.68 |     97.1 |     100 |   98.68 | 115,186           
  ...er-helpers.ts |   63.82 |    77.96 |   81.81 |   63.82 | ...16,330,332-347 
  ...w-registry.ts |    98.8 |    81.81 |     100 |    98.8 | 107               
  ...r-handlers.ts |   97.29 |       75 |     100 |   97.29 | 17                
  ...r-response.ts |   85.66 |    76.83 |     100 |   85.66 | ...02,719,782-791 
  fs-factory.ts    |     100 |    92.59 |     100 |     100 | 34,42,103,159     
  ...branch-ops.ts |     100 |      100 |     100 |     100 |                   
  ...t-deadline.ts |     100 |      100 |     100 |     100 |                   
  ...iter-setup.ts |      65 |    73.33 |   33.33 |      65 | 30-35,38-43,47-48 
  ...st-helpers.ts |   95.11 |    95.19 |     100 |   95.11 | ...65-167,422-427 
  self-origin.ts   |   76.19 |       80 |     100 |   76.19 | 45-54             
  ...e-features.ts |   94.81 |    90.32 |     100 |   94.81 | 175-181           
  ...on-archive.ts |   89.55 |    87.78 |   97.14 |   89.55 | ...32-836,888-889 
  ...ion-export.ts |     100 |    94.44 |     100 |     100 | 64                
  session-list.ts  |   93.55 |    91.01 |     100 |   93.55 | ...79,681-687,827 
  telemetry.ts     |   99.02 |    97.44 |     100 |   99.02 | ...25,639,781-783 
 src/serve/voice   |   83.35 |    92.22 |   90.47 |   83.35 |                   
  ...ice-config.ts |   84.61 |       30 |     100 |   84.61 | 90-99,103-104     
  voice-ws.ts      |   77.16 |    94.73 |   83.33 |   77.16 | ...68,483,521-523 
  ...oordinator.ts |     100 |    98.21 |     100 |     100 | 176               
 ...kspace-service |   89.11 |    86.15 |   90.69 |   89.11 |                   
  index.ts         |   88.66 |    85.77 |   89.47 |   88.66 | ...1286-1290,1293 
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/services      |   92.31 |    88.44 |   97.84 |   92.31 |                   
  ...mandLoader.ts |     100 |    88.88 |     100 |     100 | 105-118           
  ...killLoader.ts |   97.19 |    85.29 |     100 |   97.19 | 142,153-154       
  ...andService.ts |   98.73 |      100 |     100 |   98.73 | 107               
  ...mandLoader.ts |   86.83 |    83.87 |     100 |   86.83 | ...30-335,340-345 
  ...omptLoader.ts |   79.55 |    88.29 |   83.33 |   79.55 | ...48,178,245-246 
  ...mandLoader.ts |   97.77 |    92.15 |     100 |   97.77 | 176,183-184       
  ...nd-factory.ts |   91.42 |    91.66 |     100 |   91.42 | 128,137-144       
  ...ation-tool.ts |     100 |    95.45 |     100 |     100 | 125               
  ...ndMetadata.ts |   98.23 |    96.72 |     100 |   98.23 | 83,87             
  commandUtils.ts  |      96 |     90.9 |     100 |      96 | 48                
  ...and-parser.ts |   90.69 |    85.71 |     100 |   90.69 | 63-66             
  ...ionService.ts |     100 |      100 |     100 |     100 |                   
  prompt-stash.ts  |   96.66 |    92.85 |     100 |   96.66 | 34-35             
  ...tree-lease.ts |   88.23 |    86.48 |     100 |   88.23 | ...94-199,232-233 
  ...low-loader.ts |     100 |    96.15 |     100 |     100 | 88                
  setup-github.ts  |    90.8 |    80.95 |     100 |    90.8 | ...49-450,457-458 
  ...-args-file.ts |   93.93 |    91.66 |    87.5 |   93.93 | 208-210,224-230   
  types.ts         |     100 |      100 |     100 |     100 |                   
  ...e-keyterms.ts |   98.64 |    95.71 |     100 |   98.64 | 116,142-143       
  voice-model.ts   |     100 |      100 |     100 |     100 |                   
  voice-service.ts |   90.37 |    87.87 |     100 |   90.37 | ...80,287,352-357 
  ...e-settings.ts |     100 |    95.23 |     100 |     100 | 19                
  ...ranscriber.ts |   90.46 |    82.19 |      96 |   90.46 | ...66-668,671-673 
 ...rvices/insight |     100 |      100 |     100 |     100 |                   
  dates.ts         |     100 |      100 |     100 |     100 |                   
 ...ght/generators |   88.91 |    86.29 |   96.15 |   88.91 |                   
  DataProcessor.ts |   88.28 |    86.24 |   94.73 |   88.28 | ...1352,1356-1363 
  ...tGenerator.ts |   98.24 |    85.71 |     100 |   98.24 | 47                
  ...teRenderer.ts |     100 |      100 |     100 |     100 |                   
 .../insight/types |       0 |       50 |      50 |       0 |                   
  ...sightTypes.ts |       0 |        0 |       0 |       0 |                   
  ...sightTypes.ts |       0 |        0 |       0 |       0 | 1                 
 ...mpt-processors |   97.27 |    94.04 |     100 |   97.27 |                   
  ...tProcessor.ts |     100 |      100 |     100 |     100 |                   
  ...eProcessor.ts |   94.52 |    84.21 |     100 |   94.52 | 46-47,93-94       
  ...tionParser.ts |     100 |      100 |     100 |     100 |                   
  ...lProcessor.ts |   97.41 |    95.65 |     100 |   97.41 | 95-98             
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/services/tips |   97.27 |    84.61 |     100 |   97.27 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  tipHistory.ts    |   92.59 |       70 |     100 |   92.59 | ...24,146,153,162 
  tipRegistry.ts   |     100 |      100 |     100 |     100 |                   
  tipScheduler.ts  |     100 |    91.66 |     100 |     100 | 55                
 src/startup       |   88.99 |    83.47 |    90.9 |   88.99 |                   
  ...p-prefetch.ts |   98.09 |    94.23 |    87.5 |   98.09 | 50,209,225-226    
  ...reeStartup.ts |   80.53 |     74.6 |     100 |   80.53 | ...94,403,409-412 
 src/test-utils    |   93.26 |       75 |   83.33 |   93.26 |                   
  ci-env.ts        |      88 |     62.5 |     100 |      88 | 22-23,28          
  ...omMatchers.ts |   69.69 |       50 |      50 |   69.69 | 32-35,37-39,45-47 
  ...andContext.ts |     100 |      100 |     100 |     100 |                   
  render.tsx       |     100 |      100 |     100 |     100 |                   
 src/ui            |    72.7 |     75.2 |    65.9 |    72.7 |                   
  App.tsx          |   33.33 |       75 |   33.33 |   33.33 | 32-86             
  AppContainer.tsx |   73.91 |    72.08 |   70.58 |   73.91 | ...4096,4212-4218 
  ...tionNudge.tsx |    9.58 |      100 |       0 |    9.58 | 24-94             
  ...ackDialog.tsx |    30.3 |      100 |       0 |    30.3 | 26-76             
  ...tionNudge.tsx |    7.69 |      100 |       0 |    7.69 | 25-103            
  colors.ts        |      60 |      100 |   35.29 |      60 | ...52,54-55,60-61 
  constants.ts     |     100 |      100 |     100 |     100 |                   
  keyMatchers.ts   |   95.91 |    97.14 |     100 |   95.91 | 25-26             
  ...tic-colors.ts |     100 |      100 |     100 |     100 |                   
  ...ractiveUI.tsx |   68.12 |    64.86 |   33.33 |   68.12 | ...98,321,341-346 
  ...inePresets.ts |   96.27 |    83.87 |     100 |   96.27 | ...97,402,410-412 
  textConstants.ts |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/ui/auth       |   58.53 |    66.18 |   51.06 |   58.53 |                   
  AuthDialog.tsx   |   59.01 |     42.1 |   16.66 |   59.01 | ...25,332-354,358 
  ...nProgress.tsx |       0 |        0 |       0 |       0 | 1-64              
  ...etupSteps.tsx |   60.21 |    70.73 |   57.69 |   60.21 | ...90,794,803,806 
  useAuth.ts       |    94.6 |    73.52 |     100 |    94.6 | ...21-222,241-247 
  ...rSetupFlow.ts |   43.18 |    33.33 |      50 |   43.18 | ...78-399,416-459 
 src/ui/commands   |    82.5 |    82.83 |   89.12 |    82.5 |                   
  aboutCommand.ts  |     100 |      100 |     100 |     100 |                   
  agentsCommand.ts |   83.78 |      100 |      60 |   83.78 | 30-32,42-44       
  ...odeCommand.ts |    93.1 |    95.23 |     100 |    93.1 | 77-82             
  arenaCommand.ts  |   63.89 |    65.71 |   65.21 |   63.89 | ...01-606,691-699 
  authCommand.ts   |     100 |      100 |     100 |     100 |                   
  branchCommand.ts |     100 |      100 |     100 |     100 |                   
  btwCommand.ts    |   94.32 |    77.41 |     100 |   94.32 | 35-36,114-119     
  bugCommand.ts    |     100 |    77.77 |     100 |     100 | 27,61             
  cdCommand.ts     |    92.3 |    82.75 |     100 |    92.3 | ...,94-99,178,187 
  clearCommand.ts  |    80.9 |    70.83 |     100 |    80.9 | ...24-125,133-142 
  ...essCommand.ts |   68.06 |    54.05 |      75 |   68.06 | ...96-197,211-214 
  ...astCommand.ts |   84.17 |       75 |     100 |   84.17 | ...,91-97,125-130 
  ...ig-command.ts |   93.12 |    88.42 |     100 |   93.12 | ...07-315,321-323 
  ...extCommand.ts |   68.28 |    70.14 |   84.61 |   68.28 | ...66-599,610-611 
  copyCommand.ts   |    98.7 |    96.29 |     100 |    98.7 | 66-67,172,272,323 
  ...or-command.ts |   85.95 |    80.55 |   88.88 |   85.95 | ...68-274,298-309 
  deleteCommand.ts |     100 |      100 |     100 |     100 |                   
  diffCommand.ts   |     100 |    87.87 |     100 |     100 | ...63,231-232,245 
  ...ryCommand.tsx |   81.64 |    87.67 |    90.9 |   81.64 | ...73-278,325-332 
  docsCommand.ts   |     100 |     90.9 |     100 |     100 | 25                
  doctorCommand.ts |   65.37 |    81.88 |   94.11 |   65.37 | ...85-535,538-672 
  dreamCommand.ts  |   85.45 |    88.88 |     100 |   85.45 | 58-65             
  editorCommand.ts |     100 |      100 |     100 |     100 |                   
  ...rt-command.ts |   82.97 |    78.57 |     100 |   82.97 | 47-52,67-70,91-96 
  exportCommand.ts |   98.25 |    91.02 |     100 |   98.25 | ...81,198-199,364 
  ...onsCommand.ts |   52.31 |    56.25 |   69.23 |   52.31 | ...09,277-329,390 
  forgetCommand.ts |     100 |       90 |     100 |     100 | 59                
  forkCommand.ts   |     100 |    94.11 |     100 |     100 | 96,147            
  goalCommand.ts   |   72.81 |    86.84 |   66.66 |   72.81 | ...63-168,277-280 
  helpCommand.ts   |     100 |      100 |     100 |     100 |                   
  ...oryCommand.ts |     100 |      100 |     100 |     100 |                   
  hooksCommand.ts  |   81.13 |    65.71 |   85.71 |   81.13 | ...,86-93,131-132 
  ideCommand.ts    |   60.75 |    64.28 |   41.17 |   60.75 | ...05-306,310-324 
  ...figCommand.ts |   52.83 |    81.25 |      70 |   52.83 | ...74-319,321-330 
  initCommand.ts   |   91.86 |       80 |     100 |   91.86 | 48,83-88          
  ...ghtCommand.ts |   77.87 |    71.42 |     100 |   77.87 | ...44-245,250-272 
  ...ageCommand.ts |   93.45 |    89.06 |     100 |   93.45 | ...68-169,196-206 
  learn-command.ts |     100 |      100 |     100 |     100 |                   
  lspCommand.ts    |     100 |    86.95 |     100 |     100 | 31,101-102        
  mcpCommand.ts    |     100 |      100 |     100 |     100 |                   
  memoryCommand.ts |     100 |      100 |     100 |     100 |                   
  modelCommand.ts  |   84.78 |    82.47 |     100 |   84.78 | ...1071,1105-1110 
  ...onsCommand.ts |     100 |      100 |     100 |     100 |                   
  planCommand.ts   |   78.82 |    76.92 |     100 |   78.82 | 30-35,51-56,68-73 
  quitCommand.ts   |     100 |      100 |     100 |     100 |                   
  recapCommand.ts  |   21.81 |      100 |      50 |   21.81 | 24-73             
  ...ns-command.ts |   98.83 |    81.81 |     100 |   98.83 | 100               
  ...berCommand.ts |     100 |     87.5 |     100 |     100 | 46                
  renameCommand.ts |   89.06 |    88.37 |     100 |   89.06 | ...72-176,202-209 
  ...oreCommand.ts |    90.9 |    86.04 |     100 |    90.9 | ...41-146,176-177 
  resumeCommand.ts |     100 |      100 |     100 |     100 |                   
  rewindCommand.ts |   81.25 |      100 |      50 |   81.25 | 20-22             
  ...ngsCommand.ts |     100 |      100 |     100 |     100 |                   
  ...hubCommand.ts |   89.47 |       75 |      80 |   89.47 | 54-59             
  skillsCommand.ts |   78.82 |    81.81 |     100 |   78.82 | 37-52,78,97       
  statsCommand.ts  |   90.65 |    76.73 |     100 |   90.65 | ...30-733,825-832 
  ...ineCommand.ts |     100 |      100 |     100 |     100 |                   
  ...aryCommand.ts |   73.04 |     82.3 |      90 |   73.04 | ...20-547,561-565 
  tasksCommand.ts  |   77.22 |    72.13 |     100 |   77.22 | ...46-150,172-177 
  ...tupCommand.ts |     100 |      100 |     100 |     100 |                   
  themeCommand.ts  |     100 |      100 |     100 |     100 |                   
  toolsCommand.ts  |     100 |      100 |     100 |     100 |                   
  trustCommand.ts  |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
  ...te-command.ts |     100 |    94.11 |     100 |     100 | 74,148            
  vimCommand.ts    |   54.54 |      100 |      50 |   54.54 | 19-29             
  voice-command.ts |   93.57 |       88 |     100 |   93.57 | 35,97-102         
  ...owsCommand.ts |   91.86 |    78.87 |   66.66 |   91.86 | ...60-161,170-175 
 src/ui/components |   71.28 |    78.65 |   79.62 |   71.28 |                   
  AboutBox.tsx     |     100 |      100 |     100 |     100 |                   
  AnsiOutput.tsx   |   65.57 |      100 |      50 |   65.57 | 69-90             
  ApiKeyInput.tsx  |       0 |        0 |       0 |       0 | 1-97              
  AppHeader.tsx    |    88.7 |       75 |     100 |    88.7 | 36,38-43,45       
  ...odeDialog.tsx |   87.24 |    72.22 |   33.33 |   87.24 | ...85,233-238,245 
  AsciiArt.ts      |     100 |      100 |     100 |     100 |                   
  ...Indicator.tsx |   95.65 |    66.66 |     100 |   95.65 | 27,52             
  ...TextInput.tsx |   88.65 |    90.41 |     100 |   88.65 | ...84-286,300-302 
  Composer.tsx     |   94.49 |    66.66 |     100 |   94.49 | ...-72,84,139,153 
  ...entPrompt.tsx |     100 |      100 |     100 |     100 |                   
  ...ryDisplay.tsx |   75.89 |    62.06 |     100 |   75.89 | ...,88,93-108,113 
  ...geDisplay.tsx |   68.42 |    57.14 |     100 |   68.42 | 16-17,31-32,42-50 
  CronPill.tsx     |     100 |    93.75 |     100 |     100 | 19                
  ...ification.tsx |      84 |       60 |     100 |      84 | 23-24,40-42       
  ...gProfiler.tsx |       0 |        0 |       0 |       0 | 1-36              
  ...ogManager.tsx |       0 |        0 |       0 |       0 | 1-598             
  DiffDialog.tsx   |    53.5 |     37.5 |   69.23 |    53.5 | ...32-737,747-760 
  ...ngsDialog.tsx |       0 |        0 |       0 |       0 | 1-195             
  EffortDialog.tsx |   97.36 |      100 |     100 |   97.36 | 55-56             
  ExitWarning.tsx  |     100 |      100 |     100 |     100 |                   
  ...hProgress.tsx |    87.8 |    33.33 |     100 |    87.8 | 28-31,56          
  ...ustDialog.tsx |     100 |      100 |     100 |     100 |                   
  Footer.tsx       |   74.09 |     61.4 |      50 |   74.09 | ...55-260,278-282 
  ...ngSpinner.tsx |   68.42 |    85.71 |      50 |   68.42 | 35-52,73,80-81    
  GoalPill.tsx     |   93.51 |    81.81 |     100 |   93.51 | 37-38,106-109,123 
  Header.tsx       |   98.65 |    94.73 |     100 |   98.65 | 173,175           
  Help.tsx         |   98.33 |       90 |     100 |   98.33 | ...25,382,448-449 
  ...emDisplay.tsx |   79.06 |    66.33 |     100 |   79.06 | ...04,507,510-516 
  ...ngeDialog.tsx |     100 |      100 |     100 |     100 |                   
  InputPrompt.tsx  |    83.1 |    81.95 |      80 |    83.1 | ...2199,2225,2299 
  ...Shortcuts.tsx |     100 |       88 |     100 |     100 | 98,119            
  ...Indicator.tsx |   98.18 |    97.82 |     100 |   98.18 | 161-162           
  ...firmation.tsx |   91.42 |      100 |      50 |   91.42 | 26-31             
  MainContent.tsx  |    95.9 |    92.53 |      50 |    95.9 | ...99,445-449,452 
  MemoryDialog.tsx |   86.59 |    80.15 |     100 |   86.59 | ...34-435,485,553 
  ...geDisplay.tsx |       0 |        0 |       0 |       0 | 1-41              
  ModelDialog.tsx  |   81.95 |    71.27 |     100 |   81.95 | ...1045,1050-1066 
  ...tsDisplay.tsx |     100 |    97.22 |     100 |     100 | 270               
  ...fications.tsx |       0 |        0 |       0 |       0 | 1-56              
  ...onsDialog.tsx |       0 |        0 |       0 |       0 | 1-1004            
  ...ryDisplay.tsx |     100 |      100 |     100 |     100 |                   
  ...icePrompt.tsx |   92.64 |    85.71 |     100 |   92.64 | 102-106,134-139   
  PrepareLabel.tsx |   91.66 |    77.27 |     100 |   91.66 | 73-75,77-79,110   
  ...atePrompt.tsx |       0 |        0 |       0 |       0 | 1-134             
  ...geDisplay.tsx |     100 |      100 |     100 |     100 |                   
  ...ngDisplay.tsx |       0 |        0 |       0 |       0 | 1-39              
  ...hProgress.tsx |   85.25 |    88.46 |     100 |   85.25 | 121-147           
  ...dSelector.tsx |   92.79 |    82.65 |     100 |   92.79 | ...19-323,354-370 
  ...ionPicker.tsx |   83.66 |    72.13 |     100 |   83.66 | ...96,402,444-466 
  ...onPreview.tsx |   93.58 |    83.78 |     100 |   93.58 | ...,70-71,195-197 
  ...ryDisplay.tsx |     100 |      100 |     100 |     100 |                   
  ...putPrompt.tsx |   92.06 |    86.36 |   83.33 |   92.06 | ...,70-72,120-123 
  ...tedDialog.tsx |     100 |      100 |     100 |     100 |                   
  ...ngsDialog.tsx |   71.49 |    73.89 |   69.23 |   71.49 | ...1244,1250-1251 
  ...ionDialog.tsx |    92.3 |    96.15 |   33.33 |    92.3 | 60-63,68-75,164   
  ...putPrompt.tsx |    15.9 |      100 |       0 |    15.9 | 20-63             
  ...Indicator.tsx |   57.14 |      100 |       0 |   57.14 | 12-15             
  ...MoreLines.tsx |       0 |        0 |       0 |       0 | 1-40              
  ...iewDialog.tsx |   97.77 |    87.67 |     100 |   97.77 | ...97,305-307,324 
  ...tsDisplay.tsx |   95.86 |       75 |     100 |   95.86 | 67-71             
  ...ionPicker.tsx |       0 |        0 |       0 |       0 | 1-172             
  ...tivityTab.tsx |    3.94 |      100 |       0 |    3.94 | 27-275            
  StatsDialog.tsx  |    8.64 |      100 |       0 |    8.64 | ...76-111,130-322 
  StatsDisplay.tsx |     100 |      100 |     100 |     100 |                   
  ...ciencyTab.tsx |    78.9 |    56.52 |     100 |    78.9 | ...26,213,262-288 
  ...atmapView.tsx |    8.98 |      100 |       0 |    8.98 | 20-107            
  ...essionTab.tsx |      80 |    66.66 |     100 |      80 | ...70-277,283-300 
  ...ineDialog.tsx |    93.5 |    85.18 |     100 |    93.5 | ...05,267,287-289 
  ...yTodoList.tsx |   96.36 |    88.23 |     100 |   96.36 | 138-141           
  ...nsDisplay.tsx |   92.97 |    83.87 |     100 |   92.97 | ...45,248,275-277 
  ...inalImage.tsx |     100 |     90.9 |     100 |     100 | 75,93             
  ThemeDialog.tsx  |   89.95 |    46.15 |      75 |   89.95 | ...71-173,243-245 
  Tips.tsx         |   93.54 |       75 |     100 |   93.54 | 39-40             
  TodoDisplay.tsx  |     100 |      100 |     100 |     100 |                   
  ...tsDisplay.tsx |     100 |     87.5 |     100 |     100 | 31-32             
  TrustDialog.tsx  |     100 |    83.33 |     100 |     100 | 72-87             
  ...ification.tsx |   36.36 |      100 |       0 |   36.36 | 15-22             
  ...Indicator.tsx |    92.5 |     87.5 |     100 |    92.5 | 50-53             
  ...ackDialog.tsx |       0 |        0 |       0 |       0 | 1-134             
  ...xitDialog.tsx |   80.36 |    43.47 |      60 |   80.36 | ...24-238,248-251 
  ...odeVisuals.ts |   97.22 |    85.71 |     100 |   97.22 | 25                
  ...s-helpers.tsx |   66.25 |    81.25 |      50 |   66.25 | 25-32,46-53,62-72 
 ...nts/agent-view |   55.05 |    69.09 |      50 |   55.05 |                   
  ...atContent.tsx |    9.09 |      100 |       0 |    9.09 | 54-275,281-283    
  ...tChatView.tsx |   21.05 |      100 |       0 |   21.05 | 21-39             
  ...tComposer.tsx |   69.48 |    33.33 |   66.66 |   69.48 | ...51,269,277-279 
  AgentFooter.tsx  |   15.38 |      100 |       0 |   15.38 | 28-65             
  AgentHeader.tsx  |   15.38 |      100 |       0 |   15.38 | 27-64             
  AgentTabBar.tsx  |    87.9 |    63.88 |     100 |    87.9 | ...88,110-118,136 
  ...oryAdapter.ts |     100 |    91.83 |     100 |     100 | 103,109-110,138   
  index.ts         |       0 |        0 |       0 |       0 | 1-12              
 ...mponents/arena |    42.3 |    68.69 |   73.68 |    42.3 |                   
  ArenaCards.tsx   |   73.06 |    71.79 |   85.71 |   73.06 | ...83-185,321-326 
  ...ectDialog.tsx |   83.48 |    69.86 |   88.88 |   83.48 | ...88-392,409-410 
  ...artDialog.tsx |       0 |        0 |       0 |       0 | 1-166             
  ...tusDialog.tsx |       0 |        0 |       0 |       0 | 1-288             
  ...topDialog.tsx |       0 |        0 |       0 |       0 | 1-213             
 ...ackground-view |   82.95 |    81.71 |   92.72 |   82.95 |                   
  ...sksDialog.tsx |   78.73 |    77.65 |   84.61 |   78.73 | ...1809,1833-1839 
  ...TasksPill.tsx |   67.74 |    86.66 |     100 |   67.74 | ...04-124,132-140 
  ...gentPanel.tsx |   97.08 |    86.31 |     100 |   97.08 | 132,442-446,520   
  agent-forest.ts  |    99.2 |    93.93 |     100 |    99.2 | 258               
  ...Visibility.ts |     100 |      100 |     100 |     100 |                   
  ...e-overlay.tsx |    88.2 |    76.47 |     100 |    88.2 | ...36-138,140-142 
 ...nts/extensions |   84.32 |    76.78 |   83.33 |   84.32 |                   
  ...gerDialog.tsx |   82.15 |    76.08 |     100 |   82.15 | ...91-198,258,260 
  TabBar.tsx       |   97.29 |    88.88 |     100 |   97.29 | 33                
  index.ts         |       0 |        0 |       0 |       0 | 1-12              
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...tensions/steps |   46.26 |       85 |   58.82 |   46.26 |                   
  ...ctionStep.tsx |   95.12 |    92.85 |   85.71 |   95.12 | 84-86,89          
  ...etailStep.tsx |       0 |        0 |       0 |       0 | 1-145             
  ...nListStep.tsx |   75.26 |    88.37 |   66.66 |   75.26 | ...53,174,203-209 
  ...electStep.tsx |       0 |        0 |       0 |       0 | 1-83              
  ...nfirmStep.tsx |   16.32 |      100 |       0 |   16.32 | 28-74             
  index.ts         |       0 |        0 |       0 |       0 | 1-11              
 ...xtensions/tabs |   71.92 |    68.21 |   70.83 |   71.92 |                   
  DiscoverTab.tsx  |   68.22 |    67.66 |   55.55 |   68.22 | ...93,656-660,664 
  InstalledTab.tsx |   75.49 |    67.44 |   83.33 |   75.49 | ...77,782-783,820 
  SourcesTab.tsx   |   71.67 |    70.47 |   77.77 |   71.67 | ...28,547,621-633 
 ...tensions/views |   50.97 |    52.38 |   20.83 |   50.97 |                   
  ...tionsView.tsx |   73.75 |    56.36 |   66.66 |   73.75 | ...30,353,369-374 
  ...tionsView.tsx |   43.45 |    44.82 |    6.66 |   43.45 | ...98-405,408-420 
  ...etailView.tsx |    9.56 |      100 |       0 |    9.56 | 40-67,70-158      
 ...mponents/hooks |   87.11 |    81.37 |   91.89 |   87.11 |                   
  ...rListBody.tsx |   95.29 |    85.18 |     100 |   95.29 | 95-98             
  ...etailStep.tsx |   75.32 |    71.42 |      60 |   75.32 | ...56-169,173-186 
  ...etailStep.tsx |     100 |      100 |     100 |     100 |                   
  ...rListStep.tsx |     100 |      100 |     100 |     100 |                   
  ...entHeader.tsx |     100 |    85.71 |     100 |     100 | 47                
  ...rListStep.tsx |     100 |      100 |     100 |     100 |                   
  ...etailStep.tsx |     100 |      100 |     100 |     100 |                   
  ...abledStep.tsx |     100 |      100 |     100 |     100 |                   
  ...sListStep.tsx |     100 |      100 |     100 |     100 |                   
  ...entDialog.tsx |   72.29 |    70.49 |     100 |   72.29 | ...51,563-568,572 
  constants.ts     |     100 |      100 |     100 |     100 |                   
  index.ts         |       0 |        0 |       0 |       0 | 1-13              
  ...erGrouping.ts |     100 |      100 |     100 |     100 |                   
  sourceLabels.ts  |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...components/mcp |   40.04 |    61.53 |   70.58 |   40.04 |                   
  ...ealthPill.tsx |   68.42 |    85.71 |     100 |   68.42 | 40-46             
  ...entDialog.tsx |   32.09 |    26.19 |      40 |   32.09 | ...12,914,927-933 
  ...valDialog.tsx |   15.06 |      100 |       0 |   15.06 | 40-109            
  constants.ts     |     100 |      100 |     100 |     100 |                   
  index.ts         |       0 |        0 |       0 |       0 | 1-35              
  types.ts         |     100 |      100 |     100 |     100 |                   
  utils.ts         |      97 |       95 |     100 |      97 | 24,113-114        
 ...ents/mcp/steps |   53.94 |    73.51 |   57.14 |   53.94 |                   
  ...icateStep.tsx |    5.65 |      100 |       0 |    5.65 | 40-66,69-308      
  ...electStep.tsx |   10.95 |      100 |       0 |   10.95 | 16-88             
  ...etailStep.tsx |     100 |      100 |     100 |     100 |                   
  ...eListStep.tsx |   99.09 |    97.36 |     100 |   99.09 | 71                
  ...etailStep.tsx |   62.83 |       60 |   33.33 |   62.83 | ...87-296,307-332 
  ...rListStep.tsx |   88.53 |    81.25 |     100 |   88.53 | ...64,170,175-180 
  ...etailStep.tsx |    10.3 |      100 |       0 |    10.3 | ...1,67-79,82-140 
  ToolListStep.tsx |   69.29 |       50 |     100 |   69.29 | ...23,126,135-144 
 ...nents/messages |   89.93 |    86.42 |   85.29 |   89.93 |                   
  ...ionDialog.tsx |   89.23 |     84.9 |   81.81 |   89.23 | ...75,593,611-613 
  BtwMessage.tsx   |     100 |      100 |     100 |     100 |                   
  ...upDisplay.tsx |     100 |    94.73 |     100 |     100 | ...43,289,402,432 
  ...onMessage.tsx |   92.06 |    82.35 |     100 |   92.06 | 58-60,62,64       
  ...nMessages.tsx |   93.46 |      100 |   76.92 |   93.46 | ...90-292,295-298 
  DiffRenderer.tsx |   93.17 |    86.02 |     100 |   93.17 | ...07,235-236,302 
  ...tsDisplay.tsx |   97.08 |    77.77 |     100 |   97.08 | 95,97,106         
  ...usMessage.tsx |   81.73 |     65.9 |      75 |   81.73 | ...10-214,222,245 
  ...tsDisplay.tsx |   95.52 |    88.31 |     100 |   95.52 | ...40,142,175-180 
  ...ssMessage.tsx |    12.5 |      100 |       0 |    12.5 | 18-59             
  ...edMessage.tsx |   21.05 |      100 |       0 |   21.05 | 23-39             
  ...sMessages.tsx |   59.04 |       50 |    37.5 |   59.04 | ...21-126,147-159 
  ...ryMessage.tsx |   13.63 |      100 |       0 |   13.63 | 23-64             
  ...onMessage.tsx |   91.38 |    81.02 |     100 |   91.38 | ...33-635,642-644 
  ...upMessage.tsx |   98.32 |    95.16 |     100 |   98.32 | 184-187,414       
  ToolMessage.tsx  |   92.62 |    85.29 |   93.33 |   92.62 | ...-982,1009-1011 
 ...ponents/shared |   85.79 |    81.95 |   94.11 |   85.79 |                   
  ...ctionList.tsx |     100 |      100 |      75 |     100 |                   
  ...tonSelect.tsx |     100 |      100 |     100 |     100 |                   
  EnumSelector.tsx |     100 |    96.42 |     100 |     100 | 58                
  ...rBoundary.tsx |     100 |      100 |     100 |     100 |                   
  MaxSizedBox.tsx  |   84.71 |    86.95 |      90 |   84.71 | ...67-568,685-686 
  MultiSelect.tsx  |   93.58 |       75 |     100 |   93.58 | ...43,199-201,211 
  ...tonSelect.tsx |     100 |      100 |     100 |     100 |                   
  ...ontroller.tsx |     100 |    83.33 |     100 |     100 | 73,93-95          
  ...eSelector.tsx |     100 |       60 |     100 |     100 | 40-45             
  ...lableList.tsx |   81.48 |    84.84 |     100 |   81.48 | 46-66,73-76       
  StaticRender.tsx |   72.72 |      100 |     100 |   72.72 | 31-33             
  TextInput.tsx    |    80.8 |    67.24 |      80 |    80.8 | ...36-240,252-258 
  ...ontroller.tsx |     100 |    81.81 |     100 |     100 | 59-62             
  ...apsedTime.tsx |     100 |      100 |     100 |     100 |                   
  ...Indicator.tsx |     100 |      100 |     100 |     100 |                   
  ...lizedList.tsx |   88.51 |    83.75 |   81.81 |   88.51 | ...51-779,792,887 
  text-buffer.ts   |   85.98 |    81.81 |   97.91 |   85.98 | ...2664,2762-2763 
  ...er-actions.ts |   73.93 |    67.22 |     100 |   73.93 | ...32-733,934-936 
 ...ponents/skills |       0 |        0 |       0 |       0 |                   
  ...gerDialog.tsx |       0 |        0 |       0 |       0 | 1-681             
 ...ents/subagents |       0 |        0 |       0 |       0 |                   
  constants.ts     |       0 |        0 |       0 |       0 | 1-71              
  index.ts         |       0 |        0 |       0 |       0 | 1-11              
  reducers.tsx     |       0 |        0 |       0 |       0 | 1-190             
  types.ts         |       0 |        0 |       0 |       0 | 1-125             
  utils.ts         |       0 |        0 |       0 |       0 | 1-102             
 ...bagents/create |       0 |        0 |       0 |       0 |                   
  ...ionWizard.tsx |       0 |        0 |       0 |       0 | 1-299             
  ...rSelector.tsx |       0 |        0 |       0 |       0 | 1-85              
  ...onSummary.tsx |       0 |        0 |       0 |       0 | 1-331             
  ...tionInput.tsx |       0 |        0 |       0 |       0 | 1-177             
  ...dSelector.tsx |       0 |        0 |       0 |       0 | 1-63              
  ...nSelector.tsx |       0 |        0 |       0 |       0 | 1-58              
  ...EntryStep.tsx |       0 |        0 |       0 |       0 | 1-78              
  ToolSelector.tsx |       0 |        0 |       0 |       0 | 1-253             
 ...bagents/manage |   14.14 |    53.19 |    37.5 |   14.14 |                   
  ...ctionStep.tsx |       0 |        0 |       0 |       0 | 1-103             
  ...eleteStep.tsx |       0 |        0 |       0 |       0 | 1-62              
  ...tEditStep.tsx |       0 |        0 |       0 |       0 | 1-124             
  ...ctionStep.tsx |   35.61 |    59.52 |     100 |   35.61 | ...21-433,438-440 
  ...iewerStep.tsx |       0 |        0 |       0 |       0 | 1-73              
  ...gerDialog.tsx |       0 |        0 |       0 |       0 | 1-341             
 ...mponents/views |   69.81 |    72.64 |   61.11 |   69.81 |                   
  ContextUsage.tsx |   70.88 |    63.88 |      80 |   70.88 | ...20-426,463-557 
  DoctorReport.tsx |     9.8 |      100 |       0 |     9.8 | 25-54,57-131      
  ...sionsList.tsx |   88.05 |       75 |     100 |   88.05 | 70-77             
  McpStatus.tsx    |   92.01 |     73.8 |     100 |   92.01 | ...36,175-177,262 
  SkillsList.tsx   |   20.51 |      100 |       0 |   20.51 | 17-20,27-57       
  ToolsList.tsx    |     100 |      100 |     100 |     100 |                   
 src/ui/contexts   |   83.96 |    81.62 |    86.3 |   83.96 |                   
  ...ewContext.tsx |   64.83 |    88.88 |      50 |   64.83 | ...16-219,225-235 
  AppContext.tsx   |      80 |       50 |     100 |      80 | 19-20             
  ...ewContext.tsx |   92.45 |    62.79 |      50 |   92.45 | ...69-270,272-276 
  ...igContext.tsx |   81.81 |       50 |     100 |   81.81 | 15-16             
  ...ssContext.tsx |   85.65 |    84.85 |     100 |   85.65 | ...1612-1614,1620 
  ...owContext.tsx |   91.07 |    81.81 |     100 |   91.07 | 47-48,60-62       
  ...deContext.tsx |     100 |      100 |      50 |     100 |                   
  ...onContext.tsx |   80.77 |       80 |    92.3 |   80.77 | ...31-434,443-446 
  ...gsContext.tsx |     100 |      100 |     100 |     100 |                   
  ...usContext.tsx |     100 |      100 |     100 |     100 |                   
  ...ngContext.tsx |   71.42 |       50 |     100 |   71.42 | 17-20             
  ...utContext.tsx |   85.71 |      100 |   66.66 |   85.71 | 13-14             
  ...edContext.tsx |     100 |      100 |      50 |     100 |                   
  ...nsContext.tsx |   88.88 |       50 |     100 |   88.88 | 156-157           
  ...teContext.tsx |   86.66 |       50 |     100 |   86.66 | 235-236           
  ...deContext.tsx |      80 |     87.5 |      75 |      80 | ...11-112,118-120 
  ...rtContext.tsx |     100 |      100 |     100 |     100 |                   
 src/ui/daemon     |   88.35 |    73.51 |   95.45 |   88.35 |                   
  ...ui-adapter.ts |   88.35 |    73.51 |   95.45 |   88.35 | ...74,792-793,879 
 src/ui/editors    |       0 |        0 |       0 |       0 |                   
  ...ngsManager.ts |       0 |        0 |       0 |       0 | 1-67              
 src/ui/hooks      |   84.84 |    82.63 |   87.75 |   84.84 |                   
  ...dProcessor.ts |   85.53 |    85.13 |     100 |   85.53 | ...-970,1017-1018 
  ...ention-ref.ts |   97.72 |       84 |     100 |   97.72 | 65                
  keyToAnsi.ts     |    3.92 |      100 |       0 |    3.92 | 19-77             
  ...esourceRef.ts |     100 |      100 |     100 |     100 |                   
  ...completion.ts |     100 |    95.45 |     100 |     100 | 95                
  ...ention-ref.ts |     100 |      100 |     100 |     100 |                   
  ...dProcessor.ts |   94.62 |    73.58 |     100 |   94.62 | ...86-287,292-293 
  ...dProcessor.ts |   85.63 |    68.16 |   81.81 |   85.63 | ...1452,1473-1477 
  ...rt-command.ts |     100 |      100 |     100 |     100 |                   
  ...sced-flush.ts |     100 |      100 |     100 |     100 |                   
  ...ng-enabled.ts |     100 |      100 |     100 |     100 |                   
  ...oice-input.ts |   92.36 |    81.95 |   66.66 |   92.36 | ...00,502-503,658 
  ...ke-repaint.ts |     100 |      100 |     100 |     100 |                   
  ...amingState.ts |   12.22 |      100 |       0 |   12.22 | 54-157            
  ...agerDialog.ts |   88.23 |      100 |     100 |   88.23 | 20,24             
  ...dScrollbar.ts |     100 |      100 |     100 |     100 |                   
  ...ationFrame.ts |      42 |       75 |     100 |      42 | 42-44,53-59,62-87 
  ...odeCommand.ts |   58.82 |      100 |     100 |   58.82 | 28,33-48          
  ...enaCommand.ts |      85 |      100 |     100 |      85 | 23-24,29          
  ...aInProcess.ts |   27.92 |       80 |      25 |   27.92 | ...69-170,173-175 
  ...Completion.ts |   86.44 |    88.48 |     100 |   86.44 | ...14-515,525-541 
  ...ifications.ts |   87.82 |    96.77 |     100 |   87.82 | 138-152           
  ...tIndicator.ts |   88.28 |    81.57 |     100 |   88.28 | ...66,175,179-187 
  ...waySummary.ts |   96.26 |       75 |     100 |   96.26 | 126-128,170       
  ...ndTaskView.ts |   94.81 |    76.59 |     100 |   94.81 | 162-166,255,261   
  ...chedScroll.ts |     100 |      100 |     100 |     100 |                   
  ...ketedPaste.ts |    23.8 |      100 |       0 |    23.8 | 19-37             
  ...nchCommand.ts |   95.23 |    82.69 |     100 |   95.23 | ...53-154,277-280 
  ...ompletion.tsx |   97.09 |    87.09 |     100 |   97.09 | ...23-324,334-335 
  ...dMigration.ts |    92.1 |    88.88 |     100 |    92.1 | 42-44             
  useCompletion.ts |   96.29 |    90.56 |     100 |   96.29 | ...17-218,222-223 
  ...nitMessage.ts |     100 |      100 |     100 |     100 |                   
  ...extualTips.ts |   78.26 |       50 |     100 |   78.26 | ...2,75-79,96-104 
  ...eteCommand.ts |   89.52 |    90.69 |     100 |   89.52 | ...98-106,114-115 
  ...ialogClose.ts |   36.11 |       10 |     100 |   36.11 | ...89-195,202-207 
  useDiffData.ts   |       0 |        0 |       0 |       0 | 1-87              
  ...oublePress.ts |   53.12 |       75 |     100 |   53.12 | 33-35,41-54       
  ...orSettings.ts |     100 |      100 |     100 |     100 |                   
  ...Completion.ts |   99.12 |    97.67 |     100 |   99.12 | 182-183           
  ...ionUpdates.ts |   93.72 |    92.98 |     100 |   93.72 | ...87-291,314-320 
  ...agerDialog.ts |   88.88 |      100 |     100 |   88.88 | 21,25             
  ...backDialog.ts |    63.9 |    76.47 |   66.66 |    63.9 | ...66-168,190-191 
  useFocus.ts      |     100 |      100 |     100 |     100 |                   
  ...olderTrust.ts |     100 |    93.33 |     100 |     100 | 62                
  ...ggestions.tsx |   96.47 |    78.94 |     100 |   96.47 | 121,155-156       
  ...miniStream.ts |   83.07 |    80.25 |   74.35 |   83.07 | ...4909-4911,4913 
  ...BranchName.ts |     100 |    94.44 |     100 |     100 | 54                
  ...oryManager.ts |   98.01 |    98.36 |     100 |   98.01 | 139-142           
  ...ooksDialog.ts |    87.5 |      100 |     100 |    87.5 | 19,23             
  ...stListener.ts |     100 |      100 |     100 |     100 |                   
  ...nAuthError.ts |   76.19 |       50 |     100 |   76.19 | 39-40,43-45       
  ...putHistory.ts |   92.59 |    85.71 |     100 |   92.59 | 63-64,72,94-96    
  ...storyStore.ts |     100 |    94.11 |     100 |     100 | 69                
  useKeypress.ts   |     100 |      100 |     100 |     100 |                   
  ...rdProtocol.ts |   36.36 |      100 |       0 |   36.36 | 24-31             
  ...unchEditor.ts |   22.58 |      100 |      50 |   22.58 | 11-32,44-85       
  ...gIndicator.ts |     100 |    96.66 |     100 |     100 | 109               
  useLogger.ts     |      16 |      100 |       0 |      16 | 15-45             
  useMCPHealth.ts  |   63.15 |       80 |      50 |   63.15 | 42-52,64-67       
  ...cpApproval.ts |   93.12 |    86.11 |     100 |   93.12 | ...24-127,139-140 
  useMcpDialog.ts  |    87.5 |      100 |     100 |    87.5 | 19,23             
  ...moryDialog.ts |    87.5 |      100 |     100 |    87.5 | 19,23             
  ...oryMonitor.ts |   83.14 |    78.57 |     100 |   83.14 | 54-63,74-79       
  ...ssageQueue.ts |     100 |     97.4 |     100 |     100 | 175,262           
  ...delCommand.ts |     100 |       96 |     100 |     100 | 61                
  ...ouseEvents.ts |   94.89 |       95 |   83.33 |   94.89 | 78-82             
  ...raseCycler.ts |   84.74 |    76.47 |     100 |   84.74 | ...49,52-53,69-71 
  ...rredEditor.ts |   58.33 |    22.22 |     100 |   58.33 | 23-27,29-33       
  ...derUpdates.ts |    87.4 |    78.78 |     100 |    87.4 | ...71,321-333,381 
  useQwenAuth.ts   |     100 |      100 |     100 |     100 |                   
  ...lScheduler.ts |   89.11 |    87.32 |     100 |   89.11 | ...42-444,476-486 
  ...oryCommand.ts |       0 |        0 |       0 |       0 | 1-7               
  ...umeCommand.ts |   95.18 |    76.47 |     100 |   95.18 | 118-119,220-225   
  ...ompletion.tsx |   90.67 |    83.33 |     100 |   90.67 | ...02,105,138-141 
  ...ectionList.ts |   97.12 |    96.22 |     100 |   97.12 | ...92-193,247-250 
  ...sionPicker.ts |   92.87 |    90.35 |     100 |   92.87 | ...99-501,503-505 
  ...earchInput.ts |     100 |    97.29 |     100 |     100 | 82                
  ...ngsCommand.ts |   18.75 |      100 |       0 |   18.75 | 10-25             
  ...ellHistory.ts |   93.28 |    80.95 |     100 |   93.28 | ...96,153-154,164 
  ...oryCommand.ts |   85.48 |    58.33 |     100 |   85.48 | 22-28,40,71       
  ...agerDialog.ts |   88.23 |      100 |     100 |   88.23 | 20,24             
  ...Completion.ts |   82.85 |    85.13 |   94.73 |   82.85 | ...78-680,688-724 
  ...tateAndRef.ts |     100 |      100 |     100 |     100 |                   
  ...tatsDialog.ts |     100 |      100 |     100 |     100 |                   
  useStatusLine.ts |   97.13 |    93.33 |     100 |   97.13 | ...78-382,478-485 
  ...eateDialog.ts |   88.23 |      100 |     100 |   88.23 | 14,18             
  ...mInProcess.ts |   27.35 |       80 |      25 |   27.35 | ...82-183,186-188 
  ...tification.ts |     100 |     87.5 |     100 |     100 | 50                
  ...alProgress.ts |   67.34 |    58.82 |   66.66 |   67.34 | 52-53,61-68,79-85 
  ...rminalSize.ts |     100 |      100 |     100 |     100 |                   
  ...emeCommand.ts |   67.01 |    29.41 |     100 |   67.01 | ...10-111,115-116 
  useTimer.ts      |   97.59 |    94.73 |     100 |   97.59 | 17-18             
  ...lMigration.ts |       0 |        0 |       0 |       0 |                   
  ...rustModify.ts |     100 |    90.47 |     100 |     100 | 112,134           
  useTurnDiffs.ts  |   95.12 |    78.57 |     100 |   95.12 | 133-134,156-157   
  ...elcomeBack.ts |   87.36 |     90.9 |     100 |   87.36 | ...,94-96,114-115 
  ...reeSession.ts |   93.75 |       70 |     100 |   93.75 | 47-48,72          
  vim.ts           |      74 |    67.56 |   69.23 |      74 | ...1854-1861,1869 
 src/ui/layouts    |    91.2 |    89.47 |     100 |    91.2 |                   
  ...AppLayout.tsx |    90.9 |     87.5 |     100 |    90.9 | 60-62,110-115,151 
  ...AppLayout.tsx |   91.66 |    92.85 |     100 |   91.66 | 75-80             
 src/ui/models     |   80.72 |       80 |   71.42 |   80.72 |                   
  ...ableModels.ts |   80.72 |       80 |   71.42 |   80.72 | ...,61-71,125-127 
 ...noninteractive |     100 |      100 |    6.66 |     100 |                   
  ...eractiveUi.ts |     100 |      100 |    6.66 |     100 |                   
 src/ui/selection  |   86.47 |    79.88 |   96.66 |   86.47 |                   
  screen-buffer.ts |   94.73 |    64.28 |     100 |   94.73 | 51-52             
  ...ion-coords.ts |     100 |      100 |     100 |     100 |                   
  ...ction-span.ts |   92.72 |       90 |     100 |   92.72 | 37-38,67-68       
  ...tion-state.ts |   85.71 |      100 |   88.88 |   85.71 | 51-58             
  ...ction-text.ts |   92.85 |    92.45 |     100 |   92.85 | 30-34,114-115     
  ...selection.tsx |   80.31 |    59.64 |     100 |   80.31 | ...13-314,330-331 
 src/ui/state      |      95 |    81.81 |     100 |      95 |                   
  extensions.ts    |      95 |    81.81 |     100 |      95 | 69-70,89          
 src/ui/themes     |    98.5 |    73.17 |     100 |    98.5 |                   
  ansi-light.ts    |     100 |      100 |     100 |     100 |                   
  ansi.ts          |     100 |      100 |     100 |     100 |                   
  atom-one-dark.ts |     100 |      100 |     100 |     100 |                   
  ayu-light.ts     |     100 |      100 |     100 |     100 |                   
  ayu.ts           |     100 |      100 |     100 |     100 |                   
  color-utils.ts   |   99.23 |    97.05 |     100 |   99.23 | 277-278           
  default-light.ts |     100 |      100 |     100 |     100 |                   
  default.ts       |     100 |      100 |     100 |     100 |                   
  ...inal-theme.ts |   88.59 |    85.96 |     100 |   88.59 | ...57-261,266-270 
  dracula.ts       |     100 |      100 |     100 |     100 |                   
  github-dark.ts   |     100 |      100 |     100 |     100 |                   
  github-light.ts  |     100 |      100 |     100 |     100 |                   
  googlecode.ts    |     100 |      100 |     100 |     100 |                   
  no-color.ts      |     100 |      100 |     100 |     100 |                   
  qwen-dark.ts     |     100 |      100 |     100 |     100 |                   
  qwen-light.ts    |     100 |      100 |     100 |     100 |                   
  ...tic-tokens.ts |     100 |      100 |     100 |     100 |                   
  ...-of-purple.ts |     100 |      100 |     100 |     100 |                   
  theme-manager.ts |   88.68 |    84.52 |     100 |   88.68 | ...83-392,397-398 
  theme.ts         |     100 |    38.02 |     100 |     100 | ...34-449,457-461 
  xcode.ts         |     100 |      100 |     100 |     100 |                   
 src/ui/utils      |   86.74 |    84.95 |   95.48 |   86.74 |                   
  ...Colorizer.tsx |   80.31 |    85.41 |     100 |   80.31 | ...00-201,313-339 
  ...nRenderer.tsx |   79.84 |     75.6 |     100 |   79.84 | ...66,270,328-329 
  ...wnDisplay.tsx |   92.87 |    93.46 |     100 |   92.87 | ...,955,1002-1020 
  ...idDiagram.tsx |   87.79 |    95.34 |     100 |   87.79 | 156-179           
  ...eRenderer.tsx |   92.38 |    81.91 |   95.23 |   92.38 | ...43-746,799-804 
  ...odeDisplay.ts |   94.28 |    85.71 |     100 |   94.28 | 23,40             
  asciiCharts.ts   |    96.7 |     87.5 |     100 |    96.7 | 170-177,278       
  ...dWorkUtils.ts |     100 |      100 |     100 |     100 |                   
  ...boardUtils.ts |   52.52 |    73.25 |   91.66 |   52.52 | ...23,626-635,638 
  commandUtils.ts  |   96.17 |    88.88 |     100 |   96.17 | ...77,179-180,323 
  computeStats.ts  |     100 |      100 |     100 |     100 |                   
  customBanner.ts  |   90.68 |    91.22 |     100 |   90.68 | ...13,324-327,334 
  displayUtils.ts  |   73.84 |    73.91 |     100 |   73.84 | ...34,36-40,42-46 
  formatters.ts    |   94.87 |    98.18 |     100 |   94.87 | 116-119           
  goal-runtime.ts  |   91.17 |    94.73 |     100 |   91.17 | 31-33             
  gradientUtils.ts |     100 |      100 |     100 |     100 |                   
  highlight.ts     |     100 |      100 |     100 |     100 |                   
  ...gap-notice.ts |     100 |      100 |     100 |     100 |                   
  ...oryMapping.ts |     100 |       95 |     100 |     100 | 44,103            
  historyUtils.ts  |   96.03 |     97.1 |     100 |   96.03 | 103-106           
  inline-math.ts   |   98.48 |    95.23 |     100 |   98.48 | 129-130           
  input-mouse.ts   |     100 |    85.71 |     100 |     100 | 48,93             
  isNarrowWidth.ts |     100 |      100 |     100 |     100 |                   
  ...olDetector.ts |   68.81 |       75 |   66.66 |   68.81 | ...27-132,160-161 
  latexRenderer.ts |   94.95 |     73.8 |     100 |   94.95 | ...76-178,184-187 
  layoutUtils.ts   |     100 |      100 |     100 |     100 |                   
  list-mouse.ts    |     100 |      100 |     100 |     100 |                   
  ...ightLoader.ts |     100 |       95 |     100 |     100 | 81                
  ...nUtilities.ts |   98.72 |    94.36 |     100 |   98.72 | 145-146           
  ...t-position.ts |     100 |     87.5 |     100 |     100 | 85                
  ...geRenderer.ts |   86.51 |    70.16 |   95.12 |   86.51 | ...1286,1326-1332 
  ...alRenderer.ts |   86.69 |     71.9 |     100 |   86.69 | ...1476,1513-1519 
  ...lsBySource.ts |     100 |    95.23 |     100 |     100 | 84                
  mouse.ts         |   92.85 |    74.19 |     100 |   92.85 | ...38,145,149-152 
  osc8.ts          |   90.43 |    78.33 |     100 |   90.43 | ...59,244,248-249 
  ...red-height.ts |   98.38 |     97.1 |     100 |   98.38 | 195-197           
  ...mConstants.ts |     100 |      100 |     100 |     100 |                   
  restoreGoal.ts   |     100 |      100 |     100 |     100 |                   
  ...storyUtils.ts |   79.42 |    78.08 |     100 |   79.42 | ...50-572,703-704 
  ...ickerUtils.ts |     100 |      100 |     100 |     100 |                   
  ...evel-label.ts |   77.77 |    66.66 |     100 |   77.77 | 18,22-24          
  ...are-cursor.ts |   89.47 |    85.71 |     100 |   89.47 | 39-44             
  ...ataService.ts |   93.17 |     79.1 |     100 |   93.17 | ...14,227,254-256 
  suggestions.ts   |     100 |      100 |     100 |     100 |                   
  ...izedOutput.ts |   94.94 |      100 |   88.88 |   94.94 | 112-117           
  ...nal-buffer.ts |     100 |      100 |     100 |     100 |                   
  ...e-renderer.ts |   89.19 |    79.54 |     100 |   89.19 | ...14,316-318,434 
  ...wOptimizer.ts |     100 |    96.77 |     100 |     100 | 69                
  terminalSetup.ts |    4.37 |      100 |       0 |    4.37 | 44-393            
  textUtils.ts     |   97.94 |    95.45 |   94.11 |   97.94 | ...82-283,443-444 
  ...background.ts |     100 |      100 |     100 |     100 |                   
  todoSnapshot.ts  |   90.42 |    92.85 |     100 |   90.42 | ...06-207,240-241 
  ...isplay-map.ts |     100 |      100 |     100 |     100 |                   
  updateCheck.ts   |     100 |    92.75 |     100 |     100 | 227-239,331       
  ...ow-keyword.ts |     100 |      100 |     100 |     100 |                   
 ...i/utils/export |   75.03 |    59.89 |   94.59 |   75.03 |                   
  collect.ts       |   71.27 |    65.81 |      96 |   71.27 | ...90-633,655-656 
  index.ts         |     100 |      100 |     100 |     100 |                   
  normalize.ts     |   80.42 |    50.68 |     100 |   80.42 | ...59-364,376-378 
  types.ts         |       0 |        0 |       0 |       0 | 1                 
  utils.ts         |     100 |      100 |     100 |     100 |                   
 ...ort/formatters |   52.92 |    47.22 |   71.42 |   52.92 |                   
  html.ts          |   84.61 |       50 |     100 |   84.61 | ...53,57-58,62-63 
  json.ts          |     100 |      100 |     100 |     100 |                   
  jsonl.ts         |   82.45 |     37.5 |     100 |   82.45 | ...48,50-51,65-66 
  markdown.ts      |   36.32 |    47.05 |      50 |   36.32 | ...16-219,233-295 
 src/ui/voice      |   80.94 |    72.69 |   80.55 |   80.94 |                   
  ...d-recorder.ts |     6.2 |      100 |       0 |     6.2 | ...33-159,162-163 
  ...o-recorder.ts |   84.61 |    93.33 |   57.14 |   84.61 | ...16-117,131-136 
  ...me-session.ts |   89.72 |    65.33 |   93.75 |   89.72 | ...99,305,316-319 
  sox-recorder.ts  |    92.7 |    71.87 |     100 |    92.7 | ...34-135,153-154 
  ...ailability.ts |     100 |      100 |     100 |     100 |                   
  ...e-keyterms.ts |     100 |      100 |     100 |     100 |                   
  voice-model.ts   |     100 |      100 |     100 |     100 |                   
  ...e-recorder.ts |   88.29 |    67.74 |   81.81 |   88.29 | ...,98-99,112,115 
  voice-refine.ts  |     100 |    93.33 |     100 |     100 | 92                
  ...ream-retry.ts |   86.79 |    68.42 |     100 |   86.79 | 16-18,48-49,59-60 
  ...am-session.ts |   88.02 |    66.66 |   84.61 |   88.02 | ...26,343-345,363 
  ...ranscriber.ts |     100 |      100 |     100 |     100 |                   
 src/utils         |   81.37 |    86.98 |   92.54 |   81.37 |                   
  ...p-profiler.ts |   98.39 |    90.56 |     100 |   98.39 | 141,185,235       
  acpModelUtils.ts |   97.36 |    95.19 |     100 |   97.36 | ...09-210,214-215 
  apiPreconnect.ts |   96.74 |    94.59 |     100 |   96.74 | 167-170           
  ...ol-call-id.ts |   84.61 |       60 |     100 |   84.61 | 26-27,37-38       
  ...ng-failure.ts |     100 |       95 |     100 |     100 | 72                
  checks.ts        |   33.33 |      100 |       0 |   33.33 | 23-28             
  ...-api-error.ts |     100 |    96.42 |     100 |     100 | 14                
  cleanup.ts       |   84.05 |    94.11 |      80 |   84.05 | 80,111-121        
  commands.ts      |   97.45 |    96.66 |     100 |   97.45 | 153-155           
  ...Calculator.ts |     100 |      100 |     100 |     100 |                   
  cpuProfiler.ts   |   70.73 |    73.23 |   88.88 |   70.73 | ...27,430-431,438 
  deepMerge.ts     |     100 |       90 |     100 |     100 | 41-43,49          
  ...re-runtime.ts |     100 |      100 |     100 |     100 |                   
  ...ScopeUtils.ts |   97.56 |    88.88 |     100 |   97.56 | 67                
  doctorChecks.ts  |   70.31 |    74.57 |     100 |   70.31 | ...95-301,325-341 
  ...putCapture.ts |   90.65 |    86.31 |     100 |   90.65 | ...73,371,373-374 
  ...arResolver.ts |   97.14 |    96.55 |     100 |   97.14 | 125-126           
  errors.ts        |   97.56 |    94.64 |     100 |   97.56 | 69-70,304-305     
  events.ts        |     100 |      100 |     100 |     100 |                   
  ...on-mention.ts |   88.48 |     82.6 |     100 |   88.48 | ...56-160,164-168 
  gitUtils.ts      |   92.85 |    86.66 |     100 |   92.85 | ...13-116,164-167 
  ...AutoUpdate.ts |    93.1 |       94 |      90 |    93.1 | 103,108,179-190   
  ...tyWarnings.ts |     100 |      100 |     100 |     100 |                   
  ...lationInfo.ts |   97.68 |    94.28 |     100 |   97.68 | ...64,381-382,427 
  jsonc-editor.ts  |   93.18 |    92.72 |     100 |   93.18 | ...80-381,384-385 
  languageUtils.ts |   98.88 |    97.05 |     100 |   98.88 | 184-185           
  load-undici.ts   |     100 |      100 |     100 |     100 |                   
  ...npm-update.ts |   86.32 |    76.05 |     100 |   86.32 | ...02-303,331-341 
  math.ts          |       0 |        0 |       0 |       0 | 1-15              
  ...er-mention.ts |     100 |    66.66 |     100 |     100 | 14,30,44-46       
  ...iagnostics.ts |   94.57 |    83.01 |   88.88 |   94.57 | ...05,311,315-317 
  ...serMessage.ts |     100 |      100 |     100 |     100 |                   
  ...onfigUtils.ts |   94.25 |    91.17 |     100 |   94.25 | ...30,436,439-443 
  ...iveHelpers.ts |   95.13 |    91.79 |     100 |   95.13 | ...53-454,552,565 
  osc.ts           |   97.18 |      100 |    87.5 |   97.18 | 182-183           
  package.ts       |   88.88 |    85.71 |     100 |   88.88 | 31-32             
  ...uggestions.ts |   84.29 |    70.83 |     100 |   84.29 | 70-76,92-103      
  processUtils.ts  |    92.3 |       80 |     100 |    92.3 | 45-46             
  readStdin.ts     |   93.67 |    94.11 |   85.71 |   93.67 | 79-83             
  relaunch.ts      |   95.87 |    89.28 |     100 |   95.87 | 103-105,131       
  resolvePath.ts   |     100 |      100 |     100 |     100 |                   
  runBudget.ts     |   99.35 |    96.77 |     100 |   99.35 | 119               
  sandbox-path.ts  |     100 |      100 |     100 |     100 |                   
  sandbox.ts       |   45.67 |    56.93 |   76.92 |   45.67 | ...1034,1046-1069 
  ...xImageName.ts |     100 |    77.77 |     100 |     100 | 10,18             
  sandboxMounts.ts |     100 |      100 |     100 |     100 |                   
  sessionPaths.ts  |   90.84 |    90.56 |     100 |   90.84 | ...81-182,185-186 
  settingsUtils.ts |   82.35 |    89.57 |      90 |   82.35 | ...25-743,750-758 
  spawnWrapper.ts  |     100 |      100 |     100 |     100 |                   
  ...ate-verify.ts |     100 |      100 |     100 |     100 |                   
  ...one-update.ts |   39.81 |    77.44 |   62.16 |   39.81 | ...1193,1196-1215 
  ...upProfiler.ts |   98.47 |    94.66 |     100 |   98.47 | 132-133,308       
  ...upWarnings.ts |     100 |      100 |     100 |     100 |                   
  stdioHelpers.ts  |     100 |     87.5 |     100 |     100 | 23                
  systemInfo.ts    |   95.12 |    90.27 |     100 |   95.12 | ...54-255,260-264 
  ...InfoFields.ts |    87.5 |    65.85 |     100 |    87.5 | ...24-125,146-147 
  ...alSequence.ts |     100 |    97.61 |     100 |     100 | 60                
  ...iffPreview.ts |   76.47 |       25 |     100 |   76.47 | 13,17,23-24       
  ...on-handler.ts |    73.8 |       75 |     100 |    73.8 | 17-18,25-26,67-73 
  ...e-relaunch.ts |   89.61 |    86.66 |      50 |   89.61 | 56-61,83-84       
  ...entEmitter.ts |     100 |      100 |     100 |     100 |                   
  ...ansionHook.ts |     100 |      100 |     100 |     100 |                   
  ...upWarnings.ts |   87.75 |       75 |     100 |   87.75 | 47-48,53-54,57-58 
  version.ts       |     100 |    66.66 |     100 |     100 | 11                
  ...ingHandler.ts |     100 |      100 |     100 |     100 |                   
  windowTitle.ts   |   95.45 |    93.33 |     100 |   95.45 | 54-55             
  ...WithBackup.ts |   65.04 |    77.77 |     100 |   65.04 | 97,112,133-172    
 ...s/housekeeping |   91.63 |    91.02 |      95 |   91.63 |                   
  cleanup.ts       |   95.77 |    95.83 |     100 |   95.77 | 70-72             
  ...eractionAt.ts |     100 |      100 |     100 |     100 |                   
  scheduler.ts     |   91.91 |    90.47 |    87.5 |   91.91 | 58-62,73,131-135  
  throttledOnce.ts |   86.66 |     86.2 |     100 |   86.66 | ...99,105,137-138 
-------------------|---------|----------|---------|---------|-------------------
Core Package - Full Text Report
-------------------|---------|----------|---------|---------|-------------------
File               | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-------------------|---------|----------|---------|---------|-------------------
All files          |   87.65 |    86.22 |   89.24 |   87.65 |                   
 src               |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
 src/__mocks__/fs  |       0 |        0 |       0 |       0 |                   
  promises.ts      |       0 |        0 |       0 |       0 | 1-48              
 src/agents        |   90.46 |    84.13 |   95.65 |   90.46 |                   
  ...transcript.ts |   87.63 |    83.52 |     100 |   87.63 | ...80,588,594-598 
  ...ent-resume.ts |   85.59 |    77.55 |   83.33 |   85.59 | ...1793-1797,1800 
  ...ound-tasks.ts |   96.15 |    90.13 |   98.76 |   96.15 | ...1732,1752-1755 
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...ent-result.ts |    96.8 |    92.68 |     100 |    96.8 | 106,129-131       
  ...n-registry.ts |    93.3 |    86.11 |     100 |    93.3 | ...85-991,996-998 
  ...w-snapshot.ts |   91.86 |    75.75 |     100 |   91.86 | ...54,178,185-187 
 src/agents/arena  |   76.32 |    67.71 |   78.94 |   76.32 |                   
  ...gentClient.ts |   79.47 |    88.88 |   81.81 |   79.47 | ...68-183,189-204 
  ArenaManager.ts  |   75.11 |    64.51 |   78.57 |   75.11 | ...1887,1893-1894 
  arena-events.ts  |   64.44 |      100 |      50 |   64.44 | ...71-175,178-183 
  diff-summary.ts  |    87.5 |    72.34 |     100 |    87.5 | ...32-133,137-138 
  index.ts         |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...gents/backends |   78.09 |    85.23 |   76.28 |   78.09 |                   
  ITermBackend.ts  |   97.97 |    93.93 |     100 |   97.97 | ...78-180,255,307 
  ...essBackend.ts |    90.9 |    85.36 |   93.33 |    90.9 | ...70,672,674-675 
  TmuxBackend.ts   |    90.7 |    76.55 |   97.36 |    90.7 | ...87,697,743-747 
  detect.ts        |   31.25 |      100 |       0 |   31.25 | 34-88             
  index.ts         |     100 |      100 |     100 |     100 |                   
  iterm-it2.ts     |     100 |     92.1 |     100 |     100 | 37-38,106         
  tmux-commands.ts |    6.64 |      100 |    3.03 |    6.64 | ...93-363,386-503 
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...agents/runtime |   90.55 |    86.14 |   87.64 |   90.55 |                   
  agent-context.ts |     100 |      100 |     100 |     100 |                   
  agent-core.ts    |   85.07 |     76.8 |   77.77 |   85.07 | ...2291,2337-2339 
  agent-events.ts  |     100 |      100 |     100 |     100 |                   
  ...t-headless.ts |   93.49 |    89.41 |   83.33 |   93.49 | ...96-497,500-501 
  ...nteractive.ts |   81.01 |    82.35 |   76.66 |   81.01 | ...33,535-538,541 
  ...statistics.ts |   98.29 |    82.55 |     100 |   98.29 | 141,165,206,239   
  agent-types.ts   |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...ool-policy.ts |   98.34 |      100 |    92.3 |   98.34 | 81-82             
  ...low-budget.ts |     100 |      100 |     100 |     100 |                   
  ...ow-journal.ts |   91.76 |    75.86 |     100 |   91.76 | ...38-139,179-181 
  ...chestrator.ts |   91.86 |    88.71 |   82.35 |   91.86 | ...1782,1831-1834 
  ...ow-prompts.ts |     100 |      100 |     100 |     100 |                   
  ...low-runner.ts |    94.3 |    87.17 |   91.66 |    94.3 | ...74,222,242-245 
  ...ow-sandbox.ts |   96.87 |    94.64 |     100 |   96.87 | ...24-325,330-331 
  ...flow-saved.ts |   96.51 |    94.36 |     100 |   96.51 | 134-135,234-237   
  ...flow-stall.ts |    97.9 |    83.33 |     100 |    97.9 | 138-139,236       
 src/agents/tasks  |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/agents/team   |   81.81 |    83.99 |    87.5 |   81.81 |                   
  TeamManager.ts   |   72.02 |    79.41 |   79.24 |   72.02 | ...1632,1655-1656 
  identity.ts      |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...sionBridge.ts |     100 |      100 |     100 |     100 |                   
  mailbox.ts       |   94.76 |    86.36 |   92.85 |   94.76 | 86-87,348-354     
  ...ptAddendum.ts |     100 |      100 |     100 |     100 |                   
  tasks.ts         |   88.85 |    82.56 |   96.29 |   88.85 | ...-990,1034-1035 
  team-events.ts   |   60.52 |      100 |      50 |   60.52 | ...40-144,151-155 
  teamHelpers.ts   |   92.02 |    94.91 |   95.23 |   92.02 | ...31-332,368-378 
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...eam/test-utils |   94.39 |     94.3 |   98.21 |   94.39 |                   
  ...on-harness.ts |   96.49 |    84.21 |     100 |   96.49 | 128-129,141-142   
  fake-agent.ts    |   98.49 |    95.16 |     100 |   98.49 | 201-203           
  fake-backend.ts  |   86.46 |    97.61 |   95.83 |   86.46 | 124-146           
 src/config        |   84.99 |     87.1 |   75.53 |   84.99 |                   
  approval-mode.ts |     100 |      100 |     100 |     100 |                   
  ...xtDefaults.ts |     100 |      100 |     100 |     100 |                   
  config.ts        |    84.3 |    86.82 |   73.97 |    84.3 | ...8338,8342-8343 
  constants.ts     |     100 |      100 |     100 |     100 |                   
  models.ts        |     100 |      100 |     100 |     100 |                   
  storage.ts       |   94.39 |    91.57 |   88.23 |   94.39 | ...45-446,449-450 
 ...nfirmation-bus |   98.27 |    97.14 |     100 |   98.27 |                   
  message-bus.ts   |   98.14 |    97.05 |     100 |   98.14 | 42-43             
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/core          |   91.99 |    88.01 |   93.38 |   91.99 |                   
  baseLlmClient.ts |   88.37 |    83.68 |   81.81 |   88.37 | ...51,664,670-672 
  client.ts        |   91.91 |    87.39 |   91.56 |   91.91 | ...3913,4007-4008 
  ...tGenerator.ts |   86.34 |    87.34 |   84.61 |   86.34 | ...81-482,527-533 
  ...lScheduler.ts |   90.04 |    84.76 |   96.19 |   90.04 | ...6223,6251-6267 
  geminiChat.ts    |   93.03 |    89.89 |   96.29 |   93.03 | ...4931,4977-4978 
  geminiRequest.ts |     100 |      100 |     100 |     100 |                   
  genai-compat.ts  |     100 |      100 |     100 |     100 |                   
  ...MediaLimit.ts |     100 |       96 |     100 |     100 | 96                
  ...htProtocol.ts |    9.09 |      100 |       0 |    9.09 | ...9,62-66,69-110 
  ...ream-error.ts |     100 |      100 |     100 |     100 |                   
  logger.ts        |   87.41 |    87.02 |     100 |   87.41 | ...64-568,614-628 
  ...lay-buffer.ts |     100 |      100 |     100 |     100 |                   
  ...dispatcher.ts |     100 |      100 |     100 |     100 |                   
  ...tyDefaults.ts |     100 |      100 |     100 |     100 |                   
  ...olExecutor.ts |   93.54 |    83.33 |      50 |   93.54 | 49-50             
  ...on-helpers.ts |   93.49 |    78.57 |     100 |   93.49 | ...10-211,228-229 
  ...issionFlow.ts |   98.97 |    96.96 |     100 |   98.97 | 107               
  ...try-policy.ts |     100 |      100 |     100 |     100 |                   
  ...ell-policy.ts |   95.19 |    89.47 |     100 |   95.19 | ...44-245,290-291 
  prompts.ts       |   93.64 |    91.42 |   83.33 |   93.64 | ...1208,1411-1412 
  ...ing-effort.ts |     100 |      100 |     100 |     100 |                   
  ...n-recovery.ts |   95.13 |       80 |     100 |   95.13 | ...06-107,142-144 
  ...t-profiler.ts |    97.9 |    81.15 |   88.23 |    97.9 | 117,124-125,130   
  ...port-retry.ts |     100 |      100 |     100 |     100 |                   
  tokenLimits.ts   |     100 |     92.1 |     100 |     100 | 87,122-139        
  ...reparation.ts |     100 |      100 |     100 |     100 |                   
  ...tion-guard.ts |     100 |      100 |     100 |     100 |                   
  ...allIdUtils.ts |   98.41 |    93.47 |     100 |   98.41 | 36,45             
  ...okTriggers.ts |   99.45 |    92.43 |     100 |   99.45 | 182,193           
  ...terruption.ts |     100 |     92.3 |     100 |     100 | 86,104            
  turn.ts          |   98.53 |    91.74 |     100 |   98.53 | ...25,653-654,701 
  ...l-fallback.ts |     100 |      100 |     100 |     100 |                   
 ...ntentGenerator |   96.33 |    88.12 |   96.15 |   96.33 |                   
  ...tGenerator.ts |   97.24 |    86.72 |   94.87 |   97.24 | ...1429,1458,1469 
  converter.ts     |   96.19 |    89.25 |     100 |   96.19 | ...1329,1550-1552 
  index.ts         |       0 |        0 |       0 |       0 | 1-21              
  usage.ts         |     100 |      100 |     100 |     100 |                   
 ...ntentGenerator |   88.78 |    72.36 |   89.47 |   88.78 |                   
  ...tGenerator.ts |   87.18 |    71.83 |   88.88 |   87.18 | ...58-364,382-383 
  index.ts         |     100 |       80 |     100 |     100 | 50                
 ...ntentGenerator |    95.6 |    88.74 |    92.3 |    95.6 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...tGenerator.ts |   95.52 |    87.88 |   91.89 |   95.52 | ...1195-1196,1224 
  ...tDetection.ts |     100 |      100 |     100 |     100 |                   
 ...ntentGenerator |   91.68 |    90.25 |   95.28 |   91.68 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  converter.ts     |   91.15 |    89.32 |   96.87 |   91.15 | ...1914,2083-2098 
  errorHandler.ts  |     100 |      100 |     100 |     100 |                   
  index.ts         |   60.31 |       75 |      50 |   60.31 | ...71,74-78,90-94 
  ...tGenerator.ts |    66.4 |    70.58 |   88.88 |    66.4 | ...51-157,168-169 
  pipeline.ts      |   96.64 |    91.01 |     100 |   96.64 | ...1103,1111,1206 
  ...ix-caching.ts |     100 |      100 |     100 |     100 |                   
  ...ureContext.ts |     100 |      100 |     100 |     100 |                   
  ...ingOptions.ts |       0 |        0 |       0 |       0 | 1                 
  ...CallParser.ts |   92.24 |     92.4 |     100 |   92.24 | ...28-529,549-552 
  ...kingParser.ts |     100 |    96.87 |     100 |     100 | 42                
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 ...rator/provider |   96.78 |    89.89 |   98.27 |   96.78 |                   
  dashscope.ts     |   97.58 |    92.14 |      95 |   97.58 | ...90-391,533-534 
  deepseek.ts      |   94.91 |    89.36 |     100 |   94.91 | ...31-132,145-146 
  default.ts       |   99.16 |    96.96 |     100 |   99.16 | 198               
  index.ts         |     100 |      100 |     100 |     100 |                   
  mimo.ts          |   94.11 |    66.66 |     100 |   94.11 | 29,52-53          
  minimax.ts       |     100 |      100 |     100 |     100 |                   
  mistral.ts       |   96.07 |    73.33 |     100 |   96.07 | 32-33             
  modelscope.ts    |     100 |      100 |     100 |     100 |                   
  types.ts         |       0 |        0 |       0 |       0 |                   
  utils.ts         |     100 |      100 |     100 |     100 |                   
  zai.ts           |   92.13 |    82.14 |     100 |   92.13 | ...,39-40,135-137 
 src/extension     |    86.2 |    83.24 |   92.33 |    86.2 |                   
  ...ive-safety.ts |     100 |      100 |     100 |     100 |                   
  ...-converter.ts |   78.32 |    71.83 |     100 |   78.32 | ...1122,1168-1169 
  corruptFile.ts   |     100 |       50 |     100 |     100 | 40-45             
  ...-converter.ts |   80.39 |     87.5 |     100 |   80.39 | 50-59             
  ...me-refresh.ts |     100 |      100 |     100 |     100 |                   
  ...sion-store.ts |   90.82 |    86.35 |   97.82 |   90.82 | ...1215-1221,1265 
  ...ionManager.ts |   81.06 |    78.78 |   81.52 |   81.06 | ...2705,2727-2728 
  ...references.ts |     100 |     90.9 |     100 |     100 | ...05,129,197,200 
  ...onSettings.ts |    92.3 |     94.4 |     100 |    92.3 | ...98-501,570-571 
  ...-converter.ts |    75.9 |    84.61 |   85.71 |    75.9 | ...98,202,214-248 
  github.ts        |   88.58 |    82.13 |     100 |   88.58 | ...62,952-953,963 
  http-client.ts   |   84.61 |       80 |     100 |   84.61 | 20-21             
  i18n.ts          |   78.26 |       96 |      50 |   78.26 | 104-110,116-123   
  index.ts         |     100 |      100 |     100 |     100 |                   
  marketplace.ts   |   88.39 |    83.11 |     100 |   88.39 | ...08,494,507-508 
  ...ork-policy.ts |   89.72 |       90 |     100 |   89.72 | ...36,148-154,156 
  npm.ts           |   89.02 |    81.81 |     100 |   89.02 | ...86-688,695-700 
  override.ts      |   94.11 |    93.33 |     100 |   94.11 | 63-64,81-82       
  redaction.ts     |     100 |      100 |     100 |     100 |                   
  settings.ts      |   66.26 |      100 |      50 |   66.26 | 81-107,141-146    
  ...ceRegistry.ts |   94.01 |    83.14 |     100 |   94.01 | ...38-344,365-366 
  storage.ts       |     100 |      100 |     100 |     100 |                   
  ...ableSchema.ts |     100 |      100 |     100 |     100 |                   
  variables.ts     |   88.95 |    83.78 |     100 |   88.95 | ...32-235,238-241 
  ...extraction.ts |   85.77 |    80.61 |   89.47 |   85.77 | ...02-205,260-261 
 src/followup      |   79.86 |    80.36 |    90.9 |   79.86 |                   
  followupState.ts |   98.44 |    95.74 |     100 |   98.44 | 236-237           
  index.ts         |     100 |      100 |     100 |     100 |                   
  overlayFs.ts     |   96.29 |    88.88 |     100 |   96.29 | 78,108,122        
  speculation.ts   |   71.45 |    66.01 |   71.42 |   71.45 | ...49-650,657-658 
  ...onToolGate.ts |     100 |    96.55 |     100 |     100 | 97                
  ...nGenerator.ts |   72.03 |    81.15 |   83.33 |   72.03 | ...68-219,331-333 
 src/generated     |       0 |        0 |       0 |       0 |                   
  git-commit.ts    |       0 |        0 |       0 |       0 | 1-10              
 src/goals         |   94.22 |    88.93 |    95.9 |   94.22 |                   
  ...eGoalStore.ts |   87.61 |    88.88 |   86.66 |   87.61 | ...85-188,196-204 
  goal-evidence.ts |   87.61 |    85.02 |   95.65 |   87.61 | ...13-614,637-640 
  ...projection.ts |   89.41 |    72.22 |   66.66 |   89.41 | ...28,131,135-137 
  ...ersistence.ts |   87.73 |    84.84 |      80 |   87.73 | ...-94,97,101-106 
  goal-protocol.ts |      92 |       90 |     100 |      92 | 109-110           
  goal-reducer.ts  |   92.45 |    85.93 |     100 |   92.45 | ...84-385,398,453 
  goal-runtime.ts  |   99.05 |    93.64 |     100 |   99.05 | ...20-721,744-745 
  goal-tools.ts    |   98.22 |    93.02 |      95 |   98.22 | ...46-147,248-249 
  ...rn-context.ts |     100 |      100 |     100 |     100 |                   
  goal-verifier.ts |   92.46 |    92.85 |     100 |   92.46 | ...69-172,185-187 
  goal-wire.ts     |       0 |        0 |       0 |       0 | 1-27              
  goalHook.ts      |   96.91 |    92.42 |     100 |   96.91 | 115-120,221-222   
  goalJudge.ts     |   95.84 |    87.09 |     100 |   95.84 | ...55-356,448-449 
  index.ts         |     100 |      100 |     100 |     100 |                   
 src/hooks         |   88.11 |    86.38 |   88.62 |   88.11 |                   
  ...okRegistry.ts |   86.48 |    77.08 |     100 |   86.48 | ...41-344,362-369 
  ...bortSignal.ts |     100 |      100 |     100 |     100 |                   
  context-usage.ts |     100 |      100 |     100 |     100 |                   
  ...terpolator.ts |   96.66 |    93.33 |     100 |   96.66 | 66-67             
  ...HookRunner.ts |   96.68 |    87.23 |     100 |   96.68 | 110-112,231-233   
  ...Aggregator.ts |   96.57 |    91.48 |     100 |   96.57 | ...20-321,402,404 
  ...entHandler.ts |   95.57 |    84.76 |   94.73 |   95.57 | ...1040-1041,1051 
  hookPlanner.ts   |   87.55 |    85.54 |   86.66 |   87.55 | ...22-226,233-244 
  hookRegistry.ts  |   92.53 |    85.43 |     100 |   92.53 | ...39,458,462,466 
  hookRunner.ts    |   62.65 |    72.34 |   66.66 |   62.65 | ...70-771,780-781 
  hookSystem.ts    |   87.64 |     98.5 |   70.83 |   87.64 | ...58-759,765-766 
  ...HookRunner.ts |   79.06 |    66.66 |      80 |   79.06 | ...33-434,452-456 
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...edCallback.ts |     100 |      100 |     100 |     100 |                   
  ...HookRunner.ts |   94.19 |    84.37 |   81.81 |   94.19 | ...76-384,458-459 
  ...SkillHooks.ts |   78.75 |       75 |   66.66 |   78.75 | 62-66,137-152     
  ...oksManager.ts |   94.87 |    88.88 |     100 |   94.87 | ...84,325,327-329 
  ssrfGuard.ts     |   86.45 |    89.13 |     100 |   86.45 | ...85,289-295,301 
  stopHookCap.ts   |     100 |      100 |     100 |     100 |                   
  trustedHooks.ts  |      90 |    52.63 |     100 |      90 | ...53,66-67,97-98 
  types.ts         |   94.25 |    96.12 |   88.88 |   94.25 | ...46-547,632-636 
  urlValidator.ts  |     100 |      100 |     100 |     100 |                   
  ...it-context.ts |     100 |      100 |     100 |     100 |                   
 src/ide           |   76.98 |    85.03 |   79.03 |   76.98 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  detect-ide.ts    |     100 |      100 |     100 |     100 |                   
  ide-client.ts    |   69.16 |    84.65 |   68.29 |   69.16 | ...1068,1097-1105 
  ide-installer.ts |   89.06 |    79.31 |     100 |   89.06 | ...36,143-147,160 
  ideContext.ts    |     100 |      100 |     100 |     100 |                   
  process-utils.ts |   84.84 |    71.79 |     100 |   84.84 | ...37,151,193-194 
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/lsp           |   58.96 |    70.57 |   66.14 |   58.96 |                   
  ...nfigLoader.ts |   80.55 |       72 |   95.45 |   80.55 | ...02-504,508-514 
  ...ionFactory.ts |   42.81 |    73.07 |      50 |   42.81 | ...76-427,433-450 
  ...Normalizer.ts |   23.09 |    13.72 |   30.43 |   23.09 | ...04-905,909-924 
  ...verManager.ts |   75.73 |     80.1 |   79.66 |   75.73 | ...1346,1352-1382 
  ...eLspClient.ts |   32.78 |       80 |   16.66 |   32.78 | ...89-293,299-300 
  ...LspService.ts |      60 |    73.36 |   78.26 |      60 | ...1575,1635-1645 
  configHash.ts    |     100 |      100 |     100 |     100 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/mcp           |    82.3 |    77.81 |   78.33 |    82.3 |                   
  configHash.ts    |     100 |      100 |     100 |     100 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  ...h-provider.ts |   86.95 |      100 |   33.33 |   86.95 | ...,93,97,101-102 
  ...h-provider.ts |   79.31 |    58.06 |     100 |   79.31 | ...26-933,940-942 
  ...en-storage.ts |   98.78 |    97.95 |     100 |   98.78 | 106-107           
  oauth-utils.ts   |   73.61 |    85.48 |    92.3 |   73.61 | ...46-366,392-421 
  ...n-provider.ts |   89.83 |       96 |   45.45 |   89.83 | ...43,147,151-152 
 .../token-storage |   82.12 |    88.19 |   89.28 |   82.12 |                   
  ...en-storage.ts |     100 |      100 |     100 |     100 |                   
  ...en-storage.ts |   87.08 |    87.03 |   95.23 |   87.08 | ...00-201,214-215 
  ...en-storage.ts |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...en-storage.ts |   68.14 |    82.35 |   64.28 |   68.14 | ...81-295,298-314 
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/memory        |   87.58 |    83.45 |    90.5 |   87.58 |                   
  ...y-document.ts |   89.52 |    84.61 |     100 |   89.52 | ...24-325,329-330 
  ...nel-memory.ts |   97.11 |    95.72 |   96.29 |   97.11 | ...85-287,361-362 
  const.ts         |   94.28 |     92.3 |     100 |   94.28 | 66-67             
  dream.ts         |    64.6 |    72.22 |      50 |    64.6 | ...04-109,124-165 
  ...entPlanner.ts |     100 |    83.33 |     100 |     100 | 136,146           
  entries.ts       |   75.59 |    84.84 |   83.33 |   75.59 | ...56-157,172-180 
  extract.ts       |   91.48 |    75.75 |     100 |   91.48 | ...99,118-121,189 
  ...entPlanner.ts |   91.59 |    76.74 |     100 |   91.59 | ...05,114-117,293 
  ...ionPlanner.ts |       0 |        0 |       0 |       0 | 1                 
  forget.ts        |   81.83 |       75 |   83.33 |   81.83 | ...51,474,478-507 
  indexer.ts       |   94.14 |       84 |     100 |   94.14 | ...32-233,334,337 
  ...kill-agent.ts |   97.94 |    89.36 |     100 |   97.94 | 82-83,179-180     
  manager.ts       |    78.4 |    82.29 |   77.77 |    78.4 | ...1482,1495-1497 
  ...ent-config.ts |   86.95 |    82.52 |   86.36 |   86.95 | ...68,388,395-401 
  memoryAge.ts     |   90.47 |       80 |     100 |   90.47 | 50-51             
  paths.ts         |   95.29 |    96.59 |     100 |   95.29 | ...80-381,402-403 
  ...ing-skills.ts |     100 |       72 |     100 |     100 | 31-35,73-78,97    
  prompt.ts        |   97.26 |    87.03 |     100 |   97.26 | ...10-218,222,225 
  recall.ts        |   82.06 |       75 |    90.9 |   82.06 | ...59-364,395-406 
  refresh.ts       |   89.85 |    82.92 |     100 |   89.85 | ...54-155,162-163 
  ...ceSelector.ts |    93.1 |    81.81 |     100 |    93.1 | ...25,127-128,136 
  remember.ts      |   98.89 |    90.19 |     100 |   98.89 | 50,70             
  scan.ts          |   93.12 |    74.19 |     100 |   93.12 | ...08-109,154,157 
  scopes.ts        |     100 |      100 |     100 |     100 |                   
  ...et-scanner.ts |     100 |      100 |     100 |     100 |                   
  ...entPlanner.ts |   77.24 |    74.07 |   72.22 |   77.24 | ...52-456,459,465 
  status.ts        |   10.52 |      100 |       0 |   10.52 | 41-98             
  store.ts         |   92.92 |    81.81 |     100 |   92.92 | ...16-117,147-148 
  ...git-status.ts |     100 |     87.5 |     100 |     100 | 30                
  ...cret-guard.ts |     100 |      100 |     100 |     100 |                   
  ...emory-sync.ts |   94.24 |    82.85 |     100 |   94.24 | ...34-236,246-247 
  types.ts         |     100 |      100 |     100 |     100 |                   
  ...ontextFile.ts |   81.21 |    81.53 |   81.81 |   81.21 | ...63-277,291-296 
 src/mocks         |       0 |        0 |       0 |       0 |                   
  msw.ts           |       0 |        0 |       0 |       0 | 1-9               
 src/models        |   92.55 |    88.97 |   91.13 |   92.55 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  ...tor-config.ts |   97.77 |    91.83 |     100 |   97.77 | 155,161,171       
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...nfigErrors.ts |   74.22 |    47.82 |   84.61 |   74.22 | ...,67-74,106-117 
  ...igResolver.ts |   98.71 |    93.33 |     100 |   98.71 | 166,328,334       
  modelRegistry.ts |     100 |    98.11 |     100 |     100 | 177,261           
  modelsConfig.ts  |   89.36 |    86.93 |   88.09 |   89.36 | ...1404,1433-1434 
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/output        |     100 |      100 |     100 |     100 |                   
  ...-formatter.ts |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/permissions   |   83.77 |    91.26 |   71.07 |   83.77 |                   
  autoMode.ts      |   97.66 |    93.13 |     100 |   97.66 | ...82-589,635,712 
  ...transcript.ts |      98 |       84 |     100 |      98 | 200-201           
  classifier.ts    |      94 |    94.54 |     100 |      94 | 158-165,389-393   
  ...erousRules.ts |     100 |    89.36 |     100 |     100 | 110,133,147,175   
  ...alTracking.ts |     100 |      100 |     100 |     100 |                   
  ...e-commands.ts |   86.77 |     73.8 |     100 |   86.77 | 131-141,210-214   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...on-manager.ts |   86.54 |    89.63 |      80 |   86.54 | ...1096,1202-1206 
  rule-parser.ts   |   94.49 |     92.7 |     100 |   94.49 | ...1447,1481-1483 
  ...-semantics.ts |   70.44 |    91.07 |   46.66 |   70.44 | ...2237,2311-2314 
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...sifier-prompts |   99.04 |    95.23 |     100 |   99.04 |                   
  system-prompt.ts |   99.04 |    95.23 |     100 |   99.04 | 220               
 src/prompts       |   83.63 |      100 |    87.5 |   83.63 |                   
  mcp-prompts.ts   |   18.18 |      100 |       0 |   18.18 | 11-19             
  ...t-registry.ts |     100 |      100 |     100 |     100 |                   
 src/providers     |   83.71 |     78.5 |   81.25 |   83.71 |                   
  all-providers.ts |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  install.ts       |   93.11 |     84.5 |     100 |   93.11 | ...56-257,330-331 
  ...der-config.ts |   75.85 |    73.84 |   78.26 |   75.85 | ...73-474,502-503 
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 ...viders/presets |   97.82 |    91.66 |   63.63 |   97.82 |                   
  ...oding-plan.ts |   87.34 |      100 |       0 |   87.34 | 82-84,87-89,91-94 
  ...a-standard.ts |     100 |      100 |     100 |     100 |                   
  ...token-plan.ts |     100 |      100 |     100 |     100 |                   
  ...m-provider.ts |   97.05 |    81.25 |      75 |   97.05 | 118-119           
  deepseek.ts      |     100 |      100 |     100 |     100 |                   
  grok.ts          |     100 |      100 |     100 |     100 |                   
  idealab.ts       |     100 |      100 |     100 |     100 |                   
  minimax.ts       |     100 |      100 |     100 |     100 |                   
  modelscope.ts    |     100 |      100 |     100 |     100 |                   
  openrouter.ts    |     100 |      100 |     100 |     100 |                   
  requesty.ts      |     100 |      100 |     100 |     100 |                   
  zai.ts           |     100 |      100 |     100 |     100 |                   
 src/qwen          |   85.41 |    78.52 |   95.89 |   85.41 |                   
  ...tGenerator.ts |   98.64 |    98.18 |     100 |   98.64 | 105-106           
  qwenOAuth2.ts    |   82.79 |    73.29 |   90.62 |   82.79 | ...1205-1221,1251 
  ...kenManager.ts |   85.36 |    76.61 |     100 |   85.36 | ...52-757,778-783 
 src/resources     |     100 |      100 |     100 |     100 |                   
  ...e-registry.ts |     100 |      100 |     100 |     100 |                   
 src/services      |   89.57 |    84.36 |   96.84 |   89.57 |                   
  ...ionTrailer.ts |     100 |      100 |     100 |     100 |                   
  ...llRegistry.ts |   97.68 |    85.71 |     100 |   97.68 | ...96,119,490-491 
  ...ionService.ts |    97.3 |    95.09 |     100 |    97.3 | ...,870,1013-1021 
  ...ingService.ts |   90.91 |    84.17 |   95.45 |   90.91 | ...2058,2085-2086 
  ...ttribution.ts |   91.73 |    87.71 |      90 |   91.73 | ...80-685,826-827 
  ...utSlimming.ts |    97.2 |    93.93 |     100 |    97.2 | ...39-340,378-381 
  cronScheduler.ts |   94.17 |    90.45 |      98 |   94.17 | ...1333,1736-1737 
  cronTasksFile.ts |   95.49 |    90.82 |     100 |   95.49 | ...37,346-347,483 
  cronTasksLock.ts |   94.44 |    89.47 |     100 |   94.44 | ...02-103,132-133 
  ...eryService.ts |   96.22 |    93.54 |      90 |   96.22 | 121,155-156,161   
  ...oryService.ts |   88.17 |    79.02 |    92.3 |   88.17 | ...1303,1344-1347 
  fileReadCache.ts |     100 |      100 |     100 |     100 |                   
  ...temService.ts |    92.8 |    84.68 |   94.11 |    92.8 | ...41,467-474,519 
  ...ratedFiles.ts |      96 |    88.23 |     100 |      96 | 119-120,146-147   
  gitInit.ts       |     100 |      100 |     100 |     100 |                   
  ...reeService.ts |    73.7 |    68.49 |   95.83 |    73.7 | ...2196,2225-2226 
  ...on-service.ts |   87.38 |       72 |     100 |   87.38 | ...01-305,343-344 
  ...references.ts |   98.39 |    88.76 |     100 |   98.39 | 154-155,215-216   
  ...ionService.ts |   98.22 |    97.34 |     100 |   98.22 | ...75-676,723-724 
  ...ticsDumper.ts |   98.37 |    95.23 |     100 |   98.37 | 185-186           
  ...ureMonitor.ts |   95.82 |    90.52 |   97.05 |   95.82 | ...60,861,875-877 
  ...orRegistry.ts |    97.3 |    91.22 |     100 |    97.3 | ...53-454,611-612 
  ...ttachments.ts |   97.74 |    90.85 |     100 |   97.74 | 298-308,646       
  ...ersistence.ts |   90.95 |    78.75 |     100 |   90.95 | ...78,963-964,992 
  ...on-service.ts |   94.49 |    92.26 |   97.14 |   94.49 | ...98-600,656-664 
  ...ce-service.ts |   98.38 |    93.75 |   88.88 |   98.38 | 63-64             
  ...ipt-reader.ts |   93.69 |    89.22 |   96.07 |   93.69 | ...1094-1095,1158 
  ...est-helper.ts |       0 |        0 |       0 |       0 | 1-65              
  ...iter-lease.ts |   82.81 |    74.08 |    97.5 |   82.81 | ...2364,2376-2379 
  sessionRecap.ts  |   67.56 |    43.47 |     100 |   67.56 | ...60,178,180-183 
  ...ionService.ts |   88.94 |    83.69 |   97.14 |   88.94 | ...2450,2520-2540 
  sessionTitle.ts  |   94.19 |    73.21 |     100 |   94.19 | ...43-246,277-278 
  ...ionService.ts |   84.35 |    78.43 |   97.14 |   84.35 | ...2472,2478-2483 
  ...pInhibitor.ts |   97.42 |    92.77 |     100 |   97.42 | ...30,169,369-370 
  ...Estimation.ts |     100 |    88.23 |     100 |     100 | 118-119           
  ...ageService.ts |   97.76 |    91.59 |   93.75 |   97.76 | ...61-262,366,567 
  ...UseSummary.ts |   94.63 |    88.46 |     100 |   94.63 | ...62-164,214-215 
  ...rd-service.ts |     100 |    88.37 |     100 |     100 | ...29,145-146,241 
  ...oryService.ts |   90.72 |    84.07 |     100 |   90.72 | ...06-509,561-562 
  ...reeCleanup.ts |   14.42 |      100 |   33.33 |   14.42 | 58-186            
  ...ionService.ts |   87.98 |    86.95 |     100 |   87.98 | ...38-439,455-456 
 ...icrocompaction |   99.41 |    96.55 |     100 |   99.41 |                   
  microcompact.ts  |   99.41 |    96.55 |     100 |   99.41 | 244-245,677       
 ...s/visionBridge |   98.81 |    92.12 |     100 |   98.81 |                   
  ...capability.ts |     100 |      100 |     100 |     100 |                   
  ...part-utils.ts |     100 |      100 |     100 |     100 |                   
  ...ion-bridge.ts |   98.72 |    82.35 |     100 |   98.72 | 65,71             
  ...-constants.ts |     100 |      100 |     100 |     100 |                   
  ...ge-service.ts |   98.61 |     94.7 |     100 |   98.61 | ...06,666,679-680 
 src/skills        |   89.21 |    85.66 |   93.54 |   89.21 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...activation.ts |     100 |    93.33 |     100 |     100 | 93,112            
  skill-curator.ts |   89.52 |    80.95 |     100 |   89.52 | ...95-896,898-901 
  skill-load.ts    |   94.84 |     87.5 |     100 |   94.84 | ...03,223,235-237 
  skill-manager.ts |   84.82 |    85.29 |   83.33 |   84.82 | ...1243,1250-1254 
  skill-paths.ts   |   90.42 |     87.5 |     100 |   90.42 | ...19-120,125-126 
  symlinkScope.ts  |     100 |      100 |     100 |     100 |                   
  types.ts         |   97.91 |       98 |     100 |   97.91 | 277-278           
 ...ataviz/scripts |   80.06 |    95.23 |   88.23 |   80.06 |                   
  ...te_palette.js |   80.06 |    95.23 |   88.23 |   80.06 | 261-296,306-328   
 ...s/bundled/loop |   97.48 |    95.77 |     100 |   97.48 |                   
  ...omous-loop.ts |     100 |      100 |     100 |     100 |                   
  ...-task-file.ts |   94.85 |     92.4 |     100 |   94.85 | ...56,367,375-376 
  ...k-resolver.ts |     100 |      100 |     100 |     100 |                   
 src/subagents     |   87.72 |    89.01 |   96.55 |   87.72 |                   
  ...ter-schema.ts |     100 |    98.07 |     100 |     100 | 99                
  ...tin-agents.ts |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...nt-manager.ts |   84.48 |    85.91 |   94.87 |   84.48 | ...1582,1659-1660 
  types.ts         |     100 |      100 |     100 |     100 |                   
  validation.ts    |   92.46 |    95.18 |     100 |   92.46 | 47-52,63-68,71-76 
 src/telemetry     |   81.39 |    83.87 |   84.66 |   81.39 |                   
  ...ty-tracker.ts |     100 |      100 |     100 |     100 |                   
  config.ts        |     100 |      100 |     100 |     100 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  ...on-metrics.ts |   99.07 |    80.95 |     100 |   99.07 | 183,197           
  ...on-tracing.ts |   76.31 |    74.62 |   73.68 |   76.31 | ...80,387-389,405 
  ...attributes.ts |   95.15 |    87.27 |     100 |   95.15 | ...97-198,216-217 
  ...ag-metrics.ts |     100 |    77.77 |     100 |     100 | 21,40             
  ...t-loop-lag.ts |   96.85 |    85.71 |     100 |   96.85 | 170-173           
  ...-exporters.ts |   65.78 |    83.33 |   55.55 |   65.78 | ...04-105,108-109 
  ...ai-content.ts |    74.5 |    66.41 |   91.66 |    74.5 | ...1480,1493-1502 
  ...i-provider.ts |     100 |       99 |     100 |     100 | 99                
  ...ai-request.ts |   87.52 |    92.79 |   83.78 |   87.52 | ...55-561,564-570 
  gen-ai-usage.ts  |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...t.circular.ts |       0 |        0 |       0 |       0 | 1-111             
  ...-processor.ts |    99.1 |    95.72 |      95 |    99.1 | 145,369-370       
  ...t.circular.ts |       0 |        0 |       0 |       0 | 1-128             
  loggers.ts       |   57.84 |    74.16 |   65.45 |   57.84 | ...1438,1455-1475 
  metrics.ts       |   80.04 |    82.75 |   80.32 |   80.04 | ...1105,1108-1119 
  otlp-urls.ts     |     100 |      100 |     100 |     100 |                   
  ...attributes.ts |     100 |      100 |     100 |     100 |                   
  ...ime-config.ts |       0 |        0 |       0 |       0 | 1                 
  sanitize.ts      |      80 |    83.33 |     100 |      80 | 35-36,41-42       
  ...rters-grpc.ts |     100 |      100 |     100 |     100 |                   
  ...rters-http.ts |     100 |      100 |     100 |     100 |                   
  sdk-impl.ts      |   91.06 |    87.15 |   68.75 |   91.06 | ...32,478-479,495 
  sdk.ts           |   79.22 |    89.18 |   63.63 |   79.22 | ...57-161,199-221 
  ...on-context.ts |     100 |      100 |     100 |     100 |                   
  ...on-tracing.ts |    91.1 |    88.68 |   96.77 |    91.1 | ...1737,1768-1771 
  ...etry-utils.ts |     100 |      100 |     100 |     100 |                   
  ...l-decision.ts |     100 |      100 |     100 |     100 |                   
  trace-context.ts |     100 |      100 |     100 |     100 |                   
  ...e-id-utils.ts |     100 |      100 |     100 |     100 |                   
  tracer.ts        |   98.56 |    88.63 |     100 |   98.56 | 52,101            
  types.ts         |   82.51 |    94.77 |   86.04 |   82.51 | ...1374,1378-1385 
  uiTelemetry.ts   |   97.18 |    93.93 |      88 |   97.18 | ...70,314,461-462 
 ...ry/qwen-logger |   74.23 |     80.7 |      70 |   74.23 |                   
  event-types.ts   |       0 |        0 |       0 |       0 |                   
  qwen-logger.ts   |   74.23 |    80.53 |   69.49 |   74.23 | ...1122,1160-1161 
 src/test-utils    |    95.6 |    98.27 |   81.57 |    95.6 |                   
  config.ts        |     100 |      100 |     100 |     100 |                   
  ...st-helpers.ts |   94.11 |       90 |     100 |   94.11 | 69-70             
  index.ts         |     100 |      100 |     100 |     100 |                   
  mock-tool.ts     |   94.85 |      100 |   78.78 |   94.85 | ...53,227-228,241 
  ...aceContext.ts |     100 |      100 |     100 |     100 |                   
 src/tools         |    86.1 |    84.88 |   88.42 |    86.1 |                   
  ...erQuestion.ts |   89.71 |    80.76 |   91.66 |   89.71 | ...66-367,374-375 
  ...-registrar.ts |    77.7 |    66.66 |   66.66 |    77.7 | ...72-277,292-294 
  ...ub-session.ts |   89.67 |     91.3 |   81.81 |   89.67 | ...03-304,315-322 
  cron-create.ts   |   90.64 |    92.85 |   72.72 |   90.64 | ...,73-74,223-231 
  cron-delete.ts   |   97.56 |      100 |   83.33 |   97.56 | 31-32             
  cron-list.ts     |   98.23 |    95.34 |    87.5 |   98.23 | 57-58             
  diffOptions.ts   |     100 |      100 |     100 |     100 |                   
  display-image.ts |   87.42 |    84.84 |   88.88 |   87.42 | ...29-134,194-195 
  edit.ts          |    82.7 |    86.77 |   81.25 |    82.7 | ...43-744,863-913 
  ...r-worktree.ts |   83.14 |    67.56 |    87.5 |   83.14 | ...84-187,278-279 
  enterPlanMode.ts |      85 |     82.6 |    87.5 |      85 | ...28-133,161-175 
  exit-worktree.ts |   83.29 |    83.65 |   94.44 |   83.29 | ...14-515,537-538 
  exitPlanMode.ts  |      95 |    85.29 |     100 |      95 | ...21-325,344,378 
  ...permission.ts |     100 |      100 |     100 |     100 |                   
  glob.ts          |   96.33 |     88.5 |     100 |   96.33 | ...24-225,373,376 
  grep.ts          |   90.73 |    86.61 |   85.71 |   90.73 | ...76-677,727-728 
  ...adTracking.ts |     100 |      100 |     100 |     100 |                   
  image-gen.ts     |   91.66 |    77.41 |    90.9 |   91.66 | ...13-214,221-222 
  list-agents.ts   |   94.02 |    82.35 |   83.33 |   94.02 | 31-32,47-48       
  loop-wakeup.ts   |   99.27 |    92.85 |     100 |   99.27 | 45                
  ls.ts            |   96.74 |    90.27 |     100 |   96.74 | 176-181,212,216   
  lsp.ts           |   72.71 |     59.5 |   90.32 |   72.71 | ...1212,1214-1215 
  ...nt-manager.ts |   81.49 |     80.1 |   85.71 |   81.49 | ...3217,3219-3220 
  mcp-client.ts    |   79.87 |    85.58 |   89.47 |   79.87 | ...2259,2263-2266 
  ...ry-timeout.ts |     100 |      100 |     100 |     100 |                   
  mcp-errors.ts    |     100 |      100 |     100 |     100 |                   
  ...pool-entry.ts |   77.56 |    84.11 |   77.14 |   77.56 | ...1291,1299-1300 
  ...ool-events.ts |       8 |        0 |       0 |       8 | 132-158           
  mcp-pool-key.ts  |   97.46 |    93.93 |     100 |   97.46 | 175-176           
  ...ce-content.ts |   96.55 |    91.17 |     100 |   96.55 | 80-82             
  mcp-retry.ts     |   97.67 |    95.65 |     100 |   97.67 | 131-132           
  mcp-status.ts    |     100 |      100 |     100 |     100 |                   
  mcp-tool.ts      |   98.33 |    93.51 |     100 |   98.33 | ...-973,1028-1029 
  ...sport-pool.ts |   83.49 |    80.15 |   84.61 |   83.49 | ...1409,1416-1420 
  ...ace-budget.ts |   87.27 |     82.6 |     100 |   87.27 | ...00-305,340-345 
  memory-config.ts |     100 |      100 |     100 |     100 |                   
  ...iable-tool.ts |     100 |    84.61 |     100 |     100 | 101,108           
  monitor.ts       |   91.74 |    84.28 |   88.46 |   91.74 | ...93,606,804-809 
  notebook-edit.ts |   85.55 |    77.39 |   81.25 |   85.55 | ...86-902,948-949 
  ...escendants.ts |   36.17 |    64.51 |   55.55 |   36.17 | ...46-310,385-390 
  ...nforcement.ts |   81.45 |    89.74 |     100 |   81.45 | 147-158,207-220   
  read-file.ts     |   95.49 |    88.52 |   86.66 |   95.49 | ...49,464,536-537 
  ...p-resource.ts |   96.85 |      100 |   91.66 |   96.85 | 92-96             
  ...d-artifact.ts |   91.18 |    86.71 |    87.5 |   91.18 | ...26-427,441-453 
  ripGrep.ts       |    94.6 |    87.26 |   95.23 |    94.6 | ...33-734,740-741 
  ...-transport.ts |   71.42 |    55.55 |   71.42 |   71.42 | ...36-137,143-144 
  send-message.ts  |   81.13 |    89.74 |    62.5 |   81.13 | ...80-286,363-371 
  ...n-mcp-view.ts |   93.57 |     92.3 |      90 |   93.57 | 122-130           
  shell.ts         |   78.67 |    84.04 |   91.91 |   78.67 | ...5019,5082-5083 
  skill-utils.ts   |     100 |      100 |     100 |     100 |                   
  skill.ts         |   91.39 |    92.55 |      90 |   91.39 | ...84,488,534-556 
  ...eticOutput.ts |   95.12 |      100 |      80 |   95.12 | 87-88             
  task-create.ts   |    94.4 |    93.33 |   81.81 |    94.4 | 45-49,63-64,95    
  task-list.ts     |   73.38 |    77.77 |   83.33 |   73.38 | ...02,105,109-116 
  task-stop.ts     |   93.14 |    96.15 |   85.71 |   93.14 | 39-40,54-64       
  task-update.ts   |   82.89 |    83.92 |    92.3 |   82.89 | ...14-422,454-465 
  team-create.ts   |   97.22 |    85.71 |   83.33 |   97.22 | 48-49,129-130     
  team-delete.ts   |   86.74 |    83.33 |   83.33 |   86.74 | 37-38,42-48,72-73 
  ...n-approval.ts |   92.14 |    96.77 |   77.77 |   92.14 | 38-39,42-43,93-99 
  todoWrite.ts     |   95.13 |    87.85 |   93.33 |   95.13 | ...23-527,540-545 
  tool-error.ts    |     100 |      100 |     100 |     100 |                   
  tool-names.ts    |     100 |      100 |     100 |     100 |                   
  tool-registry.ts |   78.57 |    79.59 |    82.6 |   78.57 | ...89-990,998-999 
  tool-search.ts   |   96.19 |    89.72 |   93.33 |   96.19 | ...09,259-264,426 
  tools.ts         |   93.11 |    92.53 |   91.66 |   93.11 | ...69-570,586-592 
  ...reapproved.ts |   99.27 |    94.11 |     100 |   99.27 | 170               
  web-fetch.ts     |   96.05 |    90.54 |   96.77 |   96.05 | ...85-786,800-801 
  web-search.ts    |   90.53 |    83.57 |      80 |   90.53 | ...1007,1065-1068 
  write-file.ts    |    86.7 |    84.92 |   88.88 |    86.7 | ...24-827,864-899 
  zoom-image.ts    |   95.76 |    93.75 |      90 |   95.76 | 54-59,203-204     
 src/tools/agent   |   87.22 |    87.68 |   88.69 |   87.22 |                   
  agent.ts         |   85.84 |    86.59 |   86.31 |   85.84 | ...4315,4337-4347 
  fork-profile.ts  |   93.65 |       90 |     100 |   93.65 | ...33-134,171-174 
  fork-subagent.ts |   98.73 |       95 |     100 |   98.73 | 101-102,173       
 ...tools/artifact |   95.78 |    92.51 |   88.63 |   95.78 |                   
  artifact-tool.ts |   91.46 |    88.46 |   71.42 |   91.46 | ...13-314,322-325 
  ...-publisher.ts |     100 |    85.71 |     100 |     100 | 32                
  ...-publisher.ts |   96.74 |    97.72 |    87.5 |   96.74 | 29-30,156-157     
  html.ts          |     100 |    96.77 |     100 |     100 | 122               
  ...-publisher.ts |     100 |       80 |     100 |     100 | 30                
  oss-publisher.ts |    98.1 |    91.48 |     100 |    98.1 | 43-45             
  publisher.ts     |     100 |      100 |     100 |     100 |                   
 ...s/computer-use |   90.21 |    82.17 |   78.08 |   90.21 |                   
  bootstrap.ts     |   59.42 |    80.95 |   41.66 |   59.42 | ...35-339,341-345 
  client.ts        |   80.11 |       90 |   77.77 |   80.11 | ...97,242-243,274 
  constants.ts     |     100 |    94.73 |     100 |     100 | 129,256           
  downloader.ts    |   65.29 |    52.77 |   58.33 |   65.29 | ...99-300,316-355 
  index.ts         |     100 |      100 |     100 |     100 |                   
  install-state.ts |   94.44 |    72.72 |     100 |   94.44 | 44-45             
  ...n-detector.ts |     100 |     87.5 |     100 |     100 | 50                
  schemas.ts       |     100 |      100 |     100 |     100 |                   
  tool.ts          |    96.3 |    85.71 |     100 |    96.3 | 75-76,184,252-258 
 ...tools/workflow |   86.24 |    84.81 |      75 |   86.24 |                   
  workflow.ts      |   86.24 |    84.81 |      75 |   86.24 | ...61,506,508-509 
 src/utils         |   92.84 |    89.61 |   96.84 |   92.84 |                   
  LruCache.ts      |     100 |      100 |     100 |     100 |                   
  ...Controller.ts |     100 |      100 |     100 |     100 |                   
  ...ssageQueue.ts |     100 |      100 |     100 |     100 |                   
  ...cFileWrite.ts |   94.94 |    92.47 |     100 |   94.94 | ...43-544,651-655 
  bareMode.ts      |   81.81 |      100 |      50 |   81.81 | 18-19             
  ...ry-content.ts |   98.45 |    95.45 |     100 |   98.45 | 132-133,159-160   
  browser.ts       |   86.84 |    78.94 |     100 |   86.84 | 34,36-37,65-66    
  btwUtils.ts      |   13.95 |      100 |       0 |   13.95 | 17-31,34-55       
  bundlePaths.ts   |     100 |      100 |     100 |     100 |                   
  ...on-context.ts |     100 |      100 |     100 |     100 |                   
  ...ncyLimiter.ts |   94.64 |    95.23 |     100 |   94.64 | 64-66             
  ...igResolver.ts |     100 |      100 |     100 |     100 |                   
  ...engthError.ts |   91.06 |    89.47 |     100 |   91.06 | ...46-147,154-155 
  ...n-branches.ts |   95.81 |    93.95 |      95 |   95.81 | ...91-492,504-517 
  ...tion-chain.ts |     100 |      100 |     100 |     100 |                   
  cronDisplay.ts   |     100 |    97.61 |     100 |     100 | 46                
  cronParser.ts    |   95.34 |    93.33 |     100 |   95.34 | 41-42,47-48,70-71 
  debugLogger.ts   |   96.66 |    96.66 |   88.88 |   96.66 | 192-196           
  editHelper.ts    |   93.63 |     83.9 |     100 |   93.63 | ...27-428,462-463 
  editor.ts        |   97.65 |    95.45 |     100 |   97.65 | ...35-336,338-339 
  encoding.ts      |     100 |      100 |     100 |     100 |                   
  env.ts           |     100 |      100 |     100 |     100 |                   
  ...arResolver.ts |   94.28 |    88.88 |     100 |   94.28 | 28-29,125-126     
  ...entContext.ts |   96.63 |    90.13 |   96.66 |   96.63 | ...42,444-445,512 
  errorParsing.ts  |     100 |      100 |     100 |     100 |                   
  ...rReporting.ts |   95.65 |    93.33 |     100 |   95.65 | 37-38             
  errors.ts        |   82.62 |    94.32 |    61.9 |   82.62 | ...62-378,382-388 
  fetch.ts         |   90.68 |    82.51 |     100 |   90.68 | ...72,483-484,503 
  fileUtils.ts     |   94.87 |    92.95 |   96.15 |   94.87 | ...1907,1915-1916 
  forkedAgent.ts   |   92.45 |    82.35 |   93.75 |   92.45 | ...34,642,647-654 
  formatters.ts    |     100 |      100 |     100 |     100 |                   
  ...eUtilities.ts |    92.4 |    86.95 |     100 |    92.4 | ...52-158,168-169 
  ...rStructure.ts |   94.39 |    94.28 |     100 |   94.39 | ...29-132,343-348 
  getPty.ts        |   31.57 |       50 |     100 |   31.57 | 26-38             
  git-branches.ts  |    91.6 |    84.21 |    92.3 |    91.6 | ...90,405-410,570 
  gitDiff.ts       |   95.19 |    81.36 |     100 |   95.19 | ...1073,1419-1420 
  gitDirect.ts     |   98.84 |    94.28 |     100 |   98.84 | 234,318           
  ...noreParser.ts |   94.48 |    93.22 |     100 |   94.48 | ...23-124,158-159 
  gitUtils.ts      |   78.02 |    81.25 |   85.71 |   78.02 | ...22-123,147-198 
  github-prs.ts    |   95.74 |    82.27 |     100 |   95.74 | 216,314-322       
  iconvHelper.ts   |     100 |      100 |     100 |     100 |                   
  ...rePatterns.ts |     100 |      100 |     100 |     100 |                   
  image-view.ts    |   95.12 |    93.33 |     100 |   95.12 | ...68-172,240-244 
  ...ionManager.ts |     100 |     90.9 |     100 |     100 | 27                
  ...lPromptIds.ts |     100 |      100 |     100 |     100 |                   
  ...on-context.ts |     100 |      100 |     100 |     100 |                   
  jsonl-utils.ts   |   95.27 |     93.1 |     100 |   95.27 | ...16-317,359-362 
  ...-detection.ts |     100 |      100 |     100 |     100 |                   
  ...iconv-lite.ts |     100 |      100 |     100 |     100 |                   
  ...simple-git.ts |   96.77 |    91.66 |     100 |   96.77 | 38                
  ...m-headless.ts |      96 |    88.88 |     100 |      96 | 34                
  ...iagnostics.ts |    96.4 |     94.2 |     100 |    96.4 | ...66,293-294,376 
  ...yDiscovery.ts |    92.4 |    89.13 |     100 |    92.4 | ...28,331,522-525 
  ...tProcessor.ts |   94.01 |       90 |     100 |   94.01 | ...47-353,445-446 
  ...Inspectors.ts |     100 |      100 |     100 |     100 |                   
  modelId.ts       |   98.96 |    98.21 |     100 |   98.96 | 153               
  ...kerChecker.ts |    90.9 |    91.66 |     100 |    90.9 | 73-79             
  notebook.ts      |   94.57 |    89.91 |   95.83 |   94.57 | ...21,333,385-387 
  openaiLogger.ts  |   91.66 |    89.74 |     100 |   91.66 | ...26-228,251-256 
  osc8.ts          |   54.26 |    64.86 |   83.33 |   54.26 | ...72-195,197-257 
  partUtils.ts     |     100 |    98.64 |     100 |     100 | 211               
  pathReader.ts    |     100 |      100 |     100 |     100 |                   
  paths.ts         |   93.99 |    92.85 |     100 |   93.99 | ...88-489,491-493 
  pdf.ts           |   92.17 |    85.81 |     100 |   92.17 | ...64-565,606-611 
  projectPath.ts   |     100 |      100 |     100 |     100 |                   
  projectRoot.ts   |   71.73 |    78.57 |     100 |   71.73 | 54-66             
  ...ectSummary.ts |   89.62 |    72.41 |     100 |   89.62 | ...40-145,196-199 
  ...tIdContext.ts |     100 |      100 |     100 |     100 |                   
  proxyUtils.ts    |     100 |      100 |     100 |     100 |                   
  ...rDetection.ts |   71.15 |       86 |     100 |   71.15 | ...-90,96-101,147 
  ...noreParser.ts |   92.63 |    91.66 |     100 |   92.63 | ...77-178,197-198 
  rateLimit.ts     |   93.75 |    89.62 |     100 |   93.75 | ...13,218-219,262 
  ...text-range.ts |    96.9 |    86.85 |     100 |    96.9 | ...59-660,735-736 
  readManyFiles.ts |   95.75 |    80.86 |     100 |   95.75 | ...05,558,568-572 
  retry.ts         |   96.09 |    92.52 |     100 |   96.09 | ...67,558-559,577 
  retryContext.ts  |     100 |      100 |     100 |     100 |                   
  ...sification.ts |   97.63 |    97.02 |     100 |   97.63 | ...17,251-252,278 
  retryPolicy.ts   |   97.72 |    90.56 |     100 |   97.72 | 130-131           
  ripgrepUtils.ts  |   90.04 |    93.43 |   95.45 |   90.04 | ...55-565,598-599 
  ...sDiscovery.ts |   97.46 |    93.05 |     100 |   97.46 | ...04,182-183,202 
  ...iagnostics.ts |   83.08 |     67.5 |   92.59 |   83.08 | ...23,543-544,550 
  ...tchOptions.ts |   84.87 |    86.61 |   96.29 |   84.87 | ...71,696,725-734 
  ...odelPrefix.ts |     100 |      100 |     100 |     100 |                   
  runtimeStatus.ts |    97.5 |    89.74 |     100 |    97.5 | 162-163           
  safe-mode.ts     |     100 |      100 |     100 |     100 |                   
  safeJsonParse.ts |     100 |      100 |     100 |     100 |                   
  ...nStringify.ts |     100 |      100 |     100 |     100 |                   
  ...-child-env.ts |     100 |      100 |     100 |     100 |                   
  ...aConverter.ts |   98.03 |    97.75 |     100 |   98.03 | 100,102-103       
  ...aValidator.ts |   92.09 |    83.65 |   90.47 |   92.09 | ...60,882-883,896 
  ...r-launcher.ts |   96.35 |    93.97 |   85.71 |   96.35 | ...35-336,347-348 
  sedEditParser.ts |   91.78 |    92.18 |     100 |   91.78 | ...66-569,645-646 
  ...nIdContext.ts |     100 |      100 |     100 |     100 |                   
  ...orageUtils.ts |   95.98 |    83.96 |     100 |   95.98 | ...70,386,466,485 
  ...-pager-env.ts |     100 |      100 |     100 |     100 |                   
  ...fety-rules.ts |     100 |     89.7 |     100 |     100 | ...01,304,309-311 
  shell-utils.ts   |   86.07 |    88.34 |     100 |   86.07 | ...2269,2276-2280 
  ...lAstParser.ts |   98.16 |    91.91 |     100 |   98.16 | ...1244-1246,1256 
  ...ContextEnv.ts |     100 |       92 |     100 |     100 | 50-52             
  ...nlyChecker.ts |   96.33 |    96.57 |     100 |   96.33 | ...83-284,292-293 
  sideQuery.ts     |   86.82 |    86.66 |     100 |   86.82 | ...79-185,187-193 
  ...pEventSink.ts |     100 |       80 |     100 |     100 | 61                
  ...tGenerator.ts |     100 |      100 |     100 |     100 |                   
  ...ameContext.ts |     100 |      100 |     100 |     100 |                   
  symlink.ts       |   77.77 |       50 |     100 |   77.77 | 44,54-59          
  ...e-encoding.ts |   85.96 |    76.47 |     100 |   85.96 | 58-61,64-65,78-79 
  ...emEncoding.ts |   96.36 |    91.17 |     100 |   96.36 | 59-60,124-125     
  terminalSafe.ts  |     100 |      100 |     100 |     100 |                   
  ...Serializer.ts |   98.72 |       90 |     100 |   98.72 | 42-43,134,201-203 
  testUtils.ts     |   53.33 |      100 |   33.33 |   53.33 | ...53,59-64,70-72 
  ...-constants.ts |     100 |      100 |     100 |     100 |                   
  textUtils.ts     |      65 |      100 |      75 |      65 | 56-75             
  thoughtUtils.ts  |     100 |    95.65 |     100 |     100 | 99                
  ...-converter.ts |   95.23 |    85.71 |     100 |   95.23 | 36-37             
  ...name-utils.ts |     100 |      100 |     100 |     100 |                   
  ...-finalizer.ts |   97.66 |     90.9 |     100 |   97.66 | 165-166,168-172   
  tool-utils.ts    |    95.2 |    93.61 |     100 |    95.2 | ...58-159,162-163 
  ...ultCleanup.ts |   54.62 |       64 |      75 |   54.62 | ...03-105,108-134 
  ...Compaction.ts |   96.13 |    96.42 |     100 |   96.13 | ...34-339,341-346 
  ...pt-records.ts |   85.85 |    83.78 |     100 |   85.85 | ...90-394,424-439 
  truncation.ts    |   90.56 |    90.43 |     100 |   90.56 | ...35-443,480-486 
  windowsPath.ts   |   89.47 |    79.31 |     100 |   89.47 | ...57-58,62,90-91 
  ...aceContext.ts |   95.81 |    89.39 |     100 |   95.81 | ...74-275,299-301 
  xml.ts           |    97.8 |    87.69 |     100 |    97.8 | 98-99             
  yaml-parser.ts   |   83.87 |    77.27 |     100 |   83.87 | ...31-234,239-240 
 ...ils/filesearch |   83.94 |    80.72 |   94.73 |   83.94 |                   
  crawlCache.ts    |     100 |      100 |     100 |     100 |                   
  crawler.ts       |    82.9 |    76.81 |   95.08 |    82.9 | ...1563,1597-1598 
  fileSearch.ts    |   93.78 |    87.67 |     100 |   93.78 | ...71-272,274-275 
  fzfWorker.ts     |       0 |        0 |       0 |       0 | 1-109             
  ...rkerHandle.ts |   84.05 |    75.43 |   89.47 |   84.05 | ...30-334,340-341 
  ignore.ts        |     100 |    97.36 |     100 |     100 | 187               
  result-cache.ts  |     100 |    93.75 |     100 |     100 | 49                
 ...uest-tokenizer |   69.76 |    75.47 |   85.29 |   69.76 |                   
  ...eTokenizer.ts |   65.72 |    74.02 |    92.3 |   65.72 | ...65-466,479-533 
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...tTokenizer.ts |   68.39 |    69.49 |    90.9 |   68.39 | ...24-325,327-328 
  ...ageFormats.ts |   76.92 |      100 |   33.33 |   76.92 | 46-49,56-57       
  textTokenizer.ts |     100 |      100 |     100 |     100 |                   
  types.ts         |       0 |        0 |       0 |       0 | 1                 
-------------------|---------|----------|---------|---------|-------------------

For detailed HTML reports, please see the 'coverage-reports-22.x-ubuntu-latest' artifact from the main CI run.

@yiliang114 yiliang114 added the autofix/takeover Summon the autofix loop to manage this PR (remove to release; needs triage+) label Aug 3, 2026
@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

🤝 Takeover engaged: the autofix loop now manages this PR — it will address new review feedback and resolve base conflicts until the label is removed or the round cap is reached. Remove the autofix/takeover label (or comment @qwen-code /takeover stop) to release.

中文说明

🤝 已接管:autofix 循环现在管理此 PR —— 将持续处理新的评审反馈与 base 冲突,直到移除标签或达到轮次上限。移除 autofix/takeover 标签(或评论 @qwen-code /takeover stop)即可释放。

@qwen-code-dev-bot

qwen-code-dev-bot commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator

AutoFix round 8 finishedview run. See this round's report below.

中文说明

AutoFix 第 8 轮已完成 —— 查看运行。本轮报告见下方。

@qwen-code-ci-bot qwen-code-ci-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed. Suggestions are inline. Not linted (tool limitation, not a blocker): the executable-script lint — .github/workflows/ci.yml: actionlint embedded-shell source mapping is not yet supported — not linted; the executable-script lint — .github/workflows/qwen-code-pr-review.yml: actionlint embedded-shell source mapping is not yet supported — not linted.

中文说明

已审查。 建议见行内评论。 未检查(工具限制,非阻断):the executable-script lint — .github/workflows/ci.yml: actionlint embedded-shell source mapping is not yet supported — not linted; the executable-script lint — .github/workflows/qwen-code-pr-review.yml: actionlint embedded-shell source mapping is not yet supported — not linted。

— qwen3.8-max via Qwen Code /review (v0.21.3)

Comment thread .github/workflows/ci.yml Outdated
Comment thread .github/workflows/qwen-code-pr-review.yml Outdated
@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

🤖 Addressed the latest review feedback (round 1/100). What changed, and what I pushed back on: · 已处理最新评审反馈(第 1/100 轮)。改动内容与我反驳保留之处如下:

Autofix round summary — PR #8474

Feedback point

  • Failed check: Test (ubuntu-latest Node 22.x) — addressed.

There were no review comments, inline comments, or issue-level comments in this round's feedback; the failing CI check was the only item.

Diagnosis (evidence trail)

  1. The Jobs API shows the failing step was Run tests and generate reports (npm run test:ci); every earlier step — including this PR's new Clean stale .qwen before checkout block — passed, and the no-AK gate was skipped because the unit tests failed.
  2. The failure wave in this time window hit many different PRs on many different runners (both GitHub-hosted and self-hosted ECS), so this was shared broken code, not runner pollution.
  3. Root cause 1: today's safe-replay change (0cb109f51, fix(core): Avoid replaying unsafe MCP tool calls #8387) made automatic replay after a connection failure conditional on server trust plus idempotent annotations, and one fixture in packages/core/src/tools/mcp-tool.test.ts was missed. Reproduced locally: reconnects instead of reporting a timeout when the server is known disconnected failed 1/91 with the "unsafe replay" error. The fix (fix(core): align MCP reconnect timeout test with safe replay policy #8478) merged to main at 17:26 UTC — after this branch was cut, and CI tests the PR head itself, so this branch had to pick it up.
  4. Root cause 2 (found while verifying the merge): scripts/tests/qwen-resolve-workflow.test.js still asserted the hardcoded review timeouts (timeout-minutes: 300, EFFECTIVE_TIMEOUT_MINUTES=240, --timeout=240) that ci: externalize PR review timeout settings to repository variables #8460 externalized to QWEN_REVIEW_JOB_TIMEOUT_MINUTES / QWEN_REVIEW_MAX_TIMEOUT_MINUTES repository variables. ci: externalize PR review timeout settings to repository variables #8460's own final CI run failed on exactly this test step but was merged anyway, so main itself carries the broken test and every branch merging main fails test:ci.

Changes

  1. Merged origin/main into the PR branch (772d71cd2). This is the vehicle for root cause 1's fix (fix(core): align MCP reconnect timeout test with safe replay policy #8478) plus the other already-green main commits; the auto-merge was clean (--conflict was false, but the merge was necessary — the failing check cannot clear without main's test fix, since CI tests the immutable PR head). The workflow-only changes of this PR survived the merge intact.
  2. fix(tests): sync qwen-resolve-workflow expectations with externalized review timeouts (#8474) (02909bec2): updated the three stale assertions in scripts/tests/qwen-resolve-workflow.test.js to the variable-driven values now in the workflow file, and pinned where each step defines MAX_TIMEOUT_MINUTES — the same contract the old hardcoded strings enforced. Test-only change; no production logic touched. This mirrors the repo's existing precedent for such syncs (55eb8325e).

No conflicts were encountered during the merge. No review threads existed to resolve or reply to.

Verification

Commands actually run (this round, on the merged + fixed tree):

  • npx vitest run src/tools/mcp-tool.test.ts (packages/core) — failed 1/91 before the merge, 91 passed (91) after
  • npx vitest run --config ./scripts/tests/vitest.config.ts scripts/tests/qwen-resolve-workflow.test.jsfailed 3/29 before the sync, 29 passed (29) after
  • npm run build — passed
  • npm run typecheck — passed
  • npm run lint — passed (npx prettier --check and npx eslint also run separately on the edited test file — both clean)
  • actionlint with the exact CI flags (-pyflakes= -shellcheck= -ignore SC2002/SC2129/...) — passed on the merged tree
  • Focused vitest on the CLI review test files the merge touched (review.test.ts, findings.test.ts, resolve-anchors.test.ts, save-artifact.test.ts, check-coverage.test.ts) — 190 passed | 1 skipped (the skip is it.skipIf(!caseInsensitiveFs) in save-artifact.test.ts, by design on case-sensitive filesystems)
  • npm run test:scripts — 891 passed | 9 skipped | 5 failed; all 5 failures are spawnSync zip ENOENT in install-script.test.js because this review sandbox has no zip binary installed (and no package manager access to add one). GitHub-hosted runners ship zip, and these same tests pass in CI; this is an environment limitation of the verification sandbox, not a code defect.
  • yamllint could not be installed in this sandbox (no pip); actionlint fully parses both changed workflow files, and the YAML additions are inside existing block scalars or use the file's established quoting style.
中文说明

Autofix 本轮总结 — PR #8474

反馈项

  • 失败检查:Test (ubuntu-latest Node 22.x) — 已处理。

本轮反馈中没有评审意见、行内评论或 issue 级评论;失败的 CI 检查是唯一条目。

诊断(证据链)

  1. Jobs API 显示失败步骤是 Run tests and generate reportsnpm run test:ci);此前所有步骤——包括本 PR 新增的 Clean stale .qwen before checkout 清理块——全部通过;no-AK 门禁因单测失败被跳过。
  2. 该时间窗内的失败潮波及多个不同 PR、多个不同 runner(GitHub 托管与自托管 ECS 均有),因此是共享代码被破坏,而非 runner 污染。
  3. 根因 1:今天的 safe-replay 变更(0cb109f51fix(core): Avoid replaying unsafe MCP tool calls #8387)使连接失败后的自动重放以"服务器受信任 + 幂等标注"为前提,而 packages/core/src/tools/mcp-tool.test.ts 中有一个 fixture 被遗漏。本地复现:reconnects instead of reporting a timeout when the server is known disconnected 以 "unsafe replay" 错误失败(1/91)。修复(fix(core): align MCP reconnect timeout test with safe replay policy #8478)已于 17:26 UTC 合入 main——晚于本分支切出时间,而 CI 测试的是 PR head 本身,因此本分支必须带入该修复。
  4. 根因 2(验证合并时发现):scripts/tests/qwen-resolve-workflow.test.js 仍在断言硬编码的评审超时值(timeout-minutes: 300EFFECTIVE_TIMEOUT_MINUTES=240--timeout=240),而这些值已被 ci: externalize PR review timeout settings to repository variables #8460 外部化为 QWEN_REVIEW_JOB_TIMEOUT_MINUTES / QWEN_REVIEW_MAX_TIMEOUT_MINUTES 仓库变量。ci: externalize PR review timeout settings to repository variables #8460 自己的最后一次 CI 运行正是失败在这个测试步骤上,却仍被合入,因此 main 本身带着这个坏测试,任何合并 main 的分支都会在 test:ci 上失败。

变更内容

  1. origin/main 合并进 PR 分支(772d71cd2)。这是带入根因 1 修复(fix(core): align MCP reconnect timeout test with safe replay policy #8478)及其他已绿 main 提交的载体;自动合并无冲突(--conflict 为 false,但本次合并是必要的——CI 测试的是不可变的 PR head,不带入 main 的测试修复,失败检查无法转绿)。本 PR 的 workflow 改动在合并后完整保留。
  2. fix(tests): sync qwen-resolve-workflow expectations with externalized review timeouts (#8474)02909bec2):将 scripts/tests/qwen-resolve-workflow.test.js 中三处过期断言更新为 workflow 文件现在的变量驱动取值,并固定各步骤定义 MAX_TIMEOUT_MINUTES 的位置——即原硬编码字符串所约束的同一契约。纯测试变更,不触碰生产逻辑。与仓库中此类同步的先例(55eb8325e)一致。

合并过程无冲突。本轮没有需要解决或回复的评审线程。

验证

本轮实际执行的命令(在合并 + 修复后的树上):

  • npx vitest run src/tools/mcp-tool.test.ts(packages/core)— 合并前 1/91 失败,合并后 91 passed (91)
  • npx vitest run --config ./scripts/tests/vitest.config.ts scripts/tests/qwen-resolve-workflow.test.js同步前 3/29 失败,同步后 29 passed (29)
  • npm run build — 通过
  • npm run typecheck — 通过
  • npm run lint — 通过(另对修改的测试文件单独运行 npx prettier --checknpx eslint — 均通过)
  • actionlint(与 CI 完全一致的参数:-pyflakes= -shellcheck= -ignore SC2002/SC2129/...)— 在合并后的树上通过
  • 针对合并触及的 CLI review 测试文件的定向 vitest(review.test.tsfindings.test.tsresolve-anchors.test.tssave-artifact.test.tscheck-coverage.test.ts)— 190 passed | 1 skipped(该 skip 是 save-artifact.test.ts 中的 it.skipIf(!caseInsensitiveFs),在大小写敏感文件系统上按设计跳过)
  • npm run test:scripts — 891 passed | 9 skipped | 5 failed;5 个失败全部是 install-script.test.js 中的 spawnSync zip ENOENT,因为本评审沙箱未安装 zip 二进制(且无包管理器可安装)。GitHub 托管 runner 自带 zip,这些测试在 CI 中通过;这是验证沙箱的环境限制,不是代码缺陷。
  • yamllint 无法在本沙箱安装(无 pip);actionlint 会完整解析两个改动过的 workflow 文件,且新增 YAML 内容位于既有块标量内部,或沿用该文件既有的引号风格。

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/模型 qwen3.8-max

@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

🤖 Addressed the latest review feedback (round 2/100). What changed, and what I pushed back on: · 已处理最新评审反馈(第 2/100 轮)。改动内容与我反驳保留之处如下:

Review feedback addressed — PR #8474

Feedback source: one automated-reviewer Suggestion (R1-1), posted as two inline comments for the same finding: ci.yml:178 and qwen-code-pr-review.yml:1005. No failed checks and no human reviews this round.

Finding R1-1 — duplicated review-artifact cleanup recipe with no pin to paths.ts and no test coverage

Decision: addressed via the reviewer's second suggested fix (the "and/or" branch) plus error-handling alignment; the shared-script extraction was declined with evidence.

What changed

  1. New workflow test scripts/tests/review-worktree-cleanup-workflow.test.js, following the repo's scripts/tests/*-workflow.test.js convention (same shape as the existing workflow↔errorParsing.ts sync test in qwen-pr-review-workflow.test.js):
    • derives the worktree-directory prefix and the branch family from worktreePath() / reviewBranch() in packages/cli/src/commands/review/lib/paths.ts at runtime;
    • asserts both cleanup sites — Clean stale .qwen before checkout in ci.yml and Clean review worktrees in qwen-code-pr-review.yml — contain the derived awk filter, the worktree remove --force call, and the refs/heads/qwen-review/* branch glob, and follow the prune→remove→prune→branch-delete ordering (a branch checked out in a live worktree cannot be deleted, so worktree removal must precede the branch sweep);
    • asserts the awk filter is byte-identical at both sites;
    • executes the extracted awk filter against a fixture worktree list --porcelain output and asserts it selects only the review worktree — never the main checkout — so the destructive filter is now covered.
      Renaming the worktree suffix or branch prefix in paths.ts now fails this test and forces the workflow sites to be updated in the same change — exactly the drift the finding describes (and that the paths.ts JSDoc says already broke a sweeper once).
  2. Error-handling alignment in ci.yml: the two bare || true on worktree/branch removal now emit the same ::warning::could not remove review worktree/branch: … messages the review-workflow step uses, so a failed cleanup leaves a log signal instead of silently no-op'ing.
  3. A short comment in ci.yml records why this site stays inline (below), so the constraint does not get rediscovered every review round.

Declined: extracting .github/scripts/clean-review-worktrees.sh called from both steps. The ci.yml site runs before actions/checkout on the shared ecs-qwen runner pool that ci.yml, qwen-code-pr-review.yml, and qwen-triage.yml all use. That pool's workspace survives across jobs and can hold another job's leftovers — including qwen-triage's checkout of untrusted PR merge refs (the neighboring step's comment documents root-owned poisoning from prior container jobs). Executing a workspace script pre-checkout there would run stale/attacker-controlled files; inline git plumbing is the only safe shape for that site. With the pre-checkout sites excluded (the pre-existing Clean stale agent state step also runs before checkout), a shared script would have exactly one caller — an abstraction for single-use code — while the new pin test already provides the drift protection the extraction was meant to buy. This reasoning is now recorded in a comment at the ci.yml site.

Declined: copying the lease-file sweep / rm -rf .qwen/tmp/review-pr-* fallback into the ci.yml site. The line directly above already removes $GITHUB_WORKSPACE/.qwen wholesale (with a sudo -n fallback), which covers both the worktree directories and the lease files; re-adding narrower removals there would be dead code. The divergence the finding observed between the two new sites is this context difference, not accidental drift.

Out of scope: the pre-existing Clean stale agent state step and the qwen-triage.yml partial copies predate this PR's diff; they use the same greppable patterns and will be updated together with the pinned sites if paths.ts ever changes (the failing test sends the changer straight to a grep).

Conflict

None (--conflict false); no merge performed.

Verification

Commands actually run and their results:

  • npx vitest run --config ./scripts/tests/vitest.config.ts scripts/tests/review-worktree-cleanup-workflow.test.js — 4 passed
  • Drift-sensitivity check: temporarily renamed .qwen/tmp/review-pr-.qwen/tmp/review-PRX- in ci.yml → the new test failed as intended (2 failed) → file restored — passed
  • bash -n on both extracted cleanup run blocks (ci.yml and qwen-code-pr-review.yml) — syntax OK
  • Functional smoke test: ran the modified ci.yml block against a scratch repo holding a registered .qwen/tmp/review-pr-7 worktree and qwen-review/pr-7 branch — directory, registration, and branch all removed
  • Focused workflow tests (review-worktree-cleanup-workflow, qwen-pr-review-workflow, qwen-resolve-workflow, qwen-autofix-workflow) — 165 passed
  • npm run test:scripts — 45/46 files passed (895 passed, 9 skipped); the 5 failures are all spawnSync zip ENOENT in install-script.test.js — environmental: which zip → not installed on this runner, that test file shells out to the zip binary, and it is identical at origin/main (untouched by this PR), so the base fails the same way
  • npm run lint — passed
  • npm run typecheck — passed
  • npm run build — passed
  • npx prettier --check on both changed files — clean (after --write on the new test file)
  • Integration tests after npm run bundle — not applicable (touched behavior is workflow YAML + script tests, not exercised through the bundled CLI); npm run generate:settings-schema — not applicable (no settings source changed)
中文说明

已处理的审查反馈 — PR #8474

反馈来源: 自动审查器的一条 Suggestion(R1-1),以两条行内评论发布在同一个发现上:ci.yml:178qwen-code-pr-review.yml:1005。本轮没有失败的检查,也没有人工审查。

发现 R1-1 — 重复的 review 产物清理逻辑,未与 paths.ts 保持锚定,且无测试覆盖

决定:通过审查者建议的第二种修复方式("and/or" 的另一分支)加上错误处理对齐来解决;共享脚本的抽取方案附带证据予以拒绝。

变更内容

  1. 新增 workflow 测试 scripts/tests/review-worktree-cleanup-workflow.test.js,遵循仓库 scripts/tests/*-workflow.test.js 惯例(与 qwen-pr-review-workflow.test.js 中已有的 workflow↔errorParsing.ts 同步测试同一形式):
    • 运行时从 packages/cli/src/commands/review/lib/paths.tsworktreePath() / reviewBranch() 推导 worktree 目录前缀与分支族;
    • 断言两个清理位置——ci.yml 的 Clean stale .qwen before checkout 与 qwen-code-pr-review.yml 的 Clean review worktrees——均包含推导出的 awk 过滤器、worktree remove --force 调用、refs/heads/qwen-review/* 分支通配,并遵循 prune→remove→prune→删分支的顺序(仍被 worktree 占用的分支无法删除,因此必须先移除 worktree 再删分支);
    • 断言两处 awk 过滤器逐字节一致;
    • 将提取出的 awk 过滤器在一份 worktree list --porcelain 样例输出上实际执行,断言它只选中 review worktree——绝不选中主 checkout——破坏性过滤器从此有了测试覆盖。
      今后若在 paths.ts 中重命名 worktree 后缀或分支前缀,该测试会失败,迫使修改者在同一变更中同步更新 workflow 位置——这正是本发现描述的漂移(paths.ts 的 JSDoc 记载过同类漂移曾导致一个清扫器静默失效)。
  2. ci.yml 错误处理对齐: worktree/分支删除上的两处裸 || true 现在改为输出与 review workflow 步骤一致的 ::warning::could not remove review worktree/branch: … 消息,清理失败时会在日志中留下信号,而不是静默空转。
  3. ci.yml 中添加一条简短注释,记录该位置保持内联的原因(见下),避免每轮审查都要重新发现这一约束。

拒绝:抽取 .github/scripts/clean-review-worktrees.sh 并由两个步骤调用。 ci.yml 这一侧运行在 actions/checkout 之前,且运行在 ci.ymlqwen-code-pr-review.ymlqwen-triage.yml 共用的 ecs-qwen 共享 runner 池上。该池的工作区在 job 之间持久存在,可能残留其他 job 的产物——包括 qwen-triage不受信任的 PR merge ref 的 checkout(相邻步骤的注释记载过先前容器 job 遗留 root 属主文件造成的污染)。在 checkout 前执行工作区里的脚本等于运行过期/攻击者可控的文件;对该位置而言,内联 git 命令是唯一安全的形态。排除 pre-checkout 位置后(既有的 Clean stale agent state 步骤同样在 checkout 前运行),共享脚本将只有一个调用方——为一次性代码建立抽象——而新增的锚定测试已经提供了抽取方案原本要换取的漂移防护。这一理由现已以注释形式记录在 ci.yml 该位置。

拒绝:把 lease 文件清理 / rm -rf .qwen/tmp/review-pr-* 兜底复制到 ci.yml 位置。 其紧邻上方的一行已经整体删除 $GITHUB_WORKSPACE/.qwen(并带 sudo -n 兜底),worktree 目录与 lease 文件都已包含在内;在那里再加更窄的删除是死代码。本发现观察到的两个新增位置之间的差异来源于这一上下文不同,而非意外漂移。

超出范围: 既有的 Clean stale agent state 步骤与 qwen-triage.yml 中的部分副本早于本 PR 的 diff 存在;它们使用相同的可 grep 模式,若 paths.ts 变更,会与本次锚定的位置一并更新(失败的测试会直接把修改者引向 grep)。

冲突

无(--conflict false);未执行任何合并。

验证

实际执行的命令及结果:

  • npx vitest run --config ./scripts/tests/vitest.config.ts scripts/tests/review-worktree-cleanup-workflow.test.js — 4 通过
  • 漂移敏感性检查:临时将 ci.yml 中 .qwen/tmp/review-pr- 重命名为 .qwen/tmp/review-PRX- → 新测试按预期失败(2 失败)→ 恢复文件 — 通过
  • 对两个提取出的清理 run 块(ci.yml 与 qwen-code-pr-review.yml)执行 bash -n — 语法 OK
  • 功能性冒烟测试:在一个注册了 .qwen/tmp/review-pr-7 worktree 与 qwen-review/pr-7 分支的临时仓库上运行修改后的 ci.yml 块 — 目录、注册、分支全部清除
  • 聚焦 workflow 测试(review-worktree-cleanup-workflowqwen-pr-review-workflowqwen-resolve-workflowqwen-autofix-workflow)— 165 通过
  • npm run test:scripts — 45/46 文件通过(895 通过,9 跳过);5 个失败全部是 install-script.test.js 中的 spawnSync zip ENOENT — 环境问题:which zip → 本 runner 未安装 zip,该测试文件直接调用 zip 二进制,且它在 origin/main 上与本次完全相同(本 PR 未触碰),因此 base 分支同样失败
  • npm run lint — 通过
  • npm run typecheck — 通过
  • npm run build — 通过
  • 对两个变更文件执行 npx prettier --check — 干净(新测试文件经 --write 格式化后)
  • npm run bundle 后的集成测试 — 不适用(本次触及的行为是 workflow YAML 与脚本测试,不经打包后的 CLI 执行);npm run generate:settings-schema — 不适用(未改动 settings 源)

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/模型 qwen3.8-max

@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Qwen Code review timed out. Qwen review timed out after 10800 seconds (of the 180-minute budget). For large PRs, retry with a longer timeout by commenting: @qwen-code /review --timeout=360. See workflow logs.

@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

🔀 Base updated: red check(s) [review-pr] pass on current main — merged current main via update-branch; CI will re-run.

中文说明

🔀 已更新 base:红色检查 [review-pr] 在当前 main 上通过 —— 已通过 update-branch 合入当前 main,CI 将重新运行。

…worktrees

# Conflicts:
#	scripts/tests/qwen-resolve-workflow.test.js
@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

🤖 Addressed the latest review feedback (round 3/100). What changed, and what I pushed back on: · 已处理最新评审反馈(第 3/100 轮)。改动内容与我反驳保留之处如下:

🤖 Addressed the latest review feedback (round 3/100). What changed, and what I pushed back on: · 已处理最新评审反馈(第 3/100 轮)。改动内容与我反驳保留之处如下:

Autofix round summary — PR #8474

Feedback points

  1. Issue-level comment from @qwen-code-ci-bot: "Qwen Code review timed out after 10800 seconds (of the 180-minute budget)" — no code change. This is an informational notice that the automated /review run exhausted its time budget; it names no defect in this PR and no CI check failed. The remedy it suggests (@qwen-code /review --timeout=360) is a maintainer comment command, not an action available to this bot. Notably, the timeout budget is now externalized into the QWEN_REVIEW_JOB_TIMEOUT_MINUTES / QWEN_REVIEW_MAX_TIMEOUT_MINUTES repository variables (ci: externalize PR review timeout settings to repository variables #8460), so the budget can be tuned without code changes — and this PR's own test-sync commit already aligns the workflow tests with that externalization.
  2. Base conflict (--conflict true) — addressed by merging origin/main (see below).

There were no inline comments, no human or automated reviews, and no failed checks in this round's feedback.

Conflict resolution

origin/main advanced with d6f55a1c9 (fix(ci): align review workflow tests with externalized timeout variables (#8486)), which makes the same test-sync change to scripts/tests/qwen-resolve-workflow.test.js that this PR's 02909bec2 made — both fix the workflow-text assertions after #8460 moved review timeouts into repository variables. The merge conflicted in three hunks of that one file.

Resolution was decided against the actual workflow text, not by picking a side blindly:

  • .github/workflows/qwen-code-pr-review.yml line 728 contains if [ "$TIMEOUT_MINUTES" -gt "$MAX_TIMEOUT_MINUTES" ]; then, line 729 contains fail "timeout_minutes must not exceed ${MAX_TIMEOUT_MINUTES} minutes", and line 974 contains if [ "$TIMEOUT_MINUTES" -lt "$MAX_TIMEOUT_MINUTES" ]; then.
  • main's version asserts all of these (a strict superset of the PR-side assertions); the PR side asserted only the message substring without the fail prefix and omitted both guard-line assertions.

All three hunks were resolved to main's version; the merged file is byte-identical to origin/main's. Net effect: this PR's test-sync commit is fully subsumed by main's, and the post-merge tree differs from main by exactly this PR's own three files (the two cleanup steps and their workflow test). Merge commit: dbdcd7d30.

Changes

  • One additive merge commit bringing in origin/main; no source edits this round.

Verification

Commands actually run, in order:

  • npm run build — passed
  • npm run typecheck — passed
  • npm run lint — passed
  • Focused vitest (scripts/tests config): qwen-resolve-workflow.test.js + review-worktree-cleanup-workflow.test.js — 2 files, 33/33 passed (run before the merge commit and again on the committed tree)
  • npm run test:scripts (full workspace scripts suite, extra due diligence) — 895 passed, 9 skipped, 5 failed. All 5 failures are environmental, not caused by this change: each is spawnSync zip ENOENT in scripts/tests/install-script.test.js, because the zip binary is not installed in this sandbox and there is no root/sudo to install it. I verified scripts/tests/install-script.test.js and scripts/install.js are byte-identical to origin/main in the merged tree, so the failures reproduce exactly on the base branch; GitHub-hosted ubuntu-latest runners ship zip preinstalled, so CI is unaffected.
  • Integration tests — not applicable: the change is workflow YAML plus workflow-text tests only; no bundled-CLI or integration-harness behavior is touched.
  • Settings schema regeneration — not applicable: no settings source changed.
中文说明

Autofix 轮次总结 — PR #8474

反馈点

  1. @qwen-code-ci-bot 的 issue 级评论:"Qwen Code review 在 10800 秒(180 分钟预算内)后超时" —— 无需代码改动。这是一条信息性通知,说明自动化 /review 运行耗尽了时间预算;它没有指出本 PR 的任何缺陷,也没有任何 CI 检查失败。它建议的补救方式(@qwen-code /review --timeout=360)是维护者用的评论命令,不是本机器人可执行的操作。值得注意的是,超时预算现已外置为 QWEN_REVIEW_JOB_TIMEOUT_MINUTES / QWEN_REVIEW_MAX_TIMEOUT_MINUTES 仓库变量(ci: externalize PR review timeout settings to repository variables #8460),因此无需改代码即可调整预算 —— 而本 PR 自己的测试同步提交已经让工作流测试与该外置保持一致。
  2. base 冲突(--conflict true —— 已通过合并 origin/main 解决(见下文)。

本轮反馈中没有行内评论、没有人工或自动化审查、也没有失败的检查。

冲突解决

origin/main 前进了 d6f55a1c9fix(ci): align review workflow tests with externalized timeout variables (#8486)),它对 scripts/tests/qwen-resolve-workflow.test.js 做了与本 PR 的 02909bec2 相同的测试同步改动 —— 两者都是在 #8460 将审查超时迁移到仓库变量之后修正工作流文本断言。合并在该文件的三个区块上发生冲突。

解决方式是依据实际工作流文本裁决,而不是盲目选边:

  • .github/workflows/qwen-code-pr-review.yml 第 728 行包含 if [ "$TIMEOUT_MINUTES" -gt "$MAX_TIMEOUT_MINUTES" ]; then,第 729 行包含 fail "timeout_minutes must not exceed ${MAX_TIMEOUT_MINUTES} minutes,第 974 行包含 if [ "$TIMEOUT_MINUTES" -lt "$MAX_TIMEOUT_MINUTES" ]; then
  • main 的版本断言了以上全部内容(是 PR 侧断言的严格超集);PR 侧只断言了不带 fail 前缀的消息子串,并且遗漏了两条 guard 行断言。

三个区块全部采用 main 的版本解决;合并后的文件与 origin/main 逐字节一致。净效果:本 PR 的测试同步提交被 main 的版本完全涵盖,合并后的树与 main 的差异恰好只是本 PR 自己的三个文件(两处清理步骤及其工作流测试)。合并提交:dbdcd7d30

改动

  • 一个加法式合并提交,引入 origin/main;本轮没有源码编辑。

验证

实际运行的命令(按顺序):

  • npm run build —— 通过
  • npm run typecheck —— 通过
  • npm run lint —— 通过
  • 聚焦 vitest(scripts/tests 配置):qwen-resolve-workflow.test.js + review-worktree-cleanup-workflow.test.js —— 2 个文件,33/33 通过(在合并提交前运行过一次,在提交后的树上又运行了一次)
  • npm run test:scripts(完整工作区脚本测试套件,额外尽职检查)—— 895 通过、9 跳过、5 失败。这 5 个失败全部是环境问题,与本次改动无关: 全部是 scripts/tests/install-script.test.js 中的 spawnSync zip ENOENT,因为该沙箱未安装 zip 二进制,且没有 root/sudo 权限可以安装。我已验证合并树中的 scripts/tests/install-script.test.jsscripts/install.jsorigin/main 逐字节一致,因此这些失败在 base 分支上会完全相同地复现;GitHub 托管的 ubuntu-latest 运行器预装了 zip,所以 CI 不受影响。
  • 集成测试 —— 不适用:改动仅涉及工作流 YAML 和工作流文本测试;没有触及任何打包 CLI 或集成测试框架的行为。
  • settings schema 重新生成 —— 不适用:没有改动任何 settings 源。

Base-conflict check · 基分支冲突检查: conflicted with main — resolved in this push. · 与 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/模型 qwen3.8-max

@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

🤖 Reviewed the latest feedback — no changes needed. Why, point by point: · 已审阅最新反馈——无需改动。逐点说明原因如下:

Autofix review round — no action needed (PR #8474)

This round found no actionable feedback for PR #8474 (codex/cleanup-review-worktrees), so no changes were made.

What was checked:

  • New reviews: none since the last evaluation (2026-08-03T22:32:23Z).
  • Inline comments: none.
  • Issue-level comments: none.
  • Failed checks: none. All completed CI checks are SUCCESS (Classify PR, Test on ubuntu-latest Node 22.x, Desktop Shell, web-shell E2E Smoke, Post Coverage Comment, label, force-push reminder) or legitimately SKIPPED (platform-specific test shards for macOS/Windows, integration tests, review-workflow prechecks). The one QUEUED item (delay-automatic-review) is the automated review workflow's own scheduling step, not a failing check.
  • Still-red checks persisting from earlier: none.

PR state: the branch is up to date with its latest pushed commit (3e70e8dd3), the working tree is clean, and no conflicts with main were reported (--conflict false).

No commit was created this round.

中文说明

Autofix 审查轮次 — 无需操作(PR #8474

本轮未发现针对 PR #8474codex/cleanup-review-worktrees)的可处理反馈,因此未做任何更改。

已核查的内容:

  • 新审查(Reviews): 自上次评估(2026-08-03T22:32:23Z)以来没有新的审查。
  • 行内评论(Inline comments): 无。
  • Issue 级评论: 无。
  • 失败的检查(Failed checks): 无。所有已完成的 CI 检查均为 SUCCESS(Classify PR、ubuntu-latest Node 22.x 上的 Test、Desktop Shell、web-shell E2E Smoke、Post Coverage Comment、label、force-push 提醒),或属于合理的 SKIPPED(macOS/Windows 平台的测试分片、集成测试、审查工作流的预检查)。唯一一个 QUEUED 状态的项目(delay-automatic-review)是自动审查工作流自身的调度步骤,并非失败的检查。
  • 此前遗留的持续失败检查: 无。

PR 状态: 分支已包含最新推送的提交(3e70e8dd3),工作树干净,且未报告与 main 存在冲突(--conflict false)。

本轮未创建任何提交。

Base-conflict check · 基分支冲突检查: no conflict with main. · 与 main 无冲突。


🧠 Handled by Qwen Code · model/模型 qwen3.8-max

@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

🤖 Reviewed the latest feedback — no changes needed. Why, point by point: · 已审阅最新反馈——无需改动。逐点说明原因如下:

Autofix triage — PR #8474: no changes this round

The only new feedback since the last evaluation is the failed review-pr check (run 30874657133, job 91892172289, 2026-08-04 04:25–06:41 UTC). After classifying it against the evidence below, there is nothing to change in this PR.

Disposition: review-pr: FAILURE — declined (environment failure, not a defect in this PR)

What the check is. review-pr is the automated LLM code-review job ("🧐 Qwen Pull Request Review"), not a build/test/lint gate. Its actionable output is the review it posts — and this run posted nothing: there are no reviews, inline comments, or bot issue comments newer than the last evaluation, so the failed run produced no findings to address.

Why it cannot be caused by this PR's code:

  1. The workflow is triggered by pull_request_target, so GitHub runs the workflow file from the base branch and checks out the base — none of this PR's three changed files executes in that job. The Clean review worktrees step this PR adds does not exist in the version that ran.
  2. The same PR was reviewed successfully in round 1 (head d1f976a5, completed in under an hour, two suggestions posted — both addressed in later commits). The PR content does not deterministically break the review.
  3. The failure pattern points at the review infrastructure, not the diff:
    • The previous failure (fallback comment 2026-08-03 22:32) exhausted the entire 180-minute review budget on a ~150-line PR — the signature of model-side latency/quota, which the workflow's own error handling anticipates.
    • This failure ended at ~136 minutes — under both the 180-minute attempt budget and the job-level cap — and posted no fallback comment. On the main-branch version of the workflow that ran, every Run review failure path proceeds to Post fallback comment on failure (which either posts or exits 0 with a skip notice). A red check with no comment means the failure happened before Resolve PR context (e.g., the base-branch checkout on the reused self-hosted ECS runner) or the fallback's gh call itself died — both runner/environment problems outside this PR's files. (Run logs could not be fetched: this sandbox has no GitHub credentials; that point is an inference from the workflow's structure, and either branch is outside this PR regardless.)
  4. The autofix loop itself classifies review-pr as non-blocking (NON_BLOCKING_CHECKS in qwen-autofix.yml): "its output is a REVIEW … the check conclusion carries nothing the loop acts on."
  5. The loop's red-check analysis already confirmed review-pr passes on current main ("🔀 Base updated" comment, 2026-08-03 22:42) and merged main into this branch anyway.

Recovery path (no code involved): a maintainer can re-trigger with @qwen-code /review (or @qwen-code /review --timeout=360, as the earlier fallback comment suggests); any new push also re-triggers it. Nothing in this PR can influence the review job's environment.

Verification (evidence-gathering only; no code changed, nothing committed)

  • npx vitest run --config ./scripts/tests/vitest.config.ts scripts/tests/review-worktree-cleanup-workflow.test.js scripts/tests/qwen-pr-review-workflow.test.js — 2 files, 27/27 passed
  • CI at this exact head (run 30874657444): Test (ubuntu-latest, Node 22.x) — SUCCESS; that job runs npm run test:ci, which includes test:scripts, so the PR's test file is covered and green. All other checks on this head are green or skipped; review-pr is the only red.
中文说明

Autofix 分诊 — PR #8474:本轮无改动

上次评估以来唯一的新反馈是失败的 review-pr 检查(run 30874657133,job 91892172289,2026-08-04 04:25–06:41 UTC)。依据下方证据分类后,本 PR 没有可改动的内容。

处置:review-pr: FAILURE —— 驳回(环境故障,并非本 PR 的缺陷)

该检查是什么。 review-pr 是自动化 LLM 代码审查任务("🧐 Qwen Pull Request Review"),不是构建/测试/lint 门禁。它的可执行输出是其发布的审查内容 —— 而本次运行什么也没有发布:上次评估之后没有任何新的审查、行内评论或机器人 issue 评论,因此这次失败的运行没有产生任何需要处理的发现。

为什么它不可能由本 PR 的代码引起:

  1. 该工作流由 pull_request_target 触发,因此 GitHub 运行的是来自 base 分支的工作流文件,并检出 base —— 本 PR 改动的三个文件都不会在该任务中执行。本 PR 新增的 Clean review worktrees 步骤在实际运行的版本中根本不存在。
  2. 同一个 PR 在第 1 轮曾被成功审查(head d1f976a5,一小时内完成,发布了两个建议 —— 均已在后续提交中处理)。PR 内容不会确定性地破坏审查。
  3. 失败模式指向审查基础设施,而非 diff:
    • 上一次失败(2026-08-03 22:32 的兜底评论)在一个约 150 行的 PR 上耗尽了整个 180 分钟审查预算 —— 这是模型侧延迟/配额问题的特征,工作流自身的错误处理也预见到了这种情况。
    • 本次失败在约 136 分钟时结束 —— 低于 180 分钟单次尝试预算和任务级上限 —— 且没有发布兜底评论。在实际运行的 main 分支版本的工作流中,Run review 的每一条失败路径都会进入 Post fallback comment on failure(要么发布评论,要么以 exit 0 输出跳过说明)。检查变红却没有评论,意味着失败发生在 Resolve PR context 之前(例如在复用的自托管 ECS runner 上检出 base 分支时),或者兜底步骤自己的 gh 调用挂掉了 —— 两者都是本 PR 文件之外的 runner/环境问题。(运行日志无法获取:此沙箱没有 GitHub 凭据;该结论是基于工作流结构的推断,且无论哪个分支都在本 PR 范围之外。)
  4. autofix 循环本身将 review-pr 分类为非阻塞(qwen-autofix.yml 中的 NON_BLOCKING_CHECKS):"它的输出是一份审查……检查结论不携带循环会据以行动的信息。"
  5. 循环的红检查分析已确认 review-pr 在当前 main 上通过("🔀 Base updated" 评论,2026-08-03 22:42),并且无论如何都已将 main 合入了本分支。

恢复路径(不涉及代码): 维护者可以用 @qwen-code /review 重新触发(或按早先兜底评论的建议使用 @qwen-code /review --timeout=360);任何新的推送也会重新触发它。本 PR 中的任何内容都无法影响审查任务的运行环境。

验证(仅收集证据;未改动代码,未提交任何内容)

  • npx vitest run --config ./scripts/tests/vitest.config.ts scripts/tests/review-worktree-cleanup-workflow.test.js scripts/tests/qwen-pr-review-workflow.test.js —— 2 个文件,27/27 通过
  • 本 head(run 30874657444)上的 CI:Test (ubuntu-latest, Node 22.x) —— SUCCESS;该任务运行 npm run test:ci,其中包含 test:scripts,因此本 PR 的测试文件已被覆盖且为绿色。此 head 上的所有其他检查均为绿色或被跳过;review-pr 是唯一的红色检查。

Base-conflict check · 基分支冲突检查: no conflict with main. · 与 main 无冲突。


🧠 Handled by Qwen Code · model/模型 qwen3.8-max

@yiliang114

Copy link
Copy Markdown
Collaborator Author

Resolved the duplicate cleanup-extraction suggestions without code changes. I am keeping the workflow cleanup inline in this PR because extracting it into a shared script/action would broaden a targeted CI cleanup fix; that can be a separate follow-up if maintainers want it.

@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

🤖 Reviewed the latest feedback — no changes needed. Why, point by point: · 已审阅最新反馈——无需改动。逐点说明原因如下:

Autofix review round — no action needed (PR #8474)

This round found no actionable feedback for PR #8474 (codex/cleanup-review-worktrees), so no changes were made.

What was checked (feedback newer than the last evaluation, 2026-08-04T06:41:37Z):

  • New reviews: none.
  • New inline comments: none. The two existing **[Suggestion]** comments from the automated reviewer (ids 3706494135 on .github/workflows/ci.yml:183 and 3706494143 on .github/workflows/qwen-code-pr-review.yml:1005, both created 2026-08-03T17:55:42Z) predate the last evaluation and were already declined with a recorded reason in earlier rounds: extracting the duplicated cleanup recipe into a shared script/action would broaden a targeted CI cleanup fix, so the cleanup stays inline in this PR; a shared extraction can be a separate follow-up if maintainers want it. That disposition stands and nothing new was added to those threads.
  • Issue-level comments: one, from @yiliang114 (2026-08-04T07:26:55Z). It is the previous round's own disposition record — it restates exactly the decline above (duplicate cleanup-extraction suggestions resolved without code changes, cleanup kept inline, follow-up possible later). It contains no new request or finding, so there is nothing to act on.
  • Failed checks: none. All completed CI checks are SUCCESS (Test on ubuntu-latest Node 22.x, Desktop Shell, web-shell E2E Smoke, Post Coverage Comment, Classify PR, label, Remind on force-push, delay-automatic-review, authorize) or legitimately SKIPPED (macOS/Windows test shards, integration tests, review-workflow prechecks). The review-pr check is IN_PROGRESS — the automated review job itself still running, not a failure; if it produces findings they will arrive as feedback in a later round.
  • Still-red checks persisting from earlier: none.
  • Base conflicts: none reported (--conflict false); no merge of main was performed.

PR state: the branch is up to date with its latest pushed commit (3e70e8dd3), the working tree is clean, and no commit was created this round.

Verification (evidence gathering only; no code changed, nothing committed)

  • npx vitest run --config ./scripts/tests/vitest.config.ts scripts/tests/review-worktree-cleanup-workflow.test.js scripts/tests/qwen-pr-review-workflow.test.js — 2 files, 27/27 passed, confirming the current head's workflow cleanup steps remain pinned to paths.ts and green.
中文说明

Autofix 审查轮次 — 无需操作(PR #8474

本轮未发现针对 PR #8474codex/cleanup-review-worktrees)的可处理反馈,因此未做任何更改。

已核查的内容(自上次评估 2026-08-04T06:41:37Z 之后的新反馈):

  • 新审查(Reviews): 无。
  • 新的行内评论(Inline comments): 无。自动审查器已有的两条 **[Suggestion]** 评论(id 3706494135,位于 .github/workflows/ci.yml:183;id 3706494143,位于 .github/workflows/qwen-code-pr-review.yml:1005,均创建于 2026-08-03T17:55:42Z)早于上次评估,且已在更早的轮次中以记录在案的理由婉拒:把重复的清理脚本抽取为共享脚本/action 会让一个目标明确的 CI 清理修复范围膨胀,因此本 PR 保留清理逻辑内联;如果维护者需要,共享抽取可以作为单独的后续 PR。该处理决定维持不变,这两条线索也没有新增任何内容。
  • Issue 级评论: 一条,来自 @yiliang114(2026-08-04T07:26:55Z)。它是上一轮自己的处理记录——恰好复述了上述婉拒决定(重复的清理抽取建议已在不做代码更改的情况下解决,清理逻辑保留内联,后续可视需要另开 PR)。其中没有任何新的请求或发现,因此没有可执行的事项。
  • 失败的检查(Failed checks): 无。所有已完成的 CI 检查均为 SUCCESS(ubuntu-latest Node 22.x 上的 Test、Desktop Shell、web-shell E2E Smoke、Post Coverage Comment、Classify PR、label、Remind on force-push、delay-automatic-review、authorize),或属于合理的 SKIPPED(macOS/Windows 测试分片、集成测试、审查工作流的预检查)。review-pr 检查处于 IN_PROGRESS 状态——是自动审查任务本身仍在运行,并非失败;如果它产生发现,将在后续轮次作为反馈送达。
  • 此前遗留的持续失败检查: 无。
  • 基分支冲突: 未报告(--conflict false);未执行对 main 的合并。

PR 状态: 分支已包含最新推送的提交(3e70e8dd3),工作树干净,本轮未创建任何提交。

验证(仅收集证据;未改动代码,未提交任何内容)

  • npx vitest run --config ./scripts/tests/vitest.config.ts scripts/tests/review-worktree-cleanup-workflow.test.js scripts/tests/qwen-pr-review-workflow.test.js —— 2 个文件,27/27 通过,确认当前 head 的工作流清理步骤仍与 paths.ts 保持锚定且为绿色。

Base-conflict check · 基分支冲突检查: no conflict with main. · 与 main 无冲突。


🧠 Handled by Qwen Code · model/模型 qwen3.8-max

@wenshao

wenshao commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

Review @ 3e70e8d — mechanism is sound and well-layered (CLI process cleanup → post-job always() step → next-job pre-checkout sweep), and the new test is genuinely good: patterns are derived from worktreePath()/reviewBranch() instead of retyped, the awk filter is executed against a realistic porcelain fixture, and the prune → remove → prune → branch-delete order assertion encodes the "a branch checked out in a live worktree cannot be deleted" invariant. I ran the new test at this head: 4/4 pass. Cross-checked the hardcoded globs: .qwen/tmp/review-pr-* and refs/heads/qwen-review/* match paths.ts, qwen-review-lease-pr-*.json matches LEASE_PREFIX + validTarget in review-worktree-lease.ts, and the substring filter also catches the -probe/-base sibling trees. Two things worth fixing before merge, both small.

Should fix

  1. Unguarded pipeline heads can fail the recovery step itself under -eo pipefail (ci.yml Clean stale .qwen before checkout). ci.yml sets defaults.run.shell: bash, so every step runs with -e -o pipefail. The two new pipelines — git … worktree list --porcelain | awk … | while … done and git … for-each-ref … | while … done — have no guard on the pipeline: if the head git command exits non-zero while .git exists (dubious ownership after the chown fallback failed, or a partial .git left by an interrupted checkout — exactly the trashed-runner states this step exists to recover from), pipefail propagates the failure and -e fails the step, blocking the job before checkout. Pre-PR this step could not fail, and actions/checkout self-heals an invalid repo by re-initializing. Appending || true after each done (a pipeline-level guard) restores the "never fail pre-checkout" property and matches the || true discipline of the rest of the step.
    The same pattern is in the new Clean review worktrees step (that workflow has no defaults.run.shell, so it gets bash -e {0}, and the step sets pipefail itself): a git failure there would flip an otherwise-green review job red. Lower risk since .git is a fresh checkout, but it's the same one-line guard. (The pre-existing Clean stale agent state step has this same latent hole in its for-each-ref pipeline despite its "never fail the job" comment — worth aligning while here.)

  2. Backstop coverage: integration_cli checks out on the same ecs-qwen pool with no equivalent sweep. The acknowledged SIGKILL residual relies on "the next job's pre-checkout cleanup", but only jobs.test got the sweep; integration_cli goes Restore workspace ownershipCheckout directly, so on a poisoned runner it still dies with cannot delete branch … used by worktree. Since local composite actions aren't usable pre-checkout (chicken-and-egg with the untrusted workspace), inline duplication there is the honest fix. qwen-triage / sdk-java / npm-cache also schedule onto this pool — fine as a follow-up.

Nit

  1. The test pins two of the three sweep sites. The pre-existing Clean stale agent state step (review workflow, pre-checkout) hardcodes .qwen/tmp/review-pr-* and refs/heads/qwen-review/* too, and a paths.ts rename would rot it silently — the exact failure mode the test's own comment cites. Two more toContain assertions against that step's run would close it. (The lease glob is likewise unpinned, but LEASE_PREFIX isn't exported — fine to leave.)

Note (no action needed)

Running git pre-checkout against a leftover, untrusted .git honors its config, but the chosen command set avoids the config-execution surfaces: worktree remove always passes --force (no status walk → no core.fsmonitor), and none of worktree list/prune, for-each-ref, branch -D run hooks. Keep --force if this block is ever edited — or pin with git -c core.fsmonitor= -c core.hooksPath= if you want it explicit.

@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Qwen Code review timed out. Qwen review timed out after 10800 seconds (of the 180-minute budget). For large PRs, retry with a longer timeout by commenting: @qwen-code /review --timeout=360. See workflow logs.

@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

🤖 Addressed the latest review feedback (round 4/100). What changed, and what I pushed back on: · 已处理最新评审反馈(第 4/100 轮)。改动内容与我反驳保留之处如下:

Autofix review round summary — PR #8474

Addressed all actionable feedback from @wenshao's review at 3e70e8d. No base-conflict resolution was requested (--conflict false), and no merge was performed. One commit: eb1f6a6a9.

Feedback dispositions

  1. Unguarded pipeline heads can fail the recovery steps under -eo pipefailFixed. Appended a pipeline-level || true after done on every affected pipeline, restoring the "never fail pre-checkout" property and matching each step's existing || true discipline:
    • ci.ymlClean stale .qwen before checkout (test job): both new pipelines (worktree list | awk | while and for-each-ref | while) are now guarded, so a failing head git on a trashed runner can no longer block the job before checkout.
    • qwen-code-pr-review.ymlClean review worktrees (post-job always() step): both pipelines guarded, so a git failure there can no longer flip an otherwise-green review job red.
    • qwen-code-pr-review.yml → pre-existing Clean stale agent state: its for-each-ref pipeline had the same latent hole despite the step's "never fail the job" comment; aligned with the same one-line guard, as suggested.
  2. integration_cli has no equivalent pre-checkout sweepFixed. Inlined a copy of the Clean stale .qwen before checkout step into integration_cli between Restore workspace ownership and Checkout (inline duplication is the honest fix pre-checkout, as noted in the review). It carries the same || true guards from the start. Like the review, I left the other pool-sharing jobs (qwen-triage, sdk-java, npm-cache) as follow-ups; note that web_shell_e2e_smoke in ci.yml also routes onto the same pool via classify_pr and still has no sweep, so it belongs in that same follow-up set.
  3. Nit: test pins only two of the sweep sitesFixed. Added the two toContain assertions pinning the pre-existing Clean stale agent state step's hardcoded .qwen/tmp/review-pr-* directory glob and refs/heads/qwen-review/* branch pattern. The new integration_cli sweep introduced by item 2 is pinned the same way (full cleanup recipe + identical awk filter), since adding a fourth hardcoded sweep site without pinning it would reintroduce exactly the silent-rot failure mode this test exists to catch. The lease glob remains unpinned (LEASE_PREFIX is not exported), as accepted in the review.
  4. Note on git config-execution surfaces (no action needed) — Acknowledged. All copies keep worktree remove --force (no status walk, no hooks triggered by the command set used); nothing in this round changed that.
  5. Qwen Code review timeout notice (bot comment) — Informational only; no finding to address. The Failed checks and Still-red checks sections of the feedback are empty.

Changed files

  • .github/workflows/ci.yml — pipeline guards in the test job's pre-checkout sweep; new mirrored sweep step in integration_cli.
  • .github/workflows/qwen-code-pr-review.yml — pipeline guards in Clean stale agent state and Clean review worktrees.
  • scripts/tests/review-worktree-cleanup-workflow.test.js — pins the Clean stale agent state step and the new integration_cli sweep to paths.ts.

Verification

Commands actually run in this checkout (commit eb1f6a6a9):

  • npx vitest run --config ./scripts/tests/vitest.config.ts review-worktree-cleanup-workflowpassed (6/6 tests, including the new pins)
  • npm run test:scripts — 897 passed, 9 skipped, 5 failed; all 5 failures are spawnSync zip ENOENT in install-script.test.js because this ECS runner has no zip binary (also no xz, file, or pip — a minimal image). These tests package archives with the system zip, are unrelated to this diff, and pass on CI runners where zip is installed.
  • npm run buildpassed
  • npm run typecheckpassed
  • node scripts/lint.js --eslint (CI's ESLint invocation) — passed
  • node scripts/lint.js --actionlintpassed (also ran actionlint 1.7.12 directly on the two modified workflow files: clean)
  • node scripts/lint.js --shellcheckpassed. This runner lacks file(1), so the script's discovery pipeline found no scripts; I re-ran shellcheck 0.11.0 over the git-tracked shell scripts using an equivalent shebang-based discovery — no findings in any file touched by this PR (all reported warnings are pre-existing in untouched scripts, and the pipeline's exit semantics match CI's).
  • node scripts/lint.js --yamllint (yamllint 1.35.1) — passed over all tracked YAML files
  • npx prettier --check scripts/tests/review-worktree-cleanup-workflow.test.jspassed
  • Both workflow files additionally validated by parsing with the repo's yaml package; the new integration_cli step is positioned Restore workspace ownershipClean stale .qwen before checkoutCheckout.
中文说明

Autofix 评审轮次总结 — PR #8474

已处理 @wenshao3e70e8d 评审中提出的全部可操作反馈。本轮未要求解决 base 冲突(--conflict false),也未执行任何 merge。单个提交:eb1f6a6a9

反馈处理结果

  1. 未加防护的管道头部命令可能在 -eo pipefail 下让恢复步骤自身失败已修复。 在每个受影响的管道 done 之后追加了管道级 || true,恢复"预检步骤永不失败"的属性,并与各步骤既有的 || true 约定保持一致:
    • ci.ymlClean stale .qwen before checkout(test 任务):两条新管道(worktree list | awk | whilefor-each-ref | while)现已加防护,损坏的 runner 上 git 头部命令失败不会再在 checkout 之前 阻断任务。
    • qwen-code-pr-review.ymlClean review worktrees(任务结束后的 always() 步骤):两条管道均已加防护,git 失败不会再把本来绿色的评审任务变成红色。
    • qwen-code-pr-review.yml → 既有的 Clean stale agent state:其 for-each-ref 管道尽管有"永不失败"的注释,仍存在同样的隐患;按评审建议用同样的一行防护对齐。
  2. integration_cli 缺少等价的预检清扫已修复。integration_cliRestore workspace ownershipCheckout 之间内联复制了 Clean stale .qwen before checkout 步骤(正如评审所指,预检阶段内联复制是诚实的修法)。该副本从一开始就带有相同的 || true 防护。与评审一致,其他共用该 runner 池的任务(qwen-triagesdk-javanpm-cache)留作后续处理;另外说明:ci.yml 中的 web_shell_e2e_smoke 也通过 classify_pr 路由到同一池且同样没有清扫,应归入同一后续范围。
  3. Nit:测试只钉住了两处清扫点已修复。 新增两个 toContain 断言,钉住既有 Clean stale agent state 步骤中硬编码的 .qwen/tmp/review-pr-* 目录通配符与 refs/heads/qwen-review/* 分支模式。第 2 项新引入的 integration_cli 清扫点也以同样方式钉住(完整清理流程 + 相同的 awk 过滤器),因为新增第四个硬编码清扫点却不钉住,恰恰会重新引入该测试要防范的"静默失效"故障模式。lease 通配符仍不钉住(LEASE_PREFIX 未导出),与评审中的认可一致。
  4. 关于 git 配置执行面的说明(无需操作) — 已知悉。所有副本均保留 worktree remove --force(不走 status 扫描,所用命令集不触发 hooks);本轮未改动这一点。
  5. Qwen Code 评审超时通知(机器人评论) — 仅信息性提示,无需处理的发现。反馈中的 Failed checksStill-red checks 部分为空。

变更文件

  • .github/workflows/ci.yml — test 任务预检清扫的管道防护;integration_cli 新增镜像清扫步骤。
  • .github/workflows/qwen-code-pr-review.ymlClean stale agent stateClean review worktrees 的管道防护。
  • scripts/tests/review-worktree-cleanup-workflow.test.js — 将 Clean stale agent state 步骤和新的 integration_cli 清扫点钉住到 paths.ts

验证

在本次检出(提交 eb1f6a6a9)上实际执行的命令:

  • npx vitest run --config ./scripts/tests/vitest.config.ts review-worktree-cleanup-workflow通过(6/6 个测试,含新钉住项)
  • npm run test:scripts — 897 通过、9 跳过、5 失败;5 个失败全部是 install-script.test.js 中的 spawnSync zip ENOENT,原因是本 ECS runner 没有 zip 二进制(同样缺少 xzfilepip — 精简镜像)。这些测试用系统 zip 打包归档,与本 diff 无关,在安装了 zip 的 CI runner 上可以通过。
  • npm run build通过
  • npm run typecheck通过
  • node scripts/lint.js --eslint(CI 的 ESLint 调用方式)— 通过
  • node scripts/lint.js --actionlint通过(另直接对两个修改过的 workflow 文件运行 actionlint 1.7.12:无告警)
  • node scripts/lint.js --shellcheck通过。本 runner 缺少 file(1),脚本的发现管道找不到任何脚本;我用等价的基于 shebang 的发现方式对 git 跟踪的 shell 脚本重新运行了 shellcheck 0.11.0 — 本 PR 触及的文件中无任何发现(所有告警均为未触及脚本中的既有问题,管道退出语义与 CI 一致)。
  • node scripts/lint.js --yamllint(yamllint 1.35.1)— 对所有跟踪的 YAML 文件通过
  • npx prettier --check scripts/tests/review-worktree-cleanup-workflow.test.js通过
  • 两个 workflow 文件另经仓库自带 yaml 包解析校验;新的 integration_cli 步骤位置为 Restore workspace ownershipClean stale .qwen before checkoutCheckout

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/模型 qwen3.8-max

@wenshao

wenshao commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

Review — fix(ci): clean review worktrees after cancellation

What it does

Three changes: (1) an always() Clean review worktrees step at the end of review-pr, (2) the pre-checkout .qwen sweep in ci.yml extended with worktree pruneworktree remove --forcebranch -D 'qwen-review/*', and copied into integration_cli, (3) scripts/tests/review-worktree-cleanup-workflow.test.js pinning the shell recipe to worktreePath()/reviewBranch() in paths.ts.

Verification I ran

Built a fixture repo mimicking a runner workspace left over from an interrupted review (registered .qwen/tmp/review-pr-42 + -probe worktrees on qwen-review/* branches) and executed the actual run: blocks parsed out of both workflows:

  • Before (pre-existing rm -rf .qwen only): worktrees go prunable, and the branch purge actions/checkout does on a reused repo fails with exactly the reported error — error: cannot delete branch 'qwen-review/pr-42' used by worktree at '.../.qwen/tmp/review-pr-42', exit 1.
  • After: the new step prunes both registrations, deletes both branches, and the simulated checkout purge succeeds. Exit 0.
  • rm blocked (dirs survive): the worktree remove --force loop removes both worktrees and directories, branches deleted, exit 0 — so the second half of the recipe is load-bearing, not decoration.
  • Review-job step on a workspace with no .git: prints no Git checkout; nothing to clean, exit 0.
  • New spec: 6/6 pass. Mutation-tested — renaming the review-pr- suffix in paths.ts (4 failures), renaming the branch family to qwrev/ (4), dropping the post-remove prune from the review step (1), diverging integration_cli's awk filter (2). It genuinely guards the invariants it claims. eslint clean; the .js-importing-.ts path resolves fine under the scripts/tests vitest project.

The awk filter is correctly anchored (/ before .qwen) so it can never select the main checkout, and it also picks up the -probe and -base sibling trees since they share the review-pr- prefix.

Findings

1. web_shell_e2e_smoke is on the same reused workspace and was left outci.yml

test, integration_cli and web_shell_e2e_smoke all resolve runs-on from needs.classify_pr.outputs.ubuntu_runner (the self-hosted pool), all run actions/checkout, and all three open with Restore workspace ownership — i.e. the job already acknowledges it inherits a dirty workspace. It is the only one of the three with no .qwen cleanup at all, before or after this PR, and it runs on every full-profile PR. The failure this PR fixes can still land there.

The new spec can't catch this because it enumerates jobs by name. Consider inverting it:

// every ci.yml job that checks out on the shared self-hosted pool must sweep first
for (const [id, job] of Object.entries(ciYaml.jobs)) {
  if (!JSON.stringify(job['runs-on']).includes('ubuntu_runner')) continue;
  if (!job.steps.some((s) => String(s.uses ?? '').includes('actions/checkout'))) continue;
  expect(job.steps.find((s) => s.name === 'Clean stale .qwen before checkout'), id).toBeDefined();
}

That both covers web_shell_e2e_smoke and makes the next job added to the pool fail loudly instead of silently. (npm-cache.yml:save, sdk-java.yml, serve-ab.yml are on the same pool too — out of scope here, but the same hazard.)

2. The lease filename isn't pinned by the specqwen-code-pr-review.yml

rm -f .qwen/tmp/qwen-review-lease-pr-*.json hard-codes LEASE_PREFIX from packages/cli/src/services/review-worktree-lease.ts, but the spec only derives patterns from paths.ts. That's precisely the drift the spec's own header comment says it exists to prevent. One assertion closes it — export/import the prefix and add expect(reviewCleanStep).toContain(\rm -f ${REVIEW_TMP_DIR}/${LEASE_PREFIX}pr-*.json`). (Low impact — a stale lease file is inert, and the leases are session+prompt scoped so the blanket rm` can't disturb anything.)

3. Comment slightly undersells the remove loopci.yml

the rm above removed the directories, so sync Git's bookkeeping and drop the branches

If that were always true, worktree remove --force would be dead code — prune alone would suffice (confirmed in the fixture). The loop only earns its keep when the rm fails (root-owned or read-only leftovers, the case the adjacent ::warning::leaked .qwen branch anticipates). Worth saying so, otherwise a future cleanup pass will delete the loop as redundant.

4. Nitdonedone || true at qwen-code-pr-review.yml:404 is a no-op: that step has no set -e, and the loop isn't the last command. Harmless, and fine to keep for symmetry with the new blocks.

Non-issues I checked

  • always() does run on cancellation, and the step can't fail the job (every command is || true; verified exit 0 in all four fixture scenarios). timeout-minutes: 5 is a sensible guard.
  • read -r on the whole line handles worktree paths with spaces.
  • Locked worktrees would need --force --force, but nothing in review/ uses git worktree --lock, so this doesn't bite today.
  • Deleting all qwen-review/* branches rather than just this PR's is safe on a one-job-at-a-time runner and matches the pre-existing Clean stale agent state step.

Verdict

Correct fix, well-scoped, and the test is real rather than decorative. Finding 1 is worth addressing before merge — the PR's stated goal is "extend the CI pre-checkout cleanup", and leaving the third job on the same pool uncovered means the same red CI can reappear from a different direction. The rest are nits.

@wenshao

wenshao commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

Review: fix(ci): clean review worktrees after cancellation

Overview

Three changes: (1) a new always() Clean review worktrees step at the tail of review-pr; (2) the pre-checkout Clean stale .qwen before checkout step in ci.yml's test job gains a Git-bookkeeping sweep, and integration_cli gets the whole step for the first time; (3) a one-line || true on the existing Clean stale agent state loop, plus a new pinning test.

I verified this against real Git fixtures rather than by reading — extracted the four run: blocks straight out of the PR's YAML and ran them against repos carrying a live qwen-review/pr-42 worktree, a -probe sibling, a dead registration, a lease file, and an unrelated keep-me branch.

What holds up

  • The reported failure reproduces and is fixed. Baseline: error: cannot delete branch 'qwen-review/pr-42' used by worktree at .../.qwen/tmp/review-pr-42. All three new/changed steps clear it — worktree list back to just the main checkout, both review branches deleted, keep-me and the working tree untouched.
  • The || true on line 407 is a real fix, not cosmetic. GitHub's default shell is bash --noprofile --norc -eo pipefail, so a failing for-each-ref propagates through pipefail and kills the step. On a dangling gitlink (.git file pointing at a deleted gitdir — exactly what a half-cleaned workspace looks like) the main version of the step exits 128 and fails the review job before it starts; the PR version exits 0.
  • The new recipe is strictly stronger than rm-then-prune, which is the load-bearing justification for the extra lines. With .qwen made undeletable (chflags uchg — the case where the step already prints ::warning::leaked .qwen): the old recipe leaves qwen-review/pr-42 alive and the next checkout breaks; the new one still deregisters via worktree remove --force and deletes the branch, even though the directory itself survives.
  • Blast radius is correctly scoped. keep-me survives; the main worktree survives; review-pr-42-probe (probeWorktreePath, an absolute sibling) is swept by the same filter — nice, that one is easy to miss.
  • Nothing can fail the job. All four steps exit 0 under the GHA shell across: healthy repo, corrupt repo, dangling gitlink, missing .git, undeletable .qwen. Paths containing spaces round-trip correctly through worktree list --porcelain | awk | read -r.
  • Ordering (prune → remove --force → prune → branch -D) is right and the test's comment explains why it must be that order. Pinning the sweep patterns to paths.ts is the right instinct given the suffix-rename regression that module already documents.

Issues & suggestions

1. web_shell_e2e_smoke is left uncovered (medium). It runs on the same needs.classify_pr.outputs.ubuntu_runner ECS pool and does actions/checkout, but has no .qwen cleanup at all — only Restore workspace ownership. Audit of ci.yml after this PR:

job self-hosted checkout cleanup step
test yes yes
integration_cli yes yes ✅ (new)
web_shell_e2e_smoke yes yes
classify_pr yes no n/a

The comment added to integration_cli"this job lands on the same reused pool" — applies verbatim here. Either add the step or say why this job is exempt.

2. The review workflow's own pre-checkout sweep wasn't upgraded (medium). Clean stale agent state still uses the weaker rm -rf + prune recipe, and the new test encodes that weaker expectation ("Directories are rm -rf'd first there, so no worktree remove to pin"). But the E2/E3 fixture above shows the gap is real: if that rm -rf fails, the branch survives and the review's own git worktree add then hits missing but already registered / branch-in-use — the very failure this PR is about, one step earlier in the same workflow. Applying the same four-step recipe there would close the loop.

3. Duplication (low). The inline justification ("runs pre-checkout on shared runners, where leftover workspace files are untrusted") is sound for the two pre-checkout copies — there's no repo on disk to source a script from. It does not apply to Clean review worktrees, which runs post-checkout and could call a script in the repo. Not blocking; the test's "one identical awk filter at every list-driven sweep" assertion is a decent mitigation. Consider also asserting the two ci.yml copies are byte-identical, since they're meant to be.

4. timeout-minutes: 5 on an always() step (low). In the cancellation path GitHub grants a limited grace window before force-terminating the job; a 5-minute step budget may never be honored. The step is sub-second in practice — 1–2 minutes is a truer cap and leaves the runner room to finish.

5. The awk filter is substring-based (nit). index($0, "/.qwen/tmp/review-pr-") > 0 matches anywhere in the line, so it would also select the main checkout if the workspace path ever contained that substring. Harmless in practice (worktree remove on a main working tree just errors into a ::warning::), and the current runner layout is safe — but anchoring to $GITHUB_WORKSPACE would make "never the main checkout" structural rather than incidental. The test asserts it only for one hard-coded path.

6. Test coverage is structural, not behavioural (low). The suite pins strings and unit-tests the awk filter, but never executes the recipe — so ordering, quoting, or -e regressions slip through. qwen-pr-review-workflow.test.js already sets the precedent of extracting a run: block and executing the real bash against a fixture. A fixture test here (create worktree + branch, run the extracted block, assert branch gone and main checkout intact) would be materially stronger. Two smaller notes on the current test: expectCleanupRecipe uses run.indexOf('worktree remove --force'), which silently picks the first match if a second removal is ever added; and the it.skipIf(!awkAvailable) case is the only behavioural assertion, so on Windows the file degrades to pure string matching.

Security & performance

No concerns. Branch names come from for-each-ref and are quoted; a PR author can't create local qwen-review/* refs on the runner (checkout writes to refs/remotes/). rm -rf .qwen/tmp/review-pr-* is a relative glob under a cwd GHA pins to $GITHUB_WORKSPACE. Runtime is a handful of local Git calls — negligible, and it runs pre-checkout where it costs nothing.

Verdict

The change is correct, well-scoped, and the added complexity earns its place — I could measure the difference between the old and new recipes, which is not always true of CI hardening. Approve once #1 (the web_shell_e2e_smoke gap) is either fixed or explicitly ruled out of scope; #2 is the natural follow-up.

@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

🤖 Addressed the latest review feedback (round 5/100). What changed, and what I pushed back on: · 已处理最新评审反馈(第 5/100 轮)。改动内容与我反驳保留之处如下:

Review feedback round — PR #8474

Triaged the 2026-08-04 review by @wenshao (issue-level comment, four findings). Three findings fixed in code, one kept with counter-evidence. No merge performed (--conflict false).

Finding 1 — web_shell_e2e_smoke was left out of the cleanup coverage → Fixed

  • Added the same Clean stale .qwen before checkout step to web_shell_e2e_smoke in ci.yml, between Restore workspace ownership and Checkout — the run: block is byte-identical to the test/integration_cli recipe (verified programmatically). The job's job-level if: already covers skip_ci, so no step-level condition was added, matching integration_cli.
  • Inverted the spec's enumeration as suggested: it now filters ci.yml jobs by runs-on containing ubuntu_runner AND a step using actions/checkout, and requires the clean step + full recipe on every match. An arrayContaining(['test', 'web_shell_e2e_smoke', 'integration_cli']) assertion guards against the filter silently matching nothing. The awk-filter identity test now iterates the same enumeration, so a divergent filter in any pool job fails.
  • Mutation-tested: removing/renaming the web_shell_e2e_smoke step fails with job "web_shell_e2e_smoke" checks out on the shared pool and must clean stale .qwen state first; diverging its awk filter fails the identity test.
  • The other-pool workflows named in the review (npm-cache.yml:save, sdk-java.yml, serve-ab.yml) were explicitly marked out of scope and are untouched.

Finding 2 — lease filename not pinned by the spec → Fixed

  • Moved LEASE_PREFIX from review-worktree-lease.ts into packages/cli/src/commands/review/lib/paths.ts (the module the spec already treats as the layout owner; review-worktree-lease.ts already imported from it) and exported it.
  • Added expect(reviewCleanStep).toContain(\rm -f ${toPosix(REVIEW_TMP_DIR)}/${LEASE_PREFIX}pr-*.json`)` to the review-job test, so the workflow glob and the lease writer share one pinned definition.
  • Mutation-tested: renaming LEASE_PREFIX fails the spec.

Finding 3 — comment undersells the remove loop → Fixed

  • Rewrote the comment in all three ci.yml copies: it now says prune drops registrations for directories the rm removed, worktree remove --force clears the directories that survived the rm (root-owned or read-only leftovers), and branches can only be deleted once no worktree holds them.
  • The spec's ordering assertions now strip comment lines before checking command order, because the improved comment legitimately names worktree remove --force out of command order.

Finding 4 — done || true at qwen-code-pr-review.yml:404 called a no-op → Kept, with evidence

  • Kept as-is. GitHub Actions invokes run: steps as bash -e {0}, so -e is active even though the step never writes set -e (the repo's set -uo pipefail lines only add -u/pipefail to that implicit -e). Under -e + pipefail, a failing git for-each-ref would fail the pipeline and abort the step mid-script, failing the job — exactly what the step's "never fail the job" contract forbids. The || true also matches the guard on every other command in that step and the new blocks. The review explicitly allowed keeping it ("harmless, and fine to keep for symmetry"), so no code change this round.

Dispositions

Finding Disposition
1 — web_shell_e2e_smoke coverage + spec inversion Fixed
2 — lease prefix pinning Fixed
3 — comment undersells remove loop Fixed
4 — done || true no-op claim Kept (implicit bash -e makes it load-bearing)

Changed files: .github/workflows/ci.yml, packages/cli/src/commands/review/lib/paths.ts, packages/cli/src/services/review-worktree-lease.ts, scripts/tests/review-worktree-cleanup-workflow.test.js. Commit: fix(ci): extend review cleanup sweep to web_shell_e2e_smoke (#8474).

Verification

  • npm run build — passed
  • npm run typecheck — passed
  • npm run lint — passed
  • npx eslint scripts/tests/review-worktree-cleanup-workflow.test.js — passed (repo lint script only targets .ts/.tsx)
  • npx vitest run --config ./scripts/tests/vitest.config.ts review-worktree-cleanup-workflow — 5/5 passed
  • Mutation checks on the spec — LEASE_PREFIX rename, web_shell_e2e_smoke step removal, and web_shell awk-filter divergence each fail the spec; restored baseline is green
  • cd packages/cli && npx vitest run src/services/review-worktree-lease.test.ts src/commands/review — 53 files passed, 1684 tests passed / 4 skipped
  • npm run test:scripts — 896 passed / 9 skipped; 5 failures, all spawnSync zip ENOENT in install-script.test.js because this runner has no zip binary (which zip → not found, unzip exists). The tests shell out to zip; this diff touches neither them nor it. Environmental, not caused by this change
  • Structural YAML check (via the repo's yaml parser) — all three ci.yml sweep blocks byte-identical, each ordered before its job's Checkout, no trailing whitespace
  • yamllint/actionlint (node scripts/lint.js --yamllint/--actionlint) — not runnable on this runner (no pip3/binaries available); YAML validity confirmed via parser instead. CI runs both
中文说明

Review 反馈处理 — PR #8474

@wenshao 于 2026-08-04 提出的 review(issue 级评论,共四条发现)进行了分类处理。三条通过代码修复,一条以反证保留原状。未执行 merge(--conflict false)。

发现 1 — web_shell_e2e_smoke 未被清理逻辑覆盖 → 已修复

  • ci.ymlweb_shell_e2e_smoke 中,于 Restore workspace ownershipCheckout 之间加入了同样的 Clean stale .qwen before checkout 步骤——其 run: 块与 test/integration_cli 的配方逐字节一致(已用程序验证)。该 job 的 job 级 if: 已覆盖 skip_ci,因此未添加步骤级条件,与 integration_cli 保持一致。
  • 按建议反转了 spec 的枚举方式:现在通过 runs-on 包含 ubuntu_runner 且步骤中使用 actions/checkout 来过滤 ci.yml 的 job,并要求每个匹配的 job 都有清理步骤及完整配方。arrayContaining(['test', 'web_shell_e2e_smoke', 'integration_cli']) 断言防止过滤器静默匹配不到任何 job。awk 过滤器一致性测试也改为遍历同一枚举,因此任何池中 job 的过滤器不一致都会失败。
  • 变异测试验证:删除/重命名 web_shell_e2e_smoke 的步骤会以 job "web_shell_e2e_smoke" checks out on the shared pool and must clean stale .qwen state first 失败;使其 awk 过滤器不一致会让一致性测试失败。
  • review 中点名的其他同池工作流(npm-cache.yml:savesdk-java.ymlserve-ab.yml)被明确标注为超出本 PR 范围,未改动。

发现 2 — spec 未固定 lease 文件名 → 已修复

  • LEASE_PREFIXreview-worktree-lease.ts 移入 packages/cli/src/commands/review/lib/paths.ts(spec 本就视该模块为布局的唯一来源;review-worktree-lease.ts 本来就从该模块导入),并将其导出。
  • 在 review-job 测试中新增 expect(reviewCleanStep).toContain(\rm -f ${toPosix(REVIEW_TMP_DIR)}/${LEASE_PREFIX}pr-*.json`)`,使工作流中的 glob 与 lease 写入方共享同一个被固定的定义。
  • 变异测试验证:重命名 LEASE_PREFIX 会使 spec 失败。

发现 3 — 注释低估了 remove 循环的作用 → 已修复

  • 重写了 ci.yml 三处副本中的注释:现在说明 prune 会清除已被 rm 删除的目录对应的登记项,worktree remove --force 负责清理在 rm 之后仍然残留的目录(root 属主或只读残留),并且分支只有在没有 worktree 占用时才能被删除。
  • spec 中的顺序断言现在会先剔除注释行再检查命令顺序,因为改进后的注释确实会以非命令顺序提及 worktree remove --force

发现 4 — qwen-code-pr-review.yml:404done || true 被认为是空操作 → 保留,附证据

  • 保持原状。GitHub Actions 以 bash -e {0} 调用 run: 步骤,因此即使该步骤没有写 set -e-e 也是生效的(仓库中的 set -uo pipefail 只是在那个隐式 -e 之上追加 -u/pipefail)。在 -e + pipefail 下,git for-each-ref 一旦失败,管道即返回非零并在脚本中途中止该步骤,导致 job 失败——这正是该步骤"绝不使 job 失败"约定所禁止的。此处的 || true 也与该步骤中其他每条命令的守卫以及新增块保持一致。review 本身也明确允许保留("无害,为了对称性保留也可以"),因此本轮不做代码改动。

处理结果

发现 处理
1 — web_shell_e2e_smoke 覆盖 + spec 反转 已修复
2 — lease 前缀固定 已修复
3 — 注释低估 remove 循环 已修复
4 — done || true 空操作的说法 保留(隐式 bash -e 使其具有实际作用)

变更文件:.github/workflows/ci.ymlpackages/cli/src/commands/review/lib/paths.tspackages/cli/src/services/review-worktree-lease.tsscripts/tests/review-worktree-cleanup-workflow.test.js。提交:fix(ci): extend review cleanup sweep to web_shell_e2e_smoke (#8474)

验证

  • npm run build — 通过
  • npm run typecheck — 通过
  • npm run lint — 通过
  • npx eslint scripts/tests/review-worktree-cleanup-workflow.test.js — 通过(仓库的 lint 脚本只针对 .ts/.tsx
  • npx vitest run --config ./scripts/tests/vitest.config.ts review-worktree-cleanup-workflow — 5/5 通过
  • spec 变异检查 — 重命名 LEASE_PREFIX、删除 web_shell_e2e_smoke 步骤、使 web_shell 的 awk 过滤器不一致,均会使 spec 失败;恢复后的基线为绿色
  • cd packages/cli && npx vitest run src/services/review-worktree-lease.test.ts src/commands/review — 53 个文件通过,1684 个测试通过 / 4 个跳过
  • npm run test:scripts — 896 通过 / 9 跳过;5 个失败,全部是 install-script.test.js 中的 spawnSync zip ENOENT,原因是本 runner 没有 zip 可执行文件(which zip → 未找到,unzip 存在)。这些测试通过 shell 调用 zip;本 diff 既未改动这些测试也未改动 zip。属于环境问题,与本次变更无关
  • 结构化 YAML 检查(使用仓库的 yaml 解析器)— ci.yml 中三处清理块逐字节一致,且各自都排在其 job 的 Checkout 之前,无行尾空白
  • yamllint/actionlintnode scripts/lint.js --yamllint/--actionlint)— 本 runner 上无法运行(无 pip3/对应二进制);已改用解析器确认 YAML 有效性。CI 会运行这两项

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/模型 qwen3.8-max

@yiliang114

Copy link
Copy Markdown
Collaborator Author

@qwen-code-review-bot approve if no blockers

@qwen-code-review-bot qwen-code-review-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM — all of @wenshao's findings are addressed at this head. Verified f7f0954: web_shell_e2e_smoke now carries the Clean stale .qwen before checkout step (Restore workspace ownership → sweep → Checkout), closing the conditional from the last review, and the spec's inverted enumeration means the next job added to the shared pool fails loudly instead of silently. Lease-prefix pinning and the pipeline || true guards are in as well.

CI at head is green, including web-shell E2E Smoke which executes the new sweep; review-pr (automated LLM review) is still running but is non-blocking per the repo's own autofix config and has posted no findings across two infra-timeout runs — the human review here is the substantive one.

Remaining items (other pool workflows, upgrading the review workflow's own pre-checkout recipe, behavioural fixture test were explicitly marked follow-up by the reviewer. Ship it.
EOF
)

@yiliang114
yiliang114 enabled auto-merge August 4, 2026 15:06
@wenshao

wenshao commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

Review: fix(ci): clean review worktrees after cancellation

Overview

Adds an always() end-of-job sweep to review-pr that force-removes .qwen/tmp/review-pr-* worktrees, prunes registrations, deletes qwen-review/* branches and lease files; extends the pre-checkout Clean stale .qwen step in three shared-pool ci.yml jobs (test, web_shell_e2e_smoke, integration_cli) with the same recipe; hoists LEASE_PREFIX into paths.ts; and pins all of it with a new workflow test.

What I verified

Ran the PR-head files in an isolated harness rather than reading only:

  • New test passes: 5/5 against the PR-head ci.yml / qwen-code-pr-review.yml / paths.ts.
  • The test is load-bearing (mutation-tested, all caught):
    • renaming review-pr- in paths.ts → 3 failures,
    • deleting the clean step from integration_cli → 2 failures,
    • moving the branch sweep before worktree remove → 1 failure.
  • End-to-end on a fixture repo: reproduced error: cannot delete branch 'qwen-review/pr-42' used by worktree at ..., then ran the extracted Clean review worktrees body — worktree removed, -probe sibling removed, branch deleted, lease deleted, main/feature/keep-me/HEAD untouched.
  • ci.yml variant with a read-only leftover worktree: chmod -R u+wrm -rfprunebranch -D all succeed; workspace left clean.
  • Job enumeration is safe today: all 8 ci.yml jobs have both runs-on and steps; exactly the 3 shared-pool checkout jobs match the filter and all 3 carry the step.

The core fix is correct and the ordering rationale (prune → force-remove → prune → branch sweep) holds.


Findings

1. Security — the new pre-checkout git calls execute leftover repo hooks (high)

Before this PR, Clean stale .qwen before checkout in ci.yml ran no git commands — only chmod/rm. It now runs git worktree prune, worktree list, worktree remove --force, for-each-ref and branch -D against a .git directory that is, by the step's own comment, untrusted leftover state from a previous job on a reused runner.

git branch -D fires the reference-transaction hook. Reproduced on a fixture: a planted .git/hooks/reference-transaction executed 4 times during one run of the extracted ci-clean.sh, pre-checkout, as the runner user. An attacker-set core.hooksPath in the leftover .git/config works equally well.

Plausible path: qwen-triage.yml's verify lane runs untrusted fork-PR code on the same ['self-hosted','linux','x64','ecs-qwen'] pool and the same GITHUB_WORKSPACE; that workflow already scrubs .git/hooks and .git/config keys before touching git precisely for this reason (see its find "$HOOKS_DIR" \( -type f -o -type l \) ! -name '*.sample' -delete and the symlinked-hook comment). The new ci.yml git usage doesn't inherit that hardening.

Cheapest fix — a command-line -c beats the repo config (verified: attacker core.hooksPath in .git/config is overridden, 0 hook hits):

GIT_SAFE=(git -c core.hooksPath=/dev/null -c core.fsmonitor= -C "$GITHUB_WORKSPACE")
"${GIT_SAFE[@]}" worktree prune -v || true
"${GIT_SAFE[@]}" worktree list --porcelain | ...

Or follow qwen-triage.yml's precedent and scrub hooks + non-allowlisted .git/config keys before the first git invocation. The Clean review worktrees step in qwen-code-pr-review.yml runs post-checkout so it's lower risk, but the same one-liner is free there.

2. The comment overstates what worktree remove --force recovers (low)

worktree remove --force then clears the directories that survived the rm (root-owned or read-only leftovers)

chmod -R u+w already handles read-only, and git worktree remove runs as the same unprivileged user — it cannot delete root-owned files either. The only root-capable path is the sudo -n rm -rf fallback above. When worktree remove --force does fail, the registration survives, the second prune keeps it, and branch -D still fails — the ::warning:: is the real outcome, not recovery. Worth tightening the wording so a future reader doesn't over-trust the ladder.

Also note git worktree remove --force refuses locked worktrees (needs --force --force). Nothing in the review code locks today, so this is only a forward-looking hazard.

3. Scope gap — other jobs on the same pool still check out unswept (medium)

The same reused workspace is used by:

  • npm-cache.ymlruns-on: ['self-hosted','linux','x64','ecs-qwen'], plain actions/checkout, no sweep at all.
  • qwen-triage.yml → sweeps rm -rf .qwen/tmp/review-pr-* + worktree prune, but has no chmod -R u+w, no worktree remove --force, and never deletes qwen-review/*. If the directory survives the rm, prune keeps the registration and the branch stays undeletable — the exact failure this PR fixes.

The new test enumerates ci.yml only, so those two stay uncovered. Either extend the sweep/test to them, or add a line to the test's header comment stating that other workflows on the pool are deliberately out of scope.

4. Maintainability — four near-identical copies (low)

Inline is well-justified pre-checkout (you can't uses: a local action or source a repo script before checkout, and GitHub Actions has no YAML anchors), and the test pins the awk filter identical across all copies — good. But the recipe is now ~26 duplicated lines × 3 in ci.yml plus a variant in the review workflow, and the .qwen rm half isn't cross-checked.

Since the repo already manages the runner image (update-ecs-runner-qwen-workflow.test.js), an ACTIONS_RUNNER_HOOK_JOB_STARTED script on the ECS runner would collapse all four copies into one place that runs before every job on the pool — and would close finding #3 for free. Worth considering as the follow-up.

5. Test robustness nit (low)

JSON.stringify(job['runs-on']).includes('ubuntu_runner') && job.steps.some(...)

If a future ci.yml job is a reusable-workflow call (job-level uses:, no runs-on/steps), JSON.stringify(undefined) returns undefined and .includes throws a TypeError — the suite fails with a confusing error instead of a clean assertion. JSON.stringify(job['runs-on'] ?? '') and (job.steps ?? []) would be safer. (All 8 jobs are fine today.)

6. Unscoped deletion (nit)

Both new sweeps delete all qwen-review/* branches and .qwen/tmp/review-pr-*, not just the current PR's. That is safe under one-job-per-runner and matches the pre-existing Clean stale agent state step, but it's an unstated assumption — a one-line comment ("safe because a runner executes one job at a time; _work is not shared between runner processes") would document why the blast radius is acceptable.


Things done well

  • done || true on the for-each-ref | while pipelines is a real fix, not noise: GitHub's default shell is bash -e -o pipefail, so a failing for-each-ref would otherwise fail the step. Correct and necessary.
  • LEASE_PREFIX hoisted into paths.ts with a rationale tied to the sweep glob, and the test pins the glob to it — exactly the failure mode the probeWorktreePath doc-comment warns about.
  • if: always() + timeout-minutes: 5 on the review sweep, and every command || true-guarded, so cleanup can never turn a green review job red (confirmed: the step exits 0 on a repo with nothing to clean).
  • -probe worktrees are covered by both the awk filter and the rm -rf glob — verified on the fixture.
  • it.skipIf(!awkAvailable) keeps the behavioural awk test honest on Windows.

Verdict

Approve on the core mechanism once #1 is addressed — it's a one-line-per-call change and the step is newly executing git against attacker-influenced state on a shared self-hosted pool. #3 and #5 are worth a follow-up issue if you'd rather not grow this PR.

@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

🤖 Reviewed the latest feedback — no changes needed. Why, point by point: · 已审阅最新反馈——无需改动。逐点说明原因如下:

Review feedback round — PR #8474

Triaged the 2026-08-04 follow-up review by @wenshao (issue-level comment, six findings) plus @yiliang114's approval trigger. No code changes this round: the review's only merge-blocking finding (#1) was already fixed one commit before the review was posted, and the remaining findings are non-blocking follow-ups per the review's own verdict. No merge performed (--conflict false).

Context: the review crossed with the previous push

The review (posted 14:12 UTC) was written against the pre-f7f09548 state — its audit table marks web_shell_e2e_smoke ❌, but commit f7f09548 (14:05 UTC, the previous round) had already added the cleanup step there. All findings below are triaged against current HEAD.

Finding 1 — web_shell_e2e_smoke uncovered (medium; the verdict's only gate) → Already fixed, re-verified

  • ci.yml's web_shell_e2e_smoke job carries the same Clean stale .qwen before checkout step as test and integration_cli (added by f7f09548).
  • The spec enumerates ci.yml jobs by shared pool (ubuntu_runner) + actions/checkout rather than by name, requires the step on every match, asserts the three known jobs are present, and pins the full recipe on each copy; the identical-awk-filter test covers all of them.
  • Re-ran at HEAD: npx vitest run --config ./scripts/tests/vitest.config.ts scripts/tests/review-worktree-cleanup-workflow.test.js5/5 passed.

Finding 2 — upgrade Clean stale agent state to the four-step recipe (medium) → Deferred to a follow-up, per the review's verdict

The gap is real: if the pre-checkout rm -rf there fails, the worktree registration and branch survive into the review's own git worktree add. But the review explicitly gates approval only on #1 and names #2 "the natural follow-up", and the maintainer has called for approval once no blockers remain. This PR is past its fifth change-producing round, so per the repo's review-ratchet rule non-blocking suggestions are deferred instead of widening the diff now. Recorded here so it is not silently dropped: apply prune → worktree remove --force → prune → branch -D in that step (keeping its leading rm -rf), switch its spec case to expectCleanupRecipe, and add the step to the filter-identity test.

Finding 3 — assert the ci.yml copies stay byte-identical (low) → Deferred to the same follow-up

Already mitigated today: each copy independently passes the full recipe pin and all copies must share one identical awk filter, so any behaviour-changing divergence fails. The stricter Set(runs).size === 1 assertion is test-only polish; recorded for the follow-up.

Finding 4 — timeout-minutes: 5 → 1–2 on the always() step (low) → Deferred to the same follow-up

No correctness impact — the step is sub-second and every command is || true-guarded; the point is an honest cap. One-line change, recorded for the follow-up.

Finding 5 — anchor the awk filter to $GITHUB_WORKSPACE (nit) → Declined, with evidence

The filter feeds only git worktree remove --force, and Git itself refuses to remove the main working tree — the loop turns that refusal into a ::warning:: and continues, which the review's own fixture run confirmed ("The main worktree survives", "Harmless in practice"). Anchoring would require passing the workspace into awk -v in all four copies, and awk -v reinterprets escape sequences in the value — new subtlety in four places to defend a case Git already guards. The behavioural pin already asserts the real runner's main-checkout path is never selected by the filter.

Finding 6 — behavioural fixture test executing the recipe (low) → Deferred to the same follow-up

Valuable, and consistent with the qwen-pr-review-workflow.test.js precedent of executing extracted run: blocks. It belongs with the #2 upgrade so the executed recipe also covers the agent-state step; the two smaller notes (assert exactly one worktree remove --force occurrence instead of first-match indexOf; the skipIf(!awkAvailable) Windows caveat) travel with it. Recorded for the follow-up.

@yiliang114@qwen-code-review-bot approve if no blockers

An approval trigger for the review bot, not a change request for this loop; no blockers remain, since finding #1 is resolved at HEAD.

中文说明

评审反馈轮次 — PR #8474

已分诊 @wenshao 于 2026-08-04 发布的后续评审(issue 级评论,共六项发现)以及 @yiliang114 的批准触发指令。本轮不做任何代码改动:该评审中唯一阻塞合并的发现(#1)在评审发布前一个提交就已修复,其余发现按评审自身的结论均为非阻塞的后续事项。未执行合并(--conflict false)。

背景:评审与上一次推送时间交错

该评审(发布于 14:12 UTC)是针对 f7f09548 之前的代码状态撰写的——其审计表格将 web_shell_e2e_smoke 标记为 ❌,但提交 f7f09548(14:05 UTC,即上一轮)已经为该任务添加了清理步骤。以下所有发现均基于当前 HEAD 进行分诊。

发现 1 — web_shell_e2e_smoke 未覆盖(中等;评审结论中唯一的合并门槛)→ 已修复,并已重新验证

  • ci.ymlweb_shell_e2e_smoke 任务现已包含与 testintegration_cli 相同的 Clean stale .qwen before checkout 步骤(由 f7f09548 添加)。
  • 测试规约按共享池(ubuntu_runner)+ actions/checkout 枚举 ci.yml 任务而非按任务名枚举,要求每个匹配任务都必须有该步骤,断言三个已知任务均存在,并对每个副本钉住完整清理配方;awk 过滤器一致性测试覆盖所有副本。
  • 已在 HEAD 重新运行:npx vitest run --config ./scripts/tests/vitest.config.ts scripts/tests/review-worktree-cleanup-workflow.test.js5/5 通过

发现 2 — 将 Clean stale agent state 升级为四步清理配方(中等)→ 按评审结论推迟至后续 PR

该缺口确实存在:如果该处的预检出 rm -rf 失败,worktree 注册与分支会残留到评审流程自身的 git worktree add。但评审明确只以 #1 作为批准门槛,并称 #2 是"顺理成章的后续工作",且维护者已在无阻塞时要求批准。本 PR 已超过第五个产生变更的评审轮次,按仓库的评审轮次收敛规则,非阻塞建议应推迟处理而不是继续扩大当前 diff。在此记录以免被静默丢弃:在该步骤中应用 prune → worktree remove --force → prune → branch -D(保留其开头的 rm -rf),将其测试用例切换为 expectCleanupRecipe,并将该步骤加入过滤器一致性测试。

发现 3 — 断言 ci.yml 各副本保持逐字节一致(低)→ 推迟至同一后续 PR

目前已有缓解:每个副本都独立通过完整清理配方的钉住断言,且所有副本必须共用同一个 awk 过滤器,因此任何改变行为的偏差都会失败。更严格的 Set(runs).size === 1 断言属于纯测试打磨;已记录至后续 PR。

发现 4 — always() 步骤的 timeout-minutes: 5 → 1–2(低)→ 推迟至同一后续 PR

无正确性影响——该步骤耗时不足一秒,且每条命令都有 || true 保护;此建议的要义是更诚实的超时上限。一行改动,已记录至后续 PR。

发现 5 — 将 awk 过滤器锚定到 $GITHUB_WORKSPACE(nit)→ 拒绝,附证据

该过滤器只喂给 git worktree remove --force,而 Git 本身会拒绝移除主工作树——循环会把该拒绝转为一条 ::warning:: 并继续执行,评审自己的 fixture 实测也证实了这一点("主工作树幸存"、"实践中无害")。锚定将需要在全部四处副本中通过 awk -v 传入工作区路径,且 awk -v 会对取值中的转义序列做二次解释——为 Git 已经防护的场景在四处引入新的复杂性。行为钉住测试已断言真实 runner 的主检出路径不会被该过滤器选中。

发现 6 — 执行清理配方的行为级 fixture 测试(低)→ 推迟至同一后续 PR

该建议有价值,且与 qwen-pr-review-workflow.test.js 中"执行提取出的 run: 块"的先例一致。它应与 #2 的升级放在一起,使被执行的配方同时覆盖 agent-state 步骤;两个较小的备注(断言恰好一处 worktree remove --force 而非用 indexOf 取首个匹配;skipIf(!awkAvailable) 在 Windows 上的退化问题)随之一并处理。已记录至后续 PR。

@yiliang114@qwen-code-review-bot approve if no blockers

这是发给评审机器人的批准触发指令,不是对本循环的变更请求;由于发现 #1 已在 HEAD 解决,当前无阻塞项。

Base-conflict check · 基分支冲突检查: no conflict with main. · 与 main 无冲突。


🧠 Handled by Qwen Code · model/模型 qwen3.8-max

@yiliang114

Copy link
Copy Markdown
Collaborator Author

Addressed the high-security cleanup finding in commit 1c87324c000: all review-worktree cleanup git calls now run through git -c core.hooksPath=/dev/null -c core.fsmonitor= so leftover repository hooks/config cannot run before checkout. Verified locally with the workflow cleanup test, Prettier, actionlint, and yamllint.

I did not expand this PR to other workflows or runner-hook consolidation; those are follow-up scope.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

🤖 Addressed the latest review feedback (round 6/100). What changed, and what I pushed back on: · 已处理最新评审反馈(第 6/100 轮)。改动内容与我反驳保留之处如下:

Address review summary — PR #8474 (round on top of 1c87324c0)

Commit: 707aafb2ffix(ci): tighten review cleanup comments and test guards (#8474)

Feedback dispositions (review by @wenshao)

  1. Security — pre-checkout git calls executing leftover repo hooks (high, required) — already fixed by the previous commit 1c87324c0: every git call in all four cleanup steps (ci.yml test / web_shell_e2e_smoke / integration_cli pre-checkout sweeps, qwen-code-pr-review.yml Clean stale agent state and Clean review worktrees) runs through git -c core.hooksPath=/dev/null -c core.fsmonitor= -C "$GITHUB_WORKSPACE", which overrides an attacker-set core.hooksPath/core.fsmonitor in leftover .git/config. Re-verified this round: the workflow test's expectHardenedGit assertions pin the hardening (and reject any bare git worktree|for-each-ref|branch call) and pass 5/5 against the current tree. No further change needed.
  2. Comment overstates what worktree remove --force recovers (low) — fixed. Rewrote the comment above the three ci.yml sweep blocks: it no longer claims recovery of root-owned or read-only leftovers (chmod -R u+w handles read-only, only the sudo -n rm -rf fallback handles root-owned, and git worktree remove runs as the same unprivileged user). It now states what the command actually does (clears a still-registered leftover directory, --force tolerates dirty contents), and that on failure the registration survives and the branch delete below emits the warning. Did not add --force --force for locked worktrees: nothing in the review code locks worktrees today, so that would be defense for a case that cannot currently occur.
  3. Scope gap — npm-cache.yml / qwen-triage.yml on the same pool (medium) — addressed via the reviewer's offered minimal alternative: the test header now states that these two workflows are deliberately not covered and extending the sweep to them is follow-up work. Fact-checked first: npm-cache.yml does run ['self-hosted', 'linux', 'x64', 'ecs-qwen'] with a plain checkout and no sweep, and qwen-triage.yml's sweep lacks chmod -R u+w / worktree remove --force / branch deletion. Extending those workflows is not done in this PR, matching the author's earlier comment that it is follow-up scope.
  4. Runner-hook consolidation via ACTIONS_RUNNER_HOOK_JOB_STARTED (low) — declined for this PR. It requires changing the managed runner image rather than workflow files, would supersede (not complement) the inline sweeps, and the reviewer explicitly framed it as a follow-up. Recorded here so it is not silently dropped; it belongs with the finding 如何自定义密钥文件 .env可能与其他文件冲突 #3 follow-up since it would also close that gap.
  5. Test robustness — TypeError on reusable-workflow-call jobs (low) — fixed. Job enumeration now uses JSON.stringify(job['runs-on'] ?? '') and (job.steps ?? []), so a future job-level uses: job filters out cleanly instead of crashing the suite with a confusing error. The .map after the filter needs no guard: only jobs proven to have steps survive the filter.
  6. Unscoped deletion rationale (nit) — fixed. Added one line at each sweep site (three identical ci.yml copies + the review-workflow Clean review worktrees step): the sweep deletes all review artifacts, not just the current PR's, which is safe because a self-hosted runner executes one job at a time.

No conflict resolution was needed (--conflict false); origin/main was not merged.

Verification

Commands actually run this round, from the repository root:

  • npx vitest run --config ./scripts/tests/vitest.config.ts scripts/tests/review-worktree-cleanup-workflow.test.js — passed, 5/5 tests (includes the expectHardenedGit assertions re-verifying finding pre-release: fix ci #1).
  • npm run test:scripts — 896 passed, 9 skipped, 5 failed; all 5 failures are in install-script.test.js (a file untouched by this PR) with Error: spawnSync zip ENOENT — the runner has no zip binary (which zip returns nothing), an environment limitation, not a code defect.
  • npm run typecheck — passed.
  • npm run lint — passed.
  • npm run build — passed.
  • npx prettier --experimental-cli --check .github/workflows/ci.yml .github/workflows/qwen-code-pr-review.yml scripts/tests/review-worktree-cleanup-workflow.test.js — passed.
  • actionlint / yamllint are not installed on this runner (which returns nothing); YAML validity of both edited workflows is instead proven by the passing test, which parses them with the yaml package.
中文说明

处理评审意见总结 — PR #8474(基于 1c87324c0 之上的本轮)

提交:707aafb2ffix(ci): tighten review cleanup comments and test guards (#8474)

反馈处理结论(@wenshao 的评审)

  1. 安全问题 — checkout 前的 git 调用会执行残留仓库钩子(高,必须修复) — 已由上一个提交 1c87324c0 修复:四个清理步骤(ci.yml 的 test / web_shell_e2e_smoke / integration_cli 的 checkout 前清理,以及 qwen-code-pr-review.ymlClean stale agent stateClean review worktrees)中的所有 git 调用都通过 git -c core.hooksPath=/dev/null -c core.fsmonitor= -C "$GITHUB_WORKSPACE" 执行,该写法会覆盖残留在 .git/config 中被攻击者设置的 core.hooksPath/core.fsmonitor。本轮已重新验证:工作流测试中的 expectHardenedGit 断言固化了该加固(并拒绝任何裸的 git worktree|for-each-ref|branch 调用),在当前代码树上 5/5 通过。无需进一步修改。
  2. 注释夸大了 worktree remove --force 的恢复能力(低) — 已修复。重写了 ci.yml 三处清理代码块上方的注释:不再声称能恢复 root 属主或只读残留(只读由 chmod -R u+w 处理,root 属主只有 sudo -n rm -rf 回退能处理,而 git worktree remove 以同一个非特权用户运行)。现在注释准确描述该命令的实际作用(清除仍有注册信息的残留目录,--force 允许目录含脏内容),并说明若删除仍失败,注册信息会保留、下方的分支删除会输出 warning。未添加 --force --force 来处理被锁定的 worktree:当前评审代码没有任何地方会锁定 worktree,为不可能发生的情况加防御属于过度设计。
  3. 范围缺口 — 同一 runner 池上的 npm-cache.yml / qwen-triage.yml(中) — 采用评审者给出的最小替代方案处理:测试文件头部现在注明这两个工作流有意不在覆盖范围内,将清理扩展到它们属于后续工作。已先核实事实:npm-cache.yml 确实运行在 ['self-hosted', 'linux', 'x64', 'ecs-qwen'] 上、使用裸 checkout 且无任何清理;qwen-triage.yml 的清理缺少 chmod -R u+w / worktree remove --force / 分支删除。本 PR 不扩展这些工作流,与作者此前"属于后续范围"的评论一致。
  4. 通过 ACTIONS_RUNNER_HOOK_JOB_STARTED 合并到 runner 钩子(低) — 本 PR 不采纳。这需要修改托管 runner 镜像而非工作流文件,会取代(而非补充)内联清理,且评审者明确将其定位为后续工作。在此记录以免被遗漏;它应与第 3 条的后续工作放在一起,因为它同时能解决那个缺口。
  5. 测试健壮性 — 可复用工作流调用型 job 导致 TypeError(低) — 已修复。job 枚举现在使用 JSON.stringify(job['runs-on'] ?? '')(job.steps ?? []),未来出现 job 级 uses: 的 job 时会被干净地过滤掉,而不是让整个测试套件以令人困惑的错误崩溃。filter 之后的 .map 无需防护:只有已证明含 steps 的 job 才能通过 filter。
  6. 无范围限定删除的理由说明(nit) — 已修复。在每处清理位置加了一行(ci.yml 三份相同副本 + 评审工作流的 Clean review worktrees 步骤):清理会删除所有评审产物,而不只是当前 PR 的,这是安全的,因为自托管 runner 一次只执行一个 job。

无需解决冲突(--conflict false);未合并 origin/main

验证

本轮在仓库根目录实际执行的命令:

  • npx vitest run --config ./scripts/tests/vitest.config.ts scripts/tests/review-worktree-cleanup-workflow.test.js — 通过,5/5 个测试(包括重新验证第 1 条的 expectHardenedGit 断言)。
  • npm run test:scripts — 896 通过、9 跳过、5 失败;5 个失败全部位于 install-script.test.js(本 PR 未改动的文件),报错为 Error: spawnSync zip ENOENT — 该 runner 没有 zip 二进制(which zip 无输出),属于环境限制,不是代码缺陷。
  • npm run typecheck — 通过。
  • npm run lint — 通过。
  • npm run build — 通过。
  • npx prettier --experimental-cli --check .github/workflows/ci.yml .github/workflows/qwen-code-pr-review.yml scripts/tests/review-worktree-cleanup-workflow.test.js — 通过。
  • 本 runner 未安装 actionlint / yamllintwhich 无输出);两个被修改工作流的 YAML 有效性改由通过的测试证明——该测试使用 yaml 包解析了它们。

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/模型 qwen3.8-max

@doudouOUC doudouOUC left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Downgraded from Approve to Comment: CI still running. Reviewed. Not linted (tool limitation, not a blocker): the executable-script lint — .github/workflows/ci.yml: actionlint embedded-shell source mapping is not yet supported — not linted; the executable-script lint — .github/workflows/qwen-code-pr-review.yml: actionlint embedded-shell source mapping is not yet supported — not linted.

中文说明

⚠️ 已从批准降级为评论:CI still running。 已审查。 未检查(工具限制,非阻断):the executable-script lint — .github/workflows/ci.yml: actionlint embedded-shell source mapping is not yet supported — not linted; the executable-script lint — .github/workflows/qwen-code-pr-review.yml: actionlint embedded-shell source mapping is not yet supported — not linted。

— claude-opus-4-6 via Qwen Code /review (v0.21.5)

@doudouOUC

Copy link
Copy Markdown
Collaborator

Qwen Code Review — PR #8474

Title: fix(ci): clean review worktrees after cancellation
Head SHA: 707aafb2fdae4c6584199ccd92d3dffed763f969
Diff: 5 files, +328/-7 (243 source, 168 test)

Build & test: Build green (15 workspaces). 0 net-new test failures. New cleanup workflow test 5/5 pass.

Findings:

  • 1 low-confidence Suggestion: the cleanup recipe is duplicated 3× in ci.yml; the test mitigates this with an awk-filter identity check and substring/ordering assertions, but does not assert full byte-identical equality across the three copies.
  • 0 Critical / 0 Blocker inline findings.

Previously reported blockers re-checked:

  • Security finding on pre-checkout git hooks: fixed — all git calls use git -c core.hooksPath=/dev/null -c core.fsmonitor= ....
  • Scope gap (integration_cli missing sweep): fixed — sweep added to all 3 shared-pool jobs.

Verdict: Comment (base verdict was Approve, downgraded to Comment because target CI is still running).

Review run completed at 2026-08-05. Note: the qwen review process logged internal tooling noise (qwen review findings validation hiccup and a 30 s cleanup timeout) but produced this summary successfully.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

🤖 Addressed the latest review feedback (round 7/100). What changed, and what I pushed back on: · 已处理最新评审反馈(第 7/100 轮)。改动内容与我反驳保留之处如下:

Autofix review round — PR #8474

One commit this round: test(ci): pin review cleanup recipe copies byte-identical (#8474) (test-only, 9 added lines).

Feedback triage

1. Suggestion from the automated review summary — IMPLEMENTED.

The cleanup recipe is duplicated 3× in ci.yml; the test mitigates this with an awk-filter identity check and substring/ordering assertions, but does not assert full byte-identical equality across the three copies.

Verified first: the three Clean stale .qwen before checkout run bodies in ci.yml (test, web_shell_e2e_smoke, integration_cli) are currently byte-identical (1940 chars each). The duplication is deliberate and documented — pre-checkout steps on shared runners cannot source a shared script from a possibly hostile leftover workspace — so de-duplication is not an option and the right fix is a stronger test pin. Added one assertion to the existing keeps every shared-pool ci.yml checkout sweep pinned to paths.ts test: every detected copy must be strictly equal (toBe, i.e. identical run text) to the first copy, with a job-tagged failure message. Placed after the existing existence checks so a missing step still fails with its precise message.

Proved the assertion works both ways:

  • green tree: 5/5 tests pass;
  • negative check: temporarily drifted the integration_cli copy → the test failed with job "integration_cli" sweep drifted from the first copy → restored ci.yml and confirmed via git diff --quiet that it is byte-identical to the committed state.

2. Review downgraded Approve → Comment because CI was still running — no code action. Informational; CI status is resolved by the workflow's own checks, not by a code change.

3. "Not linted: actionlint embedded-shell source mapping is not yet supported" — no code action. The reviewer explicitly marks this as a tool limitation, not a blocker; there is no repository defect to fix. The embedded shell is exercised by the Vitest workflow test instead (recipe content, ordering, hardened git calls, awk filter semantics).

4. Re-verified previously reported blockers (hooks-path security, integration_cli sweep coverage) — already fixed in earlier commits; no action needed.

No inline comments existed this round, so there are no resolved threads and no reply comments.

Verification

  • npx vitest run --config ./scripts/tests/vitest.config.ts scripts/tests/review-worktree-cleanup-workflow.test.js — passed (5/5 tests; includes the new byte-identity assertion)
  • Negative drift check (temporarily mutated one ci.yml copy, re-ran the focused test) — failed as expected, then ci.yml restored and verified clean with git diff --quiet
  • npm run build — passed
  • npm run typecheck — passed
  • npm run lint — passed
  • npx prettier --check scripts/tests/review-worktree-cleanup-workflow.test.js — passed
  • Integration tests after npm run bundle — not required: the change is a test over workflow YAML, exercised by the scripts Vitest suite, not by the bundled CLI or integration harness
  • npm run generate:settings-schema — not required: no settings source changed
中文说明

Autofix 审查轮次 — PR #8474

本轮一个提交:test(ci): pin review cleanup recipe copies byte-identical (#8474)(仅测试改动,新增 9 行)。

反馈分类处理

1. 自动审查摘要中的 Suggestion — 已实现。

清理配方在 ci.yml 中重复了 3 次;测试通过 awk 过滤器一致性检查和子串/顺序断言来缓解,但没有断言三份副本完全逐字节一致。

先做了核实:ci.yml 中三个 Clean stale .qwen before checkout 步骤的 run 内容(testweb_shell_e2e_smokeintegration_cli)当前完全逐字节一致(各 1940 字符)。这种重复是有意为之且已有文档说明的——共享 runner 上的 checkout 前置步骤不能引用残留在工作区中、可能不可信的共享脚本——因此无法去重,正确的修复是加强测试约束。在现有的 keeps every shared-pool ci.yml checkout sweep pinned to paths.ts 测试中新增一个断言:每个被检测到的副本必须与第一个副本严格相等(toBe,即 run 文本完全一致),失败信息带有 job 名称。放在现有的存在性检查之后,这样缺少步骤时仍会以精确的信息报错。

双向验证了该断言的有效性:

  • 当前代码:5/5 测试通过;
  • 反向验证:临时篡改 integration_cli 副本 → 测试按预期失败,报错为 job "integration_cli" sweep drifted from the first copy → 随后恢复 ci.yml,并用 git diff --quiet 确认其与已提交状态逐字节一致。

2. 审查从 Approve 降级为 Comment,原因是 CI 仍在运行 — 无需代码改动。 仅为状态说明;CI 状态由工作流自身的检查决定,不需要代码变更。

3. “未做 lint:actionlint embedded-shell source mapping 尚不支持” — 无需代码改动。 审查者明确标注这是工具限制、非阻断项;仓库中不存在需要修复的缺陷。嵌入式 shell 改由 Vitest 工作流测试覆盖(配方内容、顺序、加固后的 git 调用、awk 过滤器语义)。

4. 复核此前提出的阻断项(hooks-path 安全问题、integration_cli 缺少清扫)— 已在之前的提交中修复,无需处理。

本轮没有任何行内评论,因此没有可解决的讨论串,也没有需要回复的评论。

验证

  • npx vitest run --config ./scripts/tests/vitest.config.ts scripts/tests/review-worktree-cleanup-workflow.test.js — 通过(5/5 个测试;包含新增的逐字节一致性断言)
  • 反向漂移验证(临时篡改 ci.yml 的一个副本后重跑聚焦测试)— 按预期失败,随后恢复 ci.yml 并用 git diff --quiet 确认已还原
  • npm run build — 通过
  • npm run typecheck — 通过
  • npm run lint — 通过
  • npx prettier --check scripts/tests/review-worktree-cleanup-workflow.test.js — 通过
  • npm run bundle 后的集成测试 — 无需执行:本次改动是针对工作流 YAML 的测试,由 scripts Vitest 套件覆盖,不经过打包后的 CLI 或集成测试框架
  • npm run generate:settings-schema — 无需执行:未改动任何 settings 源文件

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/模型 qwen3.8-max

@qwen-code-ci-bot qwen-code-ci-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed — no blockers. Suggestions are inline. Not linted (tool limitation, not a blocker): the executable-script lint — .github/workflows/ci.yml: actionlint embedded-shell source mapping is not yet supported — not linted; the executable-script lint — .github/workflows/qwen-code-pr-review.yml: actionlint embedded-shell source mapping is not yet supported — not linted.

中文说明

已审查——无阻断问题。 建议见行内评论。 未检查(工具限制,非阻断):the executable-script lint — .github/workflows/ci.yml: actionlint embedded-shell source mapping is not yet supported — not linted; the executable-script lint — .github/workflows/qwen-code-pr-review.yml: actionlint embedded-shell source mapping is not yet supported — not linted。

— qwen3.8-max via Qwen Code /review (v0.21.5)

Comment on lines +90 to +92
expect(run).not.toMatch(
/^\s+git(?:\s+-C\s+"\$GITHUB_WORKSPACE")?\s+(?:worktree|for-each-ref|branch)\b/m,
);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Suggestion] R2-1: The hardened-git regression check requires leading whitespace (^\s+), so it covers only the indented ci.yml sweep copies — the two review-workflow sweep steps, whose git calls land at column 0 after YAML block-scalar stripping, are not covered. The verb whitelist (worktree|for-each-ref|branch) additionally lets a future column-0 bare git status escape. — Failure scenario: mutation-proven → reverting "${GIT_SAFE[@]}" worktree prune -v || true (qwen-code-pr-review.yml:1009) to bare git worktree prune leaves the suite 5/5 green; an un-hardened call would then run git against leftover untrusted .git config on the shared self-hosted runner, where core.hooksPath/core.fsmonitor are code-execution vectors (a bare branch -D was proven to fire a leftover reference-transaction hook).

Suggested change
expect(run).not.toMatch(
/^\s+git(?:\s+-C\s+"\$GITHUB_WORKSPACE")?\s+(?:worktree|for-each-ref|branch)\b/m,
);
expect(run).not.toMatch(/^\s*git\s/m);

The GIT_SAFE=(git … definition line starts with GIT_SAFE=(, so the relaxed anchor cannot false-positive; verified to flag the mutation with zero false positives on the current scripts.

中文说明

加固 git 的回归检查要求行首有空白(^\s+),因此只能覆盖有缩进的 ci.yml 清扫副本;两个 review-workflow 清扫步骤的 git 调用在 YAML 块标量剥离后位于第 0 列,不会被匹配到。动词白名单(worktree|for-each-ref|branch)还会让未来第 0 列的裸 git status 漏网。失败场景:已通过变异证实——把 qwen-code-pr-review.yml:1009 的 "${GIT_SAFE[@]}" worktree prune -v || true 还原为裸 git worktree prune,测试套件仍为 5/5 全绿;未加固的调用会在共享 self-hosted runner 上对不受信任的残留 .git 配置执行 git,而 core.hooksPath/core.fsmonitor 是代码执行入口(裸 branch -D 已证实会触发残留的 reference-transaction 钩子)。建议的 /^\s*git\s/m 不会误报(GIT_SAFE=(git … 定义行以 GIT_SAFE=( 开头),并已验证能捕获该变异。

— qwen3.8-max via Qwen Code /review (v0.21.5)

| while read -r stale_ref; do
if [ -n "$stale_ref" ]; then
git branch -D "$stale_ref" || true
"${GIT_SAFE[@]}" branch -D "$stale_ref" || true

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Suggestion] R2-2: A branch-delete failure is silently swallowed here (|| true), while the three ci.yml copies and the new Clean review worktrees step added by this PR emit ::warning::could not remove review branch: … for the identical failure. — Failure scenario: if branch -D fails in this pre-review sweep (git lock contention, permissions, or a worktree the preceding rm -rf could not delete keeping the branch checked out) → the leftover qwen-review/pr-N branch survives with zero log evidence, and the next review of that PR wedges with no warning pointing at the run that left the branch behind.

Suggested change
"${GIT_SAFE[@]}" branch -D "$stale_ref" || true
"${GIT_SAFE[@]}" branch -D "$stale_ref" || echo "::warning::could not remove review branch: $stale_ref"
中文说明

此处删除分支失败被静默吞掉(|| true),而三份 ci.yml 副本和本 PR 新增的 Clean review worktrees 步骤对同样的失败都会输出 ::warning::could not remove review branch: …。失败场景:如果这次 review 前清扫中 branch -D 失败(git 锁竞争、权限、或前面的 rm -rf 未能删除、仍检出该分支的 worktree)→ 残留的 qwen-review/pr-N 分支会存活且日志中毫无痕迹,该 PR 的下一次 review 会因此卡住,且没有任何警告指向留下分支的那次运行。

— qwen3.8-max via Qwen Code /review (v0.21.5)

Comment on lines +58 to +60
const reviewCleanStep = reviewYaml.jobs['review-pr'].steps.find(
(s) => s.name === 'Clean review worktrees',
).run;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Suggestion] R2-3: This extracts only .run from the Clean review worktrees step and never pins the if: 'always()' condition or the end-of-job position — the very properties that make the step fire on the failure/cancellation paths it exists for. — Failure scenario: mutation-verified → deleting if: 'always()' from the workflow leaves all 5 tests green, yet without it Actions' default success() condition skips the step whenever any earlier step of review-pr fails or the job is cancelled/timed out — exactly the interrupted-review scenario this PR exists to sweep — and that regression ships with a green test:ci.

const reviewCleanSteps = reviewYaml.jobs['review-pr'].steps;
const reviewCleanIndex = reviewCleanSteps.findIndex(
  (s) => s.name === 'Clean review worktrees',
);
const reviewCleanStep = reviewCleanSteps[reviewCleanIndex].run;
// then, inside the test:
expect(reviewCleanSteps[reviewCleanIndex].if).toBe('always()');
expect(reviewCleanIndex).toBe(reviewCleanSteps.length - 1);
中文说明

这里只取出 Clean review worktrees 步骤的 .run,从未钉住 if: 'always()' 条件和“位于 job 末尾”这两个属性——而正是这两个属性让该步骤在其为之存在的失败/取消路径上执行。失败场景:已变异验证——删除 workflow 中的 if: 'always()' 后 5 个测试仍全绿;而缺少它时,Actions 默认的 success() 条件会在 review-pr 任何先前步骤失败或 job 被取消/超时时跳过该步骤——正是本 PR 要清扫的中断场景——该回归会在 test:ci 全绿的情况下上线。

— qwen3.8-max via Qwen Code /review (v0.21.5)

Comment on lines +1010 to +1012
"${GIT_SAFE[@]}" worktree list --porcelain \
| awk '$1 == "worktree" && index($0, "/.qwen/tmp/review-pr-") > 0 { sub(/^worktree /, ""); print }' \
| while read -r worktree; do

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Suggestion] R2-4: The sweep feeds attacker-influenceable leftover git metadata (.git/worktrees/*/gitdir contents) unnormalized into destructive git worktree remove --force; git resolves .. traversal in the registered path, so the “delete only review artifacts” guarantee rests on a substring check over an untrusted string. The three ci.yml sweep copies share the identical recipe. — Failure scenario: reproduced end-to-end → a prior job with runner-user code execution rewrites .git/worktrees/<id>/gitdir to <ws>/.qwen/tmp/review-pr-42/../../../../target/.git and plants the backlink; the awk filter matches the raw string, git backlink validation passes, and worktree remove --force deletes the attacker-chosen target directory outside the review tree. Impact is bounded (the attacker already has runner-user code execution — no privilege escalation), but the cleanup becomes a delayed, plausibly-denied arbitrary-directory-deletion primitive.

# in each loop iteration, before `worktree remove` (all four recipe copies):
case "$worktree" in
  */../*|../*|*/..)
    echo "::warning::skipping suspicious review worktree path: $worktree"
    continue
    ;;
  "$GITHUB_WORKSPACE/.qwen/tmp/review-pr-"*) : ;;
  *)
    echo "::warning::skipping unexpected review worktree path: $worktree"
    continue
    ;;
esac

Verified on a fixture: the guard skips the traversal path with a warning, the target survives, and legitimate leftover review worktrees are still removed.

中文说明

清扫把可被攻击者影响的残留 git 元数据(.git/worktrees/*/gitdir 内容)未经规范化就喂给破坏性的 git worktree remove --force;git 会解析注册路径中的 .. 穿越,因此“只删除 review 产物”的保证仅依赖对不受信任字符串的子串检查。三份 ci.yml 清扫副本的配方完全相同。失败场景:已端到端复现——先前拥有 runner 用户代码执行权限的任务把 .git/worktrees/<id>/gitdir 改写为 <ws>/.qwen/tmp/review-pr-42/../../../../target/.git 并植入回链;awk 过滤器匹配原始字符串,git 回链校验通过,worktree remove --force 删除了 review 目录之外、由攻击者选定的 target 目录。影响有界(攻击者已拥有 runner 用户代码执行权限——无提权),但清理变成了一个延迟的、可抵赖的任意目录删除原语。修复已用 fixture 验证:守卫跳过穿越路径并输出警告,目标目录幸存,合法的残留 review worktree 仍会被移除。

— qwen3.8-max via Qwen Code /review (v0.21.5)

const ciCleanSteps = Object.entries(ciYaml.jobs)
.filter(
([, job]) =>
JSON.stringify(job['runs-on'] ?? '').includes('ubuntu_runner') &&

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Suggestion] R2-5: This matches the literal output-reference name ubuntu_runner, not the pool itself, so a future ci.yml checkout job that hard-codes the shared-pool label array (fromJSON('["self-hosted", "linux", "x64", "ecs-qwen"]') — the repo's dominant routing pattern, 27 occurrences across 16 workflows) silently escapes the pinning. — Failure scenario: a future ci.yml job lands on the shared pool via the hard-coded form and checks out → this filter never requires the cleanup step for it, so that job hits exactly the interrupted-review leftover this PR exists to remove — the very checkout failure the test comment claims cannot happen. Coverage is complete today (the three ubuntu_runner-output jobs are all swept); the cost is false confidence in the enumeration.

Suggested change
JSON.stringify(job['runs-on'] ?? '').includes('ubuntu_runner') &&
/ubuntu_runner|ecs-qwen/.test(JSON.stringify(job['runs-on'] ?? '')) &&

Safe today: classify_pr also matches ecs-qwen but has no actions/checkout step, so the enumerated set stays the same three jobs.

中文说明

这里匹配的是字面输出引用名 ubuntu_runner 而非池本身;未来某个硬编码共享池标签数组(fromJSON('["self-hosted", "linux", "x64", "ecs-qwen"]')——仓库中最常见的路由模式,16 个 workflow 中有 27 处)的 ci.yml checkout 任务会静默逃脱该钉住。失败场景:未来某个 ci.yml 任务以硬编码形式落在共享池并执行 checkout → 此过滤器不会要求它带清理步骤,该任务就会撞上本 PR 要清除的中断-review 残留——正是测试注释声称不可能发生的 checkout 失败。当前覆盖是完整的(三个 ubuntu_runner 输出任务均已清扫);代价是枚举带来的虚假信心。建议的写法今天是安全的:classify_pr 也匹配 ecs-qwen,但它没有 actions/checkout 步骤,枚举出的集合仍是同样三个任务。

— qwen3.8-max via Qwen Code /review (v0.21.5)

Comment on lines +82 to +83
expect(code.indexOf('worktree prune', remove)).toBeGreaterThan(remove);
expect(code.indexOf(`refs/heads/${branchFamily}*`)).toBeGreaterThan(remove);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Suggestion] R2-6: The suite never pins the trailing || true on the piped sweep loops, so the steps' failure-isolation contract (a cleanup failure degrades to ::warning::, never fails the job) is mutation-invisible in every sweep step — including the done || true this diff newly adds to Clean stale agent state (qwen-code-pr-review.yml:408), which expectCleanupRecipe does not cover at all. — Failure scenario: mutation-proven both arms → dropping || true from the Clean review worktrees branch loop, and from all three ci.yml branch loops at once, both leave the suite 5/5 green (byte-identity only compares copies to each other). Under set -uo pipefail + bash -e, a failing for-each-ref/worktree list head — the corrupt-leftover state these steps exist to tolerate — then aborts the step: the pre-checkout gate goes red before checkout, or the always() step marks review-pr failed after the review comment was already posted.

// in expectCleanupRecipe (and applied to the agent-state step too):
const loops =
  code.match(/\|\s*while read -r \w+; do[\s\S]*?\n\s*done(?: \|\| true)?/g) ?? [];
expect(loops.length).toBeGreaterThanOrEqual(2);
for (const loop of loops) {
  expect(loop.endsWith('done || true')).toBe(true);
}

Verified: the assertion passes on the current YAML and fails both mutations.

中文说明

套件从未钉住管道清扫循环末尾的 || true,因此失败隔离契约(清理失败只降级为 ::warning::,绝不失败 job)在所有清扫步骤中都是变异不可见的——包括本 diff 新加给 Clean stale agent statedone || true(qwen-code-pr-review.yml:408),expectCleanupRecipe 完全没有覆盖该步骤。失败场景:双向变异均已证实——删掉 Clean review worktrees 分支循环的 || true,或同时删掉三份 ci.yml 分支循环的 || true,套件都保持 5/5 全绿(逐字节一致断言只在副本之间互相比较)。在 set -uo pipefail + bash -e 下,for-each-ref/worktree list 头部失败——正是这些步骤要容忍的损坏残留状态——会中止该步骤:checkout 前的门禁变红,或 always() 步骤在 review 评论已发出后把 review-pr 标记为失败。已验证:该断言在当前 YAML 上通过,并使两种变异都失败。

— qwen3.8-max via Qwen Code /review (v0.21.5)

Comment on lines +50 to +52
.map(([id, job]) => ({
id,
run: job.steps.find((s) => s.name === 'Clean stale .qwen before checkout')

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Suggestion] R2-7: This pins the ci.yml clean step's content but never its position — it must run before Checkout and after Restore workspace ownership, and the map here discards the index that would prove it. — Failure scenario: mutation-proven → moving the clean step after Checkout in web_shell_e2e_smoke leaves the suite 5/5 green; on a dirty reused runner, checkout then hits the leftover worktree/branch registrations first — the exact “cannot delete branch … used by worktree” failure this PR fixes — and the sweep no-ops on the freshly checked-out tree. Moving it before Restore workspace ownership also passes green, yet git refuses root-owned leftover repos (“detected dubious ownership”), and every sweep git call fails silently under || true.

// keep the steps array in the mapped entries, then per matched job:
const cleanIdx = steps.findIndex(
  (s) => s.name === 'Clean stale .qwen before checkout',
);
const checkoutIdx = steps.findIndex((s) =>
  String(s.uses ?? '').includes('actions/checkout'),
);
const restoreIdx = steps.findIndex(
  (s) => s.name === 'Restore workspace ownership',
);
expect(cleanIdx).toBeLessThan(checkoutIdx);
expect(cleanIdx).toBeGreaterThan(restoreIdx);
中文说明

这里钉住了 ci.yml 清理步骤的内容,却从未钉住其位置——它必须在 Checkout 之前、Restore workspace ownership 之后运行,而此处的 map 丢弃了能证明这一点的索引。失败场景:已变异证实——把 web_shell_e2e_smoke 中的清理步骤移到 Checkout 之后,套件仍 5/5 全绿;在复用的脏 runner 上,checkout 会先撞上残留的 worktree/分支注册——正是本 PR 修复的 “cannot delete branch … used by worktree” 失败——随后清扫对刚检出的目录变成空操作。移到 Restore workspace ownership 之前同样全绿,但 git 会拒绝 root 拥有的残留仓库(“detected dubious ownership”),清扫的每个 git 调用都会在 || true 下静默失败。

— qwen3.8-max via Qwen Code /review (v0.21.5)

Comment on lines +1019 to +1021
"${GIT_SAFE[@]}" for-each-ref --format='%(refname:short)' 'refs/heads/qwen-review/*' \
| while read -r review_ref; do
[ -n "$review_ref" ] || continue

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Suggestion] R2-8: The sweep only removes worktrees whose registered path contains /.qwen/tmp/review-pr-; a leftover registration elsewhere that holds a qwen-review/* branch checked out is never removed, making that branch permanently undeletable on the runner. The three ci.yml copies share the identical pinned filter. — Failure scenario: reproduced with real git → a holder worktree registered outside the filter prefix, checking out qwen-review/pr-99: the awk filter skips it, worktree prune keeps it (directory exists), and branch -D fails with this PR's verbatim motivating error on every run, emitting only ::warning::; nothing ever removes the holder, so every subsequent checkout on that runner degrades the same way. The repo's own tooling cannot produce this state (all three worktree add sites match the filter); the trigger is another actor with runner-user code execution — the same bounded prerequisite class as the traversal finding.

# on branch -D failure, find the holder by ref, remove it, retry:
holder=$("${GIT_SAFE[@]}" worktree list --porcelain \
  | awk -v ref="refs/heads/$review_ref" \
      '$1 == "worktree" { wt = $2 } $1 == "branch" && $2 == ref { print wt }')
if [ -n "$holder" ]; then
  "${GIT_SAFE[@]}" worktree remove --force "$holder" 2>/dev/null || rm -rf "$holder" 2>/dev/null || true
  "${GIT_SAFE[@]}" worktree prune -v || true
  "${GIT_SAFE[@]}" branch -D "$review_ref" ||
    echo "::warning::could not remove review branch: $review_ref"
fi

Verified on a scratch repo: the fixed sweep deletes the branch and leaves only the main worktree.

中文说明

清扫只移除注册路径包含 /.qwen/tmp/review-pr- 的 worktree;检出了 qwen-review/* 分支、却注册在别处的残留 worktree 永远不会被移除,该分支在 runner 上永久无法删除。三份 ci.yml 副本共用同一被钉住的过滤器,缺口相同。失败场景:已用真实 git 复现——过滤器前缀之外注册的 holder worktree 检出 qwen-review/pr-99:awk 过滤器跳过它,worktree prune 保留它(目录存在),branch -D 每次运行都以本 PR 要修复的原错误失败,只输出一条 ::warning::;没有任何东西移除 holder,该 runner 上后续每次 checkout 都以同样方式退化。仓库自身工具不会产生这种状态(三处 worktree add 均匹配过滤器);触发需要另一个拥有 runner 用户代码执行权限的参与者——与路径穿越发现同属有界前提类别。已在临时仓库验证:修复后的清扫能删除该分支,最终只剩主工作树。

— qwen3.8-max via Qwen Code /review (v0.21.5)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Declined for this round, with thanks for the thorough reproduction. The holder state this targets cannot be produced by this repo's own tooling — all three worktree add sites match the pinned filter, and the finding itself bounds the trigger to another actor with runner-user code execution (the same bounded prerequisite class as the traversal finding). Two concrete costs tipped the call: the retry ladder would add ~32 lines across the four test-pinned byte-identical recipe copies, and its rm -rf "$holder" operates on exactly the untrusted registered path the traversal finding warns about — it would itself need the path guard landed in this round before it could ship. Meanwhile the failure stays visible and recoverable: every affected run emits ::warning::could not remove review branch: … naming the branch, so a one-time manual git worktree remove clears it. The direction we did take narrows the sweep's destructive guarantees (prefix + traversal guard) rather than widening its reach for a state we cannot produce. Happy to revisit with the guard composed in if a maintainer wants the holder recovery regardless.

中文说明

本轮暂不采纳,感谢详尽的复现。该建议针对的 holder 状态无法由本仓库自身工具产生——三处 worktree add 调用点都匹配被钉住的过滤器,且该发现本身将触发条件限定为另一个拥有 runner 用户代码执行权限的参与者(与路径穿越发现同属有界前提类别)。有两个具体成本促成了这一决定:重试阶梯需要在四份被测试钉住逐字节一致的配方副本中各增加约 32 行;且其中的 rm -rf "$holder" 操作的正是路径穿越发现所警告的不受信任注册路径——它自己必须先套上本轮落地的路径守卫才能上线。与此同时,该失败始终可见且可恢复:每次受影响的运行都会输出点名分支的 ::warning::could not remove review branch: …,一次手动 git worktree remove 即可清除。我们选择的方向是收窄清扫的破坏性保证(前缀 + 穿越守卫),而不是为我们无法产生的状态扩大其触及范围。如果维护者仍希望加上 holder 恢复逻辑,把它与守卫组合起来后我们很乐意再议。

)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

🤖 Addressed the latest review feedback (round 8/100). What changed, and what I pushed back on: · 已处理最新评审反馈(第 8/100 轮)。改动内容与我反驳保留之处如下:

PR #8474 — review round summary

Round 2 feedback: 8 automated-reviewer suggestions (R2-1 … R2-8). 7 implemented, 1 declined with reason. One commit on the existing head branch: f19e3faae fix(ci): guard review worktree removal and pin cleanup invariants (#8474). No base merge was performed (--conflict false).

Feedback dispositions

R2-1 — implemented (rc:3716522357)

The hardened-git regression check required leading whitespace (^\s+), so the two review-workflow sweep copies — whose git calls land at column 0 after YAML block-scalar stripping — were not covered, and the verb whitelist let any other bare verb escape. Replaced with expect(run).not.toMatch(/^\s*git\s/m) (any column, any verb). Mutation-verified: reverting one "${GIT_SAFE[@]}" worktree prune in the review workflow to bare git worktree prune now fails the suite (previously 5/5 green). No false positives — the GIT_SAFE=(git … definition line starts with GIT_SAFE=(.

R2-2 — implemented (rc:3716522389)

The agent-state sweep's branch -D "$stale_ref" || true now emits ::warning::could not remove review branch: $stale_ref, matching the identical failure handling in the three ci.yml copies and the Clean review worktrees step. A failed branch delete no longer disappears without log evidence.

R2-3 — implemented (rc:3716522400)

The suite now pins if: always() and the end-of-job position of Clean review worktrees (expect(...if).toBe('always()'), index == last step). Mutation-verified: deleting if: 'always()' now fails the suite (previously 5/5 green), so the step's fire-on-failure/cancellation contract is regression-proof.

R2-4 — implemented (rc:3716522403)

Added a path guard in all four worktree-removal loops (three ci.yml copies — kept byte-identical, verified — plus the review-workflow copy), before the destructive worktree remove --force:

  • reject any registered path containing a .. component (*/../*|../*|*/..) with a ::warning::, and
  • require the path to start with "$GITHUB_WORKSPACE/.qwen/tmp/review-pr-", warning and skipping otherwise.

This closes the reproduced end-to-end traversal hole: the awk filter matches a substring of an untrusted registered path, and git resolves .., so the "delete only review artifacts" guarantee no longer rests on the substring check alone. Verified on fixtures: the guard's case logic skips traversal/non-prefix paths and accepts legitimate ones; the extracted sweep script run on a scratch repo still removes a real leftover review worktree, its branch, and its lease. The guard itself is mutation-pinned in expectCleanupRecipe (warning string + prefix arm derived from paths.ts).

R2-5 — implemented (rc:3716522405)

The shared-pool enumeration now matches the pool itself — /ubuntu_runner|ecs-qwen/ — instead of only the ubuntu_runner output reference, so a future ci.yml checkout job hard-coding the shared label array is pinned too. Safe today: classify_pr also matches ecs-qwen but has no actions/checkout step, so the enumerated set is unchanged (test/web_shell_e2e_smoke/integration_cli). Positive control verified: hard-coding the test job's pool labels keeps the suite green with the job still enumerated.

R2-6 — implemented (rc:3716522409)

New expectPipedLoopsIsolated assertion pins the trailing done || true on every piped sweep loop (≥2 in expectCleanupRecipe, ≥1 for the agent-state step). Mutation-verified both arms: dropping || true from the review-workflow branch loop or from the agent-state loop now fails the suite (previously 5/5 green), so the "cleanup failure degrades to a warning, never fails the job" contract is no longer mutation-invisible under bash -e + pipefail.

R2-7 — implemented (rc:3716522418)

The mapped ci.yml entries now keep the steps array, and each matched job asserts the clean step's position: after Restore workspace ownership and before actions/checkout. Mutation-verified: moving the clean step after Checkout in web_shell_e2e_smoke now fails the suite (previously 5/5 green).

R2-8 — declined (rc:3716522421)

The holder-recovery ladder targets a state this repository's own tooling cannot produce — every worktree add site matches the pinned filter (the finding itself confirms the trigger is another actor with runner-user code execution, the same bounded prerequisite class as R2-4). The proposed fix would add ~32 lines across the four test-pinned byte-identical copies, and its rm -rf "$holder" operates on the same untrusted registered path the traversal finding warns about — it would itself need the R2-4 guard first. Meanwhile the failure stays visible (a ::warning:: naming the branch on every run) and manually recoverable. This round deliberately keeps narrowing the sweep's guarantees (R2-4) rather than widening its destructive reach for a state we cannot produce. Reply with the full reason posted on the thread; happy to revisit if a maintainer wants the holder recovery anyway.

Verification

Commands actually run and their results:

  • npx vitest run --config ./scripts/tests/vitest.config.ts review-worktree-cleanup-workflow — passed, 5/5 tests (re-run after the commit: 5/5)
  • npm run test:scripts (full scripts suite) — 45/46 files passed; 896 passed, 9 skipped; 5 failed, all in scripts/tests/install-script.test.js with Error: spawnSync zip ENOENT — the zip binary is not installed on this runner (command -v zip → not found); that test file is untouched by this diff, so the failure is identical at HEAD and is environmental, not caused by this change
  • npm run build — passed
  • npm run typecheck — passed
  • npm run lint (ESLint) — passed
  • npx prettier --check scripts/tests/review-worktree-cleanup-workflow.test.js — passed after --write (formatting wrap only, no semantic change)
  • node scripts/lint.js --actionlint — passed, no findings on the edited workflows
  • node scripts/lint.js --yamllint / --shellcheck — not runnable on this runner (no Python pip module for yamllint; no xz binary to unpack shellcheck). YAML validity is still covered by actionlint plus the vitest suite, which parses both workflow files; the embedded-shell edits were additionally exercised end-to-end (see below)
  • Mutation checks (each applied, suite run red, then restored): bare column-0 git worktree prune in the review workflow (R2-1), deleted if: 'always()' (R2-3), dropped || true from the review branch loop and from the agent-state loop (R2-6 both arms), removed the guard from one ci.yml copy (R2-4 — caught by the guard pin and byte-identity), moved the clean step after Checkout in web_shell_e2e_smoke (R2-7). Positive control: hard-coded ecs-qwen pool labels on the test job stay enumerated and green (R2-5)
  • End-to-end fixture: extracted the real Clean review worktrees script from the YAML and ran it on a scratch repo seeded with a leftover .qwen/tmp/review-pr-42 worktree + qwen-review/pr-42 branch + lease, plus an out-of-prefix holder worktree checking out qwen-review/pr-99 — the leftover artifacts were removed, the holder was skipped with the expected ::warning:: and left intact; the guard's case statement was separately verified against .. traversal strings
  • Integration tests after npm run bundle — not applicable (no TS source changed this round)
  • npm run generate:settings-schema — not applicable (no settings source changed)
中文说明

PR #8474 — review 轮次总结

第 2 轮反馈:自动评审器 8 条建议(R2-1 … R2-8)。实现 7 条,附理由拒绝 1 条。在现有 head 分支上提交一次:f19e3faae fix(ci): guard review worktree removal and pin cleanup invariants (#8474)。未做 base 合并(--conflict false)。

反馈处置

R2-1 — 已实现(rc:3716522357)

加固 git 的回归检查原先要求行首有空白(^\s+),因此两个 review-workflow 清扫副本(其 git 调用在 YAML 块标量剥离后位于第 0 列)不被覆盖,且动词白名单会让其他裸动词漏网。已替换为 expect(run).not.toMatch(/^\s*git\s/m)(任意列、任意动词)。已变异验证:把 review workflow 中一处 "${GIT_SAFE[@]}" worktree prune 还原为裸 git worktree prune,现在会使套件失败(此前 5/5 全绿)。无误报——GIT_SAFE=(git … 定义行以 GIT_SAFE=( 开头。

R2-2 — 已实现(rc:3716522389)

agent-state 清扫中的 branch -D "$stale_ref" || true 现在输出 ::warning::could not remove review branch: $stale_ref,与三份 ci.yml 副本及 Clean review worktrees 步骤对同样失败的处理一致。分支删除失败不再毫无日志痕迹。

R2-3 — 已实现(rc:3716522400)

套件现在钉住 Clean review worktreesif: always() 与 job 末尾位置(expect(...if).toBe('always()')、索引 == 最后一步)。已变异验证:删除 if: 'always()' 现在会使套件失败(此前 5/5 全绿),该步骤"在失败/取消路径上执行"的契约从此可防回归。

R2-4 — 已实现(rc:3716522403)

在全部四处 worktree 移除循环(三份 ci.yml 副本——已验证保持逐字节一致——加 review-workflow 副本)中,在破坏性的 worktree remove --force 之前加入路径守卫:

  • 拒绝任何包含 .. 组件的注册路径(*/../*|../*|*/..)并输出 ::warning::
  • 要求路径以 "$GITHUB_WORKSPACE/.qwen/tmp/review-pr-" 开头,否则输出警告并跳过。

这堵上了已端到端复现的穿越漏洞:awk 过滤器匹配的是不受信任注册路径的子串,而 git 会解析 ..,因此"只删 review 产物"的保证不再仅依赖子串检查。已用 fixture 验证:守卫的 case 逻辑跳过穿越/前缀外路径、接受合法路径;在临时仓库上运行从 YAML 提取的真实清扫脚本,仍能移除真实残留的 review worktree、其分支与 lease。守卫本身也在 expectCleanupRecipe 中被变异钉住(警告字符串 + 从 paths.ts 派生的前缀臂)。

R2-5 — 已实现(rc:3716522405)

共享池枚举现在匹配池本身——/ubuntu_runner|ecs-qwen/——而非仅 ubuntu_runner 输出引用,未来硬编码共享标签数组的 ci.yml checkout 任务也会被钉住。今天安全:classify_pr 也匹配 ecs-qwen 但没有 actions/checkout 步骤,枚举集合不变(test/web_shell_e2e_smoke/integration_cli)。正向对照已验证:把 test 任务的池标签硬编码后,套件仍全绿且该任务仍被枚举。

R2-6 — 已实现(rc:3716522409)

新增 expectPipedLoopsIsolated 断言,钉住每个管道清扫循环末尾的 done || trueexpectCleanupRecipe 中 ≥2 个,agent-state 步骤 ≥1 个)。双向变异均已验证:删掉 review-workflow 分支循环或 agent-state 循环的 || true,现在都会使套件失败(此前 5/5 全绿)。在 bash -e + pipefail 下,"清理失败降级为警告、绝不失败 job"的契约不再是变异不可见的。

R2-7 — 已实现(rc:3716522418)

映射出的 ci.yml 条目现在保留 steps 数组,每个匹配任务都断言清理步骤的位置:在 Restore workspace ownership 之后、actions/checkout 之前。已变异验证:把 web_shell_e2e_smoke 的清理步骤移到 Checkout 之后,现在会使套件失败(此前 5/5 全绿)。

R2-8 — 已拒绝(rc:3716522421)

holder 恢复阶梯针对的状态无法由本仓库自身工具产生——所有 worktree add 调用点都匹配被钉住的过滤器(该发现本身确认触发条件是另一个拥有 runner 用户代码执行权限的参与者,与 R2-4 同属有界前提类别)。建议的修复需要在四份被测试钉住逐字节一致的副本中各增加约 32 行,且其 rm -rf "$holder" 操作的正是路径穿越发现所警告的不受信任注册路径——它自己得先套上 R2-4 的守卫。与此同时,该失败始终可见(每次运行都输出点名分支的 ::warning::),且可手动恢复。本轮刻意继续收窄清扫的保证(R2-4),而不是为我们无法产生的状态扩大其破坏性触及范围。完整理由已作为回复发到该线程;若维护者仍希望加上 holder 恢复逻辑,很乐意再议。

验证

实际运行的命令及结果:

  • npx vitest run --config ./scripts/tests/vitest.config.ts review-worktree-cleanup-workflow — 通过,5/5(提交后复跑仍 5/5)
  • npm run test:scripts(scripts 全套件)— 45/46 文件通过;896 通过、9 跳过;5 个失败全部位于 scripts/tests/install-script.test.js,报错 Error: spawnSync zip ENOENT——本 runner 未安装 zip 二进制(command -v zip → 未找到);该测试文件本 diff 未改动,因此在 HEAD 上失败完全相同,属环境问题,非本次变更引入
  • npm run build — 通过
  • npm run typecheck — 通过
  • npm run lint(ESLint)— 通过
  • npx prettier --check scripts/tests/review-worktree-cleanup-workflow.test.js--write 后通过(仅换行格式调整,无语义变化)
  • node scripts/lint.js --actionlint — 通过,编辑的 workflow 无发现
  • node scripts/lint.js --yamllint / --shellcheck — 本 runner 无法运行(无 Python pip 模块装 yamllint;无 xz 二进制解包 shellcheck)。YAML 合法性仍由 actionlint 及会解析两个 workflow 文件的 vitest 套件覆盖;嵌入式 shell 改动另有端到端 fixture 验证(见下)
  • 变异检查(逐一应用、跑红后还原):review workflow 中第 0 列裸 git worktree prune(R2-1);删除 if: 'always()'(R2-3);删掉 review 分支循环与 agent-state 循环的 || true(R2-6 双向);从一份 ci.yml 副本移除守卫(R2-4——被守卫钉住与逐字节一致断言捕获);把 web_shell_e2e_smoke 的清理步骤移到 Checkout 之后(R2-7)。正向对照:test 任务硬编码 ecs-qwen 池标签后仍被枚举且全绿(R2-5)
  • 端到端 fixture:从 YAML 提取真实 Clean review worktrees 脚本,在临时仓库运行——仓库中预置了残留的 .qwen/tmp/review-pr-42 worktree + qwen-review/pr-42 分支 + lease,以及一个注册在前缀之外、检出 qwen-review/pr-99 的 holder worktree——残留产物被移除,holder 被跳过并输出预期 ::warning::、目录保留;守卫的 case 语句另对 .. 穿越字符串单独验证
  • npm run bundle 后的集成测试 — 不适用(本轮未改 TS 源码)
  • npm run generate:settings-schema — 不适用(未改 settings 源)

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/模型 qwen3.8-max

@doudouOUC doudouOUC left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving, verified against the current HEAD f19e3fa rather than the SHA I started on — the branch moved mid-review and the earlier hardening notes are already addressed there.

What I checked at f19e3fa:

  • All git invocations in the sweep now go through GIT_SAFE=(git -c core.hooksPath=/dev/null -c core.fsmonitor= -C "$GITHUB_WORKSPACE"), in all three ci.yml copies and both qwen-code-pr-review.yml sweeps, so a core.hooksPath planted in a leftover untrusted .git no longer fires on branch -D / worktree remove.
  • The block comment no longer claims worktree remove --force clears root-owned leftovers; it now describes the real value (deregistering so branch -D can succeed even when the directory survives).
  • The workflow-parsing test guards the optional keys (job['runs-on'] ?? '', (job.steps ?? [])), so a future job-level uses: job can't turn the enumeration into a TypeError. I confirmed the broadened ubuntu_runner|ecs-qwen filter does not accidentally pull in classify_pr: it matches the label array but has no actions/checkout step, so it is correctly excluded rather than silently failing the recipe assertions.
  • Cancellation coverage is real: the cleanup step is if: always() and is the last step of review-pr, and the job-level if is evaluated at job start, so a mid-flight cancellation still reaches it.
  • Blast radius stays scoped to .qwen/tmp/review-pr-*, local refs/heads/qwen-review/*, and the qwen-review-lease-pr-*.json leases; the qwen-review-pr-* sibling prefix is deliberately not matched by review-pr-*.
  • Every added command is || true-guarded at the pipeline level, so the "never fail the job" property holds under the workflow's -e/pipefail defaults.
  • CI is green on this exact SHA: run 30959526003 has head_sha=f19e3fa, conclusion=success, and Test (ubuntu-latest, Node 22.x) passed, which is the leg that runs the new scripts/tests suite.

No blocking issues from me.

@yiliang114
yiliang114 added this pull request to the merge queue Aug 5, 2026
Merged via the queue into main with commit e34780e Aug 5, 2026
69 of 70 checks passed
@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Released in v0.21.6.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

autofix/takeover Summon the autofix loop to manage this PR (remove to release; needs triage+)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants