Skip to content

fix(cli): scrub inherited loader env vars from daemon session subprocesses - #8663

Merged
wenshao merged 18 commits into
mainfrom
fix/daemon-session-loader-env-leak
Aug 8, 2026
Merged

wenshao merged 18 commits into
mainfrom
fix/daemon-session-loader-env-leak

Conversation

@wenshao

@wenshao wenshao commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator

What this PR does

Daemon-mode sessions bound to one workspace inherited loader-affecting environment variables (NODE_OPTIONS with dev-harness --import register hooks, NODE_PATH, LD_*/DYLD_* preload vars, BASH_ENV/ENV) from whatever shell launched qwen serve, and passed them verbatim into every session subprocess. This PR scrubs that loader subset of the existing reload-exclusion list from the process environment at the two process boundaries that host sessions: the daemon, right after it freezes its boot environment, and each ACP child, after the relaunch/sandbox handoff. The frozen daemon boot env deliberately keeps the loader vars so dev-mode ACP children can still boot against the TypeScript source, and a respawned ACP child re-scrubs its own environment after boot, so protection composes across the relaunch chain. The reload-exclusion list now derives from the shared loader-key constant instead of duplicating its nine literals, and regression tests pin the scrub behavior, the exact key list, and the freeze-before-scrub ordering.

Why it's needed

In a multi-workspace daemon setup a session working in checkout B spawned subprocesses carrying checkout A's harness state — NODE_OPTIONS=--import .../qwen-code/node_modules/tsx/... --import /tmp/qwen-dev-*/register.mjs, NODE_PATH and PATH prefixes pointing at checkout A. The hijack was active, not cosmetic: import.meta.resolve('@qwen-code/qwen-code-core') from checkout B resolved into checkout A's tree, and running checkout B's built CLI failed with export errors answered by checkout A's stale source. Beyond confusing failures this is a correctness/safety gap: sessions can silently execute code built from another workspace. The existing .env reload exclusion already names exactly these keys, but the inherited launch environment bypassed it entirely.

Reviewer Test Plan

How to verify

  1. Build this branch (npm install && npm run build && npm run bundle).
  2. From workspace A, launch the daemon with poisoned loader env, e.g. env NODE_OPTIONS="--import file:///tmp/repro/ws-a/register.mjs --expose-gc" NODE_PATH=/tmp/repro/ws-a/node_modules node dist/cli.js serve --port 4171 --hostname 127.0.0.1 --enable-session-shell --token repro-token (a register.mjs that logs each execution with process.cwd() makes the hijack observable).
  3. Register workspace B, open a session there, and run POST /session/:id/shell with env | grep -E 'NODE_OPTIONS|NODE_PATH' plus node -e "console.log(typeof globalThis.gc)".
  4. Expected: NODE_OPTIONS/NODE_PATH are unset in the ws-B subprocess, globalThis.gc is undefined, and the ws-A loader never executes with cwd=ws-B. The loader still executes once per process at boot (daemon + each ACP child) — that is required for dev-mode boot and cannot be scrubbed before process start; everything each process subsequently spawns is clean.
  5. Dev-mode sanity: npm run dev interactive still runs from TypeScript source (the daemon's own children keep the harness loader via the frozen boot env).

Evidence (Before & After)

Before (reproduced against v0.21.6): ws-B session subprocess printed NODE_OPTIONS=--import file:///tmp/qwen-8653/ws-a/fake-harness/register.mjs --expose-gc, NODE_PATH=/tmp/qwen-8653/ws-a/node_modules, typeof gc === 'function', and the ws-A loader logged two executions with cwd=/private/tmp/qwen-8653/ws-b.

After (verified against this branch's built bundle, same scenario): ws-B subprocesses have no NODE_OPTIONS/NODE_PATH, typeof gc === 'undefined', and seven session subprocesses produced zero ws-A loader executions — only one loader execution per process at boot (daemon and each ACP child, both with their own cwd).

Tested on

OS Status
🍏 macOS ✅
🪟 Windows ⚠️
🐧 Linux ⚠️

Environment (optional)

E2E verified with node dist/cli.js serve --enable-session-shell against two temp workspaces plus a logging loader hook; unit tests: packages/cli env/serve suites (shared-env-keys, environment, process-env-guard, run-qwen-serve).

Risk & Scope

  • Main risk or tradeoff: operator-set NODE_OPTIONS tuning (e.g. --max-old-space-size, OTel --require) is also scrubbed from session subprocesses of daemon/ACP-hosted sessions. ACP children get explicit memory args; this matches the existing policy that these keys never flow through .env reloads.
  • Not validated / out of scope: PATH prefixes and informational vars (INIT_CWD, npm_package_json) are intentionally left intact — they cannot hijack module resolution once loader vars are gone, and sessions still need a working PATH. Channel workers on embedded (createServeApp) runtimes are unchanged.
  • Breaking changes / migration notes: none.

Linked Issues

Fixes #8653

中文说明

本 PR 做了什么

daemon 模式下绑定到某个 workspace 的会话,会从启动 qwen serve 的那个 shell 继承 loader 类环境变量(带 dev harness --import register 钩子的 NODE_OPTIONS、NODE_PATH、LD_*/DYLD_* preload 类变量、BASH_ENV/ENV),并原样传给每个会话子进程。本 PR 在宿主会话的两个进程边界上,从 process.env 中剥离既有 reload 排除列表的 loader 子集:daemon 在冻结启动环境之后立即剥离;每个 ACP 子进程在 relaunch/sandbox 交接之后剥离。daemon 冻结的启动环境刻意保留 loader 变量,以便 dev 模式下的 ACP 子进程仍能从 TypeScript 源码启动;被 respawn 的 ACP 子进程在启动后会再次自行剥离,因此保护在 relaunch 链上可组合。reload 排除列表改为派生自共享的 loader 键常量,不再重复维护那 9 个字面量;回归测试钉住了剥离行为、确切的键列表、以及“先冻结后剥离”的顺序。

为什么需要

在多 workspace 的 daemon 场景下,工作在 checkout B 的会话所派生的子进程带着 checkout A 的 harness 状态——NODE_OPTIONS=--import .../qwen-code/node_modules/tsx/... --import /tmp/qwen-dev-*/register.mjs、指向 checkout A 的 NODE_PATH 与 PATH 前缀。这个劫持是真实生效的,不只是看起来不对:从 checkout B 执行 import.meta.resolve('@qwen-code/qwen-code-core') 会解析进 checkout A 的目录树;运行 checkout B 构建好的 CLI 会因为 import 被 checkout A 的陈旧源码应答而报导出错误。除了令人困惑的失败之外,这也是正确性/安全隐患:会话可能静默执行另一个 workspace 构建出的代码。既有的 .env reload 排除列表本来就点名了这些键,但从启动 shell 继承来的环境完全绕过了这一排除。

评审者测试计划

如何验证

  1. 构建本分支(npm install && npm run build && npm run bundle)。
  2. 从 workspace A 用带毒的 loader 环境启动 daemon,例如 env NODE_OPTIONS="--import file:///tmp/repro/ws-a/register.mjs --expose-gc" NODE_PATH=/tmp/repro/ws-a/node_modules node dist/cli.js serve --port 4171 --hostname 127.0.0.1 --enable-session-shell --token repro-token(用一个会打印每次执行时 process.cwd() 的 register.mjs,可以让劫持可观测)。
  3. 注册 workspace B,在其中打开会话,通过 POST /session/:id/shell 执行 env | grep -E 'NODE_OPTIONS|NODE_PATH' 和 node -e "console.log(typeof globalThis.gc)"。
  4. 预期:ws-B 的子进程中 NODE_OPTIONS/NODE_PATH 未设置,globalThis.gc 为 undefined,且 ws-A 的 loader 从未以 cwd=ws-B 执行过。loader 仍会在每个进程启动时执行一次(daemon + 每个 ACP 子进程)——这是 dev 模式启动所必需的,无法在进程启动前剥离;每个进程此后派生的一切都是干净的。
  5. dev 模式完整性检查:npm run dev 交互模式仍从 TypeScript 源码运行(daemon 自己的子进程通过冻结的启动环境保留 harness loader)。

证据(修复前后)

修复前(在 v0.21.6 上复现):ws-B 会话子进程打印出 NODE_OPTIONS=--import file:///tmp/qwen-8653/ws-a/fake-harness/register.mjs --expose-gc、NODE_PATH=/tmp/qwen-8653/ws-a/node_modules、typeof gc === 'function',且 ws-A 的 loader 记录了两次 cwd=/private/tmp/qwen-8653/ws-b 的执行。

修复后(在本分支构建产物上用同一场景验证):ws-B 子进程没有 NODE_OPTIONS/NODE_PATH,typeof gc === 'undefined',7 个会话子进程产生零次 ws-A loader 执行——每个进程仅在启动时各执行一次 loader(daemon 与每个 ACP 子进程,cwd 均为各自所在目录)。

测试环境

OS 状态
🍏 macOS ✅
🪟 Windows ⚠️
🐧 Linux ⚠️

环境(可选)

E2E 用 node dist/cli.js serve --enable-session-shell 对两个临时 workspace 加一个会打日志的 loader 钩子进行了验证;单元测试:packages/cli 的 env/serve 相关套件(shared-env-keys、environment、process-env-guard、run-qwen-serve)。

风险与范围

  • 主要风险或权衡:操作者自行设置的 NODE_OPTIONS 调优参数(如 --max-old-space-size、OTel 的 --require)同样会从 daemon/ACP 宿主会话的会话子进程中被剥离。ACP 子进程有显式的内存参数;这也与既有策略一致——这些键本来就不允许经由 .env reload 注入。
  • 未验证 / 超出范围:PATH 前缀与信息性变量(INIT_CWD、npm_package_json)有意保留——一旦 loader 变量被剥离,它们就无法再劫持模块解析,而且会话仍然需要可用的 PATH。嵌入式(createServeApp)运行时下的 channel worker 行为不变。
  • 破坏性变更 / 迁移说明:无。

关联 Issue

Fixes #8653

…esses

Daemon-mode sessions bound to one workspace inherited loader-affecting
env vars (NODE_OPTIONS with dev-harness --import hooks, NODE_PATH,
preload-class vars) from whatever shell launched the daemon, so
subprocesses in another workspace resolved modules through the
launching checkout's tree (fixes #8653).

Scrub the loader subset of RELOAD_EXCLUDED_KEYS from process.env at the
two process boundaries that host sessions: the daemon after freezing its
boot env (the frozen copy keeps loader vars so dev-mode ACP children can
still boot), and the ACP child after the relaunch/sandbox handoff (the
respawned child re-scrubs itself).

Fixes #8653
@github-actions github-actions Bot added the review/self-reported The linked issue was opened by the PR author (self-reported) label Aug 7, 2026
@wenshao

wenshao commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator Author

E2E test report

Reproduction (pre-fix, v0.21.6 global install): daemon launched from workspace ws-a with poisoned NODE_OPTIONS=--import file:///tmp/qwen-8653/ws-a/fake-harness/register.mjs --expose-gc, NODE_PATH, PATH prefix and INIT_CWD; session opened on workspace ws-b; subprocesses executed via the session-shell route (the same ShellExecutionService the shell tool uses). The ws-b session was bound correctly (pwd = ws-b) but its subprocess env was inherited verbatim from ws-a's launch shell, typeof globalThis.gc was function (ws-a's --expose-gc active), and ws-a's loader hook executed inside processes with cwd=ws-b — cross-workspace code execution confirmed.

Verification (post-fix, built dist/cli.js, same scenario):

  • NODE_OPTIONS/NODE_PATH unset in ws-b session subprocesses; all other loader-class keys scrubbed
  • typeof globalThis.gc → undefined in ws-b subprocesses
  • Seven ws-b session subprocesses produced zero ws-a loader executions; the only loader executions were one per process at boot (daemon, ws-a ACP child, ws-b ACP child — each with its own cwd)
  • Session-shell subprocess host confirmed to be the daemon process itself ($PPID probe), i.e. the daemon-side scrub is what protects them
  • Happy path intact: workspace registration, session creation, shell execution all worked

By-design residual: the ws-a loader executes exactly once with cwd=ws-b — at ws-b's ACP child boot. A NODE_OPTIONS --import loader necessarily runs before any in-process scrub can execute, and the frozen daemon boot env intentionally keeps loader vars so dev-mode children can boot. It cannot propagate further: everything the child subsequently spawns is scrubbed.

Artifacts: /tmp/qwen-8653/ (daemon.log, daemon-verify2.log, loader-hit.log). Full reports: .qwen/issues/issue-8653.md (reproduction + verification sections).

中文

复现(修复前,全局安装 v0.21.6):从 workspace ws-a 用带毒环境启动 daemon(NODE_OPTIONS=--import .../ws-a/fake-harness/register.mjs --expose-gc、NODE_PATH、PATH 前缀、INIT_CWD),在 workspace ws-b 打开会话,通过 session-shell 路由(与 shell tool 相同的 ShellExecutionService)执行子进程。ws-b 会话绑定正确(pwd = ws-b),但子进程环境原样继承自 ws-a 的启动 shell;typeof globalThis.gc 为 function(ws-a 的 --expose-gc 生效),且 ws-a 的 loader 钩子在 cwd=ws-b 的进程中执行——确认了跨 workspace 代码执行。

验证(修复后,本分支构建产物,同一场景):ws-b 会话子进程中 NODE_OPTIONS/NODE_PATH 未设置,其余 loader 类键全部被剥离;typeof globalThis.gc 变为 undefined;7 个 ws-b 会话子进程产生零次 ws-a loader 执行,loader 仅在每个进程启动时各执行一次(daemon、ws-a ACP 子进程、ws-b ACP 子进程,cwd 均为各自目录);session-shell 子进程的宿主进程经 $PPID 探针确认就是 daemon 本身,即 daemon 侧剥离在起保护作用;正常功能完好(workspace 注册、会话创建、shell 执行均正常)。

设计内的残留:ws-a 的 loader 会在 ws-b 的 ACP 子进程启动时执行恰好一次。NODE_OPTIONS --import loader 必然先于任何进程内剥离执行,而 daemon 冻结的启动环境有意保留 loader 变量以便 dev 模式子进程启动。它无法继续传播:该子进程此后派生的一切都会被剥离。

@wenshao

wenshao commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator Author

@qwen-code /takeover

@qwen-code-dev-bot qwen-code-dev-bot added the autofix/takeover Summon the autofix loop to manage this PR (remove to release; needs triage+) label Aug 7, 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)即可释放。

@github-actions

github-actions Bot commented Aug 7, 2026 •

Copy link
Copy Markdown
Contributor

Code Coverage Summary

Package Lines Statements Functions Branches
CLI 83.7% 83.7% 89.73% 82.88%
Core 87.79% 87.79% 89.36% 86.32%
CLI Package - Full Text Report
-------------------|---------|----------|---------|---------|-------------------
File               | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-------------------|---------|----------|---------|---------|-------------------
All files          |    83.7 |    82.88 |   89.73 |    83.7 |                   
 src               |   84.96 |    81.27 |   88.49 |   84.96 |                   
  cli.ts           |   95.68 |    84.11 |     100 |   95.68 | ...60-561,565-566 
  gemini.tsx       |    72.8 |    77.39 |   80.76 |    72.8 | ...1299-1303,1424 
  ...ractiveCli.ts |   86.72 |    81.12 |   88.13 |   86.72 | ...2952,2958,3023 
  ...liCommands.ts |   89.33 |     85.6 |      90 |   89.33 | ...01,518,552,674 
  ...ActiveAuth.ts |     100 |     87.5 |     100 |     100 | 66-80             
 ...cp-integration |   70.64 |    73.08 |   90.25 |   70.64 |                   
  acpAgent.ts      |   70.11 |     72.9 |   90.07 |   70.11 | ...28,12033-12035 
  ...k-reporter.ts |     100 |    80.95 |     100 |     100 | 77,80,115,135     
  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,242-243 
 ...ration/session |   91.21 |    86.57 |   96.61 |   91.21 |                   
  Session.ts       |   90.34 |    84.99 |   95.89 |   90.34 | ...39,10466-10470 
  ...entTracker.ts |    96.8 |    89.36 |      90 |    96.8 | 137-143,221       
  ...projection.ts |   98.57 |    93.29 |     100 |   98.57 | ...76,333,344,356 
  ...stop-guard.ts |     100 |    98.07 |     100 |     100 | 37,127            
  ...eplay-page.ts |   93.44 |    91.74 |     100 |   93.44 | 74,85-88,115-125  
  ...y-replayer.ts |   98.54 |    95.65 |     100 |   98.54 | 241-243           
  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 |   96.01 |    94.15 |   96.66 |   96.01 |                   
  ...ageEmitter.ts |   95.95 |       96 |     100 |   95.95 | 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.65 |    72.18 |   64.51 |   89.65 |                   
  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.66 |      100 |      50 |   98.66 | 86                
  serve.ts         |   87.68 |    66.66 |     100 |   87.68 | ...31,743,759-763 
  sessions.ts      |     100 |      100 |      50 |     100 |                   
  update.ts        |   98.13 |    94.44 |   66.66 |   98.13 | 82-83             
 ...mmands/channel |   88.91 |     88.5 |   90.54 |   88.91 |                   
  channel-cwd.ts   |     100 |      100 |     100 |     100 |                   
  ...l-registry.ts |   95.21 |    96.73 |   88.88 |   95.21 | ...18-221,266-269 
  ...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.96 |    85.44 |   94.23 |   93.96 | ...1229,1236-1237 
  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       |      75 |      100 |      50 |      75 | 22-28,59-70       
  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.82 |   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 |     90.9 |     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 |    55.55 |     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.31 |    84.61 |   83.33 |   90.31 |                   
  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          |   93.15 |    84.84 |      80 |   93.15 | ...78-180,198-199 
  reconnect.ts     |   78.85 |    66.66 |   85.71 |   78.85 | 42-55,169-191     
  remove.ts        |     100 |       80 |     100 |     100 | 21-25             
 ...ommands/review |   87.21 |    87.92 |   88.25 |   87.21 |                   
  agent-prompt.ts  |   92.82 |    92.19 |   96.96 |   92.82 | ...2122,2236-2316 
  base-tree.ts     |   76.16 |    80.76 |   77.77 |   76.16 | ...50-371,373-386 
  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 |   96.25 |    92.07 |      96 |   96.25 | ...1853,1881-1903 
  cost-ledger.ts   |   94.67 |    95.86 |   78.57 |   94.67 | ...04-505,545-555 
  drive.ts         |   76.07 |    85.71 |   81.81 |   76.07 | ...90-492,497-499 
  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 
  match-remote.ts  |   85.54 |     92.3 |   66.66 |   85.54 | 67-72,131-136     
  mock-provider.ts |   95.44 |    90.25 |   89.47 |   95.44 | 145,690-709       
  parse-args.ts    |   99.66 |    96.55 |     100 |   99.66 | 404               
  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 |   77.18 |    82.14 |   71.42 |   77.18 | ...85-531,533-544 
  repo-context.ts  |   94.92 |    90.82 |     100 |   94.92 | ...67-368,376-377 
  ...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 |    89.9 |    81.81 |   94.11 |    89.9 | ...08-311,404-407 
  script-lint.ts   |   81.14 |    79.23 |   88.88 |   81.14 | ...59-773,775-797 
  submit.ts        |   83.88 |    84.21 |    90.9 |   83.88 | ...62-466,566-602 
  test-delta.ts    |   87.13 |    91.46 |      75 |   87.13 | 206-237,477-485   
  test-efficacy.ts |   88.04 |    84.12 |   95.45 |   88.04 | ...2602,2610-2630 
  test-plan.ts     |   91.44 |    91.39 |   89.47 |   91.44 | ...38-839,903-920 
 ...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 |   97.09 |    94.74 |   97.61 |   97.09 |                   
  agent-briefs.ts  |   98.95 |      100 |      50 |   98.95 | 695-696           
  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.94 |    95.39 |   95.65 |   95.94 | ...14,351,460-477 
  deadline.ts      |   97.68 |    91.22 |     100 |   97.68 | 140-141,190,352   
  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            |   86.42 |    91.83 |      75 |   86.42 | ...52,289-290,317 
  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 
  ...ry-context.ts |   96.19 |    94.93 |     100 |   96.19 | ...90-491,496-499 
  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 |   97.88 |    93.87 |     100 |   97.88 | 260-261,267       
  receipt.ts       |     100 |      100 |     100 |     100 |                   
  remote-match.ts  |   97.26 |    91.42 |     100 |   97.26 | 49-50             
  report.ts        |   94.68 |    93.75 |     100 |   94.68 | 189-193           
  ...ry-context.ts |     100 |    98.66 |     100 |     100 | 184               
  retirement.ts    |     100 |    89.77 |     100 |     100 | ...16-317,328,430 
  review-footer.ts |     100 |      100 |     100 |     100 |                   
  roster.ts        |     100 |    95.71 |     100 |     100 | 145,163,208       
  shell-quote.ts   |     100 |      100 |     100 |     100 |                   
  stale-bundle.ts  |   98.11 |    94.04 |     100 |   98.11 | 416,457,497-498   
  test-utils.ts    |     100 |      100 |     100 |     100 |                   
  transcripts.ts   |   96.59 |     94.5 |     100 |   96.59 | ...08,297-298,323 
  ...pace-scope.ts |     100 |    96.96 |     100 |     100 | 172               
  workspaces.ts    |     100 |     95.9 |     100 |     100 | ...27,452,499,512 
  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.84 |    89.73 |    96.2 |   94.84 |                   
  ...l-fallback.ts |     100 |      100 |     100 |     100 |                   
  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.95 |    88.61 |   83.78 |   88.95 | ...2461,2463-2471 
  ...cy-monitor.ts |   88.75 |    76.19 |     100 |   88.75 | ...3,90-92,98,101 
  ...ust-policy.ts |   83.02 |    88.88 |     100 |   83.02 | ...02-209,232-240 
  ...heme-names.ts |     100 |      100 |     100 |     100 |                   
  environment.ts   |   96.42 |    93.22 |      95 |   96.42 | ...69-570,624-625 
  ...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 |   93.33 |    93.33 |     100 |   93.33 | ...42-147,216-217 
  ...ings-cache.ts |   98.26 |    97.14 |     100 |   98.26 | 201-202           
  settings.ts      |   91.27 |    92.64 |      90 |   91.27 | ...1030,1032-1033 
  ...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 
  ...precedence.ts |   98.79 |     92.3 |     100 |   98.79 | 62                
  ...tedFolders.ts |   92.53 |    93.47 |     100 |   92.53 | ...36-337,373-384 
 ...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.98 |    77.27 |   84.12 |   80.98 |                   
  session.ts       |   84.97 |    76.31 |   96.07 |   84.97 | ...1048,1057-1067 
  types.ts         |    42.5 |      100 |   33.33 |    42.5 | ...31-632,635-636 
 ...active/control |   75.54 |    89.83 |      80 |   75.54 |                   
  ...rolContext.ts |    6.06 |        0 |       0 |    6.06 | 57-99             
  ...Dispatcher.ts |   91.95 |    92.98 |   88.88 |   91.95 | ...54-372,392,395 
  ...rolService.ts |    6.89 |        0 |       0 |    6.89 | 46-188            
 ...ol/controllers |    44.9 |    66.19 |   55.26 |    44.9 |                   
  ...Controller.ts |    42.4 |      100 |   83.33 |    42.4 | 101-105,140-223   
  ...Controller.ts |       0 |        0 |       0 |       0 | 1-56              
  ...Controller.ts |   55.01 |    67.14 |   58.33 |   55.01 | ...15-624,639-644 
  ...Controller.ts |   49.23 |       60 |      50 |   49.23 | ...07-108,111-121 
  ...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.16 |   95.23 |    98.1 |                   
  ...putAdapter.ts |   97.98 |    93.23 |   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.36 |    83.59 |   90.49 |   87.36 |                   
  ...tp-enabled.ts |     100 |      100 |     100 |     100 |                   
  ...ion-bridge.ts |     100 |      100 |     100 |     100 |                   
  auth.ts          |   93.43 |    92.95 |     100 |   93.43 | ...20-321,324-326 
  ...em-adapter.ts |     100 |      100 |     100 |     100 |                   
  capabilities.ts  |     100 |    98.07 |     100 |     100 | 670               
  ...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 |    94.1 |    86.89 |     100 |    94.1 | ...75-477,484,486 
  ...-selection.ts |     100 |      100 |     100 |     100 |                   
  ...ings-store.ts |   88.59 |    93.68 |   96.29 |   88.59 | ...95-207,451-454 
  ...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.42 |    84.44 |    97.1 |   92.42 | ...1466,1520-1524 
  ...e-grouping.ts |     100 |    94.28 |     100 |     100 | 71,137            
  core-runtime.ts  |     100 |      100 |     100 |     100 |                   
  ...ub-session.ts |    90.1 |    77.83 |   94.73 |    90.1 | ...1014,1021-1026 
  daemon-logger.ts |    82.2 |    77.42 |   91.76 |    82.2 | ...1720,1747-1753 
  ...y-pressure.ts |     100 |    96.96 |     100 |     100 | 135               
  ...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.57 |     90.8 |     100 |   98.57 | ...1411,1413-1414 
  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 
  ...d-provider.ts |   92.06 |    86.95 |     100 |   92.06 | ...72,287-293,316 
  ...-path-argv.ts |     100 |      100 |     100 |     100 |                   
  ...h-settings.ts |   94.89 |    90.25 |     100 |   94.89 | ...24,702,718,728 
  fast-path.ts     |   90.98 |    81.38 |   95.45 |   90.98 | ...32-541,607-608 
  ...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 | ...30-131,142-143 
  ...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 |   83.72 |    79.84 |   75.43 |   83.72 | ...7337,7343-7344 
  ...tup-errors.ts |     100 |      100 |     100 |     100 |                   
  ...-keepalive.ts |   94.19 |     87.5 |     100 |   94.19 | ...26,530-531,571 
  ...-lifecycle.ts |     100 |      100 |     100 |     100 |                   
  server.ts        |   90.57 |    90.92 |   71.69 |   90.57 | ...2663,2677-2681 
  ...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 | ...20,823,836-838 
  ...l-resolver.ts |   90.32 |    66.66 |     100 |   90.32 | 16,45-46          
  ...ell-static.ts |   92.18 |    88.37 |     100 |   92.18 | ...21-224,267-270 
  ...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.63 |    84.26 |     100 |   91.63 | ...71-273,306-307 
 ...serve/acp-http |   77.23 |    78.75 |   93.33 |   77.23 |                   
  ...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.55 |     100 |    98.2 | 1015,1041-1052    
  dispatch.ts      |   71.95 |    75.11 |   95.55 |   71.95 | ...4897,4945-4951 
  index.ts         |   81.97 |     79.8 |    90.9 |   81.97 | ...2296,2380-2381 
  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.39 |    80.74 |     100 |   86.39 |                   
  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.16 |    79.55 |     100 |   86.16 | ...2510,2520-2521 
 src/serve/live    |   77.28 |    69.21 |   89.91 |   77.28 |                   
  ...en-context.ts |   95.74 |    81.25 |     100 |   95.74 | ...0,66-67,99-100 
  ...-workspace.ts |   88.63 |    82.53 |     100 |   88.63 | ...40-241,253-254 
  discovery.ts     |   85.77 |    76.92 |      90 |   85.77 | ...49-250,255-256 
  ...structions.ts |     100 |      100 |     100 |     100 |                   
  ...oordinator.ts |   82.67 |    76.75 |   97.01 |   82.67 | ...1319,1351-1353 
  ...-installer.ts |   45.17 |    81.96 |   68.18 |   45.17 | ...80-381,395-407 
  ...oordinator.ts |   76.17 |     64.4 |   85.36 |   76.17 | ...1858,1949-1950 
  ...controller.ts |   67.82 |    79.31 |   72.72 |   67.82 | ...66-278,287-295 
  ...ak-to-user.ts |   96.66 |      100 |   83.33 |   96.66 | 37-38             
  ...sk-service.ts |   86.22 |    59.64 |   93.33 |   86.22 | ...1152,1175-1182 
  ...task-tools.ts |      99 |      100 |   85.71 |      99 | 205-206           
  ...redentials.ts |   96.26 |    93.47 |     100 |   96.26 | 91-94             
  ...me-session.ts |   65.63 |    57.24 |   88.88 |   65.63 | ...2270,2275-2282 
  ...up-context.ts |   94.83 |    77.58 |     100 |   94.83 | ...18,327-330,350 
  ...ion-source.ts |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/serve/routes  |   85.45 |    79.81 |   95.29 |   85.45 |                   
  a2ui-action.ts   |   96.84 |     88.5 |    87.5 |   96.84 | ...70-272,309-311 
  capabilities.ts  |     100 |      100 |     100 |     100 |                   
  ...nel-notify.ts |   86.45 |       88 |     100 |   86.45 | ...,83-87,103-104 
  ...l-webhooks.ts |   93.56 |    84.09 |     100 |   93.56 | ...42,292,332,334 
  daemon-status.ts |   85.71 |    83.33 |     100 |   85.71 | 101-108           
  goals.ts         |   98.92 |     90.9 |     100 |   98.92 | 146               
  health-demo.ts   |   95.65 |    88.88 |     100 |   95.65 | 63-67,186         
  live-setup.ts    |   33.33 |     37.5 |      50 |   33.33 | ...18-123,130-135 
  live.ts          |    82.4 |    71.42 |     100 |    82.4 | ...-94,96-101,121 
  permission.ts    |     100 |     92.3 |     100 |     100 | 50,98             
  ...uled-tasks.ts |   87.29 |    82.94 |   92.59 |   87.29 | ...1275,1318-1319 
  ...on-runtime.ts |     100 |    90.47 |     100 |     100 | 58,94             
  session.ts       |   85.42 |    81.81 |   95.31 |   85.42 | ...4777,4779-4780 
  sse-events.ts    |   86.82 |    85.71 |   94.11 |   86.82 | ...16-927,930,937 
  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.92 |    79.69 |     100 |   90.92 | ...81-482,501-502 
  ...d-contacts.ts |     100 |      100 |     100 |     100 |                   
  ...controller.ts |   83.11 |    79.31 |      90 |   83.11 | ...1033,1039,1042 
  ...extensions.ts |   88.15 |    74.95 |   92.98 |   88.15 | ...2027,2072-2073 
  ...-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 |   87.41 |    84.13 |     100 |   87.41 | ...1660,1680-1685 
  ...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 |   75.04 |    72.99 |     100 |   75.04 | ...79-690,696-697 
  ...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.92 |    66.21 |      80 |   78.92 | ...38-343,351-352 
  ...pace-voice.ts |   91.33 |    80.92 |     100 |   91.33 | ...70-673,676-678 
 src/serve/server  |   90.72 |     89.1 |   96.55 |   90.72 |                   
  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.14 |     100 |   95.11 | ...65-167,422-427 
  self-origin.ts   |   76.19 |       80 |     100 |   76.19 | 45-54             
  ...e-features.ts |      95 |     87.5 |     100 |      95 | 182-188           
  ...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   |    92.7 |    91.48 |   97.67 |    92.7 |                   
  ...ice-config.ts |   84.81 |       30 |     100 |   84.81 | 91-100,104-105    
  voice-ws.ts      |   91.58 |    93.44 |      96 |   91.58 | ...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.48 |    89.31 |      98 |   92.48 |                   
  ...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.77 |     100 |   98.64 | 116,142-143       
  voice-model.ts   |     100 |      100 |     100 |     100 |                   
  voice-service.ts |    90.4 |    87.87 |     100 |    90.4 | ...81,288,353-358 
  ...e-settings.ts |     100 |    95.23 |     100 |     100 | 19                
  ...ranscriber.ts |   91.77 |    87.11 |   97.22 |   91.77 | ...99-901,904-906 
 ...rvices/insight |     100 |      100 |     100 |     100 |                   
  dates.ts         |     100 |      100 |     100 |     100 |                   
 ...ght/generators |   88.91 |     86.8 |   96.15 |   88.91 |                   
  DataProcessor.ts |   88.28 |    86.77 |   94.73 |   88.28 | ...1362,1366-1373 
  ...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 | 96-99             
  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    |   94.09 |    79.16 |   77.77 |   94.09 |                   
  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 
  ...mised-lock.ts |     100 |      100 |   66.66 |     100 |                   
  ...andContext.ts |     100 |      100 |     100 |     100 |                   
  render.tsx       |     100 |      100 |     100 |     100 |                   
 src/ui            |   73.08 |    75.43 |   67.41 |   73.08 |                   
  App.tsx          |   33.33 |       75 |   33.33 |   33.33 | 32-86             
  AppContainer.tsx |   74.29 |    72.05 |   68.57 |   74.29 | ...4112,4228-4234 
  ...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 |   70.08 |    71.73 |   66.66 |   70.08 | ...01,324,377-382 
  ...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.67 |    83.11 |   89.15 |   82.67 |                   
  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 |   69.07 |     72.6 |   84.61 |   69.07 | ...78-611,622-623 
  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 |   94.44 |    90.14 |     100 |   94.44 | ...13-214,241-251 
  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.96 |    86.04 |     100 |   90.96 | ...41-146,177-178 
  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 |   92.92 |       85 |   66.66 |   92.92 | ...72-177,276-281 
 src/ui/components |   71.52 |    79.07 |   79.85 |   71.52 |                   
  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       |   76.99 |    66.66 |      50 |   76.99 | ...96,233,255-260 
  ...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.28 |    66.99 |     100 |   79.28 | ...08,511,514-520 
  ...ngeDialog.tsx |     100 |      100 |     100 |     100 |                   
  InputPrompt.tsx  |   83.26 |    82.23 |      80 |   83.26 | ...2231,2257,2331 
  ...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  |   96.28 |     94.8 |      50 |   96.28 | ...01,459-463,466 
  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 |   95.67 |    87.09 |     100 |   95.67 | ...24-125,275-277 
  ...inalImage.tsx |     100 |    93.93 |     100 |     100 | 75,129            
  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 |   85.34 |    84.91 |   92.98 |   85.34 |                   
  ...sksDialog.tsx |   81.87 |    82.77 |   85.71 |   81.87 | ...1853,1965-1971 
  ...TasksPill.tsx |   78.84 |    94.28 |     100 |   78.84 | 64,109-129        
  ...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.91 |    63.44 |   70.58 |   40.91 |                   
  ...ealthPill.tsx |     100 |      100 |     100 |     100 |                   
  ...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 |   90.26 |    86.89 |   85.57 |   90.26 |                   
  ...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 |   94.11 |    95.91 |   76.92 |   94.11 | ...47-349,352-355 
  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.87 |    82.63 |     100 |   91.87 | ...49-651,658-660 
  ...upMessage.tsx |   98.38 |    95.38 |     100 |   98.38 | 188-191,422       
  ToolMessage.tsx  |   93.06 |    86.32 |   93.75 |   93.06 | ...1037,1082-1084 
 ...ponents/shared |   86.29 |    82.41 |   94.17 |   86.29 |                   
  ...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 |     100 |      100 |     100 |     100 |                   
  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 |   91.49 |    86.66 |   83.33 |   91.49 | ...18-846,859,959 
  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 |    70.1 |    72.89 |   61.11 |    70.1 |                   
  ContextUsage.tsx |   71.49 |    64.86 |      80 |   71.49 | ...30-436,473-567 
  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   |   84.16 |    81.83 |   85.13 |   84.16 |                   
  ...ewContext.tsx |   64.83 |    88.88 |      50 |   64.83 | ...16-219,225-235 
  AppContext.tsx   |      80 |       50 |     100 |      80 | 19-20             
  ...ewContext.tsx |   93.83 |    68.51 |   42.85 |   93.83 | ...44,281-285,317 
  ...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      |   85.49 |    82.95 |   88.01 |   85.49 |                   
  ...dProcessor.ts |   85.53 |     85.2 |     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 | ...87-288,293-294 
  ...dProcessor.ts |   85.75 |     68.4 |   81.81 |   85.75 | ...1464,1485-1489 
  ...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 |      52 |    63.63 |     100 |      52 | ...59,67-70,76-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.89 |    77.55 |     100 |   94.89 | 164-168,257,263   
  ...chedScroll.ts |     100 |      100 |     100 |     100 |                   
  ...ketedPaste.ts |    23.8 |      100 |       0 |    23.8 | 19-37             
  ...nchCommand.ts |   95.45 |    83.01 |     100 |   95.45 | ...60-161,285-288 
  ...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 |   86.08 |    81.23 |   76.92 |   86.08 | ...5198-5200,5202 
  ...BranchName.ts |     100 |    94.44 |     100 |     100 | 54                
  ...oryManager.ts |   98.38 |    98.85 |     100 |   98.38 | 141-144           
  ...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  |   10.52 |      100 |       0 |   10.52 | 36-75             
  ...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.48 |    88.88 |     100 |   89.48 | ...54-456,489-499 
  ...oryCommand.ts |       0 |        0 |       0 |       0 | 1-7               
  ...umeCommand.ts |   95.26 |    77.14 |     100 |   95.26 | 120-121,223-228   
  ...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      |   87.07 |    85.21 |    95.6 |   87.07 |                   
  ...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.42 |       95 |     100 |   91.42 | 32-34             
  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           
  ...mage-parts.ts |   97.75 |    94.87 |     100 |   97.75 | 82-83             
  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.04 |   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.14 |     100 |   98.38 | 195-197           
  ...mConstants.ts |     100 |      100 |     100 |     100 |                   
  restoreGoal.ts   |     100 |      100 |     100 |     100 |                   
  ...storyUtils.ts |   82.73 |    79.48 |     100 |   82.73 | ...84-606,737-738 
  ...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 |   90.61 |    83.44 |     100 |   90.61 | ...80,482-484,607 
  ...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 |     60.3 |   94.59 |   75.03 |                   
  collect.ts       |   71.27 |    66.38 |      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      |   81.27 |    79.92 |   81.94 |   81.27 |                   
  ...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 |   91.09 |     92.1 |     100 |   91.09 | ...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 |       70 |     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.4 |    87.04 |   92.57 |    81.4 |                   
  ...p-profiler.ts |   98.39 |    92.59 |     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 |    89.65 |     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.64 |    77.02 |     100 |   86.64 | ...03-304,335-345 
  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.87 |    56.93 |   76.92 |   45.87 | ...1040,1052-1075 
  ...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 |       90 |     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.79 |    86.32 |   89.36 |   87.79 |                   
 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.38 |    84.54 |   94.85 |   90.38 |                   
  ...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 |   94.63 |    90.13 |   96.38 |   94.63 | ...1773,1793-1796 
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...ent-result.ts |    96.8 |    92.68 |     100 |    96.8 | 106,129-131       
  ...n-registry.ts |   94.79 |     87.7 |     100 |   94.79 | ...1067,1081-1083 
  ...w-snapshot.ts |   92.12 |    77.14 |     100 |   92.12 | ...65,189,196-198 
 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 |    91.1 |    86.68 |   89.23 |    91.1 |                   
  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 |                   
  ...-scheduler.ts |   97.43 |    96.36 |     100 |   97.43 | 128-130           
  ...ow-journal.ts |   91.76 |    75.86 |     100 |   91.76 | ...38-139,179-181 
  ...chestrator.ts |    92.4 |       90 |   83.78 |    92.4 | ...1862,1911-1914 
  ...ow-prompts.ts |     100 |      100 |     100 |     100 |                   
  ...low-runner.ts |   94.85 |     87.5 |   92.85 |   94.85 | ...93,260,280-283 
  ...ow-sandbox.ts |   96.85 |    91.28 |     100 |   96.85 | ...1705,1711-1712 
  ...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   |   82.04 |    84.17 |   88.97 |   82.04 |                   
  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       |   96.02 |    87.23 |     100 |   96.02 | 352-358           
  ...ptAddendum.ts |     100 |      100 |     100 |     100 |                   
  tasks.ts         |   89.24 |    82.82 |     100 |   89.24 | ...-994,1038-1039 
  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.26 |   98.21 |   94.39 |                   
  ...on-harness.ts |   96.49 |    84.21 |     100 |   96.49 | 128-129,141-142   
  fake-agent.ts    |   98.49 |    95.08 |     100 |   98.49 | 201-203           
  fake-backend.ts  |   86.46 |    97.61 |   95.83 |   86.46 | 124-146           
 src/config        |   84.98 |    87.13 |   75.37 |   84.98 |                   
  approval-mode.ts |     100 |      100 |     100 |     100 |                   
  ...xtDefaults.ts |     100 |      100 |     100 |     100 |                   
  config.ts        |   84.29 |    86.85 |   73.79 |   84.29 | ...8348,8352-8353 
  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          |   92.35 |    88.06 |   93.26 |   92.35 |                   
  baseLlmClient.ts |    88.4 |     83.8 |   81.81 |    88.4 | ...59,672,678-680 
  client.ts        |   91.95 |    87.18 |   91.56 |   91.95 | ...3928,4026-4027 
  ...tGenerator.ts |   86.34 |    87.34 |   84.61 |   86.34 | ...96-497,542-548 
  ...lScheduler.ts |   90.04 |    84.67 |   96.15 |   90.04 | ...6215,6243-6259 
  geminiChat.ts    |    94.7 |    90.12 |   95.53 |    94.7 | ...5052,5100-5101 
  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 | ...1209,1412-1413 
  ...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 |   90.38 |    94.73 |     100 |   90.38 | 68-72             
  ...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.67 |    93.07 |     100 |   98.67 | ...79,707-708,755 
  ...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.63 |    90.43 |   95.61 |   91.63 |                   
  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      |   95.45 |    91.18 |     100 |   95.45 | ...1301,1309,1408 
  ...ix-caching.ts |   95.23 |    92.85 |     100 |   95.23 | 45-46,69-70       
  ...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 |   97.19 |    90.44 |   98.36 |   97.19 |                   
  dashscope.ts     |   98.36 |    92.99 |   95.65 |   98.36 | ...93-494,636-637 
  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.23 |    83.31 |   92.35 |   86.23 |                   
  ...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.85 |    86.14 |   97.87 |   90.85 | ...1218-1224,1268 
  ...ionManager.ts |   81.16 |    79.18 |   81.52 |   81.16 | ...2718,2740-2741 
  ...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.62 |    82.31 |     100 |   88.62 | ...65,955-956,966 
  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.94 |    80.07 |    90.9 |   79.94 |                   
  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.7 |    65.38 |   71.42 |    71.7 | ...52-653,660-661 
  ...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         |    93.3 |    89.05 |    94.6 |    93.3 |                   
  ...eGoalStore.ts |   87.61 |    88.88 |   86.66 |   87.61 | ...85-188,196-204 
  ...t-verifier.ts |   96.27 |     90.9 |     100 |   96.27 | ...20,143-146,163 
  ...checkpoint.ts |   81.48 |    76.19 |     100 |   81.48 | ...02-105,115-118 
  goal-evidence.ts |   88.79 |     88.5 |   96.42 |   88.79 | ...04-805,828-831 
  ...projection.ts |   66.66 |    72.97 |   33.33 |   66.66 | ...83,186,190-192 
  ...ersistence.ts |   87.73 |    84.84 |      80 |   87.73 | ...-94,97,101-106 
  goal-protocol.ts |   95.74 |    93.33 |     100 |   95.74 | 154-155           
  goal-reducer.ts  |    93.4 |    90.65 |   96.96 |    93.4 | ...27,501,519-520 
  goal-runtime.ts  |   97.62 |     89.9 |     100 |   97.62 | ...1049,1169-1170 
  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-28              
  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.07 |    86.34 |   88.54 |   88.07 |                   
  ...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.83 |    83.81 |   90.47 |   87.83 |                   
  ...y-document.ts |   89.52 |    84.61 |     100 |   89.52 | ...24-325,329-330 
  ...nel-memory.ts |   97.36 |    96.63 |   96.42 |   97.36 | ...91-293,367-368 
  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       |   92.41 |    79.41 |     100 |   92.41 | 56-61,100,119-122 
  ...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         |     100 |      100 |     100 |     100 |                   
  ...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       |   93.58 |    89.58 |     100 |   93.58 | ...75-176,183-184 
  ...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 |    77.41 |     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 |     82.6 |     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 |     79.1 |   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.62 |   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 |       44 |   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.76 |   95.89 |   85.41 |                   
  ...tGenerator.ts |   98.64 |    98.18 |     100 |   98.64 | 105-106           
  qwenOAuth2.ts    |   82.79 |    73.75 |   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.74 |     84.6 |   96.91 |   89.74 |                   
  ...ionTrailer.ts |     100 |      100 |     100 |     100 |                   
  ...llRegistry.ts |   97.68 |    85.71 |     100 |   97.68 | ...96,119,490-491 
  ...ionService.ts |   97.51 |    96.15 |     100 |   97.51 | ...,929,1072-1080 
  ...ingService.ts |   91.41 |    85.15 |   95.65 |   91.41 | ...2116,2143-2144 
  ...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 |    97.5 |    96.07 |     100 |    97.5 | 349-350,363-364   
  ...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.26 |    97.35 |     100 |   98.26 | ...13-714,761-762 
  ...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.5 |    94.11 |    90.9 |    98.5 | 64-65             
  ...ipt-reader.ts |   94.55 |    89.78 |   96.66 |   94.55 | ...1353-1354,1422 
  ...est-helper.ts |       0 |        0 |       0 |       0 | 1-65              
  ...iter-lease.ts |   83.14 |    74.47 |   97.61 |   83.14 | ...2433,2445-2448 
  sessionRecap.ts  |   67.56 |    43.47 |     100 |   67.56 | ...60,178,180-183 
  ...ionService.ts |   88.95 |    84.18 |   97.14 |   88.95 | ...2450,2526-2546 
  sessionTitle.ts  |   94.19 |    73.21 |     100 |   94.19 | ...43-246,277-278 
  ...ionService.ts |    84.4 |    78.45 |   97.18 |    84.4 | ...2493,2499-2504 
  ...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 |    98.9 |    95.08 |     100 |    98.9 |                   
  microcompact.ts  |    98.9 |    95.08 |     100 |    98.9 | ...40,749,758-759 
 ...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.29 |    85.87 |   93.61 |   89.29 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...activation.ts |     100 |    93.33 |     100 |     100 | 93,112            
  skill-curator.ts |   89.71 |    81.54 |     100 |   89.71 | ...01-902,904-907 
  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.47 |   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 |    87.58 |   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    |   96.02 |    98.41 |   82.92 |   96.02 |                   
  config.ts        |     100 |      100 |     100 |     100 |                   
  ...st-helpers.ts |   94.11 |       90 |     100 |   94.11 | 69-70             
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...mised-lock.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.22 |    85.02 |   88.72 |   86.22 |                   
  ...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 |   82.13 |    80.47 |   85.71 |   82.13 | ...3234,3236-3237 
  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 |   79.21 |    85.71 |   81.57 |   79.21 | ...1341,1349-1350 
  ...ool-events.ts |       8 |      100 |       0 |       8 | 132-158           
  mcp-pool-key.ts  |   97.46 |    93.93 |     100 |   97.46 | 176-177           
  ...ce-content.ts |   96.55 |    91.17 |     100 |   96.55 | 80-82             
  mcp-retry.ts     |   97.67 |    95.65 |     100 |   97.67 | 131-132           
  ...ion-config.ts |     100 |      100 |     100 |     100 |                   
  mcp-status.ts    |     100 |      100 |     100 |     100 |                   
  mcp-tool.ts      |   98.35 |    93.71 |     100 |   98.35 | ...-990,1045-1046 
  ...sport-pool.ts |   83.98 |     80.3 |   88.46 |   83.98 | ...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.69 |    77.08 |   81.25 |   85.69 | ...95-911,957-958 
  ...escendants.ts |   36.17 |    64.51 |   55.55 |   36.17 | ...46-310,385-390 
  ...nforcement.ts |   83.21 |    90.69 |     100 |   83.21 | 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 |   94.07 |    91.89 |    90.9 |   94.07 | 131-139           
  shell.ts         |   78.72 |     84.1 |   91.91 |   78.72 | ...5032,5095-5096 
  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.86 |    89.64 |   96.85 |   92.86 |                   
  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 |                   
  ...igResolver.ts |     100 |      100 |     100 |     100 |                   
  ...engthError.ts |   91.06 |    89.47 |     100 |   91.06 | ...46-147,154-155 
  ...n-branches.ts |   95.88 |    94.11 |      95 |   95.88 | ...98-499,511-524 
  ...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        |   83.01 |    95.03 |    61.9 |   83.01 | ...62-378,382-388 
  fetch.ts         |   90.68 |    82.51 |     100 |   90.68 | ...72,483-484,503 
  file-identity.ts |     100 |      100 |     100 |     100 |                   
  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.25 |     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.61 |    92.42 |     100 |   93.61 | ...62-563,565-567 
  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.98 |    87.15 |     100 |   96.98 | ...87-688,763-764 
  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.11 |     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.71 |   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.33 |     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 |       25 |      75 |   54.62 | ...03-105,108-134 
  ...Compaction.ts |   96.13 |    96.42 |     100 |   96.13 | ...34-339,341-346 
  ...pt-records.ts |    87.5 |    86.02 |     100 |    87.5 | ...76-480,510-525 
  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 |   96.74 |    91.04 |     100 |   96.74 | ...69,196,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.

@qwen-code-dev-bot

qwen-code-dev-bot commented Aug 7, 2026 •

Copy link
Copy Markdown
Collaborator

✅ AutoFix round 11 finished — view run. See this round's report below.

中文说明

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

A trusted workspace's .env could re-populate the loader-key slots that
scrubInheritedLoaderEnv() emptied in the daemon process, because
canApplyParsedEnvKey applied RELOAD_EXCLUDED_KEYS only on reloads.
Reject the loader subset on every .env application path so one
workspace's loader hook cannot reach other workspaces' session
subprocesses through the shared daemon env.

Also make the scrub return the removed keys and emit a stderr
breadcrumb naming them at both boundaries, so a session subprocess
missing an inherited var can be traced back to the scrub.
@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 轮)。改动内容与我反驳保留之处如下:

Review feedback round — PR #8663

Feedback points and dispositions

[Critical] R1-1 (rc:3733638377) — .env re-population of scrubbed loader slots: FIXED.
Verified against the code: canApplyParsedEnvKey (packages/cli/src/config/environment.ts) applied RELOAD_EXCLUDED_KEYS only when options.reload was set, while the daemon-side trusted-workspace loadSettings callers named in the finding (workspace-skills-status.ts, workspace-service/index.ts, serve-features.ts — all pass skipLoadEnvironment: !workspaceTrusted) reach the initial loadEnvironment, which writes into process.env in no-override mode. After the daemon scrub empties the loader-key slots, a trusted workspace's .env could refill them, and reloadEnvironment never deletes those keys — the exact cross-workspace vector described.
Fix (the finding's first suggested option): reject INHERITED_LOADER_ENV_KEYS in canApplyParsedEnvKey on every .env application path, mirroring buildRuntimeEnvironment. This also closes the same leak through an ACP child hosting sessions sequentially. Audited the adjacent paths while at it: the serve fast-path loader only runs at daemon boot (before the freeze/scrub), getHomeEnvFallbackVars only resolves ${VAR} placeholders without touching process.env, and settings.env was already guarded — no further changes needed.
Regression test added in environment.test.ts (loader keys in a workspace .env are never applied on initial load; ordinary keys still are).

[Suggestion] R1-2 (rc:3733638383) — no test for the ACP-child scrub call site: FIXED.
Added a two-case test in gemini.test.tsx modeled on the existing ACP-mode env tests: stubs NODE_OPTIONS/NODE_PATH, runs main() with acp: true and QWEN_CODE_NO_RELAUNCH (final-process path), and asserts the loader vars are gone by loadCliConfig — the first expensive call past the relaunch/sandbox handoff. A second case with non-ACP argv pins the isAcpMode gate (loader vars kept). Deleting the scrub call or the gate now fails the suite.

[Suggestion] R1-3 (rc:3733638386) — silent scrub at both boundaries: FIXED.
scrubInheritedLoaderEnv now returns the removed keys. Both call sites emit one stderr breadcrumb naming them when at least one key was removed (qwen serve: scrubbed inherited loader env vars from the daemon process; ... and qwen: scrubbed inherited loader env vars from the ACP child process; ...), using the writeStderrLine channel already present next to both sites. The daemon scrub test now asserts the breadcrumb content; shared-env-keys.test.ts pins the removed-key list (present keys only, empty on second scrub).

[Suggestion] R1-8 (rc:3733638389) — PATH-prefix follow-up tracking: ESCALATED (not resolvable in this mode).
Agreed — the residual PATH-prefix portion of #8653 needs a tracking home before this PR closes the issue. Filing a GitHub issue and editing the PR description are GitHub writes, which this bot cannot perform (the workflow/maintainer owns all network writes). A ready-to-file issue draft is included in the reply on that thread (title, body, and the open design questions). The thread is intentionally left unresolved until the issue exists and is linked in the PR description.

Review verdict (CHANGES_REQUESTED) — "Integration Tests (CLI, No Sandbox) was skipped in CI and did not run locally": ADDRESSED.
Ran the exact suite locally after npm run build && npm run bundle: npm run test:integration:cli:sandbox:none — 31/38 files passed, 181 tests passed, 18 skipped, 2 failed. Both failures were investigated with evidence and are runner-environment artifacts, not code defects (see Verification).

Conflict notes

--conflict false — no merge performed; none needed.

Verification

Commands actually run and their results:

  • npm run build — passed (run twice: once to repair a stale @qwen-code/web-templates dist that pre-dated this round and blocked gemini.test.tsx collection, once before bundling).
  • npm run typecheck — passed.
  • npm run lint (full repo, eslint . --ext .ts,.tsx && eslint integration-tests) — passed; npx prettier --check on all touched files — passed.
  • Focused Vitest (packages/cli) — all passed:
    • src/config/environment.test.ts + src/config/shared-env-keys.test.ts — 12 passed (includes the new initial-load regression test and the removed-key assertions)
    • src/gemini.test.tsx — 61 passed (includes the 2 new ACP-handoff scrub cases)
    • src/serve/run-qwen-serve.test.ts + src/serve/process-env-guard.test.ts — 235 passed (daemon scrub test now also asserts the breadcrumb)
    • final combined run of all five touched test files — 308 passed
  • npm run bundle — passed.
  • npm run test:integration:cli:sandbox:none — 181 passed, 18 skipped, 2 failed; both failures evidenced as environment-specific to this autofix runner:
    • cli/monitor.test.ts > should call monitor tool when asked to watch a command — timed out at 60 s only under the full parallel suite (a sibling test in the same run took 572 s with a retry); re-run in isolation against the same bundle: 2/2 passed in 24.7 s. Resource-contention flake.
    • cli/qwen-config-dir.test.ts > 1d: CLI functions normally when QWEN_HOME is not set — EACCES: permission denied, mkdir '/home/github-runner/.qwen'; reproduced in isolation, and the runner confirms the cause: the process runs as uid=1000(node) while /home/github-runner is drwxr-xr-x root root, so ~/.qwen can never be created here when QWEN_HOME is unset. Unrelated to this PR's code path.
  • Pre-existing-failure baseline check: src/config/settings.test.ts + src/config/config.test.ts show 17 failures in this runner environment; temporarily restoring the four modified source files to HEAD and re-running produced the identical 17 failures, so they are environment-dependent and pre-existing on the PR head, not caused by this round. (Files were restored from backup afterwards and re-verified.)
  • Git: one additive commit cd3450c653 on fix/daemon-session-loader-env-leak; git status clean; only the eight intended files touched.
中文说明

评审反馈轮次 — PR #8663

反馈点与处置

[Critical] R1-1(rc:3733638377)—— .env 重新填充被清空的 loader 键槽:已修复。
已对照代码核实:canApplyParsedEnvKey(packages/cli/src/config/environment.ts)仅在设置了 options.reload 时才应用 RELOAD_EXCLUDED_KEYS,而反馈点名的 daemon 侧受信 workspace loadSettings 调用方(workspace-skills-status.ts、workspace-service/index.ts、serve-features.ts——均传 skipLoadEnvironment: !workspaceTrusted)会走到初始 loadEnvironment,以 no-override 模式写入 process.env。daemon 剥离清空 loader 键槽后,受信 workspace 的 .env 可以重新填充这些槽位,而 reloadEnvironment 从不删除这些键——正是所描述的跨 workspace 向量。
修复(采用该反馈建议的第一种方案):在 canApplyParsedEnvKey 中对 INHERITED_LOADER_ENV_KEYS 在所有 .env 应用路径上一律拒绝,与 buildRuntimeEnvironment 保持一致。这同时堵住了同一个 ACP 子进程顺序承载多个会话时的同类泄漏。顺带审计了相邻路径:serve fast-path 加载只在 daemon 启动时(冻结/剥离之前)运行;getHomeEnvFallbackVars 仅用于解析 ${VAR} 占位符、不写 process.env;settings.env 本就设防——无需其他改动。
在 environment.test.ts 中新增回归测试(workspace .env 中的 loader 键在初始加载时一律不生效,普通键不受影响)。

[Suggestion] R1-2(rc:3733638383)—— ACP 子进程剥离调用点无测试:已修复。
在 gemini.test.tsx 中参照现有 ACP 模式 env 测试新增双用例测试:stub NODE_OPTIONS/NODE_PATH,以 acp: true 且设置 QWEN_CODE_NO_RELAUNCH(final-process 路径)运行 main(),断言到 loadCliConfig(relaunch/sandbox 交接后的第一个重量级调用)时 loader 变量已被清除。第二个用例使用非 ACP argv 钉住 isAcpMode 门控(loader 变量保留)。今后删除剥离调用或门控都会使测试失败。

[Suggestion] R1-3(rc:3733638386)—— 两个边界上的剥离静默执行:已修复。
scrubInheritedLoaderEnv 现在返回被删除的键。两个调用点在至少删除了一个键时各输出一条列出这些键的 stderr 日志(qwen serve: scrubbed inherited loader env vars from the daemon process; ... 与 qwen: scrubbed inherited loader env vars from the ACP child process; ...),使用的是两处调用点旁边本就存在的 writeStderrLine 通道。daemon 剥离测试现在断言日志内容;shared-env-keys.test.ts 钉住被删键列表(仅包含实际存在的键,二次剥离返回空)。

[Suggestion] R1-8(rc:3733638389)—— PATH 前缀后续跟踪:已升级处理(本模式下无法完成)。
同意——#8653 遗留的 PATH 前缀部分在本 PR 关闭该 issue 之前需要一个跟踪载体。创建 GitHub issue 和编辑 PR 描述属于 GitHub 写操作,本机器人无法执行(所有网络写操作由 workflow/维护者负责)。该线程的回复中已附上可直接提交的 issue 草稿(标题、正文与待定设计问题)。在 issue 创建并链接到 PR 描述之前,该线程有意保持未解决状态。

评审结论(CHANGES_REQUESTED)——“Integration Tests (CLI, No Sandbox) 在 CI 中被跳过且本地未运行”:已处理。
在 npm run build && npm run bundle 之后本地运行了完全相同的套件:npm run test:integration:cli:sandbox:none —— 31/38 个文件通过,181 个测试通过,18 个跳过,2 个失败。两个失败均经证据调查,确认为本 autofix runner 的环境问题,而非代码缺陷(见 Verification)。

冲突说明

--conflict false —— 未执行合并,也无需合并。

Verification

实际执行的命令及结果:

  • npm run build —— 通过(执行了两次:一次用于修复早于本轮、阻塞 gemini.test.tsx 收集的过期 @qwen-code/web-templates dist,一次在 bundle 之前)。
  • npm run typecheck —— 通过。
  • npm run lint(全仓库,eslint . --ext .ts,.tsx && eslint integration-tests)—— 通过;对所有改动文件执行 npx prettier --check —— 通过。
  • 聚焦 Vitest(packages/cli)—— 全部通过:
    • src/config/environment.test.ts + src/config/shared-env-keys.test.ts —— 12 通过(含新的初始加载回归测试与被删键断言)
    • src/gemini.test.tsx —— 61 通过(含 2 个新的 ACP 交接剥离用例)
    • src/serve/run-qwen-serve.test.ts + src/serve/process-env-guard.test.ts —— 235 通过(daemon 剥离测试现在同时断言日志)
    • 全部 5 个改动测试文件的最终合并运行 —— 308 通过
  • npm run bundle —— 通过。
  • npm run test:integration:cli:sandbox:none —— 181 通过、18 跳过、2 失败;两个失败均有证据表明是本 autofix runner 特有的环境问题:
    • cli/monitor.test.ts > should call monitor tool when asked to watch a command —— 仅在完整并行套件中超时 60 秒(同一次运行中一个相邻测试耗时 572 秒并触发重试);用同一 bundle 单独重跑:2/2 通过,用时 24.7 秒。属资源竞争导致的 flake。
    • cli/qwen-config-dir.test.ts > 1d: CLI functions normally when QWEN_HOME is not set —— EACCES: permission denied, mkdir '/home/github-runner/.qwen';单独重跑复现,runner 本身证实了原因:进程以 uid=1000(node) 运行,而 /home/github-runner 是 drwxr-xr-x root root,因此在未设置 QWEN_HOME 时此处永远无法创建 ~/.qwen。与本 PR 的代码路径无关。
  • 既有失败基线核查:src/config/settings.test.ts + src/config/config.test.ts 在本 runner 环境中有 17 个失败;将四个改动的源文件临时还原到 HEAD 后重跑,得到完全相同的 17 个失败,证明它们是环境依赖的既有问题、并非本轮引入。(文件已从备份恢复并重新验证。)
  • Git:在 fix/daemon-session-loader-env-leak 上追加一个提交 cd3450c653;git status 干净;仅触及预期的 8 个文件。

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 round summary — PR #8663

Commit: e3cdf99b5f fix(cli): reject loader env keys in serve fast path before env freeze
Conflict: --conflict false — no merge performed.

Feedback points

Review verdict: "Not reviewed: build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally" — addressed

The reviewer could not complete verification because the CLI integration suite never ran. Ran it locally this round: npm run build && npm run bundle && npm run test:integration:cli:sandbox:none — 33 files passed, 5 skipped (gated benchmark/model-credential files), 183 tests passed, 18 skipped, exit 0 (see Verification). The suite includes the qwen-serve-* daemon tests that exercise the exact startup route this round fixes.

R2-1 [Critical] Serve fast path applies loader keys before the daemon env freeze — FIXED

Confirmed: loadServeFastPathEnvironment (packages/cli/src/serve/fast-path-settings.ts) filtered only PROJECT_ENV_HARDCODED_EXCLUSIONS / excludedVars, and it runs on the default qwen serve route (cli.ts → tryRunServeFastPath → bootstrapServeFastPathEnvironment) before runQwenServeImpl freezes daemonRuntimeBaseEnv — so loader keys from the boot workspace's .env, .qwen/.env, or settings.env were baked into the frozen base env. Both application loops now skip INHERITED_LOADER_ENV_KEYS (as a ReadonlySet, mirroring LOADER_ENV_KEYS in environment.ts). Added a fast-path regression test covering all three sources: plain .env, privileged .qwen/.env, and settings.env. The home-env bootstrap (preResolveServeFastPathHomeEnvOverrides) was audited and is not a vector (it only applies HOME_ENV_BOOTSTRAP_KEYS / storage-routing keys).

R2-3 [Suggestion] Rejected .env loader keys dropped silently — IMPLEMENTED

loadEnvironment now collects loader keys found in each parsed .env file and emits one stderr warning per file naming the file and the rejected keys, mirroring the scrub breadcrumbs. Warnings are deduped per file per process (daemon-side loadSettings() re-runs loadEnvironment for every session; repeating the warning would be noise) and the dedupe set is reset by resetEnvironmentTrackingForTesting(). ParsedEnvFile gained a path field to name the file. Test covers the warning text and the once-per-file behavior. The serve fast path intentionally does not duplicate the warning: the same .env files are re-read through the normal loadEnvironment path (daemon-side session loads), where the warning fires.

R2-4 [Suggestion] .qwen/.env privileged scope untested — IMPLEMENTED

Added a sibling regression case in environment.test.ts writing NODE_OPTIONS/NODE_PATH/LD_PRELOAD to <workspace>/.qwen/.env and asserting they stay undefined while a sibling key applies. The exempting mutant described in the finding (!envFile.isQwenScopedEnvFile) now fails the suite. The fast-path regression test also pins the .qwen/.env scope separately for the same reason.

R2-5 [Suggestion] Scrub placement and sandbox stage unpinned in gemini.test.tsx — IMPLEMENTED

Added the two suggested variants:

  • Handoff capture (no QWEN_CODE_NO_RELAUNCH): asserts NODE_OPTIONS/NODE_PATH are still present inside a relaunchAppInChildProcess mock at handoff time — kills the "move scrub above the handoff" mutant, since the respawned child boots with process.env and still needs the loader.
  • SANDBOX stage: stubs SANDBOX='sandbox-exec' with QWEN_CODE_NO_RELAUNCH falsy and asserts the vars are scrubbed by loadCliConfig — kills the "gate the scrub on NO_RELAUNCH" mutant, since sandbox.ts never sets that marker.

R2-6 [Suggestion] Copy-pasted scrub+breadcrumb block — IMPLEMENTED

Added scrubAndReportInheritedLoaderEnv(env, commandLabel, processLabel) in shared-env-keys.ts; both boundaries (gemini.tsx, run-qwen-serve.ts) now call it. The emitted message text is byte-identical to before (the existing run-qwen-serve.test.ts breadcrumb assertions pass unchanged), and shared-env-keys.test.ts pins the exact breadcrumb format and the silent no-op case. The helper returns the removed-key list so R2-7 can persist it.

R2-7 [Suggestion] Scrub breadcrumb never reaches the durable daemon log — IMPLEMENTED

runQwenServeImpl keeps scrubbedLoaderEnvKeys from the helper and, immediately after initDaemonLogger, writes one daemonLog.info entry naming the removed keys (removedKeys=... ctx). The scrub itself stays before the freeze (the freeze-before-scrub ordering is load-bearing, unchanged). New test boots runQwenServe with QWEN_RUNTIME_DIR pointed at a temp dir (same pattern as the daemon logger wiring test) and asserts daemon.log contains the scrub entry and NODE_OPTIONS.

Verification

All commands actually run this round:

  • npm run build — passed (also built packages/channels/base, whose dist/ was absent on this checkout and blocked src/serve test collection — pre-existing state, unrelated to this diff)
  • npm run typecheck — passed
  • npm run lint — passed (repo-wide)
  • npx prettier --check on the 10 touched files — passed (formatting fixed in the new code before commit; no unrelated lines touched)
  • Focused Vitest, packages/cli (CI-equivalent env — see env note below):
    • vitest run src/config/shared-env-keys.test.ts src/config/environment.test.ts src/serve/process-env-guard.test.ts — 19 passed
    • vitest run src/config — 35 files / 1081 tests passed
    • vitest run src/serve src/gemini.test.tsx — 145 files / 4161 tests passed, 1 skipped
  • npm run bundle — produced dist/cli.js
  • npm run test:integration:cli:sandbox:none (the exact CI job named in the review verdict, CI-equivalent env) — 33 files passed | 5 skipped, 183 tests passed | 18 skipped, exit 0

Env note: this autofix runner itself runs inside the project's container sandbox and exports SANDBOX, QWEN_HOME, and QWEN_CODE_CUSTOM_SANDBOX_IMAGE. With those ambient vars present, 17 pre-existing tests in settings.test.ts/config.test.ts fail even without this diff (they assert sandbox-image precedence and home-dir settings paths). They all pass with those vars removed and a writable HOME — the CI condition — so all focused Vitest runs above used that CI-equivalent env. One integration test (prompt latency > p50 / p99 over 20 prompts) passed on its built-in retry (known timing-sensitive); the final result is green.

中文说明

评审轮次总结 — PR #8663

提交:e3cdf99b5f fix(cli): reject loader env keys in serve fast path before env freeze
冲突:--conflict false — 未执行合并。

反馈点

评审判定:"Not reviewed: build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally" — 已处理

评审方无法完成验证,因为 CLI 集成测试套件从未运行。本轮已在本地运行:npm run build && npm run bundle && npm run test:integration:cli:sandbox:none — 33 个文件通过、5 个跳过(受门控的基准/模型凭据文件),183 个测试通过、18 个跳过,退出码 0(见"验证"部分)。该套件包含 qwen-serve-* daemon 测试,恰好覆盖本轮修复的启动路径。

R2-1 [Critical] serve 快速路径在 daemon env 冻结之前应用 loader 键 — 已修复

已确认:loadServeFastPathEnvironment(packages/cli/src/serve/fast-path-settings.ts)只过滤 PROJECT_ENV_HARDCODED_EXCLUSIONS / excludedVars,而它在默认 qwen serve 路径(cli.ts → tryRunServeFastPath → bootstrapServeFastPathEnvironment)上运行,早于 runQwenServeImpl 冻结 daemonRuntimeBaseEnv — 因此启动 workspace 的 .env、.qwen/.env 或 settings.env 中的 loader 键会被冻结进基座 env。两个应用循环现在都跳过 INHERITED_LOADER_ENV_KEYS(以 ReadonlySet 形式,与 environment.ts 中的 LOADER_ENV_KEYS 保持一致)。新增快速路径回归测试,覆盖全部三种来源:普通 .env、特权 .qwen/.env 与 settings.env。家目录 env 引导(preResolveServeFastPathHomeEnvOverrides)已审计,不是泄漏点(它只应用 HOME_ENV_BOOTSTRAP_KEYS / 存储路由键)。

R2-3 [Suggestion] 被拒绝的 .env loader 键被静默丢弃 — 已实现

loadEnvironment 现在会收集每个解析出的 .env 文件中出现的 loader 键,并针对每个文件输出一条 stderr 警告,列出文件路径与被拒键,与剥离日志保持同类。警告按"每进程每文件一次"去重(daemon 侧 loadSettings() 会为每个会话重新执行 loadEnvironment,重复警告只是噪音),去重集合在 resetEnvironmentTrackingForTesting() 中重置。ParsedEnvFile 新增 path 字段以便在警告中指明文件。测试覆盖警告文本与"每文件仅一次"行为。serve 快速路径有意不重复该警告:相同的 .env 文件会经由常规 loadEnvironment 路径(daemon 侧会话加载)再次读取,警告会在那里输出。

R2-4 [Suggestion] .qwen/.env 特权作用域未被测试 — 已实现

在 environment.test.ts 新增兄弟用例:把 NODE_OPTIONS/NODE_PATH/LD_PRELOAD 写入 <workspace>/.qwen/.env,断言它们保持未定义,而同文件的普通键正常生效。评审中描述的豁免突变体(!envFile.isQwenScopedEnvFile)现在会使套件失败。快速路径回归测试出于同样原因也单独钉住了 .qwen/.env 作用域。

R2-5 [Suggestion] gemini.test.tsx 未钉住剥离位置与 sandbox 阶段 — 已实现

新增两个建议的变体:

  • 交接捕获(不设置 QWEN_CODE_NO_RELAUNCH):在 relaunchAppInChildProcess mock 内断言交接时刻 NODE_OPTIONS/NODE_PATH 仍然存在 — 杀死"把剥离移到交接之前"的突变体,因为重启的子进程以 process.env 启动,仍需要 loader。
  • SANDBOX 阶段:stub SANDBOX='sandbox-exec' 且 QWEN_CODE_NO_RELAUNCH 为空值,断言到 loadCliConfig 时变量已被剥离 — 杀死"用 NO_RELAUNCH 门控剥离"的突变体,因为 sandbox.ts 从不设置该标记。

R2-6 [Suggestion] 复制粘贴的剥离+日志块 — 已实现

在 shared-env-keys.ts 新增 scrubAndReportInheritedLoaderEnv(env, commandLabel, processLabel);两个边界(gemini.tsx、run-qwen-serve.ts)都改为调用它。输出文本与之前逐字节一致(run-qwen-serve.test.ts 现有的日志断言原样通过),shared-env-keys.test.ts 钉住确切的日志格式与"无可剥离项时静默"的行为。辅助函数返回被删键列表,供 R2-7 持久化使用。

R2-7 [Suggestion] 剥离日志永远不进入持久 daemon 日志 — 已实现

runQwenServeImpl 保留辅助函数返回的 scrubbedLoaderEnvKeys,并在 initDaemonLogger 之后立即写入一条 daemonLog.info,列出被删键(ctx 为 removedKeys=...)。剥离本身保持在冻结之前的原位置(先冻结后剥离的顺序是承重的,未改动)。新测试将 QWEN_RUNTIME_DIR 指向临时目录启动 runQwenServe(与 daemon logger wiring 测试相同的模式),断言 daemon.log 包含剥离记录与 NODE_OPTIONS。

验证

本轮实际运行的所有命令:

  • npm run build — 通过(同时构建了 packages/channels/base:该包在本次检出中缺少 dist/,会阻断 src/serve 测试收集 — 属既有状态,与本 diff 无关)
  • npm run typecheck — 通过
  • npm run lint — 通过(全仓库)
  • npx prettier --check(10 个改动文件)— 通过(提交前修正了新代码的格式;未触碰无关行)
  • 聚焦 Vitest,packages/cli(CI 等效环境 — 见下方环境说明):
    • vitest run src/config/shared-env-keys.test.ts src/config/environment.test.ts src/serve/process-env-guard.test.ts — 19 通过
    • vitest run src/config — 35 个文件 / 1081 个测试通过
    • vitest run src/serve src/gemini.test.tsx — 145 个文件 / 4161 个测试通过,1 个跳过
  • npm run bundle — 生成 dist/cli.js
  • npm run test:integration:cli:sandbox:none(与评审判定中点名的 CI 作业完全一致,CI 等效环境)— 33 个文件通过 | 5 个跳过,183 个测试通过 | 18 个跳过,退出码 0

环境说明:本 autofix 运行器本身就跑在项目的容器沙箱内,导出了 SANDBOX、QWEN_HOME、QWEN_CODE_CUSTOM_SANDBOX_IMAGE。在这些环境变量存在时,即使没有本 diff,settings.test.ts/config.test.ts 中也有 17 个既有测试会失败(它们断言沙箱镜像优先级与家目录 settings 路径)。移除这些变量并使用可写 HOME(即 CI 的条件)后全部通过,因此上述所有聚焦 Vitest 均在该 CI 等效环境下运行。有一个集成测试(prompt latency > p50 / p99 over 20 prompts)经由内置重试通过(已知的时间敏感测试),最终结果为绿。

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 3/100). What changed, and what I pushed back on: · 已处理最新评审反馈(第 3/100 轮)。改动内容与我反驳保留之处如下:

Review feedback addressed — PR #8663 (round 3)

All 8 findings from round 3 were verified against the code and addressed in one commit (fix(cli): deny npm_config_node_options and report rejected loader keys). No conflicts (--conflict false; no merge performed).

Findings and dispositions

  1. [Critical] R3-1 — loader denylist misses npm_config_node_options (shared-env-keys.ts:52) — Fixed. Verified the key is in none of the consulted lists and that npm applies its node-options config to lifecycle scripts, reopening the Daemon multi-workspace sessions inherit another workspace's harness environment (NODE_OPTIONS/PATH leak) #8653 vector through an adjacent key. Added npm_config_node_options to INHERITED_LOADER_ENV_KEYS, which propagates to every derived gate and scrub: the initial .env load, buildRuntimeEnvironment, reloadEnvironment (via RELOAD_EXCLUDED_KEYS), the serve fast path (both loops), and the daemon/ACP inherited-env scrubs. Updated the pinned sorted list test and extended the scrub test fixture so every key in the list is actually exercised (previously LD_AUDIT, LD_LIBRARY_PATH, DYLD_LIBRARY_PATH were only asserted absent without being present in the fixture).

  2. [Suggestion] R3-3 — warn-once dedupe keyed on file path only (environment.ts:537) — Fixed. The dedupe is now a Map<string, Set<string>> keyed on source + rejected key; a warning fires only on the delta (already-warned keys stay rejected but are not re-reported). Pinned by a new test: a file warned for NODE_OPTIONS that later gains LD_PRELOAD produces a second warning naming only LD_PRELOAD.

  3. [Suggestion] R3-4 — per-process dedupe vs fresh ACP children (environment.ts:53) — Fixed via the comment-correction option the finding itself offers. Cross-process dedupe would require carrying marker state through every ACP spawn to suppress a one-line diagnostic; instead the comment now states the actual semantics (the dedupe is per-process; one ACP child per session starts empty and warns once for itself) so no future maintainer trusts a guarantee the code does not provide. The warning comment now lives with the dedupe state in shared-env-keys.ts.

  4. [Suggestion] R3-5, occurrence 1/3 — fast-path .env loop rejects silently (fast-path-settings.ts:275) — Fixed. Verified the round-2 compensation claim is wrong: every daemon-side loadSettings call in run-qwen-serve.ts (and across src/serve/) passes skipLoadEnvironment: true, so a boot-workspace loader key was never reported anywhere. Added a shared reject-and-report helper reportRejectedLoaderKeys() in shared-env-keys.ts (diagnostics live with the policy) and wired the fast-path .env loop through it with the same warn-once breadcrumb wording as loadEnvironment.

  5. [Suggestion] R3-5, occurrence 2/3 — fast-path settings.env loop rejects silently (fast-path-settings.ts:297) — Fixed. Same shared helper, source label settings.env. Covered by a new fast-path test asserting both breadcrumbs.

  6. [Suggestion] R3-5, occurrence 3/3 — reloadEnvironment rejects silently (environment.ts:32) — Fixed. The reload .env loop now collects rejected loader keys and reports through the same helper; the per-source+key dedupe means a key already warned about on the initial load is not re-warned. Pinned by a new test (boot without loader keys, mid-session edit adds NODE_OPTIONS, reload warns). Scope note: the settings.env loops in loadEnvironment/reloadEnvironment remain silent — that rejection predates this PR (RELOAD_EXCLUDED_KEYS already contained the loader keys on main) and the findings did not name those paths.

  7. [Suggestion] R3-6 — docs assert the opposite of the new behavior (environment.ts:541 → docs) — Fixed. docs/users/configuration/settings.md: qualified both "Variables from .qwen/.env files are never excluded" statements (settings table row and the exclusion tip) and added a warning block listing the ten loader-affecting keys that are always rejected from every .env scope and settings.json env, noting the stderr warning and that daemon-hosted sessions deliberately do not inherit these variables.

  8. [Suggestion] R3-7 — home-scoped rejection untested (environment.test.ts:252) — Fixed. Added user-level rejection tests to both environment.test.ts and fast-path.test.ts: with QWEN_HOME pointed at a temp dir, loader keys in <QWEN_HOME>/.env stay rejected while a benign sibling key applies, pinning that a home-scoped exemption mutant cannot ship green. (Implementation detail: the finding sketched writing to <tmpQwenHome>/.qwen/.env, but Storage.getGlobalQwenDir() returns QWEN_HOME itself, so the user-level candidate is <QWEN_HOME>/.env.)

Verification

  • npm run build — passed (exit 0; re-run after final formatting)
  • npm run typecheck — passed (exit 0)
  • npm run lint — passed (exit 0)
  • npx prettier --check on all changed files — passed
  • cd packages/cli && npx vitest run src/config/environment.test.ts src/config/shared-env-keys.test.ts src/serve/fast-path.test.ts src/gemini.test.tsx src/serve/process-env-guard.test.ts — 162 passed (5 files)
  • cd packages/cli && npx vitest run src/serve/run-qwen-serve.test.ts — 233 passed
  • cd packages/cli && npx vitest run src/config/settings.test.ts — 12 failures that reproduce identically on this PR's HEAD without this round's changes (verified by temporarily restoring the HEAD versions of the changed files and re-running): pre-existing on this runner, where the inherited QWEN_HOME env var overrides the mocked homedir those tests assume. Not caused by this change; all other suites covering the changed modules are green.
  • Settings schema regeneration not required (no settings source changed). Integration tests not required (behavior exercised by the focused unit suites above).
中文说明

已处理的评审反馈 — PR #8663(第 3 轮)

第 3 轮的全部 8 条发现均已对照代码核实,并在一个提交中处理完毕(fix(cli): deny npm_config_node_options and report rejected loader keys)。无冲突(--conflict false,未执行 merge)。

发现与处理

  1. [Critical] R3-1 — loader 拒绝列表遗漏 npm_config_node_options(shared-env-keys.ts:52) — 已修复。 已核实该键不在任何一份被查询的名单中,且 npm 会将其 node-options 配置应用到生命周期脚本,从而经由相邻键重新打开 Daemon multi-workspace sessions inherit another workspace's harness environment (NODE_OPTIONS/PATH leak) #8653 向量。已将 npm_config_node_options 加入 INHERITED_LOADER_ENV_KEYS,该改动会传导到所有派生的检查与剥离:初始 .env 加载、buildRuntimeEnvironment、reloadEnvironment(经 RELOAD_EXCLUDED_KEYS)、serve 快速路径(两个循环)、以及 daemon/ACP 继承环境剥离。同步更新了钉住的排序列表测试,并扩充了剥离测试夹具,使列表中的每个键都真实出现在夹具中(此前 LD_AUDIT、LD_LIBRARY_PATH、DYLD_LIBRARY_PATH 仅被断言缺失而从未放入夹具)。

  2. [Suggestion] R3-3 — warn-once 去重仅以文件路径为键(environment.ts:537) — 已修复。 去重现在是按 来源+被拒键 为键的 Map<string, Set<string>>;只对增量发警告(已警告过的键仍被拒绝但不再重复报告)。新增测试钉住该行为:已因 NODE_OPTIONS 警告过的文件之后新增 LD_PRELOAD,会产生第二条仅包含 LD_PRELOAD 的警告。

  3. [Suggestion] R3-4 — 进程内去重 vs 新生的 ACP 子进程(environment.ts:53) — 按发现本身提供的注释修正选项处理。 跨进程去重需要在每次 spawn ACP 子进程时携带标记状态,只为压制一行诊断信息;因此改为修正注释,准确说明实际语义(去重是进程内的;每会话一个的 ACP 子进程以空集合启动并为自己警告一次),避免后续维护者信任代码并未提供的保证。该警告注释现与去重状态一起位于 shared-env-keys.ts。

  4. [Suggestion] R3-5 第 1/3 处 — 快速路径 .env 循环静默拒绝(fast-path-settings.ts:275) — 已修复。 已核实第 2 轮答复中的"补偿"说法不成立:run-qwen-serve.ts(以及整个 src/serve/)中所有 daemon 侧 loadSettings 调用都传 skipLoadEnvironment: true,因此启动 workspace 的 loader 键此前在任何地方都不会被报告。在 shared-env-keys.ts 中新增共享的"拒绝并报告"辅助函数 reportRejectedLoaderKeys()(诊断与策略放在一起),快速路径 .env 循环改用该函数,面包屑措辞与 loadEnvironment 一致。

  5. [Suggestion] R3-5 第 2/3 处 — 快速路径 settings.env 循环静默拒绝(fast-path-settings.ts:297) — 已修复。 使用同一共享辅助函数,来源标签为 settings.env。新增快速路径测试同时断言两条面包屑。

  6. [Suggestion] R3-5 第 3/3 处 — reloadEnvironment 静默拒绝(environment.ts:32) — 已修复。 reload 的 .env 循环现在收集被拒的 loader 键并通过同一辅助函数报告;按 来源+键 的去重保证初始加载已警告过的键不会被重复警告。新增测试钉住该行为(启动时无 loader 键,会话中途编辑加入 NODE_OPTIONS,reload 发出警告)。范围说明:loadEnvironment/reloadEnvironment 的 settings.env 循环保持静默——该拒绝在本 PR 之前即已存在(main 上 RELOAD_EXCLUDED_KEYS 本就包含这些 loader 键),且发现并未点名这些路径。

  7. [Suggestion] R3-6 — 文档断言与新行为相反(environment.ts:541 → docs) — 已修复。 docs/users/configuration/settings.md:修正了两处 "Variables from .qwen/.env files are never excluded" 表述(设置表格行与排除项提示块),并新增警告块,列出十个从所有 .env 作用域与 settings.json env 一律拒绝的 loader 类键,说明会输出 stderr 警告,且 daemon 托管的会话有意不继承这些变量。

  8. [Suggestion] R3-7 — home 作用域拒绝未被测试覆盖(environment.test.ts:252) — 已修复。 在 environment.test.ts 与 fast-path.test.ts 中各新增用户级拒绝测试:把 QWEN_HOME 指向临时目录后,<QWEN_HOME>/.env 中的 loader 键仍被拒绝,而同文件的普通键正常生效,钉住 home 作用域豁免突变体不能绿着上线。(实现细节:发现中写的路径是 <tmpQwenHome>/.qwen/.env,但 Storage.getGlobalQwenDir() 直接返回 QWEN_HOME 本身,因此用户级候选文件是 <QWEN_HOME>/.env。)

验证

  • npm run build — 通过(exit 0;在最终格式化后重新运行)
  • npm run typecheck — 通过(exit 0)
  • npm run lint — 通过(exit 0)
  • 对所有改动文件执行 npx prettier --check — 通过
  • cd packages/cli && npx vitest run src/config/environment.test.ts src/config/shared-env-keys.test.ts src/serve/fast-path.test.ts src/gemini.test.tsx src/serve/process-env-guard.test.ts — 162 个测试通过(5 个文件)
  • cd packages/cli && npx vitest run src/serve/run-qwen-serve.test.ts — 233 个测试通过
  • cd packages/cli && npx vitest run src/config/settings.test.ts — 12 个失败,且在不含本轮改动的本 PR HEAD 上完全相同地复现(通过临时还原改动文件的 HEAD 版本重新运行验证):属于本 runner 上的既有问题——该环境继承的 QWEN_HOME 环境变量覆盖了这些测试假设的 mock homedir。并非本轮改动引入;覆盖改动模块的其他所有测试套件均为绿色。
  • 无需重新生成 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-dev-bot

Copy link
Copy Markdown
Collaborator

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

🤖 Autofix review round — no action needed (round 4/100)

The feedback window since the last evaluation (2026-08-07T12:20:10Z) contains no reviews, no inline comments, and no issue-level comments. The round-3 review findings at that timestamp (1 Critical + 6 Suggestions) were already addressed by the previous round's commit 15e7686 ("deny npm_config_node_options and report rejected loader keys"). The only new item is the cancelled Serve A/B check, which investigation shows is a CI timing/environment artifact, not a code defect:

Why the Serve A/B cancellation is not a code defect

  • The cancelled run covered the current head: it started 13:35:59Z in the same CI batch as every other check for 15e7686, and ended 14:06:21Z — 30m22s, at the workflow's timeout-minutes: 30 cap. The job runs two full npm ci + npm run build cycles (head and merge-base) plus two daemon drives on one self-hosted runner, so it is budget-bound by runner speed, not by the PR.
  • The same workflow completed successfully for e3cdf99 (the posted A/B table on this PR was captured at that head). The delta e3cdf99 → 15e7686 is one extra denylist string, synchronous stderr breadcrumbs, and docs — nothing that can make the A/B job slower or hang it.
  • Code inspection of the full diff: every change is synchronous env-key filtering and logging. There is no async work, no wait loop, and no subprocess-spawn change that could stall daemon startup or POST /session. A startup crash would surface as a fast job failure (the drive script's 30s health timeout), not a 30-minute stall.
  • Every other check in the same batch passed: Test (ubuntu-latest, Node 22.x) (full unit suite at this exact commit), web-shell E2E smoke, coverage, SDK Java, etc.

Local surrogate verification at the current head

  • npm run build && npm run bundle — passed.
  • Focused integration run integration-tests/cli/qwen-serve-routes.test.ts (spawns the real bundled qwen serve daemon with dummy creds and drives the HTTP surface, including session creation) — 35/35 passed; the daemon becomes healthy within ~1s, no hang.
  • Focused unit tests for every file this PR touches (environment, shared-env-keys, gemini, fast-path, run-qwen-serve, process-env-guard) — 395/395 passed.

No code changes were made this round; there are no threads to resolve and no findings to reply to. If the Serve A/B preview is still wanted at the current head, re-running that workflow is sufficient — the workflow's independent CI remains the final verification gate.

中文说明

🤖 Autofix 评审轮次 — 无需处理(第 4/100 轮)

自上次评估(2026-08-07T12:20:10Z)以来的反馈窗口内没有评审、没有行内评论、也没有 Issue 级评论。该时间点的第 3 轮评审发现(1 个 Critical + 6 个 Suggestion)已由上一轮的提交 15e7686("deny npm_config_node_options and report rejected loader keys")处理完毕。唯一的新条目是被取消的 Serve A/B 检查,经调查确认这是 CI 耗时/环境问题,而非代码缺陷:

为什么 Serve A/B 被取消不属于代码缺陷

  • 被取消的那次运行针对的正是当前 head:它于 13:35:59Z 与 15e7686 的其余所有检查同批开始,于 14:06:21Z 结束——历时 30 分 22 秒,恰好触及该 workflow 的 timeout-minutes: 30 上限。该任务需要在一台 self-hosted runner 上执行两次完整的 npm ci + npm run build(head 与 merge-base 各一次)并两次驱动 daemon,因此其耗时受 runner 速度约束,与本 PR 的改动无关。
  • 同一个 workflow 在 e3cdf99 上曾成功完成(本 PR 上已发布的 A/B 对照表就是在该 head 上采集的)。e3cdf99 → 15e7686 的差异仅是新增一个 denylist 字符串、同步的 stderr 提示输出以及文档——不可能让 A/B 任务变慢或挂起。
  • 对完整 diff 的代码审查:所有改动都是同步的 env 键过滤与日志输出,不存在任何异步操作、等待循环或子进程 spawn 的变化,不可能导致 daemon 启动或 POST /session 卡住。若是启动崩溃,会以任务的快速失败呈现(驱动脚本有 30 秒健康检查超时),而不是 30 分钟的停滞。
  • 同批次的其余所有检查均已通过:Test (ubuntu-latest, Node 22.x)(在该提交上运行了完整单元测试套件)、web-shell E2E smoke、覆盖率、SDK Java 等。

在当前 head 上的本地替代验证

  • npm run build && npm run bundle — 通过。
  • 聚焦集成测试 integration-tests/cli/qwen-serve-routes.test.ts(用 dummy 凭据启动真实的打包版 qwen serve daemon 并驱动其 HTTP 接口,含会话创建)——35/35 全部通过;daemon 约 1 秒内恢复健康,无挂起。
  • 对本 PR 涉及的每个文件运行聚焦单元测试(environment、shared-env-keys、gemini、fast-path、run-qwen-serve、process-env-guard)——395/395 全部通过。

本轮未做任何代码改动;没有需要解决的评审线程,也没有需要回复的发现。如果仍希望在当前 head 上获得 Serve A/B 预览,重新运行该 workflow 即可——workflow 的独立 CI 仍是最终验证关口。

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

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

Autofix round summary — PR #8663 (review round 4)

Commit: 917fe9243a fix(cli): match loader env keys case-insensitively and report settings.env rejections

All 7 inline findings were resolved in code; the review-level note about never-run integration tests was addressed by actually running the suite.

Feedback dispositions

R4-1 [Critical] Case-sensitive loader-key matching — FIXED

Verified the premise end-to-end on this machine before changing code: npm 10.9.8 applies NPM_CONFIG_NODE_OPTIONS identically to npm_config_node_options — a control npm run executed cleanly, while both variants injected a --require preload into the lifecycle script and crashed with the same MODULE_NOT_FOUND. The old code used exact-case set membership, so uppercase variants passed every gate and scrub while staying loader-effective.

Changes:

  • New shared predicate isLoaderEnvKey() in shared-env-keys.ts matches case-insensitively (lowercased denylist set). Every gate now goes through it: canApplyParsedEnvKey (covers the initial .env load, reload, and buildRuntimeEnvironment file loop), all three settings.env application loops in environment.ts, and both serve fast-path loops.
  • scrubInheritedLoaderEnv() now iterates Object.keys(env) and removes every case variant of every listed key (daemon scrub and ACP-child scrub both inherit the fix via scrubAndReportInheritedLoaderEnv).
  • Regression pins: case-variant scrub test (NPM_CONFIG_NODE_OPTIONS / Node_Options / ld_preload), .env case-variant load + reload test, settings.env case-variant test, NPM_CONFIG_NODE_OPTIONS added to the buildRuntimeEnvironment snapshot test and both fast-path loader tests.

R4-2 [Suggestion] settings.env rejections dropped silently — FIXED

All three settings.env application paths in environment.ts (loadEnvironment step 2, reloadEnvironment, and buildRuntimeEnvironment) now gate loader keys with isLoaderEnvKey() and call reportRejectedLoaderKeys('settings.env', …) after the loop, mirroring the serve fast path and matching the docs sentence this PR adds. The isLoaderEnvKey() gate also closes a secondary gap the finding implied: case variants such as Node_Options previously slipped past the exact-case RELOAD_EXCLUDED_KEYS check and were applied.

R4-3 [Suggestion] False comment premise in fast-path.test.ts — FIXED

Applied the suggested wording. Verified against the code first: workspace-service/index.ts passes skipLoadEnvironment: skipLoadEnvironment || !workspaceTrusted (false for trusted workspaces), and the skills/providers/voice/features callers gate on trust only — so the daemon-side .env load does re-run for trusted workspaces, exactly as the corrected comment now states.

R4-4 [Suggestion] No direct settings.env loader-rejection tests — FIXED

Added never applies loader-affecting keys from settings.env, including reload: loadEnvironment + reloadEnvironment with NODE_OPTIONS, npm_config_node_options, NPM_CONFIG_NODE_OPTIONS, and a benign key that must still apply; asserts loader keys stay undefined through both passes, the benign key applies, and the new settings.env warning fires once with all rejected keys. The reload assertion covers the probe-verified mutant (deleting the gate from the reload settings.env loop now fails this test).

R4-5 [Suggestion] Duplicate derived set — FIXED

Both local new Set(INHERITED_LOADER_ENV_KEYS) copies (environment.ts, fast-path-settings.ts) are deleted. Deliberate deviation from the sketch: since R4-1 requires case-insensitive matching, shared-env-keys.ts exports the isLoaderEnvKey() predicate (backed by a lowercased set) instead of the raw set, so every consumer is forced through case-insensitive matching rather than re-deriving exact-case .has(key) membership.

R4-6 [Suggestion] collect-then-report boilerplate — FIXED

reportRejectedLoaderKeys(source, candidateKeys) now intersects the candidates with the loader denylist internally (case-insensitively), so every application site reduces to one call passing Object.keys(…); the gates keep doing the rejection. The uneven buildRuntimeEnvironment path now reports too, so matching/reporting semantics are uniform across all .env and settings.env application paths.

R4-7 [Suggestion] Fast-path rejections lost under systemd/desktop launches — FIXED

loadServeFastPathEnvironment() now returns (and stashes) every rejected loader key, and runQwenServeImpl consumes the stash right after initDaemonLogger, persisting rejected loader-affecting env keys during serve fast-path boot to the durable daemon log — mirroring the adjacent scrub entry. A new run-qwen-serve.test.ts test boots a daemon after a fast-path rejection and pins the daemon.log entry. Non-fast-path boots consume an empty stash and log nothing.

Review-level note: integration tests never run — ADDRESSED

The bundled-CLI integration suite was built (npm run bundle) and run locally this round: 182 passed, 18 skipped, 1 failed. The single failure is environment-only and proven unrelated — see below.

Integration test failure diagnosis (environment-only)

cli/qwen-config-dir.test.ts > 1d: CLI functions normally when QWEN_HOME is not set failed with EACCES: permission denied, mkdir '/home/github-runner/.qwen' during output-language file bootstrap.

Evidence:

  • This runner's $HOME (/home/github-runner) is owned by root with mode 755 while tests run as uid 1000; a plain touch in $HOME fails with the same EACCES independent of any code.
  • The runner environment exports a writable QWEN_HOME, and every other integration test inherits it through env: process.env. Test 1d is the only test that deletes QWEN_HOME (that is its purpose — default-behaviour baseline), so it is the only test that falls back to ~/.qwen.
  • The failing path is byte-identical to the base branch: git diff origin/main...HEAD -- packages/cli/src/utils/languageUtils.ts packages/core/src/config/storage.ts is empty, and the gemini.tsx hunks are only the ACP scrub block and its import.
  • Positive proof: re-running just that file with a writable HOME=/tmp/int-home-probe passes 7/7, including test 1d.

Verification

  • npm run build — passed (exit 0)
  • npm run typecheck — passed (exit 0)
  • npm run lint — passed (exit 0)
  • npx prettier --check on all 8 changed files — passed
  • cd packages/cli && npx vitest run src/config/shared-env-keys.test.ts src/config/environment.test.ts — 22 passed
  • cd packages/cli && npx vitest run src/serve/fast-path.test.ts — 77 passed
  • cd packages/cli && npx vitest run src/serve/run-qwen-serve.test.ts — 234 passed
  • cd packages/cli && npx vitest run src/gemini.test.tsx src/serve/process-env-guard.test.ts — 66 passed
  • Final pass on the committed tree (fast-path.test.ts + shared-env-keys.test.ts + environment.test.ts) — 99 passed
  • npm run bundle — passed (exit 0)
  • npm run test:integration:cli:sandbox:none — 182 passed, 18 skipped, 1 failed (the environment-only qwen-config-dir 1d failure diagnosed above)
  • Diagnostic re-run of cli/qwen-config-dir.test.ts with writable HOME — 7 passed (proves the failure is runner permissions, not code)
  • npm case-insensitivity probe for R4-1: control npm run probe clean; NPM_CONFIG_NODE_OPTIONS=--require <missing> and npm_config_node_options=--require <missing> both crash with MODULE_NOT_FOUND (npm 10.9.8)
中文说明

Autofix 本轮总结 — PR #8663(评审第 4 轮)

提交:917fe9243a fix(cli): match loader env keys case-insensitively and report settings.env rejections

7 条行内评审意见全部在代码中解决;评审级别关于"集成测试从未运行"的备注已通过实际运行测试套件解决。

反馈处理

R4-1 [Critical] loader 键按大小写精确匹配 — 已修复

改动前已在本机端到端验证其前提:npm 10.9.8 对 NPM_CONFIG_NODE_OPTIONS 的应用与 npm_config_node_options 完全相同——对照 npm run 干净执行,而两个变体都向生命周期脚本注入了 --require preload 并以相同的 MODULE_NOT_FOUND 崩溃。旧代码使用精确大小写的集合成员判断,因此大写变体能穿过所有门控与剥离且仍具有 loader 效力。

改动:

  • shared-env-keys.ts 新增共享谓词 isLoaderEnvKey(),大小写不敏感匹配(集合由转小写的列表构建)。所有门控改走该谓词:canApplyParsedEnvKey(覆盖初始 .env 加载、reload 与 buildRuntimeEnvironment 的文件循环)、environment.ts 中全部三处 settings.env 应用循环、两条 serve 快速路径循环。
  • scrubInheritedLoaderEnv() 改为遍历 Object.keys(env),删除列表中每个键的所有大小写变体(daemon 剥离与 ACP 子进程剥离都经由 scrubAndReportInheritedLoaderEnv 自动获得该修复)。
  • 回归钉住:大小写变体剥离测试(NPM_CONFIG_NODE_OPTIONS / Node_Options / ld_preload)、.env 大小写变体 加载+reload 测试、settings.env 大小写变体测试,并在 buildRuntimeEnvironment 快照测试与两个快速路径 loader 测试中加入 NPM_CONFIG_NODE_OPTIONS。

R4-2 [Suggestion] settings.env 拒绝被静默丢弃 — 已修复

environment.ts 中全部三处 settings.env 应用路径(loadEnvironment step 2、reloadEnvironment、buildRuntimeEnvironment)现在都用 isLoaderEnvKey() 门控 loader 键,并在循环后调用 reportRejectedLoaderKeys('settings.env', …),与 serve 快速路径一致,也符合本 PR 新增文档的承诺。isLoaderEnvKey() 门控同时堵上了该发现隐含的次生缺口:Node_Options 这类大小写变体此前能穿过精确匹配的 RELOAD_EXCLUDED_KEYS 检查而被应用。

R4-3 [Suggestion] fast-path.test.ts 中注释前提错误 — 已修复

采用建议的措辞。先对照代码核实:workspace-service/index.ts 传 skipLoadEnvironment: skipLoadEnvironment || !workspaceTrusted(受信 workspace 为 false),skills/providers/voice/features 各调用方也只按信任度设门控——因此 daemon 侧的 .env 加载对受信 workspace 确实会重新执行,与更正后的注释一致。

R4-4 [Suggestion] 缺少 settings.env loader 拒绝的直接测试 — 已修复

新增 never applies loader-affecting keys from settings.env, including reload:对 loadEnvironment + reloadEnvironment 传入 NODE_OPTIONS、npm_config_node_options、NPM_CONFIG_NODE_OPTIONS 以及一个必须正常生效的良性键;断言两次处理中 loader 键均保持未定义、良性键生效、新的 settings.env 警告只发出一次且包含全部被拒键。reload 断言正好覆盖探针验证过的突变体(删除 reload settings.env 循环中的门控现在会使该测试失败)。

R4-5 [Suggestion] 重复的派生集合 — 已修复

两处本地 new Set(INHERITED_LOADER_ENV_KEYS) 副本(environment.ts、fast-path-settings.ts)均已删除。与建议草图有一处刻意偏差:由于 R4-1 要求大小写不敏感匹配,shared-env-keys.ts 导出的是 isLoaderEnvKey() 谓词(底层为转小写的集合)而非裸集合,从而强制所有消费方走大小写不敏感匹配,避免再出现精确匹配的 .has(key) 用法。

R4-6 [Suggestion] 先收集再报告的样板代码 — 已修复

reportRejectedLoaderKeys(source, candidateKeys) 现在在内部将候选键与 loader 拒绝列表求交(大小写不敏感),每个应用点简化为一次传 Object.keys(…) 的调用;拒绝仍由各门控完成。语义不均衡的 buildRuntimeEnvironment 路径也补上了报告,使所有 .env 与 settings.env 应用路径的匹配/报告语义一致。

R4-7 [Suggestion] systemd/桌面启动下快速路径拒绝信息丢失 — 已修复

loadServeFastPathEnvironment() 现在返回(并暂存)所有被拒 loader 键,runQwenServeImpl 在 initDaemonLogger 之后立即消费该暂存,将 rejected loader-affecting env keys during serve fast-path boot 写入持久 daemon 日志——与紧邻的剥离日志条目保持一致。run-qwen-serve.test.ts 新增测试:先触发一次快速路径拒绝再启动 daemon,钉住 daemon.log 中的条目。非快速路径启动消费到空列表、不写日志。

评审级别备注:集成测试从未运行 — 已处理

本轮构建(npm run bundle)并实际运行了捆绑 CLI 的集成测试套件:182 通过、18 跳过、1 失败。唯一失败为纯环境问题且已证明与本 PR 无关——见下文。

集成测试失败诊断(纯环境问题)

cli/qwen-config-dir.test.ts > 1d: CLI functions normally when QWEN_HOME is not set 在 output-language 文件初始化时报 EACCES: permission denied, mkdir '/home/github-runner/.qwen'。

证据:

  • 本 runner 的 $HOME(/home/github-runner)属主为 root、权限 755,而测试以 uid 1000 运行;在 $HOME 下一个普通的 touch 也会报同样的 EACCES,与任何代码无关。
  • runner 环境导出了可写的 QWEN_HOME,其余所有集成测试都通过 env: process.env 继承它。测试 1d 是唯一删除 QWEN_HOME 的测试(这正是它的目的——默认行为基线),因此也是唯一回退到 ~/.qwen 的测试。
  • 失败路径与 base 分支逐字节一致:git diff origin/main...HEAD -- packages/cli/src/utils/languageUtils.ts packages/core/src/config/storage.ts 为空;gemini.tsx 的改动块只有 ACP 剥离逻辑及其 import。
  • 正向证明:用可写的 HOME=/tmp/int-home-probe 单独重跑该文件,7/7 全部通过,包括测试 1d。

验证

  • npm run build — 通过(exit 0)
  • npm run typecheck — 通过(exit 0)
  • npm run lint — 通过(exit 0)
  • 对全部 8 个改动文件执行 npx prettier --check — 通过
  • cd packages/cli && npx vitest run src/config/shared-env-keys.test.ts src/config/environment.test.ts — 22 通过
  • cd packages/cli && npx vitest run src/serve/fast-path.test.ts — 77 通过
  • cd packages/cli && npx vitest run src/serve/run-qwen-serve.test.ts — 234 通过
  • cd packages/cli && npx vitest run src/gemini.test.tsx src/serve/process-env-guard.test.ts — 66 通过
  • 提交后树的最终复跑(fast-path.test.ts + shared-env-keys.test.ts + environment.test.ts)— 99 通过
  • npm run bundle — 通过(exit 0)
  • npm run test:integration:cli:sandbox:none — 182 通过、18 跳过、1 失败(即上文诊断的纯环境问题 qwen-config-dir 1d)
  • 用可写 HOME 对 cli/qwen-config-dir.test.ts 的诊断性重跑 — 7 通过(证明失败源于 runner 权限而非代码)
  • R4-1 的 npm 大小写不敏感探针:对照 npm run probe 干净执行;NPM_CONFIG_NODE_OPTIONS=--require <missing> 与 npm_config_node_options=--require <missing> 均以 MODULE_NOT_FOUND 崩溃(npm 10.9.8)

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

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

🤖 Autofix review round — no action needed

The feedback window since the last evaluation (2026-08-07T15:03:12Z) contains no reviews, no inline comments, and no issue-level comments. The round-4 review findings at that timestamp (1 Critical + 6 Suggestions) were addressed by the previous round's commit 917fe9243a ("match loader env keys case-insensitively and report settings.env rejections"). The only new item is the cancelled Serve A/B check on the CI batch for that head, and the evidence shows it is a CI timing/environment artifact, not a code defect.

Why the Serve A/B cancellation is not a code defect

  • The cancelled run (workflow run 31195917734) covered the current head 917fe9243a: it started 16:06:07Z in the same CI batch as every other check for this commit, and ended 16:36:29Z — 30m22s, at the workflow's timeout-minutes: 30 cap. This is the same deterministic signature as the previous cancellation at head 15e76868 (13:35:59Z → 14:06:21Z, also 30m22s). The job runs two full npm ci + npm run build cycles (head and merge-base) plus two daemon drives on one runner, so it is budget-bound by runner speed, not by the PR.
  • The same workflow completed successfully for head e3cdf99 — the posted A/B table on this PR ("✅ No response changes against the PR base across 4 scenario(s)") was captured at that head. The deltas since then are synchronous env-key filtering and logging only: 15e76868 added one denylist string plus stderr breadcrumbs; 917fe9243a switched matching to the case-insensitive isLoaderEnvKey() predicate and added rejection reporting + daemon-log persistence. There is no new async work, no wait loop, and no subprocess-spawn change that could stall daemon startup or make the A/B job slower.
  • Code inspection of the full diff confirms every change is synchronous filtering/reporting. A daemon startup crash or hang would surface as a fast job failure anyway — the drive script's waitForHealth throws after 30s — not a 30-minute stall.
  • Every other check in the same batch passed at this exact head: Test (ubuntu-latest, Node 22.x) (full unit suite), web-shell E2E smoke, Desktop Shell, coverage, SDK Java, and the rest.

Local surrogate verification at the current head (917fe9243a)

  • npm run build and npm run bundle — passed.
  • Focused integration run integration-tests/cli/qwen-serve-routes.test.ts (spawns the real bundled qwen serve daemon with dummy creds and drives the HTTP surface, including session creation) — 35/35 passed in ~12s; the daemon becomes healthy promptly, no hang.
  • Focused unit tests for every file this PR touches (shared-env-keys, environment, fast-path, run-qwen-serve, gemini, process-env-guard) — 399/399 passed.

No code changes were made this round; there are no threads to resolve and no findings to reply to. If the Serve A/B preview is still wanted at the current head, re-running that workflow is sufficient — the workflow's independent CI remains the final verification gate.

中文说明

🤖 Autofix 评审轮次 — 无需处理

自上次评估(2026-08-07T15:03:12Z)以来的反馈窗口内没有评审、没有行内评论、也没有 Issue 级评论。该时间点的第 4 轮评审发现(1 个 Critical + 6 个 Suggestion)已由上一轮的提交 917fe9243a("match loader env keys case-insensitively and report settings.env rejections")处理完毕。唯一的新条目是针对该 head 的 CI 批次中被取消的 Serve A/B 检查,证据表明这是 CI 耗时/环境问题,而非代码缺陷。

为什么 Serve A/B 被取消不属于代码缺陷

  • 被取消的运行(workflow run 31195917734)针对的正是当前 head 917fe9243a:它于 16:06:07Z 与该提交的其余所有检查同批开始,于 16:36:29Z 结束——历时 30 分 22 秒,恰好触及该 workflow 的 timeout-minutes: 30 上限。这与上一次在 head 15e76868 上的取消(13:35:59Z → 14:06:21Z,同样为 30 分 22 秒)是完全相同的确定性特征。该任务需要在一台 runner 上执行两次完整的 npm ci + npm run build(head 与 merge-base 各一次)并两次驱动 daemon,因此其耗时受 runner 速度约束,与本 PR 的改动无关。
  • 同一个 workflow 在 head e3cdf99 上曾成功完成——本 PR 上已发布的 A/B 对照表("✅ No response changes against the PR base across 4 scenario(s)")就是在该 head 上采集的。此后的差异仅为同步的 env 键过滤与日志输出:15e76868 新增了一个 denylist 字符串及 stderr 提示输出;917fe9243a 将匹配改为大小写不敏感的 isLoaderEnvKey() 谓词并补充了拒绝报告与 daemon 日志持久化。不存在任何新的异步操作、等待循环或子进程 spawn 的变化,不可能导致 daemon 启动卡住或使 A/B 任务变慢。
  • 对完整 diff 的代码审查确认所有改动都是同步的过滤/报告逻辑。即便如此,daemon 启动崩溃或挂起也只会表现为任务的快速失败——驱动脚本的 waitForHealth 在 30 秒后即抛出异常——而不是 30 分钟的停滞。
  • 同批次的其余所有检查在该 head 上均已通过:Test (ubuntu-latest, Node 22.x)(完整单元测试套件)、web-shell E2E smoke、Desktop Shell、覆盖率、SDK Java 等。

在当前 head(917fe9243a)上的本地替代验证

  • npm run build 与 npm run bundle — 通过。
  • 聚焦集成测试 integration-tests/cli/qwen-serve-routes.test.ts(用 dummy 凭据启动真实的打包版 qwen serve daemon 并驱动其 HTTP 接口,含会话创建)——35/35 全部通过,耗时约 12 秒;daemon 迅速恢复健康,无挂起。
  • 对本 PR 涉及的每个文件运行聚焦单元测试(shared-env-keys、environment、fast-path、run-qwen-serve、gemini、process-env-guard)——399/399 全部通过。

本轮未做任何代码改动;没有需要解决的评审线程,也没有需要回复的发现。如果仍希望在当前 head 上获得 Serve A/B 预览,重新运行该 workflow 即可——workflow 的独立 CI 仍是最终验证关口。

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


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

…mon workers

npm maps non-leading underscores in npm_config_* keys onto hyphens, so
npm_config_node-options injected NODE_OPTIONS exactly like
npm_config_node_options while slipping past every loader gate and scrub.
Canonicalize case and underscore/hyphen spelling on both sides of the
loader-key membership test, covering .env loads, settings.env
application, the serve fast path, and the inherited scrubs.

Channel daemon workers are spawned with the daemon's pre-scrub base env
but are not ACP children, so they never ran the self-scrub; mirror the
ACP-child scrub at the worker entry so nothing a worker spawns inherits
loader vars into another workspace.

Scope the settings.env rejection warning per workspace so a
multi-workspace daemon reports every workspace's rejection instead of
deduping them all under one label, revert the unread
loadServeFastPathEnvironment return value to void, and pin the
buildRuntimeEnvironment settings.env gate and the consume-once stash
reset with discriminating tests.

Co-authored-by: Qwen-Coder <[email protected]>
@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 addressed — round 6 (PR #8663)

Commit: a9f2afd904 on fix/daemon-session-loader-env-leak (9 files, +166/−19). No base merge performed (--conflict false).

Findings and decisions

Finding Severity Decision Summary
R5-1 (isLoaderEnvKey misses npm hyphen spelling) Critical Fixed Canonicalize case and underscore↔hyphen on both sides of the loader-key membership test (key.toLowerCase().replace(/_/gu, '-')), so npm_config_node-options is rejected by every gate and scrub. Regression tests added for the predicate, the inherited scrubs, .env loads, and settings.env on the full loader and the serve fast path (all spelling/case variants).
R5-2 (channel daemon workers keep loader vars) Suggestion Fixed Channel daemon workers are spawned with the daemon's pre-scrub base env and are not ACP children, so the gemini.tsx self-scrub never ran there. Added the same scrubAndReportInheritedLoaderEnv self-scrub at the daemon-worker entry (after the daemon-connection env scrub, before anything is spawned), mirroring the ACP-child composition. Test added.
R5-3 (warn-once dedupe hides later workspaces) Suggestion Fixed All four settings.env rejection sites now label the source with the workspace directory (settings.env (<dir>)), so a multi-workspace daemon warns once per workspace instead of silently rejecting every workspace after the first. Docs updated to state the actual warn-once semantics. Protection was never affected — this was diagnostics only.
R5-4 (dead readonly string[] return) Suggestion Fixed Reverted loadServeFastPathEnvironment to void; the module stash + consumeServeFastPathRejectedLoaderKeys() remains the single channel to the daemon log.
R5-5 (three loader-key denylists diverged) Suggestion Declined Consolidating means changing SECURITY_SENSITIVE_ENV_KEYS in packages/core/src/lsp/LspServerManager.ts and DENY_ENV_KEYS in packages/core/src/providers/install.ts — a cross-package core refactor of LSP-server env construction and install-plan contracts, out of scope for this #8653 security fix. The paths named are workspace-scoped (a workspace's own .lsp.json env), and loader keys written into settings.json env.* are rejected at apply time by the gate this PR adds. Recommended as a follow-up (single canonical set in core); see the thread reply.
R5-7 (post-init rejections not in daemon.log) Suggestion Deferred Requires a pluggable daemon-log sink installed after initDaemonLogger and cleared on daemon shutdown (embedded daemons in tests would otherwise leak the sink across runs) — lifecycle plumbing beyond this round's minimal diff. Boot-time scrub decisions and fast-path rejections are persisted; later rejections still warn on stderr. Recommended as a follow-up; see the thread reply.
R5-8 (buildRuntimeEnvironment gate undiscriminated) Suggestion Fixed Added the case variant NPM_CONFIG_NODE_OPTIONS to the buildRuntimeEnvironment settings.env fixture (exact-case RELOAD_EXCLUDED_KEYS misses it, so only the new gate rejects it). Mutation check: deleting only if (isLoaderEnvKey(key)) continue; now fails the test (verified locally, then restored).
R5-11 (consume-once reset untested) Suggestion Fixed New test primes the fast path with NODE_OPTIONS, calls consumeServeFastPathRejectedLoaderKeys() twice, and asserts the first consume returns the keys while the second returns []. Mutation check: deleting the = [] reset now fails the test (verified locally, then restored).

Review-level CHANGES_REQUESTED ("Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally"): the suite now ran locally against the freshly bundled CLI — see Verification. First run showed exactly one failure, proven environmental (the runner's HOME=/home/github-runner is root-owned and not writable by the test user uid=1000(node), so CLI boot's mkdir /home/github-runner/.qwen fails with EACCES in writeOutputLanguageFile — a code path this PR does not touch). With a writable HOME the previously failing file passes 7/7 and the entire suite is green.

Changed files

  • packages/cli/src/config/shared-env-keys.ts — canonical loader-key predicate (case + underscore/hyphen)
  • packages/cli/src/config/environment.ts — per-workspace settings.env rejection labels (3 sites)
  • packages/cli/src/serve/fast-path-settings.ts — void return; per-workspace label
  • packages/cli/src/commands/channel/daemon-worker.ts — inherited loader env self-scrub at worker entry
  • docs/users/configuration/settings.md — accurate warn-once wording
  • Tests: shared-env-keys.test.ts, environment.test.ts, fast-path.test.ts, daemon-worker.test.ts

Verification

  • npm run build — passed
  • npm run typecheck — passed
  • npm run lint — passed
  • npx prettier --check (all changed files) — passed (after formatting the new test)
  • Focused Vitest (all touched packages/cli files: shared-env-keys.test.ts, environment.test.ts, fast-path.test.ts, daemon-worker.test.ts, run-qwen-serve.test.ts, gemini.test.tsx, process-env-guard.test.ts) — 480 passed
  • Mutation probes — removing the buildRuntimeEnvironment loader gate fails environment.test.ts; removing the consume-once reset fails fast-path.test.ts; both restored and green again
  • npm run bundle — passed
  • npm run test:integration:cli:sandbox:none (after bundle) — 32 files passed, 1 file failed on EACCES: permission denied, mkdir '/home/github-runner/.qwen' (environmental: HOME root-owned, test user node cannot write; failing stack writeOutputLanguageFile is untouched by this PR)
  • Same suite with writable HOME=/home/node — 33 files passed | 5 skipped, 183 tests passed | 18 skipped, exit 0 (including the previously failing cli/qwen-config-dir.test.ts, 7/7)
中文说明

已处理的评审反馈 — 第 6 轮(PR #8663)

提交:fix/daemon-session-loader-env-leak 分支上的 a9f2afd904(9 个文件,+166/−19)。未执行 base 合并(--conflict false)。

各条发现与决定

发现 严重级别 决定 摘要
R5-1(isLoaderEnvKey 漏掉 npm 连字符拼写) Critical 已修复 在 loader 键成员判断的两侧同时对大小写与下划线↔连字符做规范化(key.toLowerCase().replace(/_/gu, '-')),使 npm_config_node-options 被所有门控与剥离拒绝。为谓词、继承剥离、.env 加载以及完整 loader 与 serve 快速路径上的 settings.env 新增了回归测试(覆盖所有拼写/大小写变体)。
R5-2(channel daemon worker 保留 loader 变量) Suggestion 已修复 channel daemon worker 以 daemon 剥离前的基础环境派生,且不是 ACP 子进程,因此 gemini.tsx 的自我剥离从不在其中运行。在 daemon-worker 入口处(daemon 连接环境变量剥离之后、派生任何进程之前)加入同样的 scrubAndReportInheritedLoaderEnv 自我剥离,与 ACP 子进程的做法保持一致。已新增测试。
R5-3(warn-once 去重遮蔽后续 workspace) Suggestion 已修复 四处 settings.env 拒绝点现在都在来源标签中带上 workspace 目录(settings.env (<dir>)),多 workspace daemon 会对每个 workspace 各警告一次,而不是在第一个之后静默拒绝其余所有 workspace。文档已更新为准确的 warn-once 表述。防护本身从未受影响——这只是诊断问题。
R5-4(无读取方的 readonly string[] 返回值) Suggestion 已修复 loadServeFastPathEnvironment 恢复为 void;模块暂存 + consumeServeFastPathRejectedLoaderKeys() 仍是通向 daemon 日志的唯一通道。
R5-5(三份 loader 键拒绝列表发生漂移) Suggestion 不予采纳 整合意味着修改 packages/core/src/lsp/LspServerManager.ts 的 SECURITY_SENSITIVE_ENV_KEYS 与 packages/core/src/providers/install.ts 的 DENY_ENV_KEYS——这是对 core 中 LSP 服务器进程环境构造与安装计划契约的跨包重构,超出本 #8653 安全修复的范围。所指出的路径属于 workspace 自身作用域(workspace 自己的 .lsp.json env),而写入 settings.json env.* 的 loader 键会被本 PR 新增的应用时门控拒绝。建议作为 follow-up(在 core 建立单一规范集合);详见该条线回复。
R5-7(初始化之后的拒绝未进入 daemon.log) Suggestion 暂缓 需要一个在 initDaemonLogger 之后安装、并在 daemon 关闭时清除的可插拔日志汇点(否则测试中的嵌入式 daemon 会在多次运行之间泄漏该汇点)——超出本轮最小 diff 的生命周期管道。启动期剥离决策与快速路径拒绝已被持久化;之后的拒绝仍会在 stderr 上告警。建议作为 follow-up;详见该条线回复。
R5-8(buildRuntimeEnvironment 门控无测试区分) Suggestion 已修复 在 buildRuntimeEnvironment 的 settings.env fixture 中加入大小写变体 NPM_CONFIG_NODE_OPTIONS(精确大小写的 RELOAD_EXCLUDED_KEYS 拦不住它,只有新门控能拒绝)。突变验证:仅删除 if (isLoaderEnvKey(key)) continue; 会使该测试失败(已在本地验证后复原)。
R5-11(consume-once 重置无测试) Suggestion 已修复 新测试先让快速路径拒绝 NODE_OPTIONS,连续调用 consumeServeFastPathRejectedLoaderKeys() 两次,断言第一次返回这些键、第二次返回 []。突变验证:删除 = [] 重置会使该测试失败(已在本地验证后复原)。

评审级 CHANGES_REQUESTED("Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally"):该套件已在本地针对新打包的 CLI 运行——见验证部分。首次运行仅有一处失败,已证明为环境问题(runner 的 HOME=/home/github-runner 属 root 所有且测试用户 uid=1000(node) 不可写,CLI 启动时 writeOutputLanguageFile 中 mkdir /home/github-runner/.qwen 报 EACCES——该代码路径本 PR 完全未改动)。使用可写的 HOME 后,先前失败的文件 7/7 通过,整个套件全绿。

变更文件

  • packages/cli/src/config/shared-env-keys.ts — 规范化的 loader 键谓词(大小写 + 下划线/连字符)
  • packages/cli/src/config/environment.ts — 按 workspace 细分的 settings.env 拒绝标签(3 处)
  • packages/cli/src/serve/fast-path-settings.ts — void 返回值;按 workspace 的标签
  • packages/cli/src/commands/channel/daemon-worker.ts — worker 入口处的继承 loader 环境自我剥离
  • docs/users/configuration/settings.md — 准确的 warn-once 表述
  • 测试:shared-env-keys.test.ts、environment.test.ts、fast-path.test.ts、daemon-worker.test.ts

验证

  • npm run build — 通过
  • npm run typecheck — 通过
  • npm run lint — 通过
  • npx prettier --check(所有变更文件)— 通过(新测试格式化后)
  • 定向 Vitest(packages/cli 全部涉及文件:shared-env-keys.test.ts、environment.test.ts、fast-path.test.ts、daemon-worker.test.ts、run-qwen-serve.test.ts、gemini.test.tsx、process-env-guard.test.ts)— 480 通过
  • 突变探针 — 删除 buildRuntimeEnvironment 的 loader 门控会使 environment.test.ts 失败;删除 consume-once 重置会使 fast-path.test.ts 失败;均已复原并重新全绿
  • npm run bundle — 通过
  • npm run test:integration:cli:sandbox:none(bundle 之后)— 32 个文件通过,1 个文件因 EACCES: permission denied, mkdir '/home/github-runner/.qwen' 失败(环境问题:HOME 属 root 所有,测试用户 node 不可写;失败堆栈 writeOutputLanguageFile 本 PR 未改动)
  • 同一套件改用可写的 HOME=/home/node — 33 个文件通过 | 5 个跳过,183 个测试通过 | 18 个跳过,exit 0(包括先前失败的 cli/qwen-config-dir.test.ts,7/7)

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

…ader-env-leak

# Conflicts:
#	packages/cli/src/config/shared-env-keys.test.ts
@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 轮)。改动内容与我反驳保留之处如下:

Autofix review round — PR #8663 (address-review)

Feedback points

None this round. The workflow-prepared feedback contained no reviews, no inline comments, no issue-level comments, and no failed or still-red checks newer than the last evaluation.

Work performed: base-conflict resolution (--conflict true)

Merged origin/main (4ec0371e61) into fix/daemon-session-loader-env-leak and resolved the conflicts.

Conflict (1 file): packages/cli/src/config/shared-env-keys.test.ts — both branches edited the import block. Main added HOME_ENV_BOOTSTRAP_KEYS (from #8670's home-env bootstrap split); this PR added vi plus the loader-key symbols (INHERITED_LOADER_ENV_KEYS, isLoaderEnvKey, scrubInheritedLoaderEnv, scrubAndReportInheritedLoaderEnv). The merged file body contains both sides' tests, so the resolution is the union of both import lists; nothing from either side was dropped.

Auto-merged overlap reviewed file by file:

  • shared-env-keys.ts — main's attribution-marker entries in PROJECT_ENV_HARDCODED_EXCLUSIONS and new HOME_ENV_BOOTSTRAP_KEYS compose with this PR's loader-key list, predicate, scrubs, and rejection reporting; all exports the merged tests use exist.
  • environment.ts / fast-path-settings.ts — main switched the home-env bootstrap loop from PROJECT_ENV_HARDCODED_EXCLUSIONS to HOME_ENV_BOOTSTRAP_KEYS; this PR's loader-key gates (isLoaderEnvKey rejections, reportRejectedLoaderKeys) are intact on every application path.
  • fast-path.test.ts — both sides' tests present (main's home-env bootstrap order test at ~L1390, this PR's loader-rejection tests at ~L1712+).
  • daemon-worker.ts — main's observed-contacts list() addition and this PR's worker self-scrub occupy independent regions.
  • docs/users/configuration/settings.md — this PR's loader-rejection warning section preserved alongside main's table edits.

Semantic interaction checked: #8670 stamps QWEN_CODE_SERVE / QWEN_CODE_DESKTOP attribution markers onto daemon-spawned children; this PR's scrubs only remove loader-affecting keys, so the markers survive every scrub boundary and channel attribution is unaffected (confirmed by the passing acp-channel-fallback, channel-worker-supervisor, and spawnChannel suites).

Merge commit: 43a0a73cb3 (parents: a9f2afd904, 4ec0371e61). No source changes beyond the conflict resolution.

Verification

All commands run on the merged tree (43a0a73cb3):

  • npm run build — passed
  • npm run typecheck — passed
  • npm run lint — passed
  • npx vitest run (packages/cli) src/config/shared-env-keys.test.ts src/config/environment.test.ts src/config/acp-channel-fallback.test.ts src/serve/fast-path.test.ts src/serve/run-qwen-serve.test.ts src/commands/channel/daemon-worker.test.ts src/gemini.test.tsx src/serve/process-env-guard.test.ts src/serve/channel-worker-supervisor.test.ts — 571 passed
  • npx vitest run (packages/acp-bridge) src/spawnChannel.test.ts — 34 passed
  • npx vitest run (packages/cli) src/config/config.test.ts src/config/settings.test.ts — 17 failures proven environmental (see below); with the container-only variables removed: 487 passed

Environmental note: this run executes inside the Qwen sandbox container, which sets SANDBOX=qwen-code-0.21.7-1 and QWEN_HOME=<temp home>. 5 config.test.ts sandbox-precedence tests fail because getSandboxCommand() short-circuits to "already sandboxed" when SANDBOX is set; 12 settings.test.ts home-scope tests fail because USER_SETTINGS_PATH is snapshotted at module load while the real QWEN_HOME is set. Both test files and the code they exercise (config.ts, settings.ts, sandboxConfig.ts) are byte-identical to origin/main (verified with git diff), and all 487 tests pass under env -u SANDBOX -u QWEN_HOME — a container artifact, not a regression from this PR or the merge. CI runners do not set these variables.

No integration-test run: the touched behavior (loader-env rejection/scrubbing) is exercised by the unit suites above, not only through the bundled CLI or integration harness.

中文说明

Autofix 审查轮次 — PR #8663(address-review)

反馈点

本轮无反馈。工作流准备的反馈文件中,在上次评估之后没有新的审查、行内评论、issue 级评论,也没有失败或仍然标红的检查。

已完成工作:base 冲突解决(--conflict true)

将 origin/main(4ec0371e61)合并进 fix/daemon-session-loader-env-leak 并解决了冲突。

冲突(1 个文件): packages/cli/src/config/shared-env-keys.test.ts — 两个分支都修改了 import 块。main 增加了 HOME_ENV_BOOTSTRAP_KEYS(来自 #8670 的 home-env bootstrap 拆分);本 PR 增加了 vi 以及 loader-key 相关符号(INHERITED_LOADER_ENV_KEYS、isLoaderEnvKey、scrubInheritedLoaderEnv、scrubAndReportInheritedLoaderEnv)。合并后的文件正文同时包含两侧的测试,因此解决方案是取两个 import 列表的并集;两侧内容均未丢弃。

逐文件审查了自动合并的重叠部分:

  • shared-env-keys.ts — main 在 PROJECT_ENV_HARDCODED_EXCLUSIONS 中新增的 attribution-marker 条目和新的 HOME_ENV_BOOTSTRAP_KEYS,与本 PR 的 loader-key 列表、判定谓词、清理函数和拒绝上报逻辑正确组合;合并后测试用到的所有导出均存在。
  • environment.ts / fast-path-settings.ts — main 将 home-env bootstrap 循环从 PROJECT_ENV_HARDCODED_EXCLUSIONS 切换为 HOME_ENV_BOOTSTRAP_KEYS;本 PR 在所有应用路径上的 loader-key 门禁(isLoaderEnvKey 拒绝、reportRejectedLoaderKeys)保持完整。
  • fast-path.test.ts — 两侧测试均在(main 的 home-env bootstrap 顺序测试约在 L1390,本 PR 的 loader 拒绝测试约在 L1712 之后)。
  • daemon-worker.ts — main 的 observed-contacts list() 新增与本 PR 的 worker 自清理位于互不相关的区域。
  • docs/users/configuration/settings.md — 本 PR 的 loader 拒绝警告章节与 main 的表格修改一并保留。

已核查语义交互: #8670 会为 daemon 派生的子进程打上 QWEN_CODE_SERVE / QWEN_CODE_DESKTOP attribution 标记;本 PR 的清理只移除 loader 相关键,因此这些标记在所有清理边界上都得以保留,channel attribution 不受影响(acp-channel-fallback、channel-worker-supervisor、spawnChannel 测试套件全部通过,已确认)。

合并提交:43a0a73cb3(父提交:a9f2afd904、4ec0371e61)。除冲突解决外没有任何源码改动。

验证

所有命令均在合并后的树(43a0a73cb3)上执行:

  • npm run build — 通过
  • npm run typecheck — 通过
  • npm run lint — 通过
  • npx vitest run(packages/cli)src/config/shared-env-keys.test.ts src/config/environment.test.ts src/config/acp-channel-fallback.test.ts src/serve/fast-path.test.ts src/serve/run-qwen-serve.test.ts src/commands/channel/daemon-worker.test.ts src/gemini.test.tsx src/serve/process-env-guard.test.ts src/serve/channel-worker-supervisor.test.ts — 571 个测试通过
  • npx vitest run(packages/acp-bridge)src/spawnChannel.test.ts — 34 个测试通过
  • npx vitest run(packages/cli)src/config/config.test.ts src/config/settings.test.ts — 17 个失败,已证明为环境因素(见下);去掉容器特有变量后重跑:487 个测试全部通过

环境说明: 本次运行在 Qwen 沙箱容器内部执行,容器设置了 SANDBOX=qwen-code-0.21.7-1 和 QWEN_HOME=<临时 home>。config.test.ts 中 5 个 sandbox 优先级测试失败,是因为 getSandboxCommand() 在设置了 SANDBOX 时直接短路为"已在沙箱内";settings.test.ts 中 12 个 home 作用域测试失败,是因为 USER_SETTINGS_PATH 在模块加载时就被快照,而当时真实的 QWEN_HOME 已设置。这两个测试文件及其被测代码(config.ts、settings.ts、sandboxConfig.ts)与 origin/main 逐字节一致(已用 git diff 验证),且在 env -u SANDBOX -u QWEN_HOME 下全部 487 个测试通过 —— 属于容器环境产物,而非本 PR 或合并引入的回归。CI runner 不设置这些变量。

未运行集成测试:本次触及的行为(loader-env 拒绝/清理)由上述单元测试套件覆盖,并非只能通过打包后的 CLI 或集成测试框架验证。

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

@wenshao wenshao left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Review: loader-env scrub (fix/daemon-session-loader-env-leak)

The core fix is right and the E2E evidence in the PR body is convincing — the daemon/ACP boundaries are the correct places to break the inheritance chain, and deriving RELOAD_EXCLUDED_KEYS from the shared constant removes a real duplication hazard. Findings below are about the edges of the policy, not the mechanism.

Each finding was re-verified against the diff vs merge-base(origin/main, 43a0a73); line references are to the PR head.

P1 (4) — ENV now rejected on the initial .env load (behavior break + per-start stderr noise) · the daemon's own per-workspace .env path rejects silently, contradicting the docs this PR adds · runQwenServe() mutates the host process.env irreversibly despite being an embeddable entry point · LD_LIBRARY_PATH/DYLD_LIBRARY_PATH are search paths, not injection vectors, and the --acp gate scrubs them far outside the daemon.

P2 (4) — docs overclaim vs mcpServers[].env / hooks[].env · missing siblings (ZDOTDIR, DYLD_FALLBACK_*, non-Node runtimes) · fast-path stash overwrites and duplicates · warn-once key mismatch (normalized vs raw .env path).

P3 (3) — writeStderrLine vs writeStderrLineSafe · call sites disagree about who filters · altitude question about sanitizeChildEnv() as the existing choke point.

Comment thread packages/cli/src/config/shared-env-keys.ts Outdated
Comment thread packages/cli/src/config/environment.ts
Comment thread packages/cli/src/serve/run-qwen-serve.ts
Comment thread packages/cli/src/config/shared-env-keys.ts Outdated
Comment thread docs/users/configuration/settings.md Outdated
Comment thread packages/cli/src/serve/fast-path-settings.ts Outdated
Comment thread packages/cli/src/serve/fast-path-settings.ts Outdated
Comment thread packages/cli/src/config/shared-env-keys.ts Outdated
Comment thread packages/cli/src/serve/fast-path-settings.ts Outdated
Comment thread packages/cli/src/gemini.tsx
@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

🤖 AutoFix updated a stale base — the fix did not pass verification, but this PR was behind main, so it merged current main in via update-branch and will retry on the next scan. A stale base (a dependency or symbol main already changed) can fail the build without being the fix's fault; if it still fails once current, it hands off to a human.

What I found before stopping:
Qwen failed during address-review: status 125.

See the Qwen Autofix agent step logs for model/tool output.

Run log: https://github.com/QwenLM/qwen-code/actions/runs/31233855628


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

@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

🔀 Base updated: red check(s) [Test (ubuntu-latest, Node 22.x)] pass on current main — merged current main via update-branch; CI will re-run.

中文说明

🔀 已更新 base:红色检查 [Test (ubuntu-latest, Node 22.x)] 在当前 main 上通过 —— 已通过 update-branch 合入当前 main,CI 将重新运行。

- report rejected loader keys through the daemon log after boot (per-workspace .env loads were silent once boot stderr was gone)

- accumulate serve fast-path rejected keys across loads instead of overwriting, dedupe, and use normalized env file paths for rejection sources

- restore scrubbed inherited loader env vars on embedded runQwenServe close()

- add regression tests for ENV scope coverage, reporter dedupe, fast-path accumulation, and post-boot daemon-log diagnostics

- scope docs: top-level env rejection does not apply to mcpServers[].env / hooks[].env; document serve loader-scrub behavior
Comment thread packages/cli/src/serve/run-qwen-serve.ts Outdated
@wenshao

wenshao commented Aug 8, 2026

Copy link
Copy Markdown
Collaborator Author

@qwen-code /triage

@wenshao

wenshao commented Aug 8, 2026

Copy link
Copy Markdown
Collaborator Author

@qwen-code /resolve

wenshao added 2 commits August 8, 2026 12:32
…ader-env-leak

# Conflicts:
#	packages/cli/src/serve/fast-path-settings.ts
#	packages/cli/src/serve/fast-path.test.ts
…boot env restore (#8663)

Address round-6 review: DEV joins the hardcoded project-env exclusions so a
workspace file cannot disable the daemon's loader-env scrub; the hardcoded
tier is enforced case-insensitively (Windows env lookup is case-insensitive)
via isHardcodedProjectEnvExclusion at every application gate; runQwenServe's
catch restores the scrubbed launch env and detaches the rejection reporter
when startup fails after the scrub. Tests gain the matching regressions,
home-env hermeticity, source-scoped warning filters, and tmpdir cleanup; the
unreachable reload delete-pass loader guard and its vacuous test are removed.
@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

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

Round-6 review feedback — address summary (PR #8663)

Also merged origin/main (required base-conflict resolution). Two conflicts,
both in serve fast-path files, resolved by understanding both sides:

  • fast-path-settings.ts: kept main's shared trust-precedence module
    adoption (CachedTrustRule = TrustPrecedenceRule<string>,
    buildTrustPrecedenceRules / resolveTrustDecision); our loader-key
    gates are elsewhere in the file and auto-merged untouched.
  • fast-path.test.ts: kept our six loader-key regression tests and adopted
    main's renamed trust test ('does not load env from an explicitly
    untrusted nested workspace' — explicit distrust now overrides inherited
    trust per fix(security): honor explicit distrust over inherited trust #8628) with main's expectation. Verified: 84/84 fast-path tests
    green on the merge resolution before making any review fixes.

Feedback dispositions

Finding Severity Decision Change
R6-2 (rc:3740614235) DEV gate spoofable from workspace files Critical Fixed DEV added to PROJECT_ENV_HARDCODED_EXCLUSIONS, so no project .env/settings.env (fast path or full loader) can set it; the serve gate now consults the launch environment only. Regression test boots a real daemon with a workspace .env carrying DEV=true and asserts the session-child sourceEnv has no loader vars. Mutation-verified: removing DEV from the list turns the test red.
R6-3 (rc:3740614236) hardcoded exclusions enforced exact-case Critical Fixed New isHardcodedProjectEnvExclusion(key) backed by a lowercased set; all six PROJECT_ENV_HARDCODED_EXCLUSIONS.includes(key) gates replaced (canApplyParsedEnvKey, buildRuntimeEnvironment, both settings.env reload loops, both fast-path loops). Every RELOAD_EXCLUDED_KEYS check at an application gate is paired with the hardcoded-tier check, so case variants are caught there too. Regression cases for node_extra_ca_certs / qwen_cli_entry / mixed-case variants in .env and settings.env, plus predicate unit tests. Mutation-verified: an exact-case predicate turns the tests red.
R6-1 (rc:3740614238) fast-path loader tests not hermetic to real home env files Suggestion Fixed useTempQwenHome() now redirects HOME/USERPROFILE to the temp home alongside QWEN_HOME (afterEach already restores both), and the accumulation test that called no helper now calls it.
R6-5 (rc:3740614239) environment.test.ts warning counts see real home files Suggestion Fixed All five warning-count filters now also require the chunk to name the test's own source (envPath, or the workspace for the settings.env test) — the least invasive of the two suggested options.
R6-4 (rc:3740614241) scrub/reporter not reverted when startup fails after the scrub Suggestion Fixed DaemonLoggerLifecycleCallbacks gains scrubApplied(restore); the impl registers the close-restore right after the scrub, and runQwenServe's catch detaches the reporter (only when this boot installed it, i.e. the logger was initialized) and restores the launch env before rethrowing. New test forces a reject-after-scrub boot (malformed QWEN_SERVE_PROMPT_DEADLINE_MS) and asserts NODE_OPTIONS is handed back.
R6-6 (rc:3740614242) accumulation test leaks two tmpdirs Suggestion Fixed Both workspaces are rmSync'd in the test's finally, matching the file's cleanup discipline.
R6-7 (rc:3740614243) unreachable delete-pass guard + vacuous test + false comment Suggestion Fixed (reviewer option a) Removed the !isLoaderEnvKey(key) clause and its false-premise comment from the reload delete pass — every lastReloadSnapshot/provenance seed site sits after a gate that rejects loader keys, so the guard defended against an impossible state (Simplicity First: no defense for a condition that cannot occur). The vacuous 'does not delete a shell-exported loader var on reload' test was deleted with it; shell-exported loader vars stay protected by the real invariant (delete pass only touches keys qwen applied/seeded).
R6-8 (rc:3740614245) reporter uninstall in close() untested Suggestion Fixed New test: boot a real daemon, close(), then run loadEnvironment against a workspace .env with NODE_OPTIONS and assert the rejection surfaces on stderr (source-scoped filter).
R6-9 (rc:3740614246) reportedLoaderKeyRejections.clear() not observably tested Suggestion Fixed New test reports the same source+key twice (second silent via dedup), calls resetLoaderKeyRejectionReportingForTesting(), and asserts the same source+key warns again.

Review-level note "Not reviewed: build-and-test — Integration Tests (CLI, No
Sandbox)": this records the reviewer's own incomplete verification, not a
code finding. The changed behavior is exercised directly by the unit suites
(env gates called in-process; run-qwen-serve.test.ts boots real daemon
instances), no integration test covers the serve/env gates, and the
workflow's CI re-runs the integration job on the pushed branch. No settings
source changed, so no settings-schema regeneration was needed.

Verification

Commands actually run and their results:

  • npm run build — passed (exit 0)
  • npm run typecheck — passed (exit 0)
  • npm run lint — passed (exit 0)
  • npx vitest run src/config/shared-env-keys.test.ts src/config/environment.test.ts (packages/cli) — 43 passed
  • npx vitest run src/serve/fast-path.test.ts (packages/cli) — 84 passed
  • npx vitest run src/serve/run-qwen-serve.test.ts (packages/cli) — 239 passed (includes the 3 new tests)
  • Consolidated npx vitest run over the 7 touched/related files (shared-env-keys.test.ts, environment.test.ts, fast-path.test.ts, run-qwen-serve.test.ts, process-env-guard.test.ts, daemon-worker.test.ts, gemini.test.tsx) — 7 files, 521 passed
  • Mutation probes (both reverted afterward): removing 'DEV' from the exclusion list fails the new DEV regression test; making isHardcodedProjectEnvExclusion exact-case fails the case-variant tests — confirming the new tests pin the fixes
  • Integration tests — not run: the touched behavior is not integration-harness-only (see note above)
  • npm run generate:settings-schema — not needed: no settings source changed
中文说明

第 6 轮评审反馈处理总结(PR #8663)

同时合并了 origin/main(必需的基线冲突解决)。两处冲突都在 serve
fast-path 文件中,均在理解双方改动后解决:

  • fast-path-settings.ts:保留 main 侧对共享 trust-precedence 模块的采用
    (CachedTrustRule = TrustPrecedenceRule<string>、
    buildTrustPrecedenceRules / resolveTrustDecision);我们的 loader 键
    门控位于文件其他位置,自动合并且未被改动。
  • fast-path.test.ts:保留我们新增的六个 loader 键回归测试,并采用 main
    侧重命名后的信任测试('does not load env from an explicitly untrusted
    nested workspace'——按 fix(security): honor explicit distrust over inherited trust #8628,显式不信任现在优先于继承的信任)及 main 侧
    断言。已验证:在做任何评审修复之前,合并结果已通过 84/84 个 fast-path 测试。

反馈处理

发现 严重度 决定 改动
R6-2(rc:3740614235)DEV 门控可被 workspace 文件伪造 Critical 已修复 DEV 加入 PROJECT_ENV_HARDCODED_EXCLUSIONS,任何项目 .env/settings.env(fast path 或完整加载器)都无法设置它;serve 门控从此只读取启动环境。回归测试启动真实 daemon,workspace .env 携带 DEV=true,断言会话子进程的 sourceEnv 中无 loader 变量。已做突变验证:从列表中移除 DEV 会使该测试变红。
R6-3(rc:3740614236)硬编码排除项以大小写精确匹配执行 Critical 已修复 新增由转小写集合支撑的 isHardcodedProjectEnvExclusion(key);替换全部六处 PROJECT_ENV_HARDCODED_EXCLUSIONS.includes(key) 门控(canApplyParsedEnvKey、buildRuntimeEnvironment、两处 reload settings.env 循环、两处 fast-path 循环)。每个应用门控处的 RELOAD_EXCLUDED_KEYS 检查都与硬编码层检查成对出现,因此大小写变体同样被拦截。补充了 node_extra_ca_certs / qwen_cli_entry / 混合大小写变体在 .env 与 settings.env 的回归用例,以及谓词单元测试。已做突变验证:大小写精确的谓词会使测试变红。
R6-1(rc:3740614238)fast-path loader 测试对真实 home env 文件不密封 Suggestion 已修复 useTempQwenHome() 现在在重定向 QWEN_HOME 的同时把 HOME/USERPROFILE 重定向到临时 home(afterEach 本就还原两者),原本未调用任何 helper 的累积测试现在也调用它。
R6-5(rc:3740614239)environment.test.ts 警告计数会看到真实 home 文件 Suggestion 已修复 五个警告计数过滤器现在都额外要求输出块包含测试自身的来源(envPath,或 settings.env 测试的 workspace)——这是两个建议选项中侵入最小的一个。
R6-4(rc:3740614241)剥离之后启动失败时 scrub/reporter 不被还原 Suggestion 已修复 DaemonLoggerLifecycleCallbacks 新增 scrubApplied(restore);impl 在 scrub 之后立即注册 close 所用的恢复函数,runQwenServe 的 catch 在重新抛出前解除 reporter(仅当本次启动安装过它,即 logger 已初始化)并还原启动环境。新增测试通过非法 QWEN_SERVE_PROMPT_DEADLINE_MS 强制"剥离后拒绝"的启动失败,断言 NODE_OPTIONS 被交还。
R6-6(rc:3740614242)累积测试泄漏两个临时目录 Suggestion 已修复 两个 workspace 在测试的 finally 中 rmSync,与文件的清理约定一致。
R6-7(rc:3740614243)不可达的删除通道守卫 + 空转测试 + 错误注释 Suggestion 已修复(评审选项 a) 从 reload 删除通道移除 !isLoaderEnvKey(key) 子句及其前提错误的注释——所有 lastReloadSnapshot/provenance 播种点都位于拒绝 loader 键的门控之后,守卫防御的是不可能出现的状态(Simplicity First:不为不可能发生的条件做防御)。声称钉住它的空转测试 'does not delete a shell-exported loader var on reload' 一并删除;shell 导出的 loader 变量仍由真正的不变量保护(删除通道只处理 qwen 应用/播种过的键)。
R6-8(rc:3740614245)close() 中的 reporter 卸载无测试 Suggestion 已修复 新增测试:启动真实 daemon、close(),然后对含 NODE_OPTIONS 的 workspace .env 运行 loadEnvironment,断言拒绝出现在 stderr(过滤器限定到测试自身来源)。
R6-9(rc:3740614246)reportedLoaderKeyRejections.clear() 未被可观测地测试 Suggestion 已修复 新增测试:对同一 来源+键 报告两次(第二次因去重静默),调用 resetLoaderKeyRejectionReportingForTesting(),再断言同一 来源+键 重新触发警告。

评审层面的说明"Not reviewed: build-and-test — Integration Tests (CLI, No
Sandbox)":这是评审器自身验证不完整的记录,不是代码发现。改动的行为由单元
套件直接验证(env 门控以进程内方式调用;run-qwen-serve.test.ts 启动真实
daemon 实例),集成测试中没有覆盖 serve/env 门控的用例,workflow 的 CI 会在
推送后的分支上重新运行集成任务。settings 来源未变更,因此无需重新生成
settings schema。

验证

实际运行的命令及结果:

  • npm run build — 通过(exit 0)
  • npm run typecheck — 通过(exit 0)
  • npm run lint — 通过(exit 0)
  • npx vitest run src/config/shared-env-keys.test.ts src/config/environment.test.ts(packages/cli)— 43 通过
  • npx vitest run src/serve/fast-path.test.ts(packages/cli)— 84 通过
  • npx vitest run src/serve/run-qwen-serve.test.ts(packages/cli)— 239 通过(含 3 个新测试)
  • 对 7 个被改动/相关文件的合并 npx vitest run(shared-env-keys.test.ts、environment.test.ts、fast-path.test.ts、run-qwen-serve.test.ts、process-env-guard.test.ts、daemon-worker.test.ts、gemini.test.tsx)— 7 个文件共 521 通过
  • 突变探针(随后均已还原):从排除列表移除 'DEV' 会使新的 DEV 回归测试失败;把 isHardcodedProjectEnvExclusion 改为大小写精确会使大小写变体测试失败——确认新测试确实钉住了修复
  • 集成测试 — 未运行:被改动的行为并非只能通过集成 harness 验证(见上方说明)
  • npm run generate: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

📊 Takeover milestone — round 10/100, in the current window. Census: 7 pushed fix(es), 3 no-change review(s), 2 timeout(s), 0 rejected attempt(s), 1 other round(s) (crash / model error / gate error / infra), 1 base update(s).

This many rounds deserves a human look. Options: keep going (fine — nothing changes), split or reduce the PR if rounds keep accumulating, or release takeover (remove the autofix/takeover label or comment @qwen-code /takeover stop). Management continues unchanged unless you act.

中文说明

📊 接管里程碑 —— 第 10/100 轮(当前窗口)。统计:推送修复 7 次、审阅无需改动 3 次、超时 2 次、验证拒绝 0 次、其他轮次(崩溃/模型错误/门错误/infra)1 次、base 更新 1 次。

轮次到这个量值得人工看一眼。可选:继续(无需操作);若轮次持续累积,考虑拆分或缩减 PR;或释放接管(移除 autofix/takeover 标签或评论 @qwen-code /takeover stop)。不操作则托管照常继续。

@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

Qwen Code did not run conflict resolution for this request.

PR #8663 does not currently have merge conflicts with main.

@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

No code changes were made this round. The only new feedback is @wenshao's independent E2E verification report, which concludes LGTM and explicitly labels all observations "none are merge blockers".

Disposition of each item:

  • LGTM / E2E verification — no change requested; nothing to do.
  • Observation (a), DEV gate spoofable via a workspace .env — already fixed on the current head. Commit de4044ed59 ("fix(cli): block DEV spoofing, case-insensitive env exclusions, serve boot env restore") adds DEV to the hardcoded project-env exclusions in shared-env-keys.ts, so a workspace file can no longer disable the daemon's loader-env scrub. This landed after the reviewed head (23829a4) the report was built against.
  • Observation (b), PATH prefix residual and (d), LD_LIBRARY_PATH/DYLD_LIBRARY_PATH — documented as out of scope in the PR body and tracked as follow-up work; no change in this PR.
  • Observation (c), npm_config_* scrub affecting npx-launched daemons — informational confirmation of the tradeoff already described in the PR's Risk section; no change requested.

Also noted: Critical-only mode is active for this PR, so the deferred non-Critical feedback listed by the workflow is an audit record and was intentionally not acted on. There are no failed or still-red checks, and no inline review threads to resolve or reply to.

中文说明

Autofix 审查轮次:无需处理

本轮没有做任何代码改动。新增反馈只有 @wenshao 的独立 E2E 验证报告,结论为 LGTM,并且明确标注所有观察项"都不构成合并阻塞"。

各条目的处理如下:

  • LGTM / E2E 验证 —— 没有提出任何改动要求,无需处理。
  • 观察 (a):DEV 门可被 workspace 的 .env 掀开 —— 当前 head 上已修复。提交 de4044ed59("fix(cli): block DEV spoofing, case-insensitive env exclusions, serve boot env restore")已把 DEV 加入 shared-env-keys.ts 中硬编码的项目环境排除清单,workspace 文件无法再关闭 daemon 的 loader 环境剥离。该提交晚于报告所验证的 head(23829a4)落库。
  • 观察 (b):PATH 前缀残留 与 (d):LD_LIBRARY_PATH/DYLD_LIBRARY_PATH —— PR 正文已明确列为超出范围,并作为后续工作跟踪,本 PR 不处理。
  • 观察 (c):npm_config_* 剥离影响以 npx 启动的 daemon —— 属于对 PR 风险章节已描述权衡的信息性确认,未提出改动要求。

另外说明:本 PR 已进入仅处理 Critical 的模式,工作流列出的延后非 Critical 反馈属于审计记录,本轮按规则不做处理。当前没有失败或持续失败的检查,也没有需要解决或回复的行内审查线程。

Deferred non-Critical feedback

Critical-only mode is active after 10 change-producing rounds. The workflow excluded the non-Critical feedback below from this round's actionable sections; the items remain open for human follow-up. Maintainer feedback is deferred only after its author has used 2 regular feedback batches in this window's Critical-only tail; authors at that budget, if any, are named below. (@qwen-code /retry starts a fresh counting window.)

中文说明

完成 10 个产生改动的轮次后进入仅处理 Critical 的模式。本轮可执行区域已排除下方非 Critical 反馈;这些条目保持开放,留待人工跟进。维护者反馈仅在其本人于本窗口 Critical-only 阶段已使用 2 批常规反馈预算后才会延后;达到预算的作者(如有)在下方点名。(评论 @qwen-code /retry 可开启新的计数窗口。)

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


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

wenshao added 2 commits August 8, 2026 22:06
Round-6 follow-up: R6-3 named RELOAD_EXCLUDED_KEYS.has() among the gates a
case variant slips, but the hardcoded-tier fix left the reload-only keys
(QWEN_SERVER_TOKEN, PATH, HOME, TMPDIR, …) on exact-case matching. On
Windows a lowercase twin names the same OS variable, so a mid-session
settings.env/.env edit could still rotate the daemon token or move PATH
through a case respelling. Fold the reload tier the same way and pin it
with a reload-behavior regression test. Also note DEV in the settings.md
exclusion docs.
…meticity

The source-scoped warning filters fixed the warning-count assertions, but
the process.env assertions (e.g. 'never applies entrypoint or trust-anchor
keys') still read state a real home .env can pollute: home scope
deliberately bypasses the hardcoded exclusions, so a dev machine with
QWEN_CLI_ENTRY in ~/.env applies it and fails the test while CI stays
green. Redirect HOME/USERPROFILE to an empty temp dir in beforeEach —
verified by running the suite with HOME pointed at a poisoned home.
@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

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

Autofix round summary — no action required (PR #8663)

What this round received

  • Nine inline comments from maintainer @wenshao (nine COMMENTED reviews, 2026-08-08 14:13–14:14 UTC). Each one is a fix confirmation ("Fixed in …") replying on one of the nine R6 threads (R6-1…R6-9, two of them Critical) that the automated reviewer raised in its 2026-08-08 11:52 UTC CHANGES_REQUESTED review. None of them reports a new defect or asks for a change.
  • No failed checks, no still-red checks, and no issue-level comments. Critical-only mode is active; the deferred non-Critical feedback section is an empty audit record.

What was verified

Each maintainer confirmation was checked against the exact code at HEAD (97dedd108c). All nine fixes are present, landed by commits already on this branch (de4044ed59, 3c80df6ad0, 97dedd108c):

  • R6-2 (Critical) — DEV spoofing (rc:3740834136): 'DEV' is in PROJECT_ENV_HARDCODED_EXCLUSIONS (shared-env-keys.ts:56); the dev-harness gate (run-qwen-serve.ts:2123) consults the launch environment only, as its comment states; pinned by 'scrubs loader vars even when a workspace .env sets DEV=true' (run-qwen-serve.test.ts:7347) and 'excludes DEV so a project .env cannot spoof the dev harness' (shared-env-keys.test.ts:67).
  • R6-3 (Critical) — case-sensitive exclusions (rc:3740834228): the hardcoded tier matches through the case-folded isHardcodedProjectEnvExclusion (shared-env-keys.ts:67) at every application gate — both fast-path loops (fast-path-settings.ts:280, 305), canApplyParsedEnvKey (environment.ts:407), and all three settings.env loops (environment.ts:480, 568, 653); the reload tier case-folds via isReloadExcludedKey / RELOAD_EXCLUDED_KEYS_CASEFOLDED (environment.ts:58–63), applied at 406/479/565/652/690. Regression tests present at shared-env-keys.test.ts:87, environment.test.ts:672, environment.test.ts:707, fast-path.test.ts:1858.
  • R6-1 — fast-path test hermeticity (rc:3740834310): useTempQwenHome() redirects HOME/USERPROFILE (fast-path.test.ts:194–203, restored in afterEach), and the accumulation test calls it (line 1990).
  • R6-5 — environment.test.ts hermeticity (rc:3740834392): warning filters are scoped per source via chunk.includes(envPath) (lines 367, 409, 451, 764) and HOME/USERPROFILE are redirected in beforeEach (lines 84–94).
  • R6-4 — startup-failure env restore (rc:3740834488): the scrubApplied lifecycle callback hands the restore closure to the wrapper (run-qwen-serve.ts:1964, 2039–2041, 2144); the wrapper's catch detaches the reporter and restores the launch environment before rethrowing (2043–2061); pinned by 'restores the launch environment when startup fails after the scrub' (run-qwen-serve.test.ts:7632).
  • R6-6 — accumulation test cleanup (rc:3740834568): both temp workspaces are rmSync'd in the test's finally (fast-path.test.ts:2021–2022).
  • R6-7 — unreachable delete-pass guard (rc:3740834648): the !isLoaderEnvKey(key) delete-pass guard and the vacuous 'does not delete a shell-exported loader var on reload' test are both gone; no such guard remains in environment.ts.
  • R6-8 — close-path reporter uninstall test (rc:3740834698): 'falls back to stderr for loader key rejections after close' exists (run-qwen-serve.test.ts:7567).
  • R6-9 — reset-reporting test efficacy (rc:3740834795): 'warns again for an already-reported source and key after the reset' exists (shared-env-keys.test.ts:296) and exercises resetLoaderKeyRejectionReportingForTesting() (shared-env-keys.ts:247).

Outcome

Nothing to change this round: no new findings, no failed checks, and every confirmation matches the code at HEAD. No commit was made; the branch stays at 97dedd108c.

Verification

  • Code inspection of every cited file/line at HEAD 97dedd108c (fixes and their named regression tests all present).
  • npx vitest run src/config/shared-env-keys.test.ts src/config/environment.test.ts (in packages/cli) — 44 passed (21 + 23), covering the R6-2, R6-3, and R6-9 behaviors.
  • The serve-side tests (R6-4, R6-8, R6-2 fast-path pinning) were verified present at HEAD by inspection; they were executed in the round that landed the fixes, and no code changed since.
  • git status --porcelain — clean; HEAD unchanged (97dedd108c).
中文说明

Autofix 轮次总结 — 本轮无需任何改动(PR #8663)

本轮收到的内容

  • 维护者 @wenshao 的 9 条行内评论(9 个 COMMENTED 评审,2026-08-08 14:13–14:14 UTC)。每条都是对九个 R6 线程(R6-1…R6-9,其中两条为 Critical)之一的修复确认("Fixed in …")回复;这些 R6 发现是自动审查器在 2026-08-08 11:52 UTC 的 CHANGES_REQUESTED 评审中提出的。没有任何一条报告新缺陷或要求改动。
  • 没有失败的检查,没有持续失败的检查,也没有 issue 级评论。当前处于仅处理 Critical 的模式;被延后的非 Critical 反馈部分为空(仅为审计记录)。

已核实的内容

每条维护者确认都对照 HEAD(97dedd108c)上的确切代码逐一核实。九项修复全部存在,均由本分支上已有的提交落地(de4044ed59、3c80df6ad0、97dedd108c):

  • R6-2(Critical)— DEV 伪造(rc:3740834136):'DEV' 已在 PROJECT_ENV_HARDCODED_EXCLUSIONS 中(shared-env-keys.ts:56);dev-harness 门(run-qwen-serve.ts:2123)仅查询启动环境,与其注释一致;由 'scrubs loader vars even when a workspace .env sets DEV=true'(run-qwen-serve.test.ts:7347)和 'excludes DEV so a project .env cannot spoof the dev harness'(shared-env-keys.test.ts:67)钉住。
  • R6-3(Critical)— 大小写敏感的排除项(rc:3740834228):硬编码层在每个应用门都通过大小写折叠的 isHardcodedProjectEnvExclusion(shared-env-keys.ts:67)匹配 —— 两个 fast-path 循环(fast-path-settings.ts:280、305)、canApplyParsedEnvKey(environment.ts:407)以及全部三个 settings.env 循环(environment.ts:480、568、653);reload 层通过 isReloadExcludedKey / RELOAD_EXCLUDED_KEYS_CASEFOLDED(environment.ts:58–63)做大小写折叠,应用于 406/479/565/652/690。回归测试位于 shared-env-keys.test.ts:87、environment.test.ts:672、environment.test.ts:707、fast-path.test.ts:1858。
  • R6-1 — fast-path 测试密封性(rc:3740834310):useTempQwenHome() 重定向 HOME/USERPROFILE(fast-path.test.ts:194–203,afterEach 中恢复),且累积测试调用了它(第 1990 行)。
  • R6-5 — environment.test.ts 密封性(rc:3740834392):警告过滤器通过 chunk.includes(envPath) 按来源限定范围(第 367、409、451、764 行),且 beforeEach 中重定向了 HOME/USERPROFILE(第 84–94 行)。
  • R6-4 — 启动失败时的环境恢复(rc:3740834488):scrubApplied 生命周期回调把恢复闭包交给包装函数(run-qwen-serve.ts:1964、2039–2041、2144);包装函数的 catch 分离 reporter 并在重新抛出前恢复启动环境(2043–2061);由 'restores the launch environment when startup fails after the scrub'(run-qwen-serve.test.ts:7632)钉住。
  • R6-6 — 累积测试清理(rc:3740834568):两个临时工作区都在测试的 finally 中被 rmSync(fast-path.test.ts:2021–2022)。
  • R6-7 — 不可达的删除守卫(rc:3740834648):!isLoaderEnvKey(key) 删除守卫和空洞的 'does not delete a shell-exported loader var on reload' 测试均已移除;environment.ts 中不再存在此类守卫。
  • R6-8 — close 路径 reporter 卸载测试(rc:3740834698):'falls back to stderr for loader key rejections after close' 存在(run-qwen-serve.test.ts:7567)。
  • R6-9 — reset 报告测试有效性(rc:3740834795):'warns again for an already-reported source and key after the reset' 存在(shared-env-keys.test.ts:296),并实际调用 resetLoaderKeyRejectionReportingForTesting()(shared-env-keys.ts:247)。

结论

本轮无需任何改动:没有新发现,没有失败的检查,每条确认都与 HEAD 上的代码一致。未创建提交;分支保持在 97dedd108c。

验证

  • 在 HEAD 97dedd108c 上对每个被引用的文件/行做代码检查(修复及其命名的回归测试全部存在)。
  • npx vitest run src/config/shared-env-keys.test.ts src/config/environment.test.ts(在 packages/cli 中)— 44 通过(21 + 23),覆盖 R6-2、R6-3、R6-9 的行为。
  • serve 侧测试(R6-4、R6-8、R6-2 的 fast-path 钉住)通过检查确认存在于 HEAD;它们在落地修复的那一轮中已实际运行过,此后代码未变。
  • git status --porcelain — 干净;HEAD 未变(97dedd108c)。

Deferred non-Critical feedback

Critical-only mode is active after 10 change-producing rounds. The workflow excluded the non-Critical feedback below from this round's actionable sections; the items remain open for human follow-up. Maintainer feedback is deferred only after its author has used 2 regular feedback batches in this window's Critical-only tail; authors at that budget, if any, are named below. (@qwen-code /retry starts a fresh counting window.)

中文说明

完成 10 个产生改动的轮次后进入仅处理 Critical 的模式。本轮可执行区域已排除下方非 Critical 反馈;这些条目保持开放,留待人工跟进。维护者反馈仅在其本人于本窗口 Critical-only 阶段已使用 2 批常规反馈预算后才会延后;达到预算的作者(如有)在下方点名。(评论 @qwen-code /retry 可开启新的计数窗口。)

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


🧠 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 — reviewed at 97dedd108c. C=0.

All 68 threads on this PR are marked resolved (7 Critical, 35 Suggestion, 26 untagged), and the standing CHANGES_REQUESTED is qwen-code-ci-bot at 23829a47c4 with five commits landed since — including two that are the fixes for its own last two findings. Nothing is actually outstanding.

I did not read the resolved flags as evidence. The seven Criticals here form an escalating series about denylist completeness, and every one of them is a pure predicate, so I re-derived their exact bypass spellings against the real isLoaderEnvKey / isHardcodedProjectEnvExclusion.

Critical audit — 7/7, probed at the exact spellings

Thread Verdict at 97dedd108c
R1-1 initial (non-reload) .env path re-populates loader keys fixed — canApplyParsedEnvKey rejects loader keys unconditionally, not just under reload
R2-1 loadServeFastPathEnvironment bypasses the loader check on the default serve route fixed — both application loops now gate on isLoaderEnvKey before the env freeze
R3-1 npm_config_node_options absent from every list fixed — probed true
R4-1 case-sensitive matching (NPM_CONFIG_NODE_OPTIONS) fixed — probed true for upper, lower and Npm_Config_Node_Options
R5-1 npm underscore↔hyphen equivalence (npm_config_node-options) fixed — probed true, including NPM_CONFIG_NODE-OPTIONS
R6-2 DEV spoofable from a project .env fixed — DEV is now a hardcoded project-env exclusion
R6-3 hardcoded tier matched exact-case (Windows case-insensitivity) fixed — probed true for DEV/dev/Dev/dEv

0 mismatches across the full sweep: all 11 declared INHERITED_LOADER_ENV_KEYS members in upper/lower/original spelling, plus hyphen variants for all five npm_config_* keys, plus the documented-but-unlisted BASH_FUNC_* prefix rule (BASH_FUNC_foo%%, BASH_FUNC_x(), and case-folded bash_func_foo%% all match, while BASHFUNC_foo correctly does not). Negative controls hold too — PATH, HOME, MY_APP_TOKEN and notably npm_config_registry are not swept up, so the widened matching did not become a blanket npm_config_* strip.

One thing worth recording: my probe initially flagged NODE_REPL_EXTERNAL_MODULE as a miss. That was my error, not a gap — it only affects node's interactive REPL, not node <script> launches or npm run lifecycle scripts, so it is not loader-effective for a daemon that spawns scripts. Its absence from the list is correct.

What makes this reviewable

The denylist carries its rationale inline — why each npm config key is a hijack one level up, why ZDOTDIR is the zsh analogue of BASH_ENV, and why a blanket child-env strip was rejected in favour of per-surface gates (trust-gated overrides that must keep working). It also names a known adjacent gap rather than hiding it: the LSP .lsp.json path keeps its own narrower SECURITY_SENSITIVE_ENV_KEYS that is missing BASH_ENV/ENV/npm_config_node_options, with the deferral justified by that surface being behind --experimental-lsp. That is the right call to defer, and the right way to record it — but it is the obvious follow-up: the two lists should converge before LSP leaves experimental, or the same class reopens through a second door.

Tests

206 pass locally at this commit — daemon-worker 78, fast-path 84, environment 23, shared-env-keys 21 — plus process-env-guard 3. CI is green on this head for web-shell smoke and coverage; review-pr is still running.

Caveat on how I ran them: I overlaid this PR's 16 changed files (plus two dependencies from its newer base, acp-channel-fallback.ts and trust-precedence.ts) onto a working checkout of another branch, because full-tree extraction kept stalling in my environment. All five suites resolved and passed, but that is not byte-identical to a clean checkout of 97dedd108c; CI is the authority for the whole-repo result.

中文说明

批准 —— 审查提交 97dedd108c,C=0。

本 PR 全部 68 条线程均标记为已解决(7 Critical、35 Suggestion、26 无标签);尚存的 CHANGES_REQUESTED 来自 qwen-code-ci-bot 在 23829a47c4,而此后已落地五个提交,其中两个正是针对它最后两条发现的修复。实际没有遗留项。

我没有把 resolved 标记当作证据。这里的七个 Critical 构成一条关于denylist完备性的递进序列,且每一条都是纯谓词,因此我针对真实的 isLoaderEnvKey / isHardcodedProjectEnvExclusion 重新推导了它们的确切绕过拼写。

7/7 全部按确切拼写实测为已修复:R1-1 初始(非 reload).env 路径现无条件拒绝 loader 键;R2-1 serve 快路径两个应用循环均在 env 冻结前加了 isLoaderEnvKey 门;R3-1 npm_config_node_options 实测 true;R4-1 大小写变体(含 Npm_Config_Node_Options)实测 true;R5-1 下划线↔连字符等价(含 NPM_CONFIG_NODE-OPTIONS)实测 true;R6-2 DEV 已纳入硬编码项目级排除;R6-3 硬编码层已大小写折叠(DEV/dev/Dev/dEv 均 true)。

全量扫描 0 处不符:11 个已声明的 INHERITED_LOADER_ENV_KEYS 成员在大写/小写/原拼写下全部命中,五个 npm_config_* 键的连字符变体全部命中,文档中说明但未列出的 BASH_FUNC_* 前缀规则也命中(含大小写折叠),而 BASHFUNC_foo 正确地不命中。反向对照同样成立——PATH、HOME、MY_APP_TOKEN,尤其是 npm_config_registry 不会被误纳,说明放宽匹配没有变成对 npm_config_* 的一刀切剥离。

一处需记录:我的探针最初把 NODE_REPL_EXTERNAL_MODULE 标为漏项。那是我的错误而非缺口——它只影响 node 的交互式 REPL,不影响 node <script> 启动或 npm run 生命周期脚本,对一个派生脚本的 daemon 而言并非 loader-effective。它不在列表中是正确的。

值得称道之处:denylist 内联记录了理由(为何每个 npm config 键是更上一层的劫持、为何 ZDOTDIR 是 BASH_ENV 的 zsh 对应物、为何拒绝一刀切剥离子进程环境而改为按面加门)。它还主动点名了一处已知的邻接缺口:LSP .lsp.json 路径保留自己更窄的 SECURITY_SENSITIVE_ENV_KEYS,缺少 BASH_ENV/ENV/npm_config_node_options,并以该面处于 --experimental-lsp 之后为由说明了延后。延后是对的,记录方式也是对的——但这是显而易见的后续项:两份列表应在 LSP 脱离实验阶段前收敛,否则同类问题会从第二道门重开。

测试:本提交下本地 206 通过(daemon-worker 78、fast-path 84、environment 23、shared-env-keys 21,另 process-env-guard 3);CI 在 web-shell smoke 与覆盖率上已绿,review-pr 仍在运行。

关于运行方式的说明:我的环境下整树解包反复卡死,因此把本 PR 的 16 个改动文件(外加其较新 base 上的两个依赖 acp-channel-fallback.ts、trust-precedence.ts)覆盖到另一分支的可用检出上运行。五个套件均正常解析并通过,但这与 97dedd108c 的干净检出并非逐字节一致;全仓库结果以 CI 为准。

@wenshao

wenshao commented Aug 8, 2026

Copy link
Copy Markdown
Collaborator Author

@qwen-code /triage

@wenshao
wenshao enabled auto-merge August 8, 2026 15:48

@yiliang114 yiliang114 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 — approving at 97dedd108c. The whole Critical series on loader-key denylist completeness (initial .env load path, serve fast path, npm_config_node_options with case and underscore↔hyphen variants, DEV spoofing, Windows case-insensitivity) is closed with mutation-probed regression tests, consistent with @doudouOUC's independent probe sweep at this head. The freeze-before-scrub ordering keeps dev-mode boot intact while every session subprocess comes out clean. Remaining PATH-prefix / INIT_CWD residual is explicitly scoped out and tracked as follow-up — non-blocking.

@yiliang114 yiliang114 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. Verified at head 97dedd1: all nine round-6 findings are fixed — DEV is in the hardcoded exclusions so a workspace .env can no longer spoof the dev gate, every exclusion gate goes through the case-folded check, the scrubbed launch env is restored when startup fails, and the tests redirect HOME/USERPROFILE for hermeticity. I also independently walked the boundaries: daemon process.env + frozen baseEnv, the ACP child after relaunch/sandbox handoff, the channel daemon worker, and every .env/settings.env application path rejecting loader keys; the freeze-before-scrub ordering holds, and the DEV exception only affects child boot — children self-scrub before hosting sessions, so protection composes across the relaunch chain. The key list is pinned by exact-array tests, so a silently shrunk list fails. PATH stays out of scope as stated in Risk & Scope. CI green on this head (mac/windows and integration are skipped for same-repo PRs, consistent across all commits). Nothing blocks merge.

@wenshao
wenshao added this pull request to the merge queue Aug 8, 2026
Merged via the queue into main with commit bb8f2c0 Aug 8, 2026
309 of 318 checks passed
@wenshao

wenshao commented Aug 8, 2026

Copy link
Copy Markdown
Collaborator Author

✅ Verification report (local, isolated container) — merge-ready

44/44 scripted assertions passed, 0 failed; no blocking findings. Advisory evidence for human reviewers — not a review, an approval, or a CI check.

  • Verified head: 97dedd108c30e20493b4bffc4497d6a1a8789955 (fix/daemon-session-loader-env-leak)
  • Base: d91c66119baa17ed3a570c1eb42611db25d0eb0f (= current main, 0 commits of drift)
  • Environment: credential-free Docker container ghcr.io/qwenlm/qwen-code:0.21.3 (Debian 12 bookworm, node v22.23.2) — untrusted PR code never saw host credentials, SSH keys, or the gh token.
中文摘要

结论:merge-ready — 44/44 条脚本化断言全部通过,无阻塞性发现。

  • A/B 核心验证(真实 daemon + 真实 session 子进程,无 mock):从 workspace A 用毒化 loader 环境启动 daemon,在 workspace B 打开会话执行 shell。
    • base 臂(对照,如预期变红):NODE_OPTIONS、NODE_PATH、npm_config_node_options、BASH_ENV、ZDOTDIR 全部泄漏进 ws-B 会话子进程 env;typeof globalThis.gc === 'function';ws-A 的 loader 在 ws-B 目录下执行 6 次——跨 workspace 劫持真实存在。
    • head 臂:会话 env 零泄漏;gc === undefined;loader 在 ws-B 执行 0 次(仅 daemon 启动时在 ws-A 执行 1 次,符合 PR 说明);stderr 有 scrub 记录。
    • head-dotenv 臂:ws-B 的 .env 里的 NODE_OPTIONS 被拒绝(daemon 侧与 ACP 子进程侧都记录到 daemon 日志),良性键 MY_ENV_PROBE 正常生效——.env 应用本身没被破坏。
  • 定向门禁:7 个相关测试文件 522 个测试全部通过。
  • Vacuity(测试非空):删 NODE_OPTIONS 键 → 7 个测试失败;禁用 daemon scrub → 对应测试失败。两个变异均被测试杀死。
  • 未覆盖:DYLD_*(macOS)与 Windows 大小写语义、LD_PRELOAD 真实注入仅由单元测试覆盖;ACP 子进程自剥离在 bundle 模式下是兜底路径(由 gemini 单测覆盖)。

Central claim + A/B

Claim: daemon/ACP-hosted session subprocesses must not inherit loader-affecting env vars (NODE_OPTIONS, npm_config_*, NODE_PATH, LD_PRELOAD, LD_AUDIT, DYLD_INSERT_LIBRARIES, BASH_ENV, ZDOTDIR, BASH_FUNC_*) from the shell that launched qwen serve, across workspace boundaries.

Harness (mock-free): daemon launched from ws-a with a poisoned loader env (NODE_OPTIONS=--import …/ws-a/register.mjs --expose-gc, NODE_PATH, npm_config_node_options, BASH_ENV, ZDOTDIR); ws-b registered as a second workspace; a session pinned to ws-b; POST /session/:id/shell runs pwd, full env, a --expose-gc probe, and a bash probe. A logging loader hook records every execution with process.cwd().

cell build session-env loader keys typeof globalThis.gc ws-a loader runs with cwd=ws-b scrub breadcrumb
head PR head bundle none undefined 0 (only 1 daemon-boot run at cwd=ws-a) present on stderr
base (control) base bundle all 5 leak function 6 (3× LOADER + 3× BASH_ENV, incl. ACP child) absent
head-dotenv head + poisoned ws-b/.env none (.env NODE_OPTIONS rejected too) undefined 0 present + daemon-log rejection entries

Base session env (verbatim): NODE_OPTIONS=--import file://…/ws-a/register.mjs --expose-gc, NODE_PATH=…/ws-a/node_modules, BASH_ENV=…/ws-a/bash-env.sh, ZDOTDIR=…/ws-a/zdotdir, npm_config_node_options=…/ws-a/register-npm.mjs. Head: none present; the benign .env key MY_ENV_PROBE does reach the session env on head-dotenv.

Findings

No blocking or material findings. The central change is load-bearing: base leaks, head scrubs, same harness both sides.

  • Expected (not a defect): the daemon's own boot still runs the loader once (cwd=ws-a) on head — unavoidable before process start, matches the PR's documented behavior. Everything it spawns afterwards is clean.
  • Expected (not a defect): the container's stock env carried NPM_CONFIG_PREFIX=/usr/local/share/npm-global (image npm setup); scrubbed on head per the denylist; inherited by base session subprocesses.
  • Secondary claim verified: ws-b/.env with NODE_OPTIONS is rejected at both sites — daemon per-workspace load and the ACP child's own load — each recorded in the durable daemon log.

Targeted gates (head)

522 tests passed, 0 failed across all 7 changed/related suites: shared-env-keys (in 283), environment (in 283), process-env-guard (in 283), daemon-worker (in 283), fast-path (84), gemini (74), run-qwen-serve (239).

Vacuity (new tests are load-bearing)

mutation expected observed
Remove NODE_OPTIONS from INHERITED_LOADER_ENV_KEYS suite fails 7 failed / 14 passed ✅
Disable the daemon loader-env scrub "scrubs loader env vars…" test fails 1 failed ✅

Not covered

  • macOS/Windows specifics: E2E ran on Linux; DYLD_* and Windows case-insensitivity are unit-pinned only.
  • LD_PRELOAD/LD_AUDIT real injection: not attempted; key list is unit-pinned.
  • ACP-child self-scrub as first defense: in the production bundle E2E the ACP child already receives a scrubbed base env, so its own post-boot scrub is a no-op there (primary in dev mode; covered by gemini.test.tsx).
  • Primary-workspace fast-path .env rejection: E2E poisoned the secondary workspace's .env; fast-path rejection covered by unit tests.
  • Repo-wide suite / lint / typecheck: not run; only the changed-surface suites.

Methodology

PR code ran only inside a credential-free container; metadata resolved outside via read-only gh pr view 8663 --repo QwenLM/qwen-code. Detached worktrees at the resolved base/head OIDs; npm ci (QWEN_SKIP_PREPARE=1) + build + bundle for both arms. Base-tree workspace symlinks asserted to resolve into the base tree; base bundle verified to lack the PR's marker strings while head contains them. Harness e2e/e2e-ab.mjs is rerunnable; raw logs and per-arm observables.json in the run artifacts.

Evidence images

A/B matrix — base leaks loader keys (gc=function, 6 ws-b loader runs), head scrubbed (gc=undefined, 0)

Targeted gates at head — 7 files, 522 tests, 0 failures

Vacuity — both mutations killed by their tests

daemon log — .env NODE_OPTIONS rejected at both application sites

@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 taken

This round triaged the feedback newer than the last evaluation (2026-08-08T14:14:15Z) and found nothing actionable:

  • Reviews: none.
  • Inline comments: none.
  • Issue-level comments: none.
  • Failed checks: none.
  • Still-red checks: none.

Critical-only mode is active for this PR after 10 change-producing rounds. The non-Critical feedback listed in the deferred section (the automated reviewer's PR comment) remains open for human follow-up but is excluded from this round's actionable scope per the workflow's ratchet rule, so no code changes, thread resolutions, or comment replies were made for those items.

No code changes were made and no commits were added; the PR head remains at the previously verified commit.

中文说明

Autofix 审查轮次:无需处理

本轮对上次评估(2026-08-08T14:14:15Z)之后的新反馈进行了分类,未发现任何可处理项:

  • Review(审查): 无。
  • 行内评论: 无。
  • Issue 级评论: 无。
  • 失败的检查: 无。
  • 持续失败的检查: 无。

本 PR 在完成 10 个产生改动的轮次后已进入仅处理 Critical 的模式。按工作流的棘轮规则,延后区域中列出的非 Critical 反馈(自动化审查器的 PR 评论)仍保持开放、留待人工跟进,但不属于本轮的可处理范围,因此未针对这些条目做任何代码修改、线程解决或评论回复。

本轮未做任何代码修改,也未新增提交;PR 的 head 仍停留在先前已通过验证的提交上。

Deferred non-Critical feedback

Critical-only mode is active after 10 change-producing rounds. The workflow excluded the non-Critical feedback below from this round's actionable sections; the items remain open for human follow-up. Maintainer feedback is deferred only after its author has used 2 regular feedback batches in this window's Critical-only tail; authors at that budget, if any, are named below. (@qwen-code /retry starts a fresh counting window.)

中文说明

完成 10 个产生改动的轮次后进入仅处理 Critical 的模式。本轮可执行区域已排除下方非 Critical 反馈;这些条目保持开放,留待人工跟进。维护者反馈仅在其本人于本窗口 Critical-only 阶段已使用 2 批常规反馈预算后才会延后;达到预算的作者(如有)在下方点名。(评论 @qwen-code /retry 可开启新的计数窗口。)

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


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

@wenshao wenshao left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

⚠️ Downgraded from Request changes to Comment: self-PR; CI failing: review-pr. Reviewed. Suggestions are inline. Not reviewed: build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally.

中文说明

⚠️ 已从请求修改降级为评论:self-PR; CI failing: review-pr。 已审查。 建议见行内评论。 未审查:build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally。

— deepseek-v4-flash via Qwen Code /review (v0.21.7)

Comment thread packages/cli/src/config/shared-env-keys.ts
Comment thread packages/cli/src/config/shared-env-keys.ts
Comment thread packages/cli/src/config/shared-env-keys.ts
Comment thread packages/cli/src/config/shared-env-keys.ts
Comment thread packages/cli/src/config/shared-env-keys.ts
Comment thread packages/cli/src/commands/channel/daemon-worker.test.ts
Comment thread packages/cli/src/config/environment.test.ts
Comment thread packages/cli/src/serve/fast-path-settings.ts
Comment thread packages/cli/src/serve/fast-path.test.ts
Comment thread packages/cli/src/serve/fast-path.test.ts
wenshao added a commit that referenced this pull request Aug 8, 2026
…ycle

Follow-up to #8663. Its inherited-env denylist closed the NODE_OPTIONS/
NODE_PATH class but left sibling code-execution and TLS-trust-anchor vars
that reach the same #8653 cross-workspace outcome — an untrusted workspace
`.env` is frozen into daemonRuntimeBaseEnv and distributed to every
workspace's session subprocesses.

Denylist additions, split by the PR's own tiering:

- Scrubbed loader tier (INHERITED_LOADER_ENV_KEYS — scrubbed from the
  inherited launch env and rejected from every `.env`/settings.env scope),
  for pure-injection vars with no legitimate operator-shell use:
  OPENSSL_CONF (startup dlopen of an attacker OpenSSL engine),
  NODE_REPL_EXTERNAL_MODULE, npm_config_node_gyp, npm_config_init_module.

- Reject-from-project-`.env` tier (PROJECT_ENV_HARDCODED_EXCLUSIONS —
  rejected from project files, preserved from the shell / home `.env`), for
  vars with a legitimate operator-shell use whose only exposed vector is an
  untrusted project file:
  * TLS trust anchors SSL_CERT_FILE, SSL_CERT_DIR, CURL_CA_BUNDLE,
    REQUESTS_CA_BUNDLE, GIT_SSL_CAINFO (siblings of NODE_EXTRA_CA_CERTS;
    an attacker CA MITMs a session's git/npm/pip/curl traffic).
  * git command-execution family GIT_SSH_COMMAND, GIT_EXTERNAL_DIFF,
    GIT_CONFIG_GLOBAL/SYSTEM/COUNT and the numbered GIT_CONFIG_KEY_<n>/
    GIT_CONFIG_VALUE_<n> pairs (matched by prefix). core/utils/git-branches.ts
    already scrubs these from the repo's own git invocations.
  * node-gyp interpreter selection NODE_GYP_FORCE_PYTHON, npm_config_python,
    PYTHON (run as the build Python during native-addon installs).

Concurrency: the daemon's process.env scrub/restore and the loader-key
rejection reporter were process-global with no guard for concurrent embedded
daemons in one process (a documented supported config). The first daemon's
close() restored loader vars into the shared env, re-poisoning a still-live
sibling's sessions, and dropped its reporter. The scrub is now reference
counted (acquireInheritedLoaderEnvScrub — snapshot on first acquire, restore
only on last release) and the reporter is cleared only when still active.

Test hardening from the same review: pin the daemon-worker scrub breadcrumb
(not just key removal); pin the fast-path settings.env case-folded
hardcoded-exclusion gate; drain the module-global fast-path stash so the
accumulate assertion is order-independent. Docs updated for the new keys.
pull Bot pushed a commit to bit-cook/qwen-code that referenced this pull request Aug 10, 2026
…eak (QwenLM#8816)

* feat(ci): A/B deterministic gate rejections against the pre-round ref

A deterministic rejection in the autofix verification gate is only
chargeable to the round if the same check passes without the round's
commit. The gate charged every red to the fix unconditionally, and run
31276008548 measured what that costs when the premise is false: PR
8614's branch predated QwenLM#8693's tsconfig guard while node_modules came
from the post-QwenLM#8693 trusted base, so `npm run build` was equally red at
origin/<branch> — 63 minutes of accepted agent work discarded, an
18-minute repair burned on a failure the repair agent is forbidden to
touch (it may only amend the round's own fix), thirteen rounds in a
row, and the same again on the QwenLM#8616 leg.

On rejection the gate now re-runs the failing check at origin/<branch>
(the branch as pushed, before the round) in the same environment:

- baseline green: today's path exactly — outcome=failed,
  retryable=true, the repair pass gets its chance.
- baseline red too: outcome=failed with preexisting=true and NO
  retryable. The repair step keys on retryable and is skipped — it
  cannot reach a failure outside the round's diff by construction —
  and gate-rejection.md says outright that the branch needs a base
  update (merge main), which flows into the failure comment as-is.

Fail-closed toward today's semantics: any A/B infrastructure problem
(missing ref, checkout failure) charges the fix as before, and a
restore failure after the baseline run rejects outright since the tree
can no longer be trusted. The round's work is still not pushed — this
changes the verdict's honesty and cost, not the push policy.

Tested by executing the real script in a real two-remote git repo with
an npm stub whose failures are keyed by commit SHA: round-caused red
(baseline green), pre-existing red (both red), and the untouched green
path. Mutation-tested, 3 of 3 caught: skipping the A/B, claiming
pre-existing without measuring, and dropping the tree restore.

* Address review: bound the A/B to checks it can honestly compare

All seven findings verified before fixing; the three Criticals were
each a way the A/B compared something other than the check that failed.

R1-1 — the contracts check feeds on stdin, which its first run drains;
the baseline leg re-ran against EOF and checked an empty file list.
R1-3 — the schema check's verdict rides on packages/core/dist, which
the core-rebuild guard built from ROUND sources and which, being
gitignored, survives the detach. Both checks are now A/B-exempt
(run_check_no_ab): their baseline verdicts prove nothing, and their
rejections stay where the repair agent can actually act on them.

R1-2 — a workspace the round ADDS does not exist at the baseline, and
npm exits 1 there with "No workspaces found" (measured; --if-present
forgives a missing script, not a missing workspace) — a round-caused
failure misread as pre-existing, skipping the one repair that can fix
the round's own package. The per-package loop now A/Bs only when the
workspace exists at origin/<branch>.

R1-4 — a chatty PASSING baseline used to flood the tail -c 3000
evidence window and push the actual failure text out of
gate-rejection.md, the sole carrier into the repair feedback, the PR
comment, and the next round's LAST_REJECTION. The baseline transcript
now goes to a side log and only a FAILING tail is merged back, where it
is the evidence.

R1-5 — the pre-existing paragraph pushed gate-rejection.md past the
report's head -c 3500 cap, truncating the closing fence for branch
names past 44 characters. Cap raised to 3900, invariant comment
updated with the new arithmetic.

R1-6 — preexisting=true had no read site. It now flows verify →
Finalize verification → the failure report, whose headline swaps the
generic gate clause for "PRE-EXISTING failure … needs a base update
(merge main)".

R1-7 — the no-round-commit guard was unpinned (deleting it kept all
tests green). Now exercised through the core-rebuild path, the one
A/B-eligible check that runs before the commit gate.

Four new behavioral scenarios (chatty baseline, no-commit round,
A/B-exempt checks, round-added workspace) plus workflow pins for the
forwarding, the clause, and the cap. Mutation-tested, 4 of 4 caught:
schema back to A/B (3 tests), guard dropped, side log reverted,
no-commit guard dropped.

* Address review round 2: A/B only what it can prove, prove what it claims

Ten findings across two rounds, each verified before fixing. The three
deepest share one lesson: the A/B is only sound for a check whose
inputs travel entirely with the git ref, and whose failure it can
IDENTIFY, not merely observe.

R2-1 — rc=1 at both legs does not make them the same failure: the
branch can fail for reason A while the round fails for reason B, and a
baseline infrastructure hiccup is a nonzero exit too. Pre-existing now
requires a MATCHING failure identity — tsc diagnostics normalized to
file + error code (positions shift with the round's edits), compared
via comm(1) on a per-check transcript. No diagnostics on either side
means identity cannot be established and the round stays charged.

R2-2 / R2-7 — gitignored dist survives the detach carrying the ROUND's
build, so any dist-consuming check A/Bs reverted sources against
round-built artifacts: package tests (channel-base resolved through
dist exports) and typecheck (sdk-typescript resolves core's d.ts —
probe-verified three-arm flip). Both are now A/B-exempt, as is lint,
leaving `npm run build` — the incident class, and the one check that
rebuilds its own inputs from the checked-out sources — as the sole A/B
candidate. The workspace-existence guard dissolves with it.

R2-3 — the fixture inherited the caller's global git config; a failing
global pre-commit hook broke all seven cases. The harness now isolates
GIT_CONFIG_GLOBAL/SYSTEM for every git child, and the suite is proven
green under a deliberately hostile hooksPath.

R2-4 — Finalize verification now selects preexisting from the same
attempt whose outcome it selects (repair verification included).

R2-5 / R2-8 — the "merge main" advice is now conditional at both
layers: the script paragraph states the measured fact and hedges the
remedy; the report headline uses the compare the step already ran —
behind/diverged gets the base-update clause, an up-to-date branch is
told its own pre-round code needs attention.

R2-6 — the rejection document now sizes its evidence tail against its
preamble (floor 500 bytes, total under the 3900-byte render cap), so
the closing fence can no longer be truncated off by a long branch name.

R2-9 — dissolved by R2-2: package tests no longer A/B, the guard and
its uncovered positive branch are gone.

R2-10 — the baseline-evidence merge is now pinned: the pre-existing
scenario asserts the baseline leg's own failure line (keyed by its SHA)
reaches gate-rejection.md.

Eight behavioral scenarios; mutation-tested 5 of 5: identity dropped,
typecheck re-enrolled, package tests re-enrolled, evidence merge
dropped, fixed tail restored.

* Address review round 4: sharpen identity, stage the git failures, sync prose

Nine findings, all refinements — the design held, the edges did not.

Identity now keeps the diagnostic MESSAGE (file + code collide: two
unrelated TS2339s in one file compared equal, skipping a repair that
could have shipped — probe-reproduced by the review), and the fixture
emits a SHIFTED position on the baseline leg so the position strip is
load-bearing instead of decorative (deleting the sed survived every
test before; it fails one now). vite/esbuild failures still yield an
empty signature by design — documented as the fail-closed limit rather
than half-widened.

The fail_signature assignments take `|| true`: grep exits 1 on the
normal no-match case and survives errexit today only because the caller
sits in an if-condition — a future unconditional call site would crash
the gate verdict-less.

The restore-failure branch is now stageable and staged: the baseline
leg recreates (untracked) a file the branch tracks, the checkout back
refuses, and the test pins retryable-not-preexisting with the
'could not restore' label. Relaxing the branch to `|| true` fails it.

Prose synced to the mechanisms that replaced it: the render-cap
invariant restates against the dynamic tail budget (the old 3000-based
arithmetic would misguide the next retune), the no-round-commit guard
comment names the core rebuild (schema/contracts left the A/B last
round), the describe wording counts both A/B-eligible builds, and the
pre-existing clauses no longer claim "the repair pass was skipped" —
with REPAIR_PREEXISTING forwarded, repair may have RUN; they now state
the invariant that is true either way: repair may only amend the
round's own fix, so it cannot reach this failure.

Mutation-tested, 3 of 3 caught: position strip dropped, message dropped
from the identity, restore rejection relaxed.

* fix(ci): watchdog silent sandbox hangs and reap the containers they leak

Four autofix rounds have died the same way (QwenLM#8663 twice, QwenLM#8761 r3,
QwenLM#8763 r4): the agent's last output is the sandbox wrapper's
"ContainerName (regular): …" line at docker container entry, then
nothing — not one event — until the 2-hour absolute budget kills the
round. Four different runners, two image versions: systemic, not a bad
machine. Where exactly the container wedges is still unknown (that
needs docker state on the runner); what is certain from the logs is the
shape — a wedged sandbox produces NOTHING, and a legitimate run is
never silent for long (the fleet's longest tolerated quiet is the
review pipeline's 10-minute stream-idle window for thinking phases).

Two mitigations, each aimed at a measured half of the damage:

- run-agent.mjs gains an idle watchdog (QWEN_IDLE_TIMEOUT_MS, default
  20 minutes = 2x that longest legitimate silence): zero output for the
  window kills the agent with a distinct "idle-timeout … the sandbox
  likely hung at startup" detail, so the failure comment names the
  right knob and a hung round costs 20 minutes instead of 120. Polled,
  not reset-per-chunk — a busy stream should not spend its time
  re-arming timers.

- Both sandboxed jobs reap stale qwen-code-* containers at job start:
  a budget kill reaps the HOST-side docker client, not the container,
  so every killed sandbox keeps running on the persistent runner —
  observed directly when a later leg's container-name counter found
  qwen-code-0.21.8-0 already occupied and picked -1. One job per runner
  at a time makes any container alive at job start stale by definition.

Tested by executing the real run-agent.mjs end to end with stub agents:
the hang shape (one line, then silence) dies at the idle window naming
the idle limit, and a slow-but-talking agent that outputs every 400ms
across a 1500ms window survives to a clean exit — the test that
distinguishes a watchdog from a disguised absolute timer. Mutation-
tested, 3 of 3 caught: watchdog disabled, last-output tracking dropped
(the disguised-timer regression), cleanup dropped from a job.

* Address review round 5: the gate's verdict defects and the reaper's live kill

Budget-warning round — the five Criticals from both reviewers, no
suggestions (each deferred with a recorded reply).

fail_signature: `[^\n]*` in an ERE bracket expression does not mean
"rest of line" — in POSIX bracket expressions `\` is literal, so it
matched "neither backslash nor the letter n" and truncated every tsc
message at its first n. Nearly every real message has an early n
("Cannot find name", "is not assignable"), so distinct same-file
failures collapsed into identical signatures and a round-caused failure
could be labeled pre-existing, skipping the repair. grep is
line-oriented: `.*` is exactly the rest of the line. New fixture: two
messages differing only after their first n.

Pre-existing verdict: the intersection test mislabeled in both
directions. A round that ADDS a diagnostic sharing one normalized line
with the baseline was called pre-existing (repair skipped for a
round-caused, repairable failure); and `comm -12 | grep -q` under
`set -eo pipefail` SIGPIPEs comm (exit 141) once the shared output
outruns the pipe buffer, charging true pre-existing failures to the
round — the exact 18-minute repair waste the gate exists to kill.
Pre-existing now means the round's failing set is a SUBSET of the
baseline's, and the difference is captured before testing. New fixture:
a round adding a second diagnostic to a failing baseline.

Restore failure after the baseline leg: was retryable=true with HEAD
still detached at the baseline commit — the repair agent works in that
very checkout and does no git recovery, so its commit would land on the
baseline and be orphaned. Now rejected non-retryable (reject_fix grows
a third arg); the next round starts clean from the trusted checkout.
The restoreClash test pins the new semantics.

Stale-container reap: the premise "a runner runs one job at a time, so
any live qwen-code-* container is stale" holds per runner registration,
but the filter queries the docker daemon, which is per host — and this
pool runs several registrations on one OS. With per-issue/PR
serialization only, a concurrent job's sandbox is a substring match
away from `docker rm -f`. The reap now takes only provably-dead
containers (--filter status=exited/dead, both jobs) and the comment
says why a running one is left alone.

Preamble printf: the `\`` escapes sat inside a single-quoted format
where backslash is literal, so every pre-existing rejection rendered
raw backticks instead of code spans (shellcheck SC2016). Backticks
need no escaping there. Also syncs the side-log comment to the dynamic
tail_budget it actually renders.

Verified: scripts suite 140/140 (was 138; the two new fixtures and the
rewritten restoreClash test all fail against the pre-fix script),
npm run build / typecheck / lint pass, bash -n clean.

* Address review round 6: reap the kill's own orphan, tolerate the reaper

* Address review: hang-bound the reaper, unblock the kill path, pin the unpinned arms

- Wrap every docker call in the stale-container reap with timeout 30: an
  alive-but-wedged daemon blocks docker ps indefinitely, and the existing
  || guards only catch nonzero exits, not hangs (R3-1).
- Make the kill-path container removal async in run-agent.mjs: the
  spawnSync blocked the event loop between SIGTERM and the 10s SIGKILL
  backstop for up to its 30s timeout — in exactly the wedged-daemon
  scenario the watchdog exists for. The main flow awaits the removal so
  the leak warning stays deterministic (R3-6).
- Split the pre-existing gate clause for an empty CMP_R: a transient
  compare-API failure is "never measured", not "measured not-behind", and
  must not assert the branch's own code is at fault (R3-7).
- Swap the timeout breaker's closing remedy to the sandbox investigation
  when every counted timeout was idle, mirroring the round-level split
  (R3-11).
- Tests: pin the budget kill path separately from the idle kill path
  (R3-3), parameterize the idle-window parse guard over -1/0/NaN (R3-5),
  add a stderr-only liveness case (R3-12), pin the strict-subset A/B arm
  via a baseline-superset fixture knob (R3-15), and pin the breaker's
  current-round idle increment (R3-18).

---------

Co-authored-by: verify <verify@local>
Co-authored-by: qwen-code-ci-bot <[email protected]>
Co-authored-by: qwen-code-dev-bot <[email protected]>
pull Bot pushed a commit to bit-cook/qwen-code that referenced this pull request Aug 10, 2026
… lifecycle (QwenLM#8763)

* fix(cli): extend the QwenLM#8663 loader denylist and harden its scrub lifecycle

Follow-up to QwenLM#8663. Its inherited-env denylist closed the NODE_OPTIONS/
NODE_PATH class but left sibling code-execution and TLS-trust-anchor vars
that reach the same QwenLM#8653 cross-workspace outcome — an untrusted workspace
`.env` is frozen into daemonRuntimeBaseEnv and distributed to every
workspace's session subprocesses.

Denylist additions, split by the PR's own tiering:

- Scrubbed loader tier (INHERITED_LOADER_ENV_KEYS — scrubbed from the
  inherited launch env and rejected from every `.env`/settings.env scope),
  for pure-injection vars with no legitimate operator-shell use:
  OPENSSL_CONF (startup dlopen of an attacker OpenSSL engine),
  NODE_REPL_EXTERNAL_MODULE, npm_config_node_gyp, npm_config_init_module.

- Reject-from-project-`.env` tier (PROJECT_ENV_HARDCODED_EXCLUSIONS —
  rejected from project files, preserved from the shell / home `.env`), for
  vars with a legitimate operator-shell use whose only exposed vector is an
  untrusted project file:
  * TLS trust anchors SSL_CERT_FILE, SSL_CERT_DIR, CURL_CA_BUNDLE,
    REQUESTS_CA_BUNDLE, GIT_SSL_CAINFO (siblings of NODE_EXTRA_CA_CERTS;
    an attacker CA MITMs a session's git/npm/pip/curl traffic).
  * git command-execution family GIT_SSH_COMMAND, GIT_EXTERNAL_DIFF,
    GIT_CONFIG_GLOBAL/SYSTEM/COUNT and the numbered GIT_CONFIG_KEY_<n>/
    GIT_CONFIG_VALUE_<n> pairs (matched by prefix). core/utils/git-branches.ts
    already scrubs these from the repo's own git invocations.
  * node-gyp interpreter selection NODE_GYP_FORCE_PYTHON, npm_config_python,
    PYTHON (run as the build Python during native-addon installs).

Concurrency: the daemon's process.env scrub/restore and the loader-key
rejection reporter were process-global with no guard for concurrent embedded
daemons in one process (a documented supported config). The first daemon's
close() restored loader vars into the shared env, re-poisoning a still-live
sibling's sessions, and dropped its reporter. The scrub is now reference
counted (acquireInheritedLoaderEnvScrub — snapshot on first acquire, restore
only on last release) and the reporter is cleared only when still active.

Test hardening from the same review: pin the daemon-worker scrub breadcrumb
(not just key removal); pin the fast-path settings.env case-folded
hardcoded-exclusion gate; drain the module-global fast-path stash so the
accumulate assertion is order-independent. Docs updated for the new keys.

* fix(cli): keep the loader-scrub process.env access in the serve guard surface

The refcounted acquireInheritedLoaderEnvScrub read/wrote process.env from
config/shared-env-keys.ts, which the serve process.env guard does not scan —
moving the access out of run-qwen-serve.ts dropped its allowlisted count and
failed process-env-guard.test.ts. Pass the env into the coordinator instead so
run-qwen-serve.ts still owns the process.env reference (matching the existing
scrub helpers), and update the allowlist to the new count.

* fix(cli): block GIT_SSH and GIT_CONFIG_PARAMETERS in the project-env denylist

Co-authored-by: Qwen-Coder <[email protected]>

* fix(cli): extend the project-env denylist across git exec, TLS, and rc-file tiers

Close the round-2 review findings: block the remaining git
command-execution siblings (GIT_EXEC_PATH, GIT_TEMPLATE_DIR, GIT_ASKPASS,
GIT_PROXY_COMMAND, GIT_EDITOR), the npm/pip TLS trust knobs
(npm_config_cafile, npm_config_ca, npm_config_strict_ssl, PIP_CERT,
GIT_SSL_CAPATH), and the curl/wget rc-file redirects (CURL_HOME, WGETRC)
from project .env files. Freeze the numbered GIT_CONFIG_KEY_/VALUE_ pairs
on reload together with GIT_CONFIG_COUNT, and sync the qwen-serve.md
loader-key enumeration with settings.md.

* fix(cli): harden the project-env denylist and nested scrub snapshot (QwenLM#8763)

* fix(cli): merge the loader-env scrub snapshot into one pass (QwenLM#8763)

acquireInheritedLoaderEnvScrub iterated process.env twice (a snapshot
pass, then the scrub); record the originals inside the scrub's single
pass instead. Drop the acquire-time snapshot clear, which the
release-time clear made unreachable defense, and add tests that kill
the previously surviving mutants on the release-time clear, the
test-only reset, and the undefined-value guard.

* fix(cli): block the round-4 exec-redirect env keys from project files (QwenLM#8763)

---------

Co-authored-by: qwen-code-dev-bot <[email protected]>
Co-authored-by: Qwen-Coder <[email protected]>
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+) review/self-reported The linked issue was opened by the PR author (self-reported)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Daemon multi-workspace sessions inherit another workspace's harness environment (NODE_OPTIONS/PATH leak)

4 participants