Skip to content

fix(core): Enforce single-writer session persistence - #7166

Closed
doudouOUC wants to merge 10 commits into
mainfrom
agent/session-writer-lease
Closed

fix(core): Enforce single-writer session persistence#7166
doudouOUC wants to merge 10 commits into
mainfrom
agent/session-writer-lease

Conversation

@doudouOUC

Copy link
Copy Markdown
Collaborator

What this PR does

This PR introduces a process-level single-writer lease for every (runtimeBase, sessionId), reloads the transcript authoritatively only after ownership is acquired, and fences every JSONL append with both the lease owner token and the expected UTF-8 byte length. Losing ownership or observing an unexpected transcript change becomes a permanent integrity failure for that recorder and blocks new model turns instead of allowing another history branch.

It makes resume, clear, branch, working-directory relocation, shutdown, and offline session-management operations ownership-safe. Session transitions keep the old recorder and lease available until the new Core and UI state commit; forks consume one stable snapshot; maintenance operations use the same lease namespace; ACP runtime paths are pinned per workspace; daemon, TUI, desktop, and VS Code lifecycle paths close recorders consistently; and structured ACP/HTTP errors plus telemetry expose conflicts without leaking local process details.

Why it's needed

Two Qwen Code processes could restore the same session from different in-memory tail nodes and append valid-looking records to the same JSONL file. Both processes could return successful answers, but the resulting parent chains diverged. Restarting only reconstructed the branch ending at the physical file tail, so content already shown to the user, including tool results or Wiki answers, could disappear from the restored conversation.

Restarting cannot repair that corruption because it only chooses one existing tail. Enforcing one writer, reloading under the lease, and fencing every append prevents new divergence and fails closed whenever safe ownership cannot be proven.

Reviewer Test Plan

How to verify

  1. Keep a recorded session open in process A, then try to load or resume the same session from process B. Process B should receive session_writer_conflict before it can start a prompt or model turn, while process A continues normally.
  2. Terminate process A and resume from process B. A stale local lock should be reclaimed, the complete transcript should be restored, and subsequent writes plus another restart should preserve one linear parent chain.
  3. Exercise /resume, /clear, /branch, and working-directory relocation across success, target-conflict, initialization-failure, and rollback paths. The old session should remain usable until commit, and a failed transition should not repoint delayed callbacks or runtime sidecars.
  4. Try rename, delete, archive, unarchive, and fork against a live session from another owner, then repeat against an offline session. Live conflicts should fail closed; offline maintenance should acquire a temporary lease and leave no lock behind.
  5. Verify daemon close, authentication failure, restore failure, ACP detach, and process shutdown release only the matching owner lease and runtime sidecar.
  6. Run the changed test files across ACP bridge, CLI, Core, Desktop shared, and VS Code companion. The local result was 3,209 passing tests with zero failures, followed by successful build, bundle, typecheck, lint, and diff checks.

Evidence (Before & After)

Before: a second process could append from a stale in-memory tail, both answers appeared successful, and a later restart silently restored only the physical-tail branch, hiding content that the user had already seen.

After: the second writer is rejected before a model turn with a structured conflict; after the original owner exits, a replacement reloads the authoritative transcript under the lease and continues the same linear history.

Tested on

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

Environment (optional)

macOS source checkout rebased onto 1cacbb1bcc; Node.js v22.22.3; npm 10.9.8; local filesystem; npm run build, bundle through the install prepare step, npm run typecheck, npm run lint, and 3,209 changed-file tests passed.

Risk & Scope

  • Main risk or tradeoff: This is a broad cross-package consistency change spanning 78 files and more than 5,000 production-logic lines in Core, CLI, ACP bridge, daemon, desktop, and VS Code paths. It intentionally rejects concurrent operations that previously appeared to work, and lease/lifecycle mistakes could make sessions temporarily unavailable; fail-closed behavior and focused ownership tests mitigate data-loss risk.
  • Not validated / out of scope: Windows and Linux runtime behavior, unreliable shared/network filesystems, authenticated CLI and interactive integration after the final rebase, and automatic repair or merge of transcripts that already contain divergent branches. Local integration dry-runs were environment-limited by missing OPENAI_API_KEY/authentication timeouts, with one unrelated MCP-count assertion.
  • Breaking changes / migration notes: Mixed old/new Qwen versions are not safe because old binaries do not honor the lock. Deployments and rollbacks must stop older daemons and interactive processes before switching binaries. Foreign-host locks are never reclaimed automatically, and the first safe release does not provide a feature flag that disables single-writer protection.

Linked Issues

Closes #7164

中文说明

本 PR 做了什么

本 PR 为每个 (runtimeBase, sessionId) 引入进程级单写者租约,只在取得写入所有权后权威重载会话记录,并在每次追加 JSONL 时同时校验租约 owner token 与预期 UTF-8 字节长度。一旦失去所有权或检测到会话文件发生非预期变化,当前 recorder 会永久进入完整性失败状态并阻止新的模型轮次,不再允许继续形成另一条历史分支。

同时,本 PR 使 resume、clear、branch、工作目录迁移、关闭流程和离线会话管理操作都遵循一致的所有权规则。会话切换在新 Core 与 UI 状态提交前保留旧 recorder 和旧租约;fork 只消费一次稳定快照;维护操作使用同一租约命名空间;ACP 按工作区固定 runtime 路径;daemon、TUI、desktop 和 VS Code 生命周期路径统一关闭 recorder;结构化 ACP/HTTP 错误与遥测能够暴露冲突,同时不泄漏本地进程信息。

为什么需要

此前两个 Qwen Code 进程可以从不同的内存尾节点恢复同一个会话,并向同一个 JSONL 文件追加看似有效的记录。两个进程都可能成功返回答案,但生成的 parent 链会发生分叉。重启时只能重建物理文件尾部所在的分支,因此用户已经看到的内容(包括工具返回或 Wiki 答案)可能从恢复后的会话中消失。

重启无法修复这种损坏,因为它只能选择已经存在的一条尾分支。强制单写者、在租约内重新加载并对每次追加做 fencing,可以阻止新的分叉;任何无法证明安全所有权的状态都会失败关闭。

Reviewer 测试计划

如何验证

  1. 让进程 A 保持一个已记录会话处于打开状态,再让进程 B 加载或恢复同一个会话。进程 B 应在开始 prompt 或模型轮次之前收到 session_writer_conflict,进程 A 则应继续正常工作。
  2. 终止进程 A 后由进程 B 恢复。本机过期锁应被回收,完整会话记录应被恢复,后续写入及再次重启后仍应保持一条线性的 parent 链。
  3. 覆盖 /resume/clear/branch 和工作目录迁移的成功、目标冲突、初始化失败及回滚路径。旧会话在提交前应保持可用,失败的切换不得重新指向延迟回调或 runtime sidecar。
  4. 由另一个 owner 对 live session 执行 rename、delete、archive、unarchive 和 fork,再对 offline session 重复操作。live 冲突应失败关闭;offline 维护应获取临时租约并且操作后不遗留锁。
  5. 验证 daemon close、认证失败、恢复失败、ACP detach 和进程关闭只释放 owner 匹配的租约与 runtime sidecar。
  6. 运行 ACP bridge、CLI、Core、Desktop shared 和 VS Code companion 中所有发生变更的测试文件。本地结果为 3,209 项测试全部通过,随后 build、bundle、typecheck、lint 和 diff 检查也全部成功。

证据(Before & After)

Before:第二个进程可以从过期的内存尾节点追加;两个答案都表现为成功,但之后重启只恢复物理尾分支,静默隐藏用户已经看到的内容。

After:第二个 writer 会在模型轮次之前收到结构化冲突;原 owner 退出后,新进程会在租约内权威加载 transcript,并沿同一条线性历史继续运行。

测试平台

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

环境(可选)

macOS 源码工作区,已 rebase 到 1cacbb1bcc;Node.js v22.22.3;npm 10.9.8;本地文件系统;npm run build、安装 prepare 阶段的 bundle、npm run typechecknpm run lint 以及 3,209 项变更文件测试均已通过。

风险与范围

  • 主要风险或权衡:这是一个跨 78 个文件、超过 5,000 行生产逻辑的广泛一致性改动,涉及 Core、CLI、ACP bridge、daemon、desktop 和 VS Code 路径。它会有意拒绝过去看似可行的并发操作,租约或生命周期错误也可能造成会话暂时不可用;失败关闭语义与针对所有权的测试用于降低数据丢失风险。
  • 未验证或不在范围内:Windows 和 Linux 运行时行为、不可靠的共享或网络文件系统、最终 rebase 后需要认证的 CLI/interactive 集成测试,以及对已经包含分叉的 transcript 进行自动修复或合并。本地集成 dry-run 受缺少 OPENAI_API_KEY/认证超时限制,另有一项与本改动无关的 MCP 数量断言失败。
  • Breaking change / 迁移说明:新旧 Qwen 混合版本不安全,因为旧二进制不会遵守锁。发布或回滚时必须先停止旧 daemon 和交互进程,再切换二进制。foreign-host 锁不会被自动回收,首个安全版本也不提供关闭单写保护的 feature flag。

关联 Issue

Closes #7164

@doudouOUC

Copy link
Copy Markdown
Collaborator Author

E2E / verification report

Final validation was performed after rebasing the single feature commit onto main at 1cacbb1bcc.

Passed

  • All changed test files passed: 3,209 tests total — ACP bridge 433, CLI 1,601, Core 1,128, Desktop shared 36, and VS Code companion 11.
  • npm run build passed after synchronizing the latest main dependencies; the install prepare step also completed the bundle successfully.
  • npm run typecheck, npm run lint, git diff --check, conflict-marker checks, and a clean-worktree check passed.
  • The final branch is exactly one commit ahead of the current origin/main and contains no generated dependency, notices, or test-fixture artifacts.

Environment-limited integration dry-run

An earlier CLI integration dry-run reported 126 passed, 18 skipped, and 12 failed cases: 11 failures required an unavailable OPENAI_API_KEY, and one was an unrelated MCP-count assertion. The interactive dry-run reported 6 passed, 2 skipped, and 4 authentication timeouts. These authenticated integration suites were not rerun after the final rebase and are not claimed as green evidence.

Still to verify in review / CI

  • Run the two-process live-session scenario from the PR test plan: process B must be rejected before a model turn while process A owns the lease, then recover the complete linear history after A exits.
  • Exercise the same lifecycle on Windows and Linux CI/runtime filesystems.
  • Confirm mixed-version rollout is performed only after stopping old daemons and interactive processes; historical divergent transcripts are intentionally not repaired by this P0.

@qwen-code-ci-bot

qwen-code-ci-bot commented Jul 18, 2026

Copy link
Copy Markdown
Collaborator

🩺 serve daemon A/B

Built the PR base vs this PR head 39d1837, drove a fixed endpoint set against each, and diffed the JSON responses. Only fields that changed are shown.

No response changes against the PR base across 4 scenario(s).

Qwen Code · serve A/B

@github-actions

github-actions Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Summary

Package Lines Statements Functions Branches
CLI 82.12% 82.12% 88.08% 82.21%
Core 86.84% 86.84% 88.23% 85.95%
CLI Package - Full Text Report
-------------------|---------|----------|---------|---------|-------------------
File               | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-------------------|---------|----------|---------|---------|-------------------
All files          |   82.12 |    82.21 |   88.08 |   82.12 |                   
 src               |   81.36 |    79.24 |    86.9 |   81.36 |                   
  cli.ts           |   94.41 |    83.78 |     100 |   94.41 | ...75-476,486-487 
  gemini.tsx       |   73.58 |    76.99 |    82.6 |   73.58 | ...1163-1167,1288 
  ...ractiveCli.ts |   78.94 |    76.87 |   81.25 |   78.94 | ...2238-2240,2277 
  ...liCommands.ts |   88.34 |    83.87 |      90 |   88.34 | ...63,480,514,635 
  ...ActiveAuth.ts |     100 |     87.5 |     100 |     100 | 66-80             
 ...cp-integration |   66.99 |    70.19 |   87.71 |   66.99 |                   
  acpAgent.ts      |   66.57 |    69.97 |   87.67 |   66.57 | ...36,10141-10143 
  authMethods.ts   |      92 |       60 |     100 |      92 | 33-34             
  errorCodes.ts    |       0 |        0 |       0 |       0 | 1-22              
  ...ion-skills.ts |     100 |    88.23 |     100 |     100 | 17,32             
  generation.ts    |    97.1 |    81.25 |     100 |    97.1 | 109,112           
  ...DirContext.ts |     100 |      100 |     100 |     100 |                   
 ...ration/service |   97.04 |    95.71 |   93.33 |   97.04 |                   
  filesystem.ts    |   97.04 |    95.71 |   93.33 |   97.04 | ...21-122,238-239 
 ...ration/session |   91.44 |    85.35 |   95.66 |   91.44 |                   
  Session.ts       |   90.97 |    84.08 |   94.85 |   90.97 | ...7711,7738-7742 
  ...entTracker.ts |   91.53 |    89.47 |   88.88 |   91.53 | ...32,196,270-279 
  ...stop-guard.ts |     100 |    97.05 |     100 |     100 | 37,127,247        
  ...eplay-page.ts |   91.81 |    84.14 |     100 |   91.81 | ...08-118,121,217 
  ...y-replayer.ts |    98.5 |    95.38 |     100 |    98.5 | 229-231           
  index.ts         |       0 |        0 |       0 |       0 | 1-40              
  ...ssionUtils.ts |      89 |    87.87 |     100 |      89 | ...49-165,221-223 
  tasksSnapshot.ts |   94.21 |     87.5 |     100 |   94.21 | 65-71             
  ...on-tracker.ts |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...ssion/emitters |   95.68 |     93.7 |   96.66 |   95.68 |                   
  ...ageEmitter.ts |   95.34 |    94.11 |     100 |   95.34 | 52-59             
  PlanEmitter.ts   |     100 |    83.33 |     100 |     100 | 59                
  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.17 |    97.43 |     100 |   99.17 | 352-353           
 ...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/commands      |   88.74 |    73.52 |   64.51 |   88.74 |                   
  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        |   97.77 |      100 |      50 |   97.77 | 56                
  serve.ts         |   86.42 |    67.64 |     100 |   86.42 | ...98-601,615-619 
  sessions.ts      |     100 |      100 |      50 |     100 |                   
  update.ts        |   98.11 |    94.44 |   66.66 |   98.11 | 81-82             
 ...mmands/channel |   85.61 |    87.24 |   88.23 |   85.61 |                   
  channel-cwd.ts   |     100 |      100 |     100 |     100 |                   
  ...l-registry.ts |    6.52 |      100 |       0 |    6.52 | 6-33,36-54        
  ...entry-path.ts |      75 |       50 |     100 |      75 | 8-9               
  config-utils.ts  |   95.85 |    96.29 |     100 |   95.85 | ...08-213,271-274 
  configure.ts     |    14.7 |      100 |       0 |    14.7 | 18-21,23-84       
  daemon-worker.ts |   94.67 |    85.71 |   97.61 |   94.67 | ...86-987,991-992 
  ...classifier.ts |   98.49 |    96.51 |     100 |   98.49 | 115-116,161       
  ...tact-store.ts |   93.51 |    87.65 |     100 |   93.51 | ...71,288-289,337 
  pairing.ts       |   72.85 |      100 |      50 |   72.85 | 22-28,57-68       
  pidfile.ts       |   95.55 |       90 |     100 |   95.55 | ...50-251,315-316 
  proxy.ts         |     100 |      100 |     100 |     100 |                   
  reload.ts        |    77.5 |    86.95 |      75 |    77.5 | 72-84,93-97       
  runtime.ts       |   79.03 |    87.23 |     100 |   79.03 | ...65-169,199-201 
  set.ts           |   75.72 |    85.71 |      50 |   75.72 | 65-83,111-116     
  start.ts         |   75.42 |    75.28 |   66.66 |   75.42 | ...46,552-555,567 
  ...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.17 |    84.39 |   83.33 |   90.17 |                   
  add.ts           |    99.3 |    96.07 |     100 |    99.3 | 154-155           
  approve.ts       |   76.19 |     87.5 |   66.66 |   76.19 | ...,89-99,114-124 
  list.ts          |   92.59 |    83.87 |      80 |   92.59 | ...62-164,180-181 
  reconnect.ts     |   78.85 |    66.66 |   85.71 |   78.85 | 42-55,169-191     
  remove.ts        |     100 |       80 |     100 |     100 | 21-25             
 ...ommands/review |   78.06 |       87 |    78.9 |   78.06 |                   
  agent-prompt.ts  |   90.78 |    92.71 |      96 |   90.78 | ...1256,1693-1762 
  capture-local.ts |   72.16 |     90.9 |      75 |   72.16 | 101-105,152-174   
  ...k-coverage.ts |   48.38 |    14.28 |   66.66 |   48.38 | ...21-226,239-249 
  cleanup.ts       |   17.72 |      100 |       0 |   17.72 | ...27-132,134-135 
  ...ose-review.ts |   94.18 |    95.97 |      90 |   94.18 | ...78-681,709-725 
  fetch-pr.ts      |   25.44 |      100 |    12.5 |   25.44 | ...15-304,345-347 
  load-rules.ts    |   26.41 |      100 |   16.66 |   26.41 | ...41-153,155-156 
  parse-args.ts    |   99.25 |       96 |     100 |   99.25 | 341,413           
  plan-diff.ts     |    67.9 |      100 |   66.66 |    67.9 | 121-148           
  pr-context.ts    |   84.02 |    76.37 |   91.66 |   84.02 | ...22-903,932-934 
  presubmit.ts     |   74.32 |       82 |   85.71 |   74.32 | ...46-347,399-429 
  ...ve-anchors.ts |   77.02 |    88.46 |      75 |   77.02 | ...70-175,187-204 
  submit.ts        |   74.44 |    80.82 |      80 |   74.44 | ...48-584,586-587 
  test-efficacy.ts |   80.68 |    69.41 |    92.3 |   80.68 | ...93-594,602-622 
 ...nds/review/lib |   93.92 |    93.02 |   91.47 |   93.92 |                   
  agent-briefs.ts  |   98.26 |      100 |       0 |   98.26 | 439-440           
  anchors.ts       |     100 |    94.79 |     100 |     100 | ...33,169,178,225 
  coverage.ts      |   93.68 |    94.25 |   94.73 |   93.68 | ...45,261,327-344 
  diff-flags.ts    |     100 |        0 |     100 |     100 | 63                
  diff-plan.ts     |   98.73 |    92.93 |     100 |   98.73 | ...40,263,289-290 
  gh.ts            |   52.87 |      100 |      30 |   52.87 | ...81-182,190-197 
  git.ts           |   97.64 |    95.65 |     100 |   97.64 | 180-181           
  heavy.ts         |     100 |      100 |     100 |     100 |                   
  inline-counts.ts |     100 |      100 |     100 |     100 |                   
  local-diff.ts    |    84.4 |    88.46 |     100 |    84.4 | ...63-473,475-483 
  merge-base.ts    |     100 |      100 |     100 |     100 |                   
  path-rules.ts    |     100 |      100 |     100 |     100 |                   
  paths.ts         |   84.61 |       80 |   66.66 |   84.61 | 42-43,76-77       
  prompt-record.ts |   94.73 |    88.23 |     100 |   94.73 | ...28,151-152,156 
  report.ts        |   92.13 |    86.66 |     100 |   92.13 | 170-171,173-177   
  roster.ts        |     100 |    92.85 |     100 |     100 | 104,118,163       
  shell-quote.ts   |     100 |      100 |     100 |     100 |                   
  transcripts.ts   |   96.27 |    93.18 |     100 |   96.27 | ...83,269-270,294 
  workspaces.ts    |   97.76 |     91.3 |     100 |   97.76 | 186-187,212-213   
 ...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.42 |    88.29 |   95.47 |   94.42 |                   
  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 
  config.ts        |   88.03 |    87.42 |   84.37 |   88.03 | ...2321,2323-2331 
  ...heme-names.ts |     100 |      100 |     100 |     100 |                   
  environment.ts   |   94.18 |    88.51 |   94.73 |   94.18 | ...22-626,642-643 
  ...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.74 |     100 |     100 | 47,160,220        
  keyBindings.ts   |   97.24 |       50 |     100 |   97.24 | 221-224           
  ...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.87 |     100 |   98.97 | 85                
  mcpApprovals.ts  |   96.55 |    95.65 |     100 |   96.55 | 223-224,229-231   
  mcpJson.ts       |     100 |      100 |     100 |     100 |                   
  mcpServers.ts    |   92.85 |     87.5 |     100 |   92.85 | 46-47             
  ...idersScope.ts |      95 |    94.73 |     100 |      95 | 11-12             
  ...abledTools.ts |     100 |      100 |     100 |     100 |                   
  ...comparison.ts |     100 |      100 |     100 |     100 |                   
  ...n-settings.ts |   99.15 |    93.75 |     100 |   99.15 | 63                
  sandboxConfig.ts |   61.64 |    71.87 |   66.66 |   61.64 | ...54-68,73,77-89 
  ...ings-cache.ts |   96.52 |    93.93 |     100 |   96.52 | 90-91,201-202     
  settings.ts      |    90.6 |    91.84 |   89.65 |    90.6 | ...61,963,965-966 
  ...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 |                   
  ...paths-lite.ts |   89.47 |       88 |     100 |   89.47 | 43-44,53-54,56-57 
  ...tedFolders.ts |   94.46 |    95.65 |     100 |   94.46 | ...53-354,390-401 
 ...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.61 |    70.31 |   66.66 |   71.61 |                   
  ...tputBridge.ts |   71.76 |    70.96 |   68.42 |   71.76 | ...05-406,414-417 
  ...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/i18n          |   86.69 |    81.92 |   89.65 |   86.69 |                   
  index.ts         |   75.35 |    77.77 |      90 |   75.35 | ...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 |    79.6 |    76.08 |   81.35 |    79.6 |                   
  session.ts       |    83.7 |       75 |   93.61 |    83.7 | ...-994,1003-1013 
  types.ts         |    42.5 |      100 |   33.33 |    42.5 | ...24-625,628-629 
 ...active/control |   76.11 |    89.09 |      80 |   76.11 |                   
  ...rolContext.ts |    6.45 |        0 |       0 |    6.45 | 56-95             
  ...Dispatcher.ts |   91.79 |    92.45 |   88.88 |   91.79 | ...49-367,387,390 
  ...rolService.ts |     7.4 |        0 |       0 |     7.4 | 46-185            
 ...ol/controllers |   41.09 |       60 |   47.22 |   41.09 |                   
  ...Controller.ts |   39.49 |      100 |      80 |   39.49 | 88-92,127-210     
  ...Controller.ts |       0 |        0 |       0 |       0 | 1-56              
  ...Controller.ts |    50.6 |    57.14 |   54.54 |    50.6 | ...73-678,680-685 
  ...Controller.ts |   14.06 |      100 |       0 |   14.06 | ...82-117,130-133 
  ...Controller.ts |    37.8 |       60 |   46.66 |    37.8 | ...40-652,661-690 
 .../control/types |       0 |        0 |       0 |       0 |                   
  serviceAPIs.ts   |       0 |        0 |       0 |       0 | 1                 
 ...Interactive/io |   97.52 |    93.98 |   95.23 |   97.52 |                   
  ...putAdapter.ts |   97.19 |     93.1 |   98.07 |   97.19 | ...1317,1420-1421 
  ...putAdapter.ts |      96 |    91.66 |   85.71 |      96 | 51-52             
  ...nputReader.ts |     100 |    94.73 |     100 |     100 | 67                
  ...putAdapter.ts |   98.38 |      100 |   90.47 |   98.38 | 84-85,125-126     
  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/serve         |   87.45 |    84.05 |   90.17 |   87.45 |                   
  ...tp-enabled.ts |     100 |      100 |     100 |     100 |                   
  ...ion-bridge.ts |     100 |      100 |     100 |     100 |                   
  auth.ts          |    93.4 |    92.95 |     100 |    93.4 | ...16-317,320-322 
  ...em-adapter.ts |     100 |      100 |     100 |     100 |                   
  capabilities.ts  |     100 |    97.61 |     100 |     100 | 578               
  ...cp-command.ts |     100 |      100 |     100 |     100 |                   
  ...-selection.ts |     100 |      100 |     100 |     100 |                   
  ...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 |   90.97 |    85.26 |     100 |   90.97 | ...80-684,690-694 
  ...er-manager.ts |   95.12 |    88.82 |   94.28 |   95.12 | ...68,492,503-505 
  ...tartup-ipc.ts |   97.72 |    96.66 |     100 |   97.72 | 82-83             
  ...supervisor.ts |   96.57 |     86.9 |   96.49 |   96.57 | ...1026,1134-1138 
  ...e-grouping.ts |     100 |    94.11 |     100 |     100 | 69,132            
  ...ub-session.ts |   92.04 |    77.77 |     100 |   92.04 | ...36-445,470,508 
  daemon-logger.ts |    82.2 |    77.26 |   91.76 |    82.2 | ...1720,1747-1753 
  ...trics-ring.ts |     100 |      100 |     100 |     100 |                   
  ...s-provider.ts |   68.04 |    52.77 |     100 |   68.04 | ...44-249,282-290 
  daemon-status.ts |   98.36 |       90 |     100 |   98.36 | ...1033,1035-1036 
  debug-mode.ts    |     100 |      100 |     100 |     100 |                   
  demo.ts          |     100 |      100 |     100 |     100 |                   
  env-snapshot.ts  |    91.3 |       80 |     100 |    91.3 | ...24-127,205-212 
  ...-scheduler.ts |   87.34 |    83.87 |     100 |   87.34 | 33-36,48-50,79-81 
  ...-path-argv.ts |     100 |      100 |     100 |     100 |                   
  ...h-settings.ts |   94.39 |     88.7 |     100 |   94.39 | ...22,700,716,726 
  fast-path.ts     |   91.28 |    81.98 |   95.45 |   91.28 | ...64-473,539-540 
  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                
  ...iders-edit.ts |     100 |    82.14 |     100 |     100 | 58-60,65,81       
  ...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 |   84.95 |    80.91 |   72.68 |   84.95 | ...5518,5523-5524 
  ...tup-errors.ts |     100 |      100 |     100 |     100 |                   
  ...-keepalive.ts |   96.21 |    91.08 |     100 |   96.21 | ...54,519-521,561 
  ...-lifecycle.ts |     100 |      100 |     100 |     100 |                   
  server.ts        |   95.47 |    92.93 |   78.18 |   95.47 | ...1734,1754-1757 
  ...on-helpers.ts |   95.23 |      100 |     100 |   95.23 | 24                
  ...t-event-id.ts |     100 |    91.66 |     100 |     100 | 12                
  ...-admission.ts |   98.71 |    89.65 |     100 |   98.71 | 68                
  types.ts         |     100 |      100 |     100 |     100 |                   
  ...erver-name.ts |     100 |      100 |     100 |     100 |                   
  ...ion-limits.ts |     100 |      100 |     100 |     100 |                   
  ...l-resolver.ts |   90.32 |    66.66 |     100 |   90.32 | 16,45-46          
  ...ell-static.ts |   91.07 |    86.66 |     100 |   91.07 | ...79-182,216-219 
  ...ace-agents.ts |   57.15 |    67.61 |   86.66 |   57.15 | ...1821,1831-1841 
  ...-git-state.ts |     100 |       90 |    87.5 |     100 | 61,121            
  ...ace-inputs.ts |     100 |      100 |     100 |     100 |                   
  ...-constants.ts |     100 |      100 |     100 |     100 |                   
  ...-summaries.ts |   86.66 |       50 |     100 |   86.66 | 11,19             
  ...ace-memory.ts |   82.19 |    75.28 |     100 |   82.19 | ...82-489,549-556 
  ...ers-status.ts |   98.52 |       79 |     100 |   98.52 | 94,122,162,165    
  ...tion-store.ts |    85.6 |    85.98 |   90.47 |    85.6 | ...82-291,302-305 
  ...e-registry.ts |   91.26 |     90.8 |     100 |   91.26 | ...93-294,300-301 
  ...ber-errors.ts |     100 |    95.32 |     100 |     100 | 53,93-94,172,192  
  ...e-remember.ts |   97.94 |    94.39 |     100 |   97.94 | ...00,304-309,350 
  ...te-runtime.ts |   93.14 |    87.93 |     100 |   93.14 | ...-88,92,145-150 
  ...management.ts |   71.84 |    71.67 |      96 |   71.84 | ...65-866,873-877 
  ...ls-mapping.ts |     100 |      100 |     100 |     100 |                   
  ...lls-status.ts |     100 |    94.73 |     100 |     100 | 109               
 ...serve/acp-http |   75.74 |    78.21 |   93.78 |   75.74 |                   
  ...r-registry.ts |     100 |    95.45 |     100 |     100 | 191               
  client-mcp-ws.ts |   54.85 |    58.62 |   72.72 |   54.85 | ...99-300,304-305 
  ...n-registry.ts |   98.19 |    88.55 |     100 |   98.19 | 1015,1037-1048    
  dispatch.ts      |    69.2 |    74.55 |     100 |    69.2 | ...4500,4548-4554 
  index.ts         |   81.98 |    78.69 |   89.58 |   81.98 | ...2182,2213-2215 
  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 |   85.73 |    73.17 |    97.5 |   85.73 |                   
  ...r-emulator.ts |   88.57 |    63.63 |     100 |   88.57 | ...72-175,194-195 
  ...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 |       0 |        0 |       0 |       0 |                   
  ...mcp-smoke.mjs |       0 |        0 |       0 |       0 | 1-119             
  ...cceptance.mjs |       0 |        0 |       0 |       0 | 1-473             
  real-tab.mjs     |       0 |        0 |       0 |       0 | 1-218             
 src/serve/fs      |   85.68 |    80.12 |     100 |   85.68 |                   
  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 |    74.01 |     100 |   77.64 | ...65,594-598,611 
  policy.ts        |   90.32 |    89.18 |     100 |   90.32 | 142-150           
  ...ile-system.ts |   85.19 |     78.6 |     100 |   85.19 | ...2094,2104-2105 
 src/serve/routes  |   85.82 |    79.85 |   95.79 |   85.82 |                   
  a2ui-action.ts   |   99.49 |    94.52 |    87.5 |   99.49 | 250               
  capabilities.ts  |     100 |      100 |     100 |     100 |                   
  ...l-webhooks.ts |   93.56 |    84.09 |     100 |   93.56 | ...42,292,332,334 
  daemon-status.ts |   85.45 |    83.33 |     100 |   85.45 | 98-105            
  goals.ts         |    98.8 |    88.46 |     100 |    98.8 | 134               
  health-demo.ts   |   94.17 |    83.33 |     100 |   94.17 | 62-66,143         
  permission.ts    |     100 |     92.3 |     100 |     100 | 50,98             
  ...uled-tasks.ts |   84.91 |    83.82 |     100 |   84.91 | ...-891,1013-1014 
  ...on-runtime.ts |     100 |    86.66 |     100 |     100 | 43,79             
  session.ts       |    88.4 |    83.87 |   95.08 |    88.4 | ...3384,3386-3387 
  sse-events.ts    |   86.25 |     88.6 |   77.77 |   86.25 | ...81,387,404-407 
  usage-stats.ts   |     100 |    95.65 |     100 |     100 | 116               
  ...space-auth.ts |    83.7 |       75 |     100 |    83.7 | ...23,328,340-344 
  ...el-control.ts |   86.26 |    78.94 |     100 |   86.26 | ...17-318,339-347 
  ...d-contacts.ts |     100 |      100 |     100 |     100 |                   
  ...controller.ts |   81.71 |    77.09 |   89.65 |   81.71 | ...73,975,981,984 
  ...extensions.ts |   87.44 |    72.76 |   95.74 |   87.44 | ...1788,1830-1831 
  ...-file-read.ts |   92.32 |       80 |     100 |   92.32 | ...94-595,598-599 
  ...file-write.ts |   84.44 |    64.13 |     100 |   84.44 | ...73-275,355-357 
  ...e-git-diff.ts |   94.11 |    91.89 |     100 |   94.11 | ...54-155,201-206 
  workspace-git.ts |     100 |      100 |     100 |     100 |                   
  ...-lifecycle.ts |   96.85 |       75 |     100 |   96.85 | 130-131,161-162   
  ...management.ts |   86.98 |    84.75 |     100 |   86.98 | ...1001,1021-1026 
  ...cp-control.ts |   70.14 |    63.21 |     100 |   70.14 | ...14-520,529-530 
  ...ace-models.ts |   95.87 |    92.42 |     100 |   95.87 | 38-39,136-141     
  ...ermissions.ts |   74.66 |    69.23 |     100 |   74.66 | ...25-233,254-271 
  ...e-settings.ts |   72.81 |     69.9 |     100 |   72.81 | ...85-589,594-604 
  ...tup-github.ts |   77.58 |    70.27 |   84.21 |   77.58 | ...88,310,354-355 
  ...ace-skills.ts |   69.87 |    78.12 |     100 |   69.87 | ...59-284,290-324 
  ...ace-status.ts |   75.33 |    61.97 |     100 |   75.33 | ...34-335,359-360 
  ...pace-tools.ts |   74.82 |    69.23 |     100 |   74.82 | ...41-146,175-176 
  ...pace-trust.ts |   76.08 |       50 |   66.66 |   76.08 | ...01-206,214-215 
  ...pace-voice.ts |   91.45 |    82.35 |     100 |   91.45 | ...21-624,627-629 
 src/serve/server  |   90.86 |    89.64 |   95.04 |   90.86 |                   
  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 |    86.95 |     100 |    98.8 | 107               
  ...r-handlers.ts |   97.14 |    71.42 |     100 |   97.14 | 16                
  ...r-response.ts |    85.4 |    76.16 |     100 |    85.4 | ...91,708,771-780 
  fs-factory.ts    |     100 |    92.59 |     100 |     100 | 33,41,100,156     
  ...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.09 |    95.09 |     100 |   95.09 | ...59-161,416-421 
  self-origin.ts   |   76.19 |       80 |     100 |   76.19 | 45-54             
  ...e-features.ts |   93.96 |       92 |     100 |   93.96 | 149-155           
  ...on-archive.ts |   90.42 |    90.74 |   88.23 |   90.42 | ...46-450,526-536 
  ...ion-export.ts |     100 |    94.44 |     100 |     100 | 64                
  session-list.ts  |   95.09 |    92.08 |     100 |   95.09 | ...22-637,639-645 
  telemetry.ts     |    98.7 |    97.41 |     100 |    98.7 | ...14-616,757-759 
 src/serve/voice   |   85.15 |     93.1 |   90.47 |   85.15 |                   
  ...ice-config.ts |   96.77 |       30 |     100 |   96.77 | 85-86             
  voice-ws.ts      |   77.97 |    96.39 |   83.33 |   77.97 | ...55,470,508-510 
  ...oordinator.ts |     100 |    98.11 |     100 |     100 | 171               
 ...kspace-service |   88.48 |    81.81 |   89.47 |   88.48 |                   
  index.ts         |   87.93 |    81.25 |   87.87 |   87.93 | ...1126-1130,1133 
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/services      |   92.18 |    88.35 |   97.65 |   92.18 |                   
  ...mandLoader.ts |     100 |    88.88 |     100 |     100 | 104-117           
  ...killLoader.ts |   97.14 |    87.87 |     100 |   97.14 | 140,151-152       
  ...andService.ts |   98.73 |      100 |     100 |   98.73 | 107               
  ...mandLoader.ts |   86.83 |    83.87 |     100 |   86.83 | ...30-335,340-345 
  ...omptLoader.ts |   77.17 |    83.82 |   83.33 |   77.17 | ...43,168,210-211 
  ...mandLoader.ts |   97.36 |    92.68 |     100 |   97.36 | 153,160-161       
  ...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 |    93.75 |     100 |   96.66 | 34-35             
  ...low-loader.ts |     100 |    96.15 |     100 |     100 | 88                
  setup-github.ts  |    90.5 |    81.81 |     100 |    90.5 | ...35-436,443-444 
  ...-args-file.ts |   93.54 |    90.47 |    87.5 |   93.54 | 201-203,217-223   
  types.ts         |     100 |      100 |     100 |     100 |                   
  ...e-keyterms.ts |   98.64 |    95.71 |     100 |   98.64 | 116,142-143       
  voice-model.ts   |     100 |      100 |     100 |     100 |                   
  voice-service.ts |   88.14 |    87.69 |     100 |   88.14 | ...80,287,352-357 
  ...e-settings.ts |     100 |    95.23 |     100 |     100 | 19                
  ...ranscriber.ts |   90.46 |    82.02 |      96 |   90.46 | ...66-668,671-673 
 ...ght/generators |   88.86 |    85.78 |   96.29 |   88.86 |                   
  DataProcessor.ts |   88.23 |    85.71 |      95 |   88.23 | ...1348,1352-1359 
  ...tGenerator.ts |   98.21 |    85.71 |     100 |   98.21 | 46                
  ...teRenderer.ts |     100 |      100 |     100 |     100 |                   
 .../insight/types |       0 |       50 |      50 |       0 |                   
  ...sightTypes.ts |       0 |        0 |       0 |       0 |                   
  ...sightTypes.ts |       0 |        0 |       0 |       0 | 1                 
 ...mpt-processors |   97.27 |    94.04 |     100 |   97.27 |                   
  ...tProcessor.ts |     100 |      100 |     100 |     100 |                   
  ...eProcessor.ts |   94.52 |    84.21 |     100 |   94.52 | 46-47,93-94       
  ...tionParser.ts |     100 |      100 |     100 |     100 |                   
  ...lProcessor.ts |   97.41 |    95.65 |     100 |   97.41 | 95-98             
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/services/tips |   97.27 |    84.61 |     100 |   97.27 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  tipHistory.ts    |   92.59 |       70 |     100 |   92.59 | ...24,146,153,162 
  tipRegistry.ts   |     100 |      100 |     100 |     100 |                   
  tipScheduler.ts  |     100 |    91.66 |     100 |     100 | 55                
 src/startup       |   88.86 |    83.33 |      90 |   88.86 |                   
  ...p-prefetch.ts |   98.04 |    94.11 |   85.71 |   98.04 | 50,201,217-218    
  ...reeStartup.ts |   80.53 |     74.6 |     100 |   80.53 | ...94,403,409-412 
 src/test-utils    |   94.04 |    83.33 |      80 |   94.04 |                   
  ...omMatchers.ts |   69.69 |       50 |      50 |   69.69 | 32-35,37-39,45-47 
  ...andContext.ts |     100 |      100 |     100 |     100 |                   
  render.tsx       |     100 |      100 |     100 |     100 |                   
 src/ui            |   71.01 |    73.04 |    67.5 |   71.01 |                   
  App.tsx          |   33.33 |       75 |   33.33 |   33.33 | 32-86             
  AppContainer.tsx |   72.21 |     69.8 |   66.66 |   72.21 | ...4040,4044-4048 
  ...tionNudge.tsx |    9.58 |      100 |       0 |    9.58 | 24-94             
  ...ackDialog.tsx |   29.23 |      100 |       0 |   29.23 | 25-75             
  ...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 |   62.03 |       50 |      80 |   62.03 | ...40-241,258-263 
  ...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.45 |    66.18 |   51.06 |   58.45 |                   
  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.03 |    70.73 |   57.69 |   60.03 | ...87,791,800,803 
  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   |   80.69 |    83.23 |   88.83 |   80.69 |                   
  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  |   62.81 |    58.73 |   65.21 |   62.81 | ...90-595,680-688 
  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.1 |     84.9 |     100 |    92.1 | ...4-69,94-99,178 
  clearCommand.ts  |   77.03 |       70 |     100 |   77.03 | ...31-138,146-155 
  ...essCommand.ts |   67.95 |    55.88 |      75 |   67.95 | ...86-187,201-204 
  ...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 |   67.81 |    69.69 |   84.61 |   67.81 | ...59-592,603-604 
  copyCommand.ts   |   98.49 |    95.78 |     100 |   98.49 | ...80,280,321,327 
  deleteCommand.ts |     100 |      100 |     100 |     100 |                   
  diffCommand.ts   |     100 |    87.87 |     100 |     100 | ...63,231-232,245 
  ...ryCommand.tsx |   81.43 |     88.4 |    90.9 |   81.43 | ...59-264,311-318 
  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   |   91.13 |    83.72 |      90 |   91.13 | ...81-184,196-199 
  helpCommand.ts   |     100 |      100 |     100 |     100 |                   
  ...oryCommand.ts |     100 |      100 |     100 |     100 |                   
  hooksCommand.ts  |   81.13 |    65.71 |   85.71 |   81.13 | ...,86-93,131-132 
  ideCommand.ts    |   60.75 |    64.28 |   41.17 |   60.75 | ...05-306,310-324 
  ...figCommand.ts |   52.83 |    81.25 |      70 |   52.83 | ...74-319,321-330 
  initCommand.ts   |   91.86 |       80 |     100 |   91.86 | 48,83-88          
  ...ghtCommand.ts |   77.87 |    71.42 |     100 |   77.87 | ...44-245,250-272 
  ...ageCommand.ts |   93.45 |    89.06 |     100 |   93.45 | ...68-169,196-206 
  learn-command.ts |     100 |      100 |     100 |     100 |                   
  lspCommand.ts    |     100 |    86.95 |     100 |     100 | 31,101-102        
  mcpCommand.ts    |     100 |      100 |     100 |     100 |                   
  memoryCommand.ts |     100 |      100 |     100 |     100 |                   
  modelCommand.ts  |    81.1 |     89.5 |   88.23 |    81.1 | ...80-793,827-832 
  ...onsCommand.ts |     100 |      100 |     100 |     100 |                   
  planCommand.ts   |   78.82 |    76.92 |     100 |   78.82 | 30-35,51-56,68-73 
  quitCommand.ts   |     100 |      100 |     100 |     100 |                   
  recapCommand.ts  |   21.81 |      100 |      50 |   21.81 | 24-73             
  ...ns-command.ts |   98.83 |    81.81 |     100 |   98.83 | 100               
  ...berCommand.ts |     100 |     87.5 |     100 |     100 | 46                
  renameCommand.ts |   89.06 |    88.37 |     100 |   89.06 | ...72-176,202-209 
  ...oreCommand.ts |    90.9 |    86.04 |     100 |    90.9 | ...41-146,176-177 
  resumeCommand.ts |     100 |      100 |     100 |     100 |                   
  rewindCommand.ts |   81.25 |      100 |      50 |   81.25 | 20-22             
  ...ngsCommand.ts |     100 |      100 |     100 |     100 |                   
  ...hubCommand.ts |   89.47 |       75 |      80 |   89.47 | 54-59             
  skillsCommand.ts |   78.82 |    81.81 |     100 |   78.82 | 37-52,78,97       
  statsCommand.ts  |    90.6 |    77.95 |     100 |    90.6 | ...91-694,785-792 
  ...ineCommand.ts |     100 |      100 |     100 |     100 |                   
  ...aryCommand.ts |    6.43 |      100 |      50 |    6.43 | 31-330            
  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 | 73,147            
  vimCommand.ts    |   54.54 |      100 |      50 |   54.54 | 19-29             
  voice-command.ts |   93.57 |       88 |     100 |   93.57 | 35,97-102         
  ...owsCommand.ts |   91.82 |    78.87 |   66.66 |   91.82 | ...59-160,169-174 
 src/ui/components |    69.5 |     78.2 |   76.11 |    69.5 |                   
  AboutBox.tsx     |     100 |      100 |     100 |     100 |                   
  ...ateScreen.tsx |   97.29 |     87.5 |   66.66 |   97.29 | 49                
  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 |   86.72 |    86.66 |     100 |   86.72 | ...00-302,355-359 
  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 | 18                
  ...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-596             
  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       |   78.39 |    63.15 |     100 |   78.39 | ...24-229,247-251 
  ...ngSpinner.tsx |   68.42 |    85.71 |      50 |   68.42 | 35-52,73,80-81    
  GoalPill.tsx     |   83.33 |    76.92 |     100 |   83.33 | 24-30             
  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 |   78.22 |    64.28 |     100 |   78.22 | ...94,497,500-506 
  ...ngeDialog.tsx |     100 |      100 |     100 |     100 |                   
  InputPrompt.tsx  |   82.25 |    79.81 |      80 |   82.25 | ...2161,2187,2247 
  ...Shortcuts.tsx |   20.65 |      100 |       0 |   20.65 | ...7,50-52,68-126 
  ...Indicator.tsx |   98.18 |    97.82 |     100 |   98.18 | 161-162           
  ...firmation.tsx |   91.42 |      100 |      50 |   91.42 | 26-31             
  MainContent.tsx  |   95.54 |    93.84 |      50 |   95.54 | ...93,436-440,443 
  MemoryDialog.tsx |   86.59 |    80.15 |     100 |   86.59 | ...34-435,485,553 
  ...geDisplay.tsx |       0 |        0 |       0 |       0 | 1-41              
  ModelDialog.tsx  |   86.41 |       73 |     100 |   86.41 | ...74,876,881-897 
  ...tsDisplay.tsx |     100 |    97.22 |     100 |     100 | 270               
  ...fications.tsx |       0 |        0 |       0 |       0 | 1-58              
  ...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 |    84.21 |     100 |   93.58 | ...,70-71,195-197 
  ...ryDisplay.tsx |     100 |      100 |     100 |     100 |                   
  ...putPrompt.tsx |   72.56 |       80 |      40 |   72.56 | ...06-109,114-117 
  ...tedDialog.tsx |     100 |      100 |     100 |     100 |                   
  ...ngsDialog.tsx |   71.47 |    73.89 |   69.23 |   71.47 | ...1243,1249-1250 
  ...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 |    5.46 |      100 |       0 |    5.46 | 24-215            
  ...ineDialog.tsx |    93.5 |    85.18 |     100 |    93.5 | ...05,267,287-289 
  ...yTodoList.tsx |   96.33 |    88.23 |     100 |   96.33 | 137-140           
  ...nsDisplay.tsx |   92.95 |       85 |     100 |   92.95 | ...79,182,209-211 
  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             
  ...criptView.tsx |   98.27 |    84.21 |     100 |   98.27 | 45,53             
  TrustDialog.tsx  |     100 |    81.81 |     100 |     100 | 71-86             
  ...ification.tsx |       0 |        0 |       0 |       0 | 1-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 |   53.72 |    70.87 |   42.85 |   53.72 |                   
  ...atContent.tsx |    9.09 |      100 |       0 |    9.09 | 54-275,281-283    
  ...tChatView.tsx |   21.05 |      100 |       0 |   21.05 | 21-39             
  ...tComposer.tsx |   64.78 |    29.41 |   33.33 |   64.78 | ...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.38 |    68.69 |   73.68 |   42.38 |                   
  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-164             
  ...tusDialog.tsx |       0 |        0 |       0 |       0 | 1-288             
  ...topDialog.tsx |       0 |        0 |       0 |       0 | 1-213             
 ...ackground-view |    82.2 |    81.36 |    90.9 |    82.2 |                   
  ...sksDialog.tsx |   77.53 |     76.9 |   80.76 |   77.53 | ...1781,1803-1809 
  ...TasksPill.tsx |   67.03 |     86.2 |     100 |   67.03 | ...02-122,130-138 
  ...gentPanel.tsx |   97.08 |    86.31 |     100 |   97.08 | 132,442-446,520   
  agent-forest.ts  |    99.2 |    93.93 |     100 |    99.2 | 256               
  ...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.86 |    68.14 |   70.83 |   71.86 |                   
  DiscoverTab.tsx  |   68.22 |    67.66 |   55.55 |   68.22 | ...93,656-660,664 
  InstalledTab.tsx |   75.45 |    67.28 |   83.33 |   75.45 | ...76,781-782,819 
  SourcesTab.tsx   |   71.52 |    70.47 |   77.77 |   71.52 | ...27,546,618-630 
 ...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 |   86.99 |    81.37 |   91.89 |   86.99 |                   
  ...rListBody.tsx |   95.29 |    85.18 |     100 |   95.29 | 95-98             
  ...etailStep.tsx |   75.32 |    71.42 |      60 |   75.32 | ...56-169,173-186 
  ...etailStep.tsx |     100 |      100 |     100 |     100 |                   
  ...rListStep.tsx |     100 |      100 |     100 |     100 |                   
  ...entHeader.tsx |     100 |    85.71 |     100 |     100 | 47                
  ...rListStep.tsx |     100 |      100 |     100 |     100 |                   
  ...etailStep.tsx |     100 |      100 |     100 |     100 |                   
  ...abledStep.tsx |     100 |      100 |     100 |     100 |                   
  ...sListStep.tsx |     100 |      100 |     100 |     100 |                   
  ...entDialog.tsx |   72.29 |    70.49 |     100 |   72.29 | ...51,563-568,572 
  constants.ts     |     100 |      100 |     100 |     100 |                   
  index.ts         |       0 |        0 |       0 |       0 | 1-13              
  ...erGrouping.ts |     100 |      100 |     100 |     100 |                   
  sourceLabels.ts  |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...components/mcp |   40.04 |    61.53 |   70.58 |   40.04 |                   
  ...ealthPill.tsx |   68.42 |    85.71 |     100 |   68.42 | 40-46             
  ...entDialog.tsx |   32.09 |    26.19 |      40 |   32.09 | ...12,914,927-933 
  ...valDialog.tsx |   15.06 |      100 |       0 |   15.06 | 40-109            
  constants.ts     |     100 |      100 |     100 |     100 |                   
  index.ts         |       0 |        0 |       0 |       0 | 1-35              
  types.ts         |     100 |      100 |     100 |     100 |                   
  utils.ts         |      97 |       95 |     100 |      97 | 24,113-114        
 ...ents/mcp/steps |    53.9 |    73.51 |   57.14 |    53.9 |                   
  ...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.46 |    81.25 |     100 |   88.46 | ...63,169,174-179 
  ...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 |   88.53 |    85.77 |   82.29 |   88.53 |                   
  ...ionDialog.tsx |   89.23 |    84.27 |   81.81 |   89.23 | ...75,593,611-613 
  BtwMessage.tsx   |     100 |      100 |     100 |     100 |                   
  ...upDisplay.tsx |     100 |    94.79 |     100 |     100 | 38,42,44,290,366  
  ...onMessage.tsx |   91.93 |    82.35 |     100 |   91.93 | 57-59,61,63       
  ...nMessages.tsx |   92.16 |     92.3 |   91.66 |   92.16 | ...82-286,304-310 
  DiffRenderer.tsx |   93.15 |    86.17 |     100 |   93.15 | ...07,235-236,302 
  ...tsDisplay.tsx |   97.08 |    77.77 |     100 |   97.08 | 95,97,106         
  ...usMessage.tsx |   76.31 |     42.1 |   66.66 |   76.31 | ...99,101,124,155 
  ...tsDisplay.tsx |    95.5 |    88.31 |     100 |    95.5 | ...39,141,174-179 
  ...ssMessage.tsx |    12.5 |      100 |       0 |    12.5 | 18-59             
  ...edMessage.tsx |   16.66 |      100 |       0 |   16.66 | 22-38             
  ...sMessages.tsx |   58.65 |       50 |    37.5 |   58.65 | ...20-125,146-158 
  ...ryMessage.tsx |   14.28 |      100 |       0 |   14.28 | 23-62             
  ...onMessage.tsx |   82.16 |    74.02 |   33.33 |   82.16 | ...77-479,486-488 
  ...upMessage.tsx |   98.32 |    95.16 |     100 |   98.32 | 183-186,413       
  ToolMessage.tsx  |   92.31 |    85.12 |   93.33 |   92.31 | ...40-945,972-974 
 ...ponents/shared |   85.58 |    81.92 |   93.93 |   85.58 |                   
  ...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  |   83.01 |    86.15 |   88.88 |   83.01 | ...17-518,623-624 
  MultiSelect.tsx  |   93.58 |       75 |     100 |   93.58 | ...43,199-201,211 
  ...tonSelect.tsx |     100 |      100 |     100 |     100 |                   
  ...ontroller.tsx |     100 |    83.33 |     100 |     100 | 73,93-95          
  ...eSelector.tsx |     100 |       60 |     100 |     100 | 40-45             
  ...lableList.tsx |   81.48 |    84.84 |     100 |   81.48 | 46-66,73-76       
  StaticRender.tsx |   72.72 |      100 |     100 |   72.72 | 31-33             
  TextInput.tsx    |    80.8 |    67.24 |      80 |    80.8 | ...36-240,252-258 
  ...ontroller.tsx |     100 |    81.81 |     100 |     100 | 59-62             
  ...apsedTime.tsx |     100 |      100 |     100 |     100 |                   
  ...Indicator.tsx |     100 |      100 |     100 |     100 |                   
  ...lizedList.tsx |   88.46 |    85.11 |   81.81 |   88.46 | ...51-779,792,883 
  text-buffer.ts   |   85.94 |    81.73 |   97.91 |   85.94 | ...2651,2749-2750 
  ...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-678             
 ...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.04 |    53.19 |    37.5 |   14.04 |                   
  ...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.42 |    59.52 |     100 |   35.42 | ...20-432,437-439 
  ...iewerStep.tsx |       0 |        0 |       0 |       0 | 1-73              
  ...gerDialog.tsx |       0 |        0 |       0 |       0 | 1-341             
 ...mponents/views |   69.81 |    72.64 |   61.11 |   69.81 |                   
  ContextUsage.tsx |   70.88 |    63.88 |      80 |   70.88 | ...20-426,463-557 
  DoctorReport.tsx |     9.8 |      100 |       0 |     9.8 | 25-54,57-131      
  ...sionsList.tsx |   88.05 |       75 |     100 |   88.05 | 70-77             
  McpStatus.tsx    |   92.01 |     73.8 |     100 |   92.01 | ...36,175-177,262 
  SkillsList.tsx   |   20.51 |      100 |       0 |   20.51 | 17-20,27-57       
  ToolsList.tsx    |     100 |      100 |     100 |     100 |                   
 src/ui/contexts   |   82.17 |    79.38 |   84.37 |   82.17 |                   
  ...ewContext.tsx |   64.83 |    88.88 |      50 |   64.83 | ...16-219,225-235 
  AppContext.tsx   |      80 |       50 |     100 |      80 | 19-20             
  ...ewContext.tsx |   92.45 |    62.79 |      50 |   92.45 | ...69-270,272-276 
  ...igContext.tsx |   81.81 |       50 |     100 |   81.81 | 15-16             
  ...ssContext.tsx |   83.18 |    83.54 |     100 |   83.18 | ...1289,1297-1299 
  ...owContext.tsx |   91.07 |    81.81 |     100 |   91.07 | 47-48,60-62       
  ...deContext.tsx |     100 |      100 |      50 |     100 |                   
  ...onContext.tsx |   78.68 |    73.33 |   91.66 |   78.68 | ...86-389,398-401 
  ...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 | 150-151           
  ...teContext.tsx |   86.66 |       50 |     100 |   86.66 | 233-234           
  ...deContext.tsx |      80 |     87.5 |      75 |      80 | ...11-112,118-120 
 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      |   83.76 |    81.53 |   88.25 |   83.76 |                   
  ...dProcessor.ts |   81.73 |    81.69 |     100 |   81.73 | ...41-742,748-753 
  ...ention-ref.ts |   97.67 |       84 |     100 |   97.67 | 65                
  keyToAnsi.ts     |    3.92 |      100 |       0 |    3.92 | 19-77             
  ...esourceRef.ts |     100 |      100 |     100 |     100 |                   
  ...dProcessor.ts |   94.62 |    73.58 |     100 |   94.62 | ...86-287,292-293 
  ...dProcessor.ts |   85.14 |    66.27 |   81.81 |   85.14 | ...1400,1421-1425 
  ...rt-command.ts |     100 |      100 |     100 |     100 |                   
  ...sced-flush.ts |     100 |      100 |     100 |     100 |                   
  ...oice-input.ts |   92.36 |    81.95 |   66.66 |   92.36 | ...00,502-503,658 
  ...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 |   89.83 |    88.97 |     100 |   89.83 | ...49-456,496-505 
  ...ifications.ts |   87.82 |    96.77 |     100 |   87.82 | 138-152           
  ...tIndicator.ts |   88.28 |    81.08 |     100 |   88.28 | ...66,175,179-187 
  ...waySummary.ts |   96.22 |    69.69 |     100 |   96.22 | 125-127,169       
  ...ndTaskView.ts |   94.73 |    76.59 |     100 |   94.73 | 162-166,255,261   
  ...chedScroll.ts |     100 |      100 |     100 |     100 |                   
  ...ketedPaste.ts |    23.8 |      100 |       0 |    23.8 | 19-37             
  ...nchCommand.ts |   87.55 |       75 |     100 |   87.55 | ...85-288,294-297 
  ...ompletion.tsx |   96.75 |    81.81 |     100 |   96.75 | ...78-279,289-290 
  ...dMigration.ts |    92.1 |    88.88 |     100 |    92.1 | 42-44             
  useCompletion.ts |   94.11 |    89.65 |     100 |   94.11 | ...32-133,137-138 
  ...nitMessage.ts |     100 |      100 |     100 |     100 |                   
  ...extualTips.ts |   78.26 |       50 |     100 |   78.26 | ...2,75-79,96-104 
  ...eteCommand.ts |   78.53 |    88.57 |     100 |   78.53 | ...96-104,112-113 
  ...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 |      100 |     100 |     100 |                   
  ...ggestions.tsx |   96.47 |    78.94 |     100 |   96.47 | 121,155-156       
  ...miniStream.ts |   83.43 |    79.27 |    92.3 |   83.43 | ...3744,3829-3837 
  ...BranchName.ts |     100 |    91.66 |     100 |     100 | 30                
  ...oryManager.ts |   98.01 |    98.36 |     100 |   98.01 | 139-142           
  ...ooksDialog.ts |    87.5 |      100 |     100 |    87.5 | 19,23             
  ...stListener.ts |     100 |      100 |     100 |     100 |                   
  ...nAuthError.ts |   76.19 |       50 |     100 |   76.19 | 39-40,43-45       
  ...putHistory.ts |   92.59 |    85.71 |     100 |   92.59 | 63-64,72,94-96    
  ...storyStore.ts |     100 |    94.11 |     100 |     100 | 69                
  useKeypress.ts   |     100 |      100 |     100 |     100 |                   
  ...rdProtocol.ts |   36.36 |      100 |       0 |   36.36 | 24-31             
  ...unchEditor.ts |       0 |        0 |       0 |       0 | 1-90              
  ...gIndicator.ts |     100 |    96.66 |     100 |     100 | 109               
  useLogger.ts     |      16 |      100 |       0 |      16 | 15-45             
  useMCPHealth.ts  |   63.15 |       80 |      50 |   63.15 | 42-52,64-67       
  ...cpApproval.ts |   93.12 |    86.11 |     100 |   93.12 | ...24-127,139-140 
  useMcpDialog.ts  |    87.5 |      100 |     100 |    87.5 | 19,23             
  ...moryDialog.ts |    87.5 |      100 |     100 |    87.5 | 19,23             
  ...oryMonitor.ts |   83.14 |    78.57 |     100 |   83.14 | 54-63,74-79       
  ...ssageQueue.ts |     100 |    96.55 |     100 |     100 | 73                
  ...delCommand.ts |     100 |    92.85 |     100 |     100 | 48                
  ...ouseEvents.ts |   94.31 |     97.5 |   83.33 |   94.31 | 76-80             
  ...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 |   86.95 |    77.41 |   91.66 |   86.95 | ...70,311-323,371 
  useQwenAuth.ts   |     100 |      100 |     100 |     100 |                   
  ...lScheduler.ts |   91.43 |    89.55 |     100 |   91.43 | ...45-348,463-473 
  ...oryCommand.ts |       0 |        0 |       0 |       0 | 1-7               
  ...tleRepaint.ts |     100 |      100 |     100 |     100 |                   
  ...umeCommand.ts |    87.3 |    70.83 |     100 |    87.3 | ...04-209,225-228 
  ...ompletion.tsx |   90.67 |    83.33 |     100 |   90.67 | ...02,105,138-141 
  ...ectionList.ts |   97.12 |    96.19 |     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 |       0 |        0 |       0 |       0 | 1-73              
  ...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 |   53.06 |       50 |   66.66 |   53.06 | ...53,61-68,79-85 
  ...rminalSize.ts |   76.19 |      100 |      50 |   76.19 | 21-25             
  ...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 |      100 |     100 |     100 |                   
  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 |    72.72 |     100 |   93.75 | 47-48,72          
  vim.ts           |      74 |    67.56 |   69.23 |      74 | ...1854-1861,1869 
 src/ui/layouts    |    90.8 |    87.87 |     100 |    90.8 |                   
  ...AppLayout.tsx |   90.47 |    85.71 |     100 |   90.47 | 59-61,103-108,144 
  ...AppLayout.tsx |    91.3 |    91.66 |     100 |    91.3 | 71-76             
 src/ui/models     |   80.24 |    79.16 |   71.42 |   80.24 |                   
  ...ableModels.ts |   80.24 |    79.16 |   71.42 |   80.24 | ...,61-71,123-125 
 ...noninteractive |     100 |      100 |    6.66 |     100 |                   
  ...eractiveUi.ts |     100 |      100 |    6.66 |     100 |                   
 src/ui/selection  |    85.2 |    75.78 |   96.42 |    85.2 |                   
  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 |   88.46 |    91.66 |     100 |   88.46 | 31-33             
  ...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      |   85.32 |    84.65 |   94.01 |   85.32 |                   
  ...Colorizer.tsx |   80.31 |    85.41 |     100 |   80.31 | ...00-201,313-339 
  ...nRenderer.tsx |   68.83 |    70.14 |      50 |   68.83 | ...52-254,274-293 
  ...wnDisplay.tsx |   92.85 |    93.46 |     100 |   92.85 | ...,953,1000-1018 
  ...idDiagram.tsx |   87.79 |    95.34 |     100 |   87.79 | 156-179           
  ...eRenderer.tsx |   92.68 |    82.35 |   95.23 |   92.68 | ...34-737,790-795 
  ...odeDisplay.ts |   94.28 |    85.71 |     100 |   94.28 | 23,40             
  asciiCharts.ts   |   96.77 |    87.62 |     100 |   96.77 | 173-180,281       
  ...dWorkUtils.ts |     100 |      100 |     100 |     100 |                   
  ...boardUtils.ts |   52.52 |    73.25 |   91.66 |   52.52 | ...23,626-635,638 
  commandUtils.ts  |    96.1 |    88.65 |     100 |    96.1 | ...73,175-176,320 
  computeStats.ts  |     100 |      100 |     100 |     100 |                   
  customBanner.ts  |   90.68 |    91.22 |     100 |   90.68 | ...13,324-327,334 
  displayUtils.ts  |   90.38 |    73.91 |     100 |   90.38 | 23,25,29,31,33    
  formatters.ts    |    95.4 |    98.43 |     100 |    95.4 | 123-126           
  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  |    95.4 |    95.08 |     100 |    95.4 | 96-99             
  input-mouse.ts   |     100 |    85.71 |     100 |     100 | 48,93             
  isNarrowWidth.ts |     100 |      100 |     100 |     100 |                   
  ...olDetector.ts |    8.23 |      100 |       0 |    8.23 | ...31-132,135-136 
  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.59 |     100 |   98.72 | 145-146           
  ...t-position.ts |     100 |     87.5 |     100 |     100 | 85                
  ...geRenderer.ts |   86.23 |    69.06 |   95.12 |   86.23 | ...1284,1324-1330 
  ...alRenderer.ts |   86.69 |     71.9 |     100 |   86.69 | ...1476,1513-1519 
  ...lsBySource.ts |     100 |    95.23 |     100 |     100 | 84                
  mouse.ts         |   92.85 |    73.77 |     100 |   92.85 | ...38,145,149-152 
  osc8.ts          |   94.84 |    88.74 |     100 |   94.84 | ...57,442,446-447 
  ...red-height.ts |   96.85 |    95.45 |     100 |   96.85 | 71-73,201-203     
  ...mConstants.ts |     100 |      100 |     100 |     100 |                   
  restoreGoal.ts   |     100 |      100 |     100 |     100 |                   
  ...storyUtils.ts |   71.02 |    78.86 |   93.75 |   71.02 | ...03-525,655-656 
  ...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           
  ...wOptimizer.ts |     100 |    96.77 |     100 |     100 | 69                
  terminalSetup.ts |    4.37 |      100 |       0 |    4.37 | 44-393            
  textUtils.ts     |   94.73 |    91.52 |   94.44 |   94.73 | ...21-322,482-483 
  ...background.ts |     100 |      100 |     100 |     100 |                   
  todoSnapshot.ts  |   89.65 |       92 |     100 |   89.65 | ...83-184,217-218 
  ...isplay-map.ts |     100 |      100 |     100 |     100 |                   
  updateCheck.ts   |     100 |    81.81 |     100 |     100 | 34,81-93,184      
  ...ow-keyword.ts |     100 |      100 |     100 |     100 |                   
 ...i/utils/export |      75 |    59.68 |   94.59 |      75 |                   
  collect.ts       |   71.21 |    65.51 |      96 |   71.21 | ...88-631,653-654 
  index.ts         |     100 |      100 |     100 |     100 |                   
  normalize.ts     |   80.42 |    50.68 |     100 |   80.42 | ...59-364,376-378 
  types.ts         |       0 |        0 |       0 |       0 | 1                 
  utils.ts         |     100 |      100 |     100 |     100 |                   
 ...ort/formatters |   52.92 |    47.22 |   71.42 |   52.92 |                   
  html.ts          |   84.61 |       50 |     100 |   84.61 | ...53,57-58,62-63 
  json.ts          |     100 |      100 |     100 |     100 |                   
  jsonl.ts         |   82.45 |     37.5 |     100 |   82.45 | ...48,50-51,65-66 
  markdown.ts      |   36.32 |    47.05 |      50 |   36.32 | ...16-219,233-295 
 src/ui/voice      |   80.94 |    72.69 |   80.55 |   80.94 |                   
  ...d-recorder.ts |     6.2 |      100 |       0 |     6.2 | ...33-159,162-163 
  ...o-recorder.ts |   84.61 |    93.33 |   57.14 |   84.61 | ...16-117,131-136 
  ...me-session.ts |   89.72 |    65.33 |   93.75 |   89.72 | ...99,305,316-319 
  sox-recorder.ts  |    92.7 |    71.87 |     100 |    92.7 | ...34-135,153-154 
  ...ailability.ts |     100 |      100 |     100 |     100 |                   
  ...e-keyterms.ts |     100 |      100 |     100 |     100 |                   
  voice-model.ts   |     100 |      100 |     100 |     100 |                   
  ...e-recorder.ts |   88.29 |    67.74 |   81.81 |   88.29 | ...,98-99,112,115 
  voice-refine.ts  |     100 |    93.33 |     100 |     100 | 92                
  ...ream-retry.ts |   86.79 |    68.42 |     100 |   86.79 | 16-18,48-49,59-60 
  ...am-session.ts |   88.02 |    66.66 |   84.61 |   88.02 | ...26,343-345,363 
  ...ranscriber.ts |     100 |      100 |     100 |     100 |                   
 src/utils         |   77.91 |    88.46 |   90.28 |   77.91 |                   
  ...p-profiler.ts |   98.39 |    90.56 |     100 |   98.39 | 141,185,235       
  acpModelUtils.ts |    97.3 |    95.09 |     100 |    97.3 | ...04-205,209-210 
  apiPreconnect.ts |   96.72 |    97.05 |     100 |   96.72 | 165-168           
  ...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       |   82.53 |    93.33 |      80 |   82.53 | 74,105-115        
  commands.ts      |   96.96 |    97.95 |     100 |   96.96 | 123-125           
  commentJson.ts   |   90.51 |     92.1 |     100 |   90.51 | 67-76,116         
  ...Calculator.ts |     100 |      100 |     100 |     100 |                   
  cpuProfiler.ts   |   70.38 |    71.83 |   88.88 |   70.38 | ...27,430-431,438 
  deepMerge.ts     |     100 |       90 |     100 |     100 | 41-43,49          
  ...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.17 |     100 |   90.65 | ...72,370,372-373 
  ...arResolver.ts |   97.14 |    96.55 |     100 |   97.14 | 125-126           
  errors.ts        |   97.56 |    94.73 |     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.7 |    84.09 |     100 |    92.7 | ...07-110,158-161 
  ...AutoUpdate.ts |   92.89 |    94.59 |   88.88 |   92.89 | 148-159           
  ...tyWarnings.ts |     100 |      100 |     100 |     100 |                   
  ...lationInfo.ts |   97.45 |       94 |     100 |   97.45 | ...17,334-335,380 
  languageUtils.ts |   98.88 |    97.01 |     100 |   98.88 | 184-185           
  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.5 |      100 |   88.88 |    97.5 | 195-196           
  package.ts       |   88.88 |    85.71 |     100 |   88.88 | 31-32             
  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.83 |    88.88 |     100 |   95.83 | 101-103,129       
  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       |   17.91 |    58.33 |   23.07 |   17.91 | ...0-778,785-1062 
  ...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.85 |    77.44 |   62.16 |   39.85 | ...1190,1193-1212 
  ...upProfiler.ts |   98.47 |    94.66 |     100 |   98.47 | 132-133,308       
  ...upWarnings.ts |     100 |      100 |     100 |     100 |                   
  stdioHelpers.ts  |     100 |     87.5 |     100 |     100 | 23                
  systemInfo.ts    |   95.12 |    90.27 |     100 |   95.12 | ...54-255,260-264 
  ...InfoFields.ts |    87.5 |    65.85 |     100 |    87.5 | ...24-125,146-147 
  ...alSequence.ts |     100 |    97.61 |     100 |     100 | 60                
  ...iffPreview.ts |   76.47 |       25 |     100 |   76.47 | 13,17,23-24       
  ...e-relaunch.ts |   88.46 |    81.25 |   66.66 |   88.46 | 55-60,71,84-85    
  ...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          |   86.84 |    85.95 |   88.23 |   86.84 |                   
 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.65 |    84.26 |   95.45 |   90.65 |                   
  ...transcript.ts |    92.6 |    88.88 |     100 |    92.6 | ...51,370-371,502 
  ...ent-resume.ts |   83.53 |    72.79 |   79.41 |   83.53 | ...1285-1289,1292 
  ...ound-tasks.ts |   96.69 |    91.31 |     100 |   96.69 | ...1515,1535-1538 
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...ent-result.ts |    96.8 |    92.68 |     100 |    96.8 | 106,129-131       
  ...n-registry.ts |   95.65 |    89.28 |     100 |   95.65 | ...12-413,485-489 
  ...w-snapshot.ts |   91.86 |       75 |     100 |   91.86 | ...54,178,185-187 
 src/agents/arena  |    76.9 |    68.22 |   78.94 |    76.9 |                   
  ...gentClient.ts |   79.47 |    88.88 |   81.81 |   79.47 | ...68-183,189-204 
  ArenaManager.ts  |   75.83 |     65.2 |   78.57 |   75.83 | ...1876,1882-1883 
  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.02 |    85.19 |   76.28 |   78.02 |                   
  ITermBackend.ts  |   97.97 |    93.93 |     100 |   97.97 | ...78-180,255,307 
  ...essBackend.ts |    90.8 |    85.24 |   93.33 |    90.8 | ...64,666,668-669 
  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 |   88.43 |    85.84 |   83.54 |   88.43 |                   
  agent-context.ts |     100 |      100 |     100 |     100 |                   
  agent-core.ts    |   79.81 |    76.22 |      68 |   79.81 | ...2036,2063-2110 
  agent-events.ts  |     100 |      100 |     100 |     100 |                   
  ...t-headless.ts |   87.93 |    79.06 |   63.63 |   87.93 | ...00-401,404-405 
  ...nteractive.ts |   81.01 |    82.35 |   76.66 |   81.01 | ...33,535-538,541 
  ...statistics.ts |   98.19 |    82.35 |     100 |   98.19 | 127,151,192,225   
  agent-types.ts   |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...ool-policy.ts |   98.34 |      100 |    92.3 |   98.34 | 81-82             
  ...low-budget.ts |     100 |      100 |     100 |     100 |                   
  ...ow-journal.ts |   91.76 |    75.86 |     100 |   91.76 | ...38-139,179-181 
  ...chestrator.ts |   91.79 |    87.79 |   82.35 |   91.79 | ...1774,1823-1826 
  ...ow-prompts.ts |     100 |      100 |     100 |     100 |                   
  ...ow-sandbox.ts |   96.87 |    94.51 |     100 |   96.87 | ...24-325,330-331 
  ...flow-saved.ts |   96.51 |    94.36 |     100 |   96.51 | 134-135,234-237   
  ...flow-stall.ts |    97.9 |    83.33 |     100 |    97.9 | 138-139,236       
 src/agents/tasks  |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/agents/team   |   81.86 |    84.09 |    87.4 |   81.86 |                   
  TeamManager.ts   |    72.1 |     79.6 |   78.84 |    72.1 | ...1628,1651-1652 
  identity.ts      |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...sionBridge.ts |     100 |      100 |     100 |     100 |                   
  mailbox.ts       |   94.76 |    86.36 |   92.85 |   94.76 | 86-87,348-354     
  ...ptAddendum.ts |     100 |      100 |     100 |     100 |                   
  tasks.ts         |   88.85 |    82.56 |   96.29 |   88.85 | ...-990,1034-1035 
  team-events.ts   |   60.52 |      100 |      50 |   60.52 | ...37-141,148-152 
  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.17 |    86.28 |    72.5 |   84.17 |                   
  approval-mode.ts |     100 |      100 |     100 |     100 |                   
  ...xtDefaults.ts |     100 |      100 |     100 |     100 |                   
  config.ts        |    83.4 |    85.81 |   70.36 |    83.4 | ...7449,7453-7454 
  constants.ts     |     100 |      100 |     100 |     100 |                   
  models.ts        |     100 |      100 |     100 |     100 |                   
  storage.ts       |   94.11 |     93.1 |      88 |   94.11 | ...25-426,429-430 
 ...nfirmation-bus |   98.29 |    97.14 |     100 |   98.29 |                   
  message-bus.ts   |   98.14 |    97.05 |     100 |   98.14 | 42-43             
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/core          |   91.45 |    87.02 |   93.14 |   91.45 |                   
  baseLlmClient.ts |   88.28 |    82.48 |   81.81 |   88.28 | ...47,660,666-668 
  client.ts        |   90.64 |    85.47 |    91.3 |   90.64 | ...3059,3155-3156 
  ...tGenerator.ts |   88.07 |       75 |     100 |   88.07 | ...89-393,401-405 
  ...lScheduler.ts |   90.39 |    85.31 |   95.78 |   90.39 | ...5073,5101-5112 
  geminiChat.ts    |   91.74 |     89.2 |   95.65 |   91.74 | ...4043,4091-4092 
  geminiRequest.ts |     100 |      100 |     100 |     100 |                   
  ...MediaLimit.ts |     100 |    95.83 |     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 |   92.59 |       75 |      50 |   92.59 | 41-42             
  ...on-helpers.ts |   92.03 |    76.19 |     100 |   92.03 | ...00-201,218-219 
  ...issionFlow.ts |   98.96 |    96.96 |     100 |   98.96 | 106               
  prompts.ts       |   92.17 |    88.23 |   78.57 |   92.17 | ...-961,1164-1165 
  ...ing-effort.ts |     100 |      100 |     100 |     100 |                   
  ...n-recovery.ts |   95.13 |       80 |     100 |   95.13 | ...06-107,142-144 
  ...t-profiler.ts |   96.89 |    80.88 |   88.23 |   96.89 | ...10,117-118,123 
  ...port-retry.ts |     100 |      100 |     100 |     100 |                   
  tokenLimits.ts   |     100 |     92.3 |     100 |     100 | 87,122-123        
  ...reparation.ts |     100 |      100 |     100 |     100 |                   
  ...allIdUtils.ts |   98.41 |    93.02 |     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.49 |    91.17 |     100 |   98.49 | ...93,621-622,668 
 ...ntentGenerator |   96.31 |    87.24 |   95.31 |   96.31 |                   
  ...tGenerator.ts |   97.52 |    87.74 |   94.28 |   97.52 | ...1235-1239,1279 
  converter.ts     |   96.03 |     86.8 |     100 |   96.03 | ...,928,1083-1085 
  index.ts         |       0 |        0 |       0 |       0 | 1-21              
  usage.ts         |     100 |      100 |     100 |     100 |                   
 ...ntentGenerator |   89.93 |    71.83 |   93.33 |   89.93 |                   
  ...tGenerator.ts |    88.3 |    71.21 |   92.85 |    88.3 | ...19-325,343-344 
  index.ts         |     100 |       80 |     100 |     100 | 50                
 ...ntentGenerator |    94.7 |    85.66 |    92.1 |    94.7 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...tGenerator.ts |    94.6 |     84.5 |   91.66 |    94.6 | ...1129-1130,1158 
  ...tDetection.ts |     100 |      100 |     100 |     100 |                   
 ...ntentGenerator |   91.17 |    89.22 |   95.09 |   91.17 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  converter.ts     |   90.45 |    87.69 |   96.87 |   90.45 | ...1864,2033-2048 
  errorHandler.ts  |     100 |      100 |     100 |     100 |                   
  index.ts         |   60.31 |       75 |      50 |   60.31 | ...71,74-78,90-94 
  ...tGenerator.ts |    66.4 |    70.58 |   88.88 |    66.4 | ...51-157,168-169 
  pipeline.ts      |   96.66 |    90.21 |     100 |   96.66 | ...1021,1029,1097 
  ...ureContext.ts |     100 |      100 |     100 |     100 |                   
  ...ingOptions.ts |       0 |        0 |       0 |       0 | 1                 
  ...CallParser.ts |    92.2 |     92.4 |     100 |    92.2 | ...15-516,536-539 
  ...kingParser.ts |     100 |    96.87 |     100 |     100 | 42                
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 ...rator/provider |   96.48 |    89.54 |   96.55 |   96.48 |                   
  dashscope.ts     |   97.45 |    91.79 |      95 |   97.45 | ...76-377,519-520 
  deepseek.ts      |   94.91 |    89.36 |     100 |   94.91 | ...31-132,145-146 
  default.ts       |    97.5 |    96.55 |   88.88 |    97.5 | 123-124,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.05 |    82.91 |   92.19 |   86.05 |                   
  ...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.69 |    85.18 |   97.82 |   90.69 | ...1189-1195,1239 
  ...ionManager.ts |   80.56 |    77.97 |   80.23 |   80.56 | ...2577,2599-2600 
  ...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.35 |    82.13 |     100 |   88.35 | ...42,932-933,943 
  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      |   77.94 |    79.45 |    90.9 |   77.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   |      66 |    60.46 |   71.42 |      66 | ...87-588,595-596 
  ...onToolGate.ts |     100 |    96.55 |     100 |     100 | 96                
  ...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         |   92.24 |    87.05 |   95.12 |   92.24 |                   
  ...eGoalStore.ts |   87.61 |    89.28 |   86.66 |   87.61 | ...85-188,196-204 
  goalHook.ts      |    96.7 |    93.33 |     100 |    96.7 | 99-104,205-206    
  goalJudge.ts     |   90.07 |     81.7 |     100 |   90.07 | ...35-336,379-380 
  index.ts         |     100 |      100 |     100 |     100 |                   
 src/hooks         |   87.49 |    86.12 |   88.69 |   87.49 |                   
  ...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.43 |    84.53 |   94.59 |   95.43 | ...1010-1011,1021 
  hookPlanner.ts   |    87.5 |    85.18 |   86.66 |    87.5 | ...21-225,232-243 
  hookRegistry.ts  |   92.53 |    85.43 |     100 |   92.53 | ...39,458,462,466 
  hookRunner.ts    |   62.42 |    72.04 |   66.66 |   62.42 | ...64-765,774-775 
  hookSystem.ts    |    87.5 |      100 |   70.21 |    87.5 | ...43-744,750-751 
  ...HookRunner.ts |   75.51 |     61.9 |      80 |   75.51 | ...05-406,424-425 
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...edCallback.ts |     100 |      100 |     100 |     100 |                   
  ...HookRunner.ts |   96.37 |     90.9 |      90 |   96.37 | 342-350,424-425   
  ...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     |   77.22 |    85.36 |     100 |   77.22 | ...57,261-267,273 
  stopHookCap.ts   |     100 |      100 |     100 |     100 |                   
  trustedHooks.ts  |      90 |    52.63 |     100 |      90 | ...53,66-67,97-98 
  types.ts         |   94.24 |    96.09 |   88.88 |   94.24 | ...42-543,628-632 
  urlValidator.ts  |     100 |      100 |     100 |     100 |                   
 src/ide           |   76.87 |    84.98 |   79.03 |   76.87 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  detect-ide.ts    |     100 |      100 |     100 |     100 |                   
  ide-client.ts    |   68.92 |    84.57 |   68.29 |   68.92 | ...1057,1086-1094 
  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.39 |    77.81 |   78.33 |   82.39 |                   
  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.52 |    58.06 |     100 |   79.52 | ...33-940,947-949 
  ...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        |   86.88 |    82.52 |   90.06 |   86.88 |                   
  ...y-document.ts |   89.52 |    84.61 |     100 |   89.52 | ...24-325,329-330 
  ...nel-memory.ts |   97.11 |    95.72 |   96.29 |   97.11 | ...85-287,361-362 
  const.ts         |   94.28 |     92.3 |     100 |   94.28 | 66-67             
  dream.ts         |    64.6 |    72.22 |      50 |    64.6 | ...04-109,124-165 
  ...entPlanner.ts |     100 |    81.81 |     100 |     100 | 126,136           
  entries.ts       |   75.59 |    84.84 |   83.33 |   75.59 | ...56-157,172-180 
  extract.ts       |   91.48 |    75.75 |     100 |   91.48 | ...99,118-121,189 
  ...entPlanner.ts |   91.51 |    76.19 |     100 |   91.51 | ...04,113-116,290 
  ...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 |     100 |      100 |     100 |     100 |                   
  manager.ts       |   78.44 |    82.29 |   77.77 |   78.44 | ...1482,1495-1497 
  ...ent-config.ts |   82.27 |    77.92 |   83.33 |   82.27 | ...66,285,292-298 
  memoryAge.ts     |   90.47 |       80 |     100 |   90.47 | 50-51             
  paths.ts         |   94.73 |    95.94 |     100 |   94.73 | ...35-336,357-358 
  ...ing-skills.ts |     100 |       72 |     100 |     100 | 31-35,73-78,97    
  prompt.ts        |   96.96 |    85.96 |     100 |   96.96 | ...22,225,560-561 
  recall.ts        |   82.06 |       75 |    90.9 |   82.06 | ...59-364,395-406 
  refresh.ts       |   89.85 |    82.92 |     100 |   89.85 | ...54-155,162-163 
  ...ceSelector.ts |    93.1 |    81.81 |     100 |    93.1 | ...25,127-128,136 
  remember.ts      |   98.89 |    89.79 |     100 |   98.89 | 50,70             
  scan.ts          |   93.12 |    77.41 |     100 |   93.12 | ...08-109,154,157 
  ...et-scanner.ts |     100 |      100 |     100 |     100 |                   
  ...entPlanner.ts |   71.68 |    65.51 |   68.75 |   71.68 | ...90-394,397,403 
  status.ts        |   10.52 |      100 |       0 |   10.52 | 41-98             
  store.ts         |   93.33 |    81.25 |     100 |   93.33 | ...,94-95,119-120 
  ...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 |   79.38 |    78.33 |   81.81 |   79.38 | ...58-272,286-291 
 src/mocks         |       0 |        0 |       0 |       0 |                   
  msw.ts           |       0 |        0 |       0 |       0 | 1-9               
 src/models        |   92.41 |    88.58 |   91.13 |   92.41 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  ...tor-config.ts |   97.63 |       90 |     100 |   97.63 | 146,152,162       
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...nfigErrors.ts |   74.22 |    47.82 |   84.61 |   74.22 | ...,67-74,106-117 
  ...igResolver.ts |   98.71 |    93.33 |     100 |   98.71 | 166,328,334       
  modelRegistry.ts |     100 |    98.11 |     100 |     100 | 177,259           
  modelsConfig.ts  |   89.23 |    86.49 |   88.09 |   89.23 | ...1393,1422-1423 
  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.23 |     91.1 |   70.46 |   83.23 |                   
  autoMode.ts      |   97.78 |    94.14 |     100 |   97.78 | ...42,570-577,686 
  ...transcript.ts |      98 |    84.61 |     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 |   85.48 |     89.5 |      80 |   85.48 | ...1046,1152-1156 
  rule-parser.ts   |   93.96 |     91.6 |     100 |   93.96 | ...1303,1337-1339 
  ...-semantics.ts |   70.36 |    91.07 |   46.66 |   70.36 | ...2237,2300-2303 
  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     |   81.91 |    76.58 |   78.12 |   81.91 |                   
  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 |    72.6 |       70 |   73.91 |    72.6 | ...94-495,502-511 
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 ...viders/presets |   97.67 |    89.28 |   55.55 |   97.67 |                   
  ...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.3 |     78.8 |   95.89 |    85.3 |                   
  ...tGenerator.ts |   98.64 |    98.18 |     100 |   98.64 | 105-106           
  qwenOAuth2.ts    |   82.55 |    73.71 |   90.62 |   82.55 | ...1183-1199,1229 
  ...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      |   90.07 |    85.44 |   96.06 |   90.07 |                   
  ...ionTrailer.ts |     100 |      100 |     100 |     100 |                   
  ...llRegistry.ts |   97.35 |    85.34 |     100 |   97.35 | ...94,117,417-418 
  ...ionService.ts |   96.71 |    95.79 |     100 |   96.71 | ...83,699,832-840 
  ...ingService.ts |   88.92 |    85.02 |   88.52 |   88.92 | ...1799,1813-1814 
  ...ttribution.ts |   91.73 |    87.71 |      90 |   91.73 | ...80-685,826-827 
  ...utSlimming.ts |    97.2 |       94 |     100 |    97.2 | ...39-340,378-381 
  cronScheduler.ts |   94.29 |    91.06 |   97.91 |   94.29 | ...1274,1673-1674 
  cronTasksFile.ts |   94.76 |    89.77 |     100 |   94.76 | ...19,328-329,437 
  cronTasksLock.ts |   94.44 |    89.47 |     100 |   94.44 | ...02-103,132-133 
  ...eryService.ts |   96.22 |    93.54 |      90 |   96.22 | 121,155-156,161   
  ...oryService.ts |   88.17 |    79.02 |    92.3 |   88.17 | ...1303,1344-1347 
  fileReadCache.ts |     100 |      100 |     100 |     100 |                   
  ...temService.ts |   92.07 |    85.93 |    90.9 |   92.07 | ...09,211,323-330 
  ...ratedFiles.ts |      96 |    88.23 |     100 |      96 | 119-120,146-147   
  gitInit.ts       |     100 |      100 |     100 |     100 |                   
  ...reeService.ts |   74.05 |       69 |   95.74 |   74.05 | ...2170,2198-2199 
  ...references.ts |   98.39 |    88.88 |     100 |   98.39 | 154-155,215-216   
  ...ionService.ts |   98.22 |    97.34 |     100 |   98.22 | ...63-664,711-712 
  ...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.27 |    91.22 |     100 |   97.27 | ...50-451,606-607 
  ...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.16 |   97.14 |   94.49 | ...98-600,656-664 
  ...ipt-reader.ts |   94.27 |    88.34 |   97.95 |   94.27 | ...1019,1027-1028 
  ...iter-lease.ts |   78.97 |    80.21 |   90.62 |   78.97 | ...98-699,714-715 
  sessionRecap.ts  |   67.56 |    43.47 |     100 |   67.56 | ...60,178,180-183 
  ...ionService.ts |   89.77 |     83.6 |   94.73 |   89.77 | ...2500,2570-2590 
  sessionTitle.ts  |   94.19 |    73.21 |     100 |   94.19 | ...43-246,277-278 
  ...ionService.ts |    84.2 |    78.16 |   97.14 |    84.2 | ...2451,2457-2462 
  ...pInhibitor.ts |   97.42 |    92.77 |     100 |   97.42 | ...30,169,369-370 
  ...Estimation.ts |     100 |    86.66 |     100 |     100 | 96-97             
  ...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 |   92.07 |    84.69 |     100 |   92.07 | ...47-450,502-503 
  ...reeCleanup.ts |   14.56 |      100 |   33.33 |   14.56 | 58-185            
  ...ionService.ts |   88.99 |     87.5 |     100 |   88.99 | ...39-440,456-457 
 ...icrocompaction |   99.41 |    96.03 |     100 |   99.41 |                   
  microcompact.ts  |   99.41 |    96.03 |     100 |   99.41 | 243-244,676       
 ...s/visionBridge |    98.6 |    94.08 |     100 |    98.6 |                   
  ...capability.ts |     100 |      100 |     100 |     100 |                   
  ...part-utils.ts |     100 |      100 |     100 |     100 |                   
  ...-constants.ts |     100 |      100 |     100 |     100 |                   
  ...ge-service.ts |   98.31 |    92.59 |     100 |   98.31 | ...21,645,658-659 
 src/skills        |   88.22 |    87.05 |   90.16 |   88.22 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...activation.ts |     100 |    93.33 |     100 |     100 | 93,112            
  skill-load.ts    |   94.84 |     87.5 |     100 |   94.84 | ...03,223,235-237 
  skill-manager.ts |   83.44 |    82.16 |   82.35 |   83.44 | ...1202,1209-1213 
  skill-paths.ts   |   89.65 |    86.95 |     100 |   89.65 | ...11-112,117-118 
  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.26 |    87.17 |   96.42 |   87.26 |                   
  ...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 |   83.48 |    82.81 |   94.59 |   83.48 | ...1480,1557-1558 
  types.ts         |     100 |      100 |     100 |     100 |                   
  validation.ts    |   92.46 |    95.18 |     100 |   92.46 | 47-52,63-68,71-76 
 src/telemetry     |   80.45 |    88.02 |   82.83 |   80.45 |                   
  ...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 |   97.47 |    93.15 |     100 |   97.47 | 39-44             
  ...ag-metrics.ts |     100 |    77.77 |     100 |     100 | 21,40             
  ...t-loop-lag.ts |     100 |    90.47 |     100 |     100 | 49,76             
  ...-exporters.ts |   65.78 |    83.33 |   55.55 |   65.78 | ...04-105,108-109 
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...t.circular.ts |       0 |        0 |       0 |       0 | 1-111             
  ...-processor.ts |   99.09 |    95.61 |      95 |   99.09 | 141,365-366       
  ...t.circular.ts |       0 |        0 |       0 |       0 | 1-128             
  loggers.ts       |   54.12 |    71.13 |   62.74 |   54.12 | ...1347,1364-1384 
  metrics.ts       |   76.55 |       78 |   79.31 |   76.55 | ...1038,1041-1052 
  ...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       
  sdk.ts           |   86.75 |     88.4 |   66.66 |   86.75 | ...17-621,659-681 
  ...on-context.ts |     100 |      100 |     100 |     100 |                   
  ...on-tracing.ts |   89.89 |    88.03 |   96.55 |   89.89 | ...1550,1581-1584 
  ...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         |   81.64 |    94.21 |   85.36 |   81.64 | ...1328,1332-1339 
  uiTelemetry.ts   |   97.29 |    93.65 |   88.88 |   97.29 | ...02,346,466-467 
 ...ry/qwen-logger |   73.62 |    81.08 |   69.49 |   73.62 |                   
  event-types.ts   |       0 |        0 |       0 |       0 |                   
  qwen-logger.ts   |   73.62 |     80.9 |   68.96 |   73.62 | ...1095,1133-1134 
 src/test-utils    |      94 |    98.24 |   78.94 |      94 |                   
  config.ts        |     100 |      100 |     100 |     100 |                   
  ...st-helpers.ts |   94.11 |       90 |     100 |   94.11 | 69-70             
  index.ts         |     100 |      100 |     100 |     100 |                   
  mock-tool.ts     |   92.57 |      100 |   75.75 |   92.57 | ...63,227-228,241 
  ...aceContext.ts |     100 |      100 |     100 |     100 |                   
 src/tools         |   85.08 |    84.28 |    88.1 |   85.08 |                   
  ...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 |                   
  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 |   84.67 |    81.81 |   85.71 |   84.67 | ...27-132,160-174 
  exit-worktree.ts |   83.29 |    83.65 |   94.44 |   83.29 | ...14-515,537-538 
  exitPlanMode.ts  |   94.04 |    82.53 |     100 |   94.04 | ...92,311,342-344 
  glob.ts          |   96.33 |     88.5 |     100 |   96.33 | ...24-225,373,376 
  grep.ts          |   83.21 |    86.66 |   80.95 |   83.21 | ...65-666,716-717 
  ...adTracking.ts |     100 |      100 |     100 |     100 |                   
  loop-wakeup.ts   |   99.24 |    92.85 |     100 |   99.24 | 44                
  ls.ts            |   96.74 |    90.27 |     100 |   96.74 | 176-181,212,216   
  lsp.ts           |   72.71 |     59.5 |   90.32 |   72.71 | ...1212,1214-1215 
  ...nt-manager.ts |   81.63 |       79 |   85.41 |   81.63 | ...3221,3223-3224 
  mcp-client.ts    |   79.35 |    84.71 |   88.67 |   79.35 | ...2167,2171-2174 
  ...ry-timeout.ts |     100 |      100 |     100 |     100 |                   
  mcp-errors.ts    |     100 |      100 |     100 |     100 |                   
  ...pool-entry.ts |   77.56 |    84.11 |   77.14 |   77.56 | ...1291,1299-1300 
  ...ool-events.ts |       8 |      100 |       0 |       8 | 132-158           
  mcp-pool-key.ts  |   97.46 |    93.93 |     100 |   97.46 | 175-176           
  ...ce-content.ts |   96.55 |    91.17 |     100 |   96.55 | 80-82             
  mcp-retry.ts     |   97.67 |    95.65 |     100 |   97.67 | 131-132           
  mcp-status.ts    |     100 |      100 |     100 |     100 |                   
  mcp-tool.ts      |   91.99 |    93.04 |   96.77 |   91.99 | ...15-716,766-767 
  ...sport-pool.ts |   83.49 |    80.15 |   84.61 |   83.49 | ...1409,1416-1420 
  ...ace-budget.ts |   87.27 |     82.6 |     100 |   87.27 | ...00-305,340-345 
  memory-config.ts |     100 |      100 |     100 |     100 |                   
  ...iable-tool.ts |     100 |    84.61 |     100 |     100 | 101,108           
  monitor.ts       |   91.72 |    84.28 |   88.46 |   91.72 | ...92,605,803-808 
  notebook-edit.ts |   85.55 |    77.39 |   81.25 |   85.55 | ...86-902,948-949 
  ...escendants.ts |   36.17 |    64.51 |   55.55 |   36.17 | ...46-310,385-390 
  ...nforcement.ts |   82.57 |    88.88 |     100 |   82.57 | 174-185,234-247   
  read-file.ts     |   95.64 |    88.88 |   86.66 |   95.64 | ...74,489,561-562 
  ...p-resource.ts |   96.85 |      100 |   91.66 |   96.85 | 92-96             
  ...d-artifact.ts |    90.9 |    86.71 |    87.5 |    90.9 | ...13-414,428-440 
  ripGrep.ts       |    95.9 |     88.4 |   94.73 |    95.9 | ...61-662,668-669 
  ...-transport.ts |   71.42 |    55.55 |   71.42 |   71.42 | ...36-137,143-144 
  send-message.ts  |    82.3 |    89.65 |    62.5 |    82.3 | ...37-243,326-334 
  ...n-mcp-view.ts |   93.57 |     92.3 |      90 |   93.57 | 122-130           
  shell.ts         |   78.37 |    83.35 |   91.75 |   78.37 | ...4947,5010-5011 
  skill-utils.ts   |     100 |      100 |     100 |     100 |                   
  skill.ts         |   91.06 |    93.33 |   89.47 |   91.06 | ...71,475,520-542 
  ...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     |   93.92 |    83.13 |   92.85 |   93.92 | ...86-391,413-414 
  tool-error.ts    |     100 |      100 |     100 |     100 |                   
  tool-names.ts    |     100 |      100 |     100 |     100 |                   
  tool-registry.ts |   77.03 |    75.39 |   82.97 |   77.03 | ...04-905,913-914 
  tool-search.ts   |   96.19 |    89.72 |   93.33 |   96.19 | ...09,259-264,426 
  tools.ts         |   92.72 |    91.52 |    91.3 |   92.72 | ...48-549,565-571 
  ...reapproved.ts |   99.27 |    94.11 |     100 |   99.27 | 170               
  web-fetch.ts     |   95.66 |    89.92 |   96.55 |   95.66 | ...12-713,727-728 
  write-file.ts    |   85.52 |    84.61 |   85.71 |   85.52 | ...32-735,772-807 
 src/tools/agent   |   84.73 |    84.62 |   86.31 |   84.73 |                   
  agent.ts         |    84.8 |    84.71 |    86.2 |    84.8 | ...3754,3776-3786 
  fork-subagent.ts |   83.14 |       80 |    87.5 |   83.14 | 83-101,133-134    
 ...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 |   87.46 |    79.41 |   85.71 |   87.46 |                   
  workflow.ts      |   87.46 |    79.41 |   85.71 |   87.46 | ...51-652,664-667 
 src/utils         |   92.02 |    89.38 |    96.3 |   92.02 |                   
  LruCache.ts      |     100 |      100 |     100 |     100 |                   
  ...Controller.ts |     100 |      100 |     100 |     100 |                   
  ...ssageQueue.ts |     100 |      100 |     100 |     100 |                   
  ...cFileWrite.ts |   94.76 |    93.26 |     100 |   94.76 | ...30-531,634-638 
  bareMode.ts      |   81.81 |      100 |      50 |   81.81 | 18-19             
  ...ry-content.ts |   98.45 |    95.45 |     100 |   98.45 | 132-133,159-160   
  browser.ts       |   86.84 |    78.94 |     100 |   86.84 | 34,36-37,65-66    
  btwUtils.ts      |   13.95 |      100 |       0 |   13.95 | 17-31,34-55       
  bundlePaths.ts   |     100 |      100 |     100 |     100 |                   
  ...on-context.ts |     100 |      100 |     100 |     100 |                   
  ...ncyLimiter.ts |   94.64 |    95.23 |     100 |   94.64 | 64-66             
  ...igResolver.ts |     100 |      100 |     100 |     100 |                   
  ...engthError.ts |   91.11 |    89.47 |     100 |   91.11 | ...46-147,154-155 
  ...tion-chain.ts |     100 |      100 |     100 |     100 |                   
  cronDisplay.ts   |     100 |    91.66 |     100 |     100 | 15,43,57          
  cronParser.ts    |   95.34 |    93.33 |     100 |   95.34 | 41-42,47-48,70-71 
  debugLogger.ts   |   96.66 |    96.61 |   88.88 |   96.66 | 192-196           
  editHelper.ts    |   93.63 |     83.9 |     100 |   93.63 | ...28-429,463-464 
  editor.ts        |   97.65 |    95.45 |     100 |   97.65 | ...35-336,338-339 
  env.ts           |     100 |      100 |     100 |     100 |                   
  ...arResolver.ts |   94.28 |    88.88 |     100 |   94.28 | 28-29,125-126     
  ...entContext.ts |   96.63 |    88.88 |   96.66 |   96.63 | ...42,444-445,512 
  errorParsing.ts  |    97.7 |    97.05 |     100 |    97.7 | 72-73             
  ...rReporting.ts |   95.65 |    93.33 |     100 |   95.65 | 37-38             
  errors.ts        |   81.73 |    90.32 |   57.89 |   81.73 | ...08-324,328-334 
  fetch.ts         |   90.68 |    82.51 |     100 |   90.68 | ...72,483-484,503 
  fileUtils.ts     |   95.33 |    92.02 |   96.15 |   95.33 | ...1747,1772-1773 
  forkedAgent.ts   |   92.45 |    82.35 |   93.75 |   92.45 | ...34,642,647-654 
  formatters.ts    |   81.81 |       75 |     100 |   81.81 | 15-16             
  ...eUtilities.ts |    92.4 |    86.95 |     100 |    92.4 | ...52-158,168-169 
  ...rStructure.ts |   94.36 |    94.28 |     100 |   94.36 | ...17-120,330-335 
  getPty.ts        |   31.57 |       50 |     100 |   31.57 | 26-38             
  gitDiff.ts       |   93.99 |    79.94 |     100 |   93.99 | ...1141,1385-1386 
  gitDirect.ts     |   98.46 |    90.17 |     100 |   98.46 | 148,268,352       
  ...noreParser.ts |   94.59 |    92.59 |     100 |   94.59 | ...05-106,140-141 
  gitUtils.ts      |      75 |    88.88 |   83.33 |      75 | ...,78-79,103-154 
  iconvHelper.ts   |     100 |      100 |     100 |     100 |                   
  ...rePatterns.ts |     100 |      100 |     100 |     100 |                   
  ...ionManager.ts |     100 |     90.9 |     100 |     100 | 27                
  ...lPromptIds.ts |     100 |      100 |     100 |     100 |                   
  jsonl-utils.ts   |   95.27 |    92.85 |     100 |   95.27 | ...16-317,356-359 
  ...-detection.ts |     100 |      100 |     100 |     100 |                   
  ...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 |   93.77 |    89.15 |     100 |   93.77 | ...13-319,406-407 
  ...Inspectors.ts |     100 |      100 |     100 |     100 |                   
  modelId.ts       |     100 |      100 |     100 |     100 |                   
  ...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 
  partUtils.ts     |     100 |    98.61 |     100 |     100 | 206               
  pathReader.ts    |   97.77 |       90 |     100 |   97.77 | 93,121            
  paths.ts         |   93.95 |    92.79 |     100 |   93.95 | ...78-479,481-483 
  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 |   59.15 |    76.92 |     100 |   59.15 | ...5,89-90,96-101 
  ...noreParser.ts |   92.63 |    91.37 |     100 |   92.63 | ...72-173,192-193 
  rateLimit.ts     |   93.75 |    89.62 |     100 |   93.75 | ...13,218-219,262 
  ...text-range.ts |   97.73 |    93.24 |     100 |   97.73 | 85-86,107,262-263 
  readManyFiles.ts |   96.29 |     87.5 |     100 |   96.29 | 225,275,286-290   
  retry.ts         |   95.93 |    92.23 |     100 |   95.93 | ...33,524-525,543 
  retryContext.ts  |     100 |      100 |     100 |     100 |                   
  ...sification.ts |   97.65 |    96.96 |     100 |   97.65 | ...00,250-251,277 
  retryPolicy.ts   |   97.72 |    90.56 |     100 |   97.72 | 130-131           
  ripgrepUtils.ts  |   50.94 |    85.71 |      70 |   50.94 | ...54-255,268-346 
  ...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 |   83.09 |    86.77 |   95.45 |   83.09 | ...70,595,624-633 
  ...odelPrefix.ts |     100 |      100 |     100 |     100 |                   
  runtimeStatus.ts |   85.05 |    89.47 |     100 |   85.05 | ...56-261,288-289 
  safe-mode.ts     |     100 |      100 |     100 |     100 |                   
  safeJsonParse.ts |     100 |      100 |     100 |     100 |                   
  ...nStringify.ts |     100 |      100 |     100 |     100 |                   
  ...aConverter.ts |   91.13 |    89.47 |     100 |   91.13 | ...41-42,96,98-99 
  ...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.72 |    92.12 |     100 |   91.72 | ...36-539,615-616 
  ...nIdContext.ts |     100 |    80.95 |     100 |     100 | 59,84-85,104      
  ...orageUtils.ts |   95.98 |    83.65 |     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.05 |    88.54 |     100 |   86.05 | ...2246,2253-2257 
  ...lAstParser.ts |   98.16 |    91.89 |     100 |   98.16 | ...1244-1246,1256 
  ...ContextEnv.ts |     100 |    90.47 |     100 |     100 | 46-48             
  ...nlyChecker.ts |   96.33 |    96.57 |     100 |   96.33 | ...83-284,292-293 
  sideQuery.ts     |   86.82 |    86.66 |     100 |   86.82 | ...81-187,189-195 
  ...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          
  ...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             
  tool-utils.ts    |    95.2 |    93.61 |     100 |    95.2 | ...58-159,162-163 
  ...ultCleanup.ts |   55.55 |    65.38 |      75 |   55.55 | ...04-105,108-134 
  ...Compaction.ts |   96.11 |    96.33 |     100 |   96.11 | ...22-327,329-334 
  ...pt-records.ts |   85.78 |    83.63 |     100 |   85.78 | ...84-388,418-433 
  truncation.ts    |   75.55 |    86.02 |   71.42 |   75.55 | ...44-449,453-477 
  windowsPath.ts   |   89.47 |    79.31 |     100 |   89.47 | ...57-58,62,90-91 
  ...aceContext.ts |   95.81 |    89.39 |     100 |   95.81 | ...74-275,299-301 
  xml.ts           |    97.8 |    87.69 |     100 |    97.8 | 98-99             
  yaml-parser.ts   |   83.87 |    77.27 |     100 |   83.87 | ...31-234,239-240 
 ...ils/filesearch |   83.68 |    80.38 |   94.69 |   83.68 |                   
  crawlCache.ts    |     100 |      100 |     100 |     100 |                   
  crawler.ts       |   82.47 |    76.22 |      95 |   82.47 | ...1525,1559-1560 
  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.01 |     74.5 |   84.37 |   69.01 |                   
  ...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.

@doudouOUC
doudouOUC marked this pull request as ready for review July 18, 2026 14:15
@doudouOUC
doudouOUC enabled auto-merge July 18, 2026 14:16
@qwen-code-ci-bot

qwen-code-ci-bot commented Jul 18, 2026

Copy link
Copy Markdown
Collaborator

Thanks for the PR!

Template looks good ✓ — all required sections filled in, including Risk & Scope and Linked Issues.

Problem: Real and well-documented. Issue #7164 describes a P1 data-consistency bug — two processes can fork the transcript history, causing already-shown responses to silently disappear on restart. The architectural gap is confirmed in the source: async-mutex is in-process only, appendFile() has no cross-process exclusion, and buildOrderedUuidChain() silently drops the losing branch. The maintainer has independently verified the incident against captured logs. This is not theoretical hardening.

Direction: Aligned. The single-writer lease with ownership token + authoritative reload + append fencing follows standard distributed-systems fencing patterns. The acceptance criteria in the issue map cleanly to the implementation. Design doc at docs/design/session-writer-lease.md is thorough.

Size: 5,917 production logic lines (additions+deletions, excluding test and generated files), 6,340 test lines, 91 docs lines, 84 files across Core, CLI, ACP bridge, Desktop, and VS Code. Stage 0 Tier 1 hard block does not apply (title is fix, not refactor). The 1,000+ production lines advisory applies — this is a large PR, but the breadth is the cost of closing every session-lifecycle path that could bypass the lease. The maintainer has been flagged and has verified the PR on Linux.

Approach: The core mechanism (new session-writer-lease.ts at 717 lines, plus modifications to sessionService.ts, chatRecordingService.ts, config.ts, and runtimeStatus.ts) addresses the root cause directly. The breadth across ACP bridge, CLI serve, daemon, desktop, and VS Code paths closes every escape hatch. The three-phase session transition (prepare/commit/rollback) and the closing flag on ACP bridge entries are well-motivated by the design doc.

Moving on to code review. 🔍

中文说明

感谢贡献!

模板完整 ✓ — 所有章节都已填写,包括 Risk & Scope 和 Linked Issues。

问题: 真实且有充分文档记录。Issue #7164 描述了 P1 数据一致性 bug——两个进程可以分叉 transcript 历史,导致已展示的回复在重启后静默消失。源码中的架构缺陷已确认:async-mutex 仅限进程内,appendFile() 无跨进程互斥,buildOrderedUuidChain() 静默丢弃失败分支。维护者已独立对照事故日志验证。这不是理论性加固。

方向: 对齐。单写者租约 + 所有权令牌 + 权威性重新加载 + 追加 fencing 遵循标准分布式系统 fencing 模式。issue 中的验收标准与实现对齐。设计文档 docs/design/session-writer-lease.md 内容充实。

规模: 5,917 行生产逻辑(additions+deletions,排除测试和生成文件),6,340 行测试,91 行文档,84 个文件跨越 Core、CLI、ACP bridge、Desktop 和 VS Code。Stage 0 Tier 1 硬限制不适用(标题是 fix 而非 refactor)。1,000+ 生产行大 PR 建议适用——这是一个大型 PR,但广度是关闭所有可能绕过租约的 session 生命周期路径的必要代价。维护者已知晓并在 Linux 上验证了该 PR。

方案: 核心机制(新增 session-writer-lease.ts 717 行,加上对 sessionService.tschatRecordingService.tsconfig.tsruntimeStatus.ts 的修改)直接解决根因。跨 ACP bridge、CLI serve、daemon、desktop 和 VS Code 的广度关闭了所有逃逸通道。三阶段 session 切换(prepare/commit/rollback)和 ACP bridge 条目上的 closing 标志在设计文档中有充分动机。

进入代码审查 🔍

Qwen Code · qwen3.7-max

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

@qwen-code-ci-bot

qwen-code-ci-bot commented Jul 18, 2026

Copy link
Copy Markdown
Collaborator

Code Review

Independent proposal: I would have used proper-lockfile (already a dep) for fd-based cross-process locking on a sidecar file per (runtimeBase, sessionId), with authoritative reload after lock acquisition, byte-length fencing on each append, and a resume guard checking PID liveness. ~300-500 production lines, ~10 files.

Comparison: The PR's approach exceeds my proposal in robustness. Instead of proper-lockfile (fd-based locking, no fencing token), the author built a custom lease module with: random UUID owner_id as a fencing token, atomic wx lock creation, stale-owner reclamation via rename-aside with post-rename verification, foreign-host conservative handling (never auto-reclaim), process-start-time PID-reuse detection, and byte-length tracking for append fencing. The tradeoff is more complexity (717 lines for the lease alone vs ~100 for a proper-lockfile wrapper), but the design doc justifies each piece. For a production data-consistency fix, this extra rigor is warranted.

Correctness: No critical bugs found across the lease module, Config integration, session transitions, ACP bridge, CLI serve routes, session service maintenance operations, chat recording service, runtime status, desktop agent, or VS Code companion. Key highlights:

  • The three-phase session transition (prepare/commit/rollback) is carefully implemented — old recorder stays paused until commit, rollback restores all snapshotted state
  • The ACP bridge closing flag correctly gates all admission points and fails closed on timeout
  • The recorder state machine (inactive → active → paused → closed / integrity_failed) is correct with proper lease release on every exit path
  • Maintenance operations (rename, delete, archive, fork) all acquire temporary leases with full ownership assertions
  • Desktop and VS Code correctly remove direct filesystem mutation, routing through ACP to enforce single-writer
  • The inspectExistingLock retry loop for malformed locks (3 attempts, 50ms delay, 5s grace period) handles the race where a concurrent writer is mid-write on the lock file

Non-blocking observations:

  1. Dead code in hasMatchingLiveRuntime (~line 280 of session-writer-lease.ts): await fs.readFile(statusPath) result is discarded before readRuntimeStatus(statusPath) reads the same file again. Wasted I/O on every scan iteration. Low severity.

  2. Minor scope creep in scheduled-tasks.ts: runtime-base plumbing changes (runInTargetRuntime wrapping, runtimeBaseDir field additions) are unrelated to the lease work. Correct in isolation but ideally a separate commit.

sequenceDiagram
    participant P1 as Process A
    participant Lk as Lock File
    participant Tr as Transcript JSONL
    participant P2 as Process B
    P1->>Lk: acquire (wx create, owner_id=uuid)
    P1->>Tr: readStableTranscript (reload under lease)
    P1->>Tr: appendJsonLine (assert owner + byte length)
    P2->>Lk: acquire (EEXIST, read existing)
    Lk-->>P2: conflict (live owner, PID alive)
    P2->>P2: SessionWriterConflictError
    Note over P1: session continues normally
    P1->>Lk: release (verify owner_id match, unlink)
    Note over P2: retry after Process A exits
    P2->>Lk: acquire (stale reclaim via rename-aside)
    P2->>Tr: readStableTranscript (authoritative reload)
Loading

Testing

Unit Tests (worktree, commit 39d1837)

Ran all 22 changed test files across Core, ACP bridge, CLI, and VS Code:

Package Test Files Tests Result
Core (lease, session, recording, config, runtime, telemetry, tools) 15 1,147 ✅ all pass
ACP bridge (bridge, status) 2 433 ✅ all pass
CLI (ACP agent, Session, serve routes, UI hooks, config) 12 1,652 ✅ all pass
VS Code companion 1 11 ✅ all pass
Total 30 3,243 ✅ all pass

Real-Scenario Testing (tmux, built from PR branch)

Built the bundle from the PR branch and drove two real qwen CLI processes against the same session.

Test 1 — Lease lifecycle (headless prompt):

$ QWEN_HOME="$TESTDIR/qwen-home" node dist/cli.js -p 'Say hello in one word' --output-format json
[{"type":"system","subtype":"init","session_id":"508b28dc-bf30-4376-94ec-05e14e244030",...}]
[{"type":"assistant",...,"message":{"content":[{"type":"text","text":"Hello"}],...}}]
[{"type":"result","subtype":"success","result":"Hello","duration_ms":6955,...}]

$ find "$QWEN_HOME" -name '*.lock' -path '*/session-writer-locks/*'
(no lock files — lease properly released after exit)

Test 2 — Conflict detection (two processes, same session):

Process A resumed the session interactively and acquired the lease:

$ find "$QWEN_HOME" -name '*.lock' -path '*/session-writer-locks/*'
/home/.../qwen-home/tmp/session-writer-locks/b3a5ec06-652e-4ff3-9a00-152d42ed85f8.lock

$ cat .../b3a5ec06-652e-4ff3-9a00-152d42ed85f8.lock
{
    "schema_version": 1,
    "session_id": "b3a5ec06-652e-4ff3-9a00-152d42ed85f8",
    "owner_id": "daf8ae78-f15c-4540-8b69-1caf319bc59d",
    "pid": 4172721,
    "process_start_time_ms": 1784476758620,
    "hostname": "iZt4neqpisqczs6hsm7xn2Z",
    "process_kind": "interactive",
    "acquired_at": "2026-07-19T15:59:20.299Z",
    "qwen_version": "0.19.12"
}

Process B tried to resume the same session — rejected before model turn:

$ QWEN_HOME="$QWEN_HOME" node dist/cli.js --resume 'b3a5ec06-...' -p 'Say goodbye' --output-format json
An unexpected critical error occurred:
SessionWriterConflictError: This session is already open in another Qwen process.
    at SessionWriterLease.acquire (chunk-LATKLHBJ.js:39783:40)
    at async Config.activateChatRecording (chunk-LATKLHBJ.js:153548:15)
    at async Config.initializeInternal (chunk-LATKLHBJ.js:153220:5)
    at async Config.initialize (chunk-LATKLHBJ.js:153184:7)
    at async main (gemini-NCXMDVTT.js:2976:7)

After Process A exited (/exit), the lease was cleaned up:

$ find "$QWEN_HOME" -name '*.lock' -path '*/session-writer-locks/*'
(no lock files — cleaned up)

Process A exit summary confirmed the session remained intact:

  ╭──────────────────────────────────────────────────────────────────╮
  │  Agent powering down. Goodbye!                                   │
  │  Session ID:  b3a5ec06-652e-4ff3-9a00-152d42ed85f8              │
  │  Wall Time:   1m 57s                                            │
  │  Model:       qwen3.8-max-preview                               │
  ╰──────────────────────────────────────────────────────────────────╯
  To continue this session, run qwen --resume b3a5ec06-652e-4ff3-9a00-152d42ed85f8

Result: All three core guarantees verified end-to-end — (1) lease acquired on session resume with proper fencing data, (2) second writer rejected with SessionWriterConflictError before starting a model turn, (3) lease released on clean exit. This matches the maintainer's independent Linux verification.

中文说明

代码审查

独立方案: 我会使用 proper-lockfile(已是项目依赖)对每个 (runtimeBase, sessionId) 的 sidecar 文件做 fd 级跨进程锁,获取锁后权威性重新加载,每次追加做字节长度 fencing,并在 resume 时检查 PID 存活状态。约 300-500 行生产代码,约 10 个文件。

对比: PR 的方案在健壮性上超出了我的方案。作者构建了自定义租约模块:随机 UUID owner_id 作为 fencing token、原子 wx 锁创建、通过 rename-aside 加 rename 后验证回收过期 owner、对外部主机保守处理(永不自动回收)、进程启动时间 PID 复用检测、以及字节长度追踪用于追加 fencing。代价是更多复杂度(仅租约模块就 717 行),但设计文档对每个部分都有充分理由。对于生产级数据一致性修复,这种额外的严谨是合理的。

正确性: 在所有模块中均未发现关键 bug。三阶段 session 切换、ACP bridge closing 标志、recorder 状态机、维护操作临时租约、Desktop/VS Code 路由均正确实现。

非阻塞观察:

  1. hasMatchingLiveRuntime 中有死代码(fs.readFile 结果被丢弃)
  2. scheduled-tasks.ts 中有少量范围蔓延(runtime-base 管道改动与租约无关)

测试

单元测试

在 worktree 中运行了所有 30 个变更测试文件,共 3,243 个测试全部通过。

真实场景(tmux)

从 PR 分支构建 bundle,驱动两个真实 qwen CLI 进程访问同一 session:

  1. ✅ 租约在 session resume 时获取,包含完整 fencing 数据(owner_id UUID、PID、进程启动时间、主机名)
  2. ✅ 第二个 writer 在模型轮次开始前被 SessionWriterConflictError 拒绝
  3. ✅ 进程退出后租约正确释放

与维护者的独立 Linux 验证结果一致。

Qwen Code · qwen3.7-max

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

@qwen-code-ci-bot

qwen-code-ci-bot commented Jul 18, 2026

Copy link
Copy Markdown
Collaborator

Confidence: 4/5 — clean review across all stages, tmux-verified conflict detection, and maintainer-confirmed on Linux; the only deduction is the scale (5,917 production lines, 84 files) which demands ongoing maintenance attention, but the design doc and test coverage justify it.

This is a well-engineered fix for a real P1 data-consistency bug. The custom lease implementation is more robust than what I would have proposed (proper-lockfile wrapper) — the UUID fencing token, rename-aside stale reclamation with post-rename verification, PID-reuse detection via process start time, and byte-length append fencing are each motivated by a concrete failure mode documented in the design doc.

The tmux test I ran confirms the core promise end-to-end: a second process is rejected with SessionWriterConflictError before it can start a model turn, and the lease is cleanly released on exit. This matches the maintainer's independent multi-process harness and live E2E verification on Linux.

3,243 tests pass across all 30 changed test files in my worktree run. No critical bugs, no security holes, no regressions found in the code review. The three-phase session transition protocol, the ACP bridge closing gate, and the recorder state machine are all correctly implemented with proper lease release on every exit path.

Non-blocking items for the author (carry forward from previous rounds, not blockers):

  • Dead fs.readFile in hasMatchingLiveRuntime (~line 280 of session-writer-lease.ts) — wasted I/O
  • scheduled-tasks.ts runtime-base plumbing is unrelated scope — consider splitting in a follow-up

The maintainer has verified this PR on Linux with real processes and confirmed the single-writer guarantee holds in every scenario tested. The previous Stage 0 escalation for maintainer awareness is resolved.

中文说明

置信度:4/5 — 所有阶段审查均干净,tmux 验证了冲突检测,维护者在 Linux 上确认;唯一扣分是规模(5,917 行生产代码,84 个文件)需要持续的维护关注,但设计文档和测试覆盖证明了其合理性。

这是一个针对真实 P1 数据一致性 bug 的精心设计的修复。自定义租约实现比我原本会提议的方案(proper-lockfile 封装)更健壮——UUID fencing token、rename-aside 加 rename 后验证的过期回收、通过进程启动时间的 PID 复用检测、以及字节长度追加 fencing,每一项都有设计文档中记录的具体失败模式作为动机。

我运行的 tmux 测试端到端确认了核心承诺:第二个进程在开始模型轮次之前被 SessionWriterConflictError 拒绝,租约在退出时正确释放。这与维护者在 Linux 上的独立多进程 harness 和实时 E2E 验证结果一致。

3,243 个测试在 worktree 中全部通过。代码审查中未发现关键 bug、安全漏洞或回归。

维护者已在 Linux 上用真实进程验证了此 PR,确认单写者保证在所有测试场景中成立。之前的 Stage 0 维护者关注升级已解决。

Qwen Code · qwen3.7-max

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

@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

⏸️ Deferring to @wenshao — this is a 5,556-line cross-package fix for a P1 data-consistency bug (#7164). The code review is clean (no bugs, no security issues, 1,111 tests pass in my worktree run), but the scale and architectural impact need a maintainer's sign-off. Needs a human call on this one.

@doudouOUC
doudouOUC force-pushed the agent/session-writer-lease branch from 5a0dbc5 to 0f268dc Compare July 18, 2026 14:38
@doudouOUC

Copy link
Copy Markdown
Collaborator Author

[codex] Conflict/CI remediation pushed in 0f268dc486.

Item Action
Branch state Rebasing onto current main completed without file conflicts; the branch is now based on af6a9b640c.
Ubuntu CI failures Fixed stale ACP/Session runtime-storage mocks and transcript telemetry expectations. The 10 failing tests and 2 teardown rejections now pass.
hasMatchingLiveRuntime readability probe Not taking. The first read is a strict fail-closed probe because readRuntimeStatus intentionally converts every read/parse error to null; removing it would treat EACCES/EIO as no live sidecar and could reclaim an unverifiable lock.
Scheduled-task runtime-base plumbing Not splitting. Scheduled-task CRUD, rollback, rehydration, and keepalive can mutate session state, so they must select the same runtime base and maintenance lease as the owning workspace rather than process-global storage.
Error-response scope No split needed. This module already existed; the PR only adds direct and ACP-proxied SessionWriterError translation to the required 409/503 wire contract.

Validation on the pushed commit: npm run build, npm run typecheck, npm run lint, and the 17 directly affected Vitest cases all pass. Expanded ACP tests (295 cases) and the Session suite also passed before the final gate.

Inline review threads: 0 total, 0 unresolved. New CI is running on the rebased SHA.

@github-actions

Copy link
Copy Markdown
Contributor

Please do not rebase or force-push to an active PR as it invalidates existing review comments. Note for future reference, the bots always squash all changes into a single commit automatically as part of the integration.

中文

请勿对活跃的 PR 执行 rebase 或 force-push,因为这会使已有的评审评论失效。另外,供日后参考:作为集成流程的一部分,机器人始终会自动将所有改动压缩(squash)为单个提交。

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

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Reviewed. Suggestions are inline. 1 Suggestion-level finding(s) could not be anchored to the diff; see the terminal output. Not reviewed: verification — a verifier ran and opened its brief, but no agent was launched with the prompt the CLI built — the launch was written by hand, and the posted findings cannot be counted as verified against it.

— qwen3.7-max via Qwen Code /review

Comment thread packages/cli/src/ui/AppContainer.test.tsx
Comment thread packages/cli/src/ui/hooks/useBranchCommand.test.ts
Comment thread packages/core/src/services/chatRecordingService.ts
Comment thread packages/core/src/services/session-writer-lease.ts
Comment thread packages/cli/src/acp-integration/acpAgent.ts
Comment thread packages/core/src/services/sessionService.ts
@doudouOUC

Copy link
Copy Markdown
Collaborator Author

Incident validation

I compared this change with the captured incident logs. It directly addresses the observed failure mode: process A was still completing a tool turn while process B restored the same session from an older tail, after which both processes could append valid-looking children and the daemon/UI followed the stale branch instead of the final Wiki answer written by A.

With this PR, process B reaches Config.initialize()activateChatRecording()SessionWriterLease.acquire() before session registration, history replay, or a model turn. While A owns the live lease, B should fail with session_writer_conflict (-32012 / HTTP 409), so the stale preview cannot become a writable session or accept the next prompt. A can finish the linear append; after A releases ownership, B can acquire the lease and reload the complete authoritative transcript.

The focused Wiki conflict/handoff/restart test, live child-process lock test, ACP error mapping, and prompt-admission tests provide good layered evidence that this prevents recurrence of the diagnosed root cause.

Before treating the incident as fully closed, I recommend one real two-process E2E using the same runtime output directory and session ID:

  1. Hold process A inside a tool turn.
  2. Verify process B is rejected before replay, registration, or model invocation.
  3. Let A persist the tool result and final answer, then close A.
  4. Let B acquire and replay through the real ACP/HTTP/SSE path, asserting the final answer appears exactly once and no parent has sibling conversation children.
  5. Repeat the handoff after terminating A to cover stale-lock reclamation.

Rollout is also part of the fix: all old daemons and interactive processes must be drained before upgrading because old binaries do not honor the lease. Existing divergent transcripts remain a separate recovery task.

@doudouOUC doudouOUC 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.

Reviewed. Suggestions are inline. 1 Suggestion-level finding(s) could not be anchored to the diff; see the terminal output. Not reviewed: This PR introduces a process-level single-writer lease fo... — pointed at diff lines it never opened: it made tool calls, but none of them read the diff. Not reviewed: This PR introduces a process-level single-writer lease fo... — pointed at diff lines it never opened: it made tool calls, but none of them read the diff.

— bailian/glm-5.2 via Qwen Code /review

Comment thread packages/core/src/config/config.ts
Comment thread packages/cli/src/ui/commands/clearCommand.test.ts
Comment thread packages/core/src/services/worktreeSessionService.ts
Comment thread packages/cli/src/acp-integration/acpAgent.worktree.test.ts
@doudouOUC

Copy link
Copy Markdown
Collaborator Author

Review feedback addressed in b6f62eae93.

Feedback Decision Action
Pre-flight rewind flush coverage Fixed Added a regression asserting no file, recorder, model-history, UI-history, or prompt mutation after the initial flush fails.
Branch rollback error expectation Pushed back Rollback failure intentionally takes precedence because failed rollback leaves session identity and ownership uncertain.
Simultaneous recorder flush/release failures Fixed Kept the ownership/release failure primary and retained the flush failure as a non-enumerable cause.
Strict runtime-sidecar read Pushed back Retained fail-closed handling for unreadable or unverifiable sidecar state during stale-lock reclamation.
ACP creation failure masked by cleanup failure Partially fixed Kept cleanup/ownership failure primary and retained the original creation failure as a non-enumerable cause across all matching cleanup paths.
Direct snapshot-fork coverage Partially fixed Added direct helper coverage and verified target-lease release by reacquisition. Partial published targets are excluded because transcript publication is atomic; pre-marking ownership would risk deleting an external conflict target.

Verification: Core and CLI builds passed; full workspace typecheck passed; 179 affected Core tests and 441 affected CLI tests passed; changed-file ESLint and repository pre-commit checks passed.

@doudouOUC

Copy link
Copy Markdown
Collaborator Author

Review feedback addressed in 764ce067bd.

Feedback Decision Action
Activation failure overwritten by lease-release failure Fixed Preserved the normalized activation failure, logged the first cleanup failure, and retained outer retry plus fail-closed ownership verification.
Duplicate clear-command assertions Fixed Removed duplicate task and monitor ordering checks while retaining task, monitor, and shell coverage.
Missing inactive-runtime test Fixed Added a live-PID regression for an explicitly deactivated runtime sidecar.
Desktop adapter test not in root npm CI Deferred Desktop is an intentionally isolated nested Bun workspace whose tests are collected by its own test command; PR-wide Desktop CI is separate infrastructure scope.
Worktree restore test does not exercise leases Pushed back The test intentionally mocks Core and verifies worktree restore plumbing; lease behavior is covered at the real Config, lease, conflict, and ACP admission boundaries.

Verification: Core and CLI builds passed; full workspace typecheck passed; 448 affected Core tests and 18 affected CLI tests passed; changed-file ESLint and repository pre-commit checks passed.

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

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Blocking: the required Ubuntu test currently fails in Check VS Code companion notices are up-to-date. The job regenerates packages/vscode-ide-companion/NOTICES.txt and finds an uncommitted 13,218-line update, so this PR cannot pass its required CI as submitted. Please run npm run generate:notices --workspace=qwen-code-vscode-ide-companion and commit the resulting NOTICES.txt update, then rerun the check.

doudouOUC and others added 4 commits July 19, 2026 02:19
Prevent concurrent processes from appending divergent JSONL histories, fence transcript writes, and make session transitions and maintenance operations ownership-safe.

Refs #7164

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Update ACP and Session test doubles for pinned runtime storage, and include the optional runtime argument in transcript telemetry assertions.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
@doudouOUC
doudouOUC force-pushed the agent/session-writer-lease branch from 764ce06 to e5ade64 Compare July 18, 2026 18:25
@doudouOUC

Copy link
Copy Markdown
Collaborator Author

Addressed the blocking notices CI review in e5ade64.

Item Action
VS Code companion notices check Fixed by rebasing the PR onto current main, which includes #7161 and its synchronized generator/NOTICES.txt output.
Suggested duplicate 13,218-line notices commit Not taken because the update is already owned by #7161; duplicating it here would add unrelated generated churn.

Verification: npm run build; npm run typecheck; 1,149 Core tests; 1,620 CLI tests; 433 ACP bridge tests; 11 VS Code companion tests; 36 desktop tests. Re-running the notices generator now produces no diff.

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

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Not reviewed: chunk 27, chunk 28, chunk 32, chunk 35, chunk 36, chunk 40 — no agent reported covering these; nobody read them.

Not reviewed: chunks 27, 28, 32, 35, 36, 40 — not reviewed (agents could not be launched).

Not reviewed: test-coverage matrix — agent could not be launched.

Not reviewed: invariant agents for acpAgent.ts and useBranchCommand.ts — agents could not be launched.

Not reviewed: reverse audit — auditor ran but was not launched with the CLI-built prompt.

Not reviewed: chunk 1 — launched with a prompt that is not the one the CLI built.

Not reviewed: chunk 41 — launched with a prompt that is not the one the CLI built.

Not reviewed: Agent 0: Issue fidelity & root-cause ownership — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 1 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 2 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 3 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 4 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 5 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 6 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 7 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 8 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 9 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 10 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 11 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 12 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 13 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 14 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 15 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 16 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 17 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 18 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 19 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 20 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 21 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 22 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 23 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 24 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 25 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 26 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 27 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 28 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 29 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 30 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 31 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 32 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 33 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 34 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 35 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 36 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 37 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 38 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 39 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 40 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 41 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 42 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 43 — its prompt was built, but no agent on record was launched with it.

Not reviewed: Test coverage matrix (whole-diff) — its prompt was built, but no agent on record was launched with it.

Not reviewed: Agent 1b: Removed-behavior audit — its prompt was built, but no agent on record was launched with it.

Not reviewed: Agent 1c: Cross-file tracer — its prompt was built, but no agent on record was launched with it.

Not reviewed: Agent 7: Build & test verification — its prompt was built, but no agent on record was launched with it.

Not reviewed: Invariant agent A: state, timers, collections — packages/cli/src/acp-integration/acpAgent.ts — its prompt was built, but no agent on record was launched with it.

Not reviewed: Invariant agent B: counters, return values, error taxonomies — packages/cli/src/acp-integration/acpAgent.ts — its prompt was built, but no agent on record was launched with it.

Not reviewed: Invariant agent C: config fields, early returns — packages/cli/src/acp-integration/acpAgent.ts — its prompt was built, but no agent on record was launched with it.

Not reviewed: Invariant agent A: state, timers, collections — packages/cli/src/ui/hooks/useBranchCommand.ts — its prompt was built, but no agent on record was launched with it.

Not reviewed: Invariant agent B: counters, return values, error taxonomies — packages/cli/src/ui/hooks/useBranchCommand.ts — its prompt was built, but no agent on record was launched with it.

Not reviewed: Invariant agent C: config fields, early returns — packages/cli/src/ui/hooks/useBranchCommand.ts — its prompt was built, but no agent on record was launched with it.

Not reviewed: reverse audit — no auditor was launched with a prompt this skill builds — the pass that hunts what the rest of the review missed ran, if at all, without the method its brief carries.

Not reviewed: verification — the review posts findings, but no verifier was launched with a prompt this skill builds — they were ruled on, if at all, without the verdict bar its brief carries.

— qwen3.7-max via Qwen Code /review

Comment thread packages/core/src/services/session-writer-lease.ts
Comment thread packages/core/src/config/config.ts
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
@doudouOUC

Copy link
Copy Markdown
Collaborator Author

Review fix round 4 summary

Item Result
PID reuse fencing Fixed in 77d5971 by comparing the current process start time with the lock owner identity, including malformed-lock runtime-sidecar recovery.
Initialization error context Fixed in 77d5971 by retaining the original failure as the native non-enumerable cause of the sanitized lease error.
Compatibility Kept schema v1 and made process_start_time_ms optional so older readers tolerate the record and missing/unreadable identity remains fail-closed.
Verification 450 targeted Core tests passed; Core build, typecheck, and scoped lint passed; root npm run build and npm run typecheck passed.

The automated reviewer message about unreviewed chunks is informational tool output and requires no code change.

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

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Reviewed. Suggestions are inline. Not reviewed: chunk 21, chunk 27, chunk 36 — no agent reported covering these; nobody read them. Not reviewed: chunk 21 — not reviewed (agent prompt mismatch). Not reviewed: chunk 27 — not reviewed (agent prompt mismatch). Not reviewed: chunk 36 — not reviewed (agent prompt mismatch). Not reviewed: build-and-test — build-test still running at review time. Not reviewed: Agent 0: Issue fidelity & root-cause ownership — its prompt was built, but no agent on record was launched with it. Not reviewed: chunk 1 — its prompt was built, but no agent on record was launched with it. Not reviewed: chunk 2 — its prompt was built, but no agent on record was launched with it. Not reviewed: chunk 3 — its prompt was built, but no agent on record was launched with it. Not reviewed: chunk 4 — its prompt was built, but no agent on record was launched with it. Not reviewed: chunk 5 — its prompt was built, but no agent on record was launched with it. Not reviewed: chunk 6 — its prompt was built, but no agent on record was launched with it. Not reviewed: chunk 7 — its prompt was built, but no agent on record was launched with it. Not reviewed: chunk 8 — its prompt was built, but no agent on record was launched with it. Not reviewed: chunk 9 — its prompt was built, but no agent on record was launched with it. Not reviewed: chunk 10 — its prompt was built, but no agent on record was launched with it. Not reviewed: chunk 11 — its prompt was built, but no agent on record was launched with it. Not reviewed: chunk 12 — its prompt was built, but no agent on record was launched with it. Not reviewed: chunk 13 — its prompt was built, but no agent on record was launched with it. Not reviewed: chunk 14 — its prompt was built, but no agent on record was launched with it. Not reviewed: chunk 15 — its prompt was built, but no agent on record was launched with it. Not reviewed: chunk 16 — its prompt was built, but no agent on record was launched with it. Not reviewed: chunk 17 — its prompt was built, but no agent on record was launched with it. Not reviewed: chunk 18 — its prompt was built, but no agent on record was launched with it. Not reviewed: chunk 19 — its prompt was built, but no agent on record was launched with it. Not reviewed: chunk 20 — its prompt was built, but no agent on record was launched with it. Not reviewed: chunk 21 — its prompt was built, but no agent on record was launched with it. Not reviewed: chunk 22 — its prompt was built, but no agent on record was launched with it. Not reviewed: chunk 23 — its prompt was built, but no agent on record was launched with it. Not reviewed: chunk 24 — its prompt was built, but no agent on record was launched with it. Not reviewed: chunk 25 — its prompt was built, but no agent on record was launched with it. Not reviewed: chunk 26 — its prompt was built, but no agent on record was launched with it. Not reviewed: chunk 27 — its prompt was built, but no agent on record was launched with it. Not reviewed: chunk 28 — its prompt was built, but no agent on record was launched with it. Not reviewed: chunk 29 — its prompt was built, but no agent on record was launched with it. Not reviewed: chunk 30 — its prompt was built, but no agent on record was launched with it. Not reviewed: chunk 31 — its prompt was built, but no agent on record was launched with it. Not reviewed: chunk 32 — its prompt was built, but no agent on record was launched with it. Not reviewed: chunk 33 — its prompt was built, but no agent on record was launched with it. Not reviewed: chunk 34 — its prompt was built, but no agent on record was launched with it. Not reviewed: chunk 35 — its prompt was built, but no agent on record was launched with it. Not reviewed: chunk 36 — its prompt was built, but no agent on record was launched with it. Not reviewed: chunk 37 — its prompt was built, but no agent on record was launched with it. Not reviewed: chunk 38 — its prompt was built, but no agent on record was launched with it. Not reviewed: chunk 39 — its prompt was built, but no agent on record was launched with it. Not reviewed: chunk 40 — its prompt was built, but no agent on record was launched with it. Not reviewed: chunk 41 — its prompt was built, but no agent on record was launched with it. Not reviewed: chunk 42 — its prompt was built, but no agent on record was launched with it. Not reviewed: chunk 43 — its prompt was built, but no agent on record was launched with it. Not reviewed: Test coverage matrix (whole-diff) — its prompt was built, but no agent on record was launched with it. Not reviewed: Agent 1b: Removed-behavior audit — its prompt was built, but no agent on record was launched with it. Not reviewed: Agent 1c: Cross-file tracer — its prompt was built, but no agent on record was launched with it. Not reviewed: Agent 7: Build & test verification — its prompt was built, but no agent on record was launched with it. Not reviewed: Invariant agent A: state, timers, collections — packages/cli/src/acp-integration/acpAgent.ts — its prompt was built, but no agent on record was launched with it. Not reviewed: Invariant agent B: counters, return values, error taxonomies — packages/cli/src/acp-integration/acpAgent.ts — its prompt was built, but no agent on record was launched with it. Not reviewed: Invariant agent C: config fields, early returns — packages/cli/src/acp-integration/acpAgent.ts — its prompt was built, but no agent on record was launched with it. Not reviewed: Invariant agent A: state, timers, collections — packages/cli/src/ui/hooks/useBranchCommand.ts — its prompt was built, but no agent on record was launched with it. Not reviewed: Invariant agent B: counters, return values, error taxonomies — packages/cli/src/ui/hooks/useBranchCommand.ts — its prompt was built, but no agent on record was launched with it. Not reviewed: Invariant agent C: config fields, early returns — packages/cli/src/ui/hooks/useBranchCommand.ts — its prompt was built, but no agent on record was launched with it. Not reviewed: reverse audit — no auditor was launched with a prompt this skill builds — the pass that hunts what the rest of the review missed ran, if at all, without the method its brief carries. Not reviewed: verification — the review posts findings, but no verifier was launched with a prompt this skill builds — they were ruled on, if at all, without the verdict bar its brief carries.

— qwen3.7-max via Qwen Code /review

Comment thread packages/cli/src/acp-integration/acpAgent.ts Outdated
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
@doudouOUC

Copy link
Copy Markdown
Collaborator Author

Review fix round 5 summary

Item Result
ACP live-session workspace mismatch Fixed in e21d3e8. Both loadSession and unstable_resumeSession now return JSON-RPC -32602 with errorKind invalid_params.
Regression coverage Added coverage proving both live-session fast paths preserve the structured error and do not create a second Config.
Automated review coverage report No actionable code finding; informational review-tool output only.
Cancelled Qwen Autofix route Not retried because the new fix commit supersedes the prior SHA and retriggers checks.
Verification 298 targeted ACP tests passed; scoped Prettier and ESLint passed; root npm run build and npm run typecheck passed.

@wenshao

wenshao commented Jul 19, 2026

Copy link
Copy Markdown
Collaborator

Re: review 4729338733 — two facts worth separating: the process that posted it, and the finding it posted.

Process: that run built its roster prompts and launched almost none of them — all 43 chunk agents ran on rewritten prompts, and Step 4 verification never ran; the body itself discloses "the posted findings cannot be counted as verified". A CHANGES_REQUESTED resting on an unverified finding is a pipeline defect on our side: the 99-clause disclosure wall is collapsed by #7190 (merged), and #7191 makes an unverified blocker soften to Comment with disclosure instead of formally blocking.

The finding: I verified it by hand against config.ts at e21d3e86a, and it stands. In prepareSessionArtifactMigration, when the inner rollback fully succeeds (artifacts restored, transcript rebound, runtime status rewritten, recorder resumed) and only process.chdir(oldDir) then fails, the chdir-catch unconditionally sets sessionTransitionFailure, closes the just-resumed recorder, and throws — permanently gating assertCanStartTurn() for a session whose persisted state is fully consistent (session storage lives under ~/.qwen, so an externally removed workspace dir does not impair the rollback). No test pins that poisoning, so it reads as unconsidered rather than deliberate fail-closed. Recommend handling the Critical on its merits — the verdict's process was broken, but the finding is real.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
@doudouOUC

Copy link
Copy Markdown
Collaborator Author

Review fix round 8 (Critical-only)

Feedback Judgment Action
Recovered session is permanently poisoned when only cwd rollback fails Accepted after maintainer confirmation Removed the cwd-only permanent failure and recorder close; the original migration error is returned while the recovered writer, transcript binding, and lease remain usable. True artifact or recorder rollback failures continue to fail closed.

Validation on a18bbef: npm run build; npm run typecheck; packages/core config.test.ts (428/428).

The remaining non-Critical review threads stay unresolved under the post-round-5 policy.

pull Bot pushed a commit to bit-cook/qwen-code that referenced this pull request Jul 19, 2026
…se an all-built-none-launched roster (QwenLM#7190)

* fix(review): one disclosure per subject — dedupe the Not-reviewed list, collapse an all-built-none-launched roster

A public review body on QwenLM#7188 was a wall of twenty-two "Not reviewed"
clauses for eleven roles: the run built every roster prompt, launched
not one agent, and every disclosure appeared twice.

Two defects, one wall:

- compose-review's `unreviewed` list fills from two sides -- the
  caller's `unreviewedDimensions` and the coverage recomputation -- and
  a run that pastes the gate's own gap lines into its input posts every
  one of them twice. The chunk list has deduped by its `chunk <id>`
  prefix since that exact bug shipped there; the role list now dedupes
  by label too (everything before the entry's last em-dash segment,
  because an invariant agent's label legitimately carries one). When
  both sides name the same subject, the coverage-derived text wins --
  it is the evidence-bounded register the body is written in.

- coverage collapses "nobody BUILT anything" to one line, but the
  launched-side twin -- every prompt built, none launched -- was still
  one line per dimension, burying the single fact that explains all of
  them: the run stopped at the builder. Collapsed the same way, one
  line for the run; the per-role selectors survive for the repair.

* fix(review): group Not-reviewed disclosures by cause, prefer the precise text on collision

Second exhibit, same wall: the review posted on QwenLM#7166 was ninety-nine
disclosure paragraphs over four causes -- forty-three chunks all
launched with rewritten prompts, fifty-five roles built and never
launched -- with the six real findings buried beneath. Neither QwenLM#7190
mechanism touched it: nothing was duplicated, and the roster was not
all-unlaunched (the chunk agents ran).

- Explained disclosures now group by their reason text, the same last
  em-dash segment the dedup keys on: same cause, one sentence, every
  subject on it -- exactly as the bare names already grouped under the
  shared whiff sentence. A reason embedding per-subject detail (an
  unread brief's path) differs per entry and keeps its own line.

- The dedup now prefers coverage-derived text over the caller's AND the
  earliest coverage category on a within-coverage collision: a rewritten
  chunk is also, to the roster, a requirement with no verbatim launch,
  and the later roster text told the author "no agent was launched"
  about an agent that demonstrably ran.

* fix(review): make the discarded-suggestions clause self-contained in the posted body

"see the terminal output" pointed the PR author at a terminal only the
operator has -- a dead reference that eight hours of real bot reviews
carried onto five different pull requests. Say what happened and that
nothing is owed, in the body's own register.

* fix(review): carry disclosures structurally -- no reparsed prose, no coverage-side collapse

Review follow-through on three confirmed Criticals, which converge on
one design:

- The all-built-none-launched collapse misfired on the exhibit it was
  built for: candidatesOf is also all-empty when every agent ran on a
  REWRITTEN prompt, so the aggregate claimed "the run stopped at the
  prompt builder" beside forty-three rewritten-launch disclosures that
  said otherwise. Removed -- and it also discarded the per-role subjects
  before the caller's echoes could dedupe against them.

- The last-em-dash subject/reason split reparsed rendered prose, and a
  reason is free-form: labels carry a dash for an invariant's file,
  error interpolations carry anything. Coverage now hands compose the
  entries as {subject, reason} pairs (a new `disclosures` field beside
  the prose twins the stderr formatting keeps); the caller's entries are
  never parsed at all -- they dedupe by prefix against known coverage
  subjects, exactly as the chunk list already did, and render verbatim
  otherwise.

- With subjects structural and per-role entries surviving to the dedup,
  the same-reason grouping does the collapsing for every shape at once:
  the QwenLM#7188 wall, the QwenLM#7166 wall, and the caller-echo variant all render
  as one sentence per cause -- with each subject under its most precise
  cause only.

* refactor(review): single-source each disclosure's prose from its structural entry

Review follow-through: every reason lived twice -- the prose push that
feeds check-coverage's stderr and the disclose() that feeds the posted
body -- and an edit to one and not the other would silently diverge what
the operator reads from what the author is told. disclose() now returns
the joined prose and the stderr arrays consume it, so there is one
statement of each sentence. Plus the two nits: the needless covEntries
copy, and a -1 guard on the verification-gap split (safe today by
construction, latent tomorrow).
@wenshao
wenshao requested a review from Copilot July 19, 2026 05:41

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@wenshao

wenshao commented Jul 19, 2026

Copy link
Copy Markdown
Collaborator

🧪 Local build & real-machine verification on Linux (merge reference)

Since the PR's own test matrix left Linux as ⚠️, I checked out agent/session-writer-lease (contains latest main), built it locally, and exercised the lease behavior with real TUI processes against a live model (qwen3.7-max via DashScope). Summary: the single-writer guarantee holds in every scenario I tested — but I found one interactive UX bug (silent hang) and one test-hygiene issue that leaks files into the developer's real ~/.qwen.

Environment: Debian 13 (kernel 6.12.63), Node v22.22.2, npm 10.9.7 · npm run build -- --cli-only + npm run bundle → OK · all runs used the built dist/cli.js.

1. Unit tests — all changed test files pass

Package Runner Files Tests Result
core vitest 17 1,151
cli vitest 17 1,622
acp-bridge vitest 2 433
vscode-ide-companion vitest 1 11
desktop/shared bun test 1 36
Total 38 3,253 0 failures

2. Real two-process E2E (built TUI, live model)

# Scenario Result
1 In-TUI /resume of a session held by a live process → fail-closed, clear error, both processes stay healthy
2 Headless qwen --resume <id> -p "…" of a held session → SessionWriterConflictError, exit 1, no writes
3 Startup qwen --resume <id> (interactive) of a held session → hangs forever at "Initializing…", no error shown ❌ bug
4 Control: startup --resume of a free session → full transcript restored instantly
5 kill -9 the owner → stale lock reclaimed on next /resume; transcript fully restored; lock re-owned by new PID
6 New turn after reclaim, then clean /quit → lock file removed
7 /clear and /branch → work; /branch acquires the branch-session lock and releases the old one (process holds exactly 1 lock)
8 Transcript integrity after kill→reclaim→append cycle: 11 records, single linear parent chain, zero forked parents, both turn markers present

Scenario 1 — fail-closed conflict (screenshot):

in-TUI resume conflict

Scenario 5+8 — transcript restored after kill -9 + reclaim, second turn appended, chain stays linear (screenshot):

reclaimed session with both turns

Lock record on disk while owned (pid matches the live TUI process; removed on clean /quit):

{"schema_version":1,"session_id":"79604444-…","owner_id":"89bc4b8e-…","pid":511276,
 "process_start_time_ms":1784438518410,"hostname":"iZbp…","process_kind":"interactive",
 "acquired_at":"2026-07-19T05:21:59.354Z","qwen_version":"0.19.12"}
More screenshots: owner session · /branch lock swap

owner session live

branch swaps lock

3. Finding 1 (bug): interactive startup --resume of a held session hangs silently

Process B stayed on the "Initializing…" spinner for 150+ seconds (~0 CPU) with no message; the PR's Reviewer Test Plan step 1 expects a session_writer_conflict surface here. Screenshot after 150 s:

interactive resume hang

Root cause (verified in source): Config.initialize()activateChatRecording()SessionWriterLease.acquire() throws SessionWriterConflictError. In interactive mode that await config.initialize() happens inside AppContainer's mount effect (packages/cli/src/ui/AppContainer.tsx, the "Initialize config" effect whose comment defers errors to "the global catch"), so the rejection only reaches setupUnhandledRejectionHandler() in gemini.tsx, which logs to the debug console — the UI keeps spinning forever. The headless path prints the error and exits 1, and in-TUI /resume shows a clean message; only this startup path lacks handling. SessionWriterConflictError is imported in packages/cli/src/config/config.ts solely for the --fork-session branch.

Importantly, fail-closed still holds — the hung process never writes and the owner is unaffected — so this is a UX gap, not a corruption risk. This also matches the author's stated caveat that interactive integration wasn't validated after the final rebase. Suggested fix: catch SessionWriterConflictError around startup initialization and render the same "already open in another Qwen process" error (or exit non-zero), instead of leaving the spinner.

4. Finding 2 (test hygiene): unit tests leak lock files into the real ~/.qwen

Running the changed test files wrote ~165 lock files into my real ~/.qwen/tmp/session-writer-locks/ and left them behind (dead vitest-worker PIDs, process_kind: "unknown", qwen_version: null). Attribution by isolated re-runs:

  • packages/core/src/config/config.test.ts alone → 55 leaked locks
  • packages/cli/src/ui/hooks/useResumeCommand.test.ts + packages/cli/src/ui/AppContainer.test.tsx → 100 leaked locks
  • clearCommand.test.ts / useBranchCommand.test.ts → clean (0)

These tests construct Config instances whose session runtime base resolves to the real home directory. They should pin runtimeBaseDir/storage to a per-test temp dir so npm test never writes outside the sandbox. Harmless for correctness (stale local locks are reclaimable) but it pollutes every contributor's home and could interact with a concurrently running real session.

5. Minor notes

  • Headless conflict exits via "An unexpected critical error occurred" plus a raw stack trace; a one-line structured error would be friendlier (the message itself is good: "This session is already open in another Qwen process.").
  • Stale lock files are only reclaimed when that same session is next resumed; there's no sweep for abandoned locks, so ~/.qwen/tmp/session-writer-locks/ grows over time (each file ~300 B — cosmetic).

Verdict

Core mechanism verified end-to-end on Linux: conflicts fail closed before any write, stale local locks are reclaimed safely, clean exits release ownership, /clear///branch lifecycles swap leases correctly, and the parent chain stays linear through a kill→reclaim→append cycle — exactly the corruption class #7164 describes. I'd like to see Finding 1 (silent hang, the PR's own headline scenario) fixed in this PR or an immediate follow-up, and Finding 2 addressed so the suite stops writing into contributors' home directories. No objection to the overall design based on observed behavior.

中文版本

🧪 Linux 本地构建 + 真机验证(合并参考)

由于 PR 自身的测试矩阵中 Linux 为 ⚠️,我在本地检出 agent/session-writer-lease(已包含最新 main),完成构建,并用真实 TUI 进程 + 真实模型(DashScope qwen3.7-max)验证了租约行为。结论:所有测试场景下单写者保证均成立——但发现一个交互模式 UX bug(静默卡死)和一个会向开发者真实 ~/.qwen 泄漏文件的测试卫生问题。

环境: Debian 13(内核 6.12.63)、Node v22.22.2、npm 10.9.7 · npm run build -- --cli-only + npm run bundle → 成功 · 全部使用构建产物 dist/cli.js 运行。

1. 单元测试——全部变更测试文件通过

运行器 文件数 测试数 结果
core vitest 17 1,151
cli vitest 17 1,622
acp-bridge vitest 2 433
vscode-ide-companion vitest 1 11
desktop/shared bun test 1 36
合计 38 3,253 0 失败

2. 真实双进程 E2E(构建版 TUI + 真实模型)

# 场景 结果
1 TUI 内 /resume 一个被存活进程持有的会话 → 失败关闭,报错清晰,两个进程均正常
2 无头模式 qwen --resume <id> -p "…" 目标为被持有会话 → SessionWriterConflictError,退出码 1,无写入
3 启动参数 qwen --resume <id>(交互模式)目标为被持有会话 → 永远停在 "Initializing…",无任何报错 ❌ bug
4 对照组:启动参数 --resume 空闲会话 → 立即恢复完整会话记录
5 kill -9 杀掉持有者 → 下次 /resume 回收过期锁;会话记录完整恢复;锁归新 PID 所有
6 回收后继续新对话,然后 /quit 干净退出 → 锁文件被删除
7 /clear/branch → 正常;/branch 获取分支会话锁并释放旧锁(进程恰好持有 1 把锁)
8 kill→回收→追加 之后的记录完整性:11 条记录,单一线性 parent 链、零分叉,两个标记均在

场景 1(失败关闭)与场景 5+8(kill -9 后恢复、继续对话且链保持线性)的截图见上方英文部分。

3. 发现 1(bug):交互模式启动 --resume 被持有会话时静默卡死

进程 B 在 "Initializing…" 停留 150+ 秒(CPU 几乎为 0),无任何提示;而 PR 的 Reviewer Test Plan 第 1 条预期此处应出现 session_writer_conflict

根因(已在源码验证):Config.initialize()activateChatRecording()SessionWriterLease.acquire() 抛出 SessionWriterConflictError。交互模式下这个 await config.initialize() 位于 AppContainer 的挂载 effect(packages/cli/src/ui/AppContainer.tsx 中注释写明错误交给"全局捕获"),因此 rejection 只会到达 gemini.tsxsetupUnhandledRejectionHandler(),仅写入 debug console——UI 无限转圈。无头路径会打印错误并以退出码 1 结束,TUI 内 /resume 也有清晰报错;唯独这个启动路径没有处理。packages/cli/src/config/config.ts 中导入的 SessionWriterConflictError 只用于 --fork-session 分支。

重要的是失败关闭语义仍然成立——卡住的进程不会写入,持有者不受影响——所以这是 UX 缺口而非数据损坏风险,也与作者声明的"最终 rebase 后未验证交互集成"一致。建议:在启动初始化处捕获 SessionWriterConflictError,渲染与 TUI 内一致的"已被另一个 Qwen 进程打开"错误(或非零退出),而不是留在转圈状态。

4. 发现 2(测试卫生):单元测试向真实 ~/.qwen 泄漏锁文件

运行变更的测试文件后,我的真实 ~/.qwen/tmp/session-writer-locks/ 里多出 约 165 个锁文件且未清理(PID 为已死亡的 vitest worker,process_kind: "unknown"qwen_version: null)。单独复跑定位:

  • packages/core/src/config/config.test.ts → 泄漏 55 个
  • packages/cli/src/ui/hooks/useResumeCommand.test.ts + packages/cli/src/ui/AppContainer.test.tsx → 泄漏 100 个
  • clearCommand.test.ts / useBranchCommand.test.ts → 干净(0)

这些测试构造的 Config 实例其会话 runtime base 解析到了真实 home 目录。应将 runtimeBaseDir/storage 固定到每个测试的临时目录,确保 npm test 不写沙箱之外。对正确性无害(本机过期锁可回收),但会污染每位贡献者的 home,也可能与同时运行的真实会话产生交互。

5. 其他小问题

  • 无头模式冲突时输出 "An unexpected critical error occurred" + 原始堆栈;换成一行结构化错误会更友好(报错文案本身不错:"This session is already open in another Qwen process.")。
  • 过期锁文件只有在同一会话下次被 resume 时才会回收,没有针对废弃锁的清扫机制,~/.qwen/tmp/session-writer-locks/ 会随时间增长(每个约 300 B——仅观感问题)。

结论

核心机制在 Linux 上端到端验证通过:冲突在任何写入前失败关闭、本机过期锁安全回收、干净退出释放所有权、/clear///branch 生命周期正确交接租约、kill→回收→追加全程 parent 链保持线性——恰好覆盖 #7164 描述的损坏类型。希望发现 1(静默卡死,即本 PR 自己的旗舰场景)在本 PR 或紧随的 follow-up 中修复,发现 2 也应处理以免测试写入贡献者 home 目录。基于实测行为,对整体设计无异议。


🤖 Verified locally with Claude Code (model: claude-fable-5)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
@doudouOUC

Copy link
Copy Markdown
Collaborator Author

@wenshao Thanks for the thorough Linux verification and real-process E2E report.

Finding Decision Action
Interactive startup --resume silently remains on “Initializing…” when the session is owned Fixed (Critical regression) Commit 8fdd934b79 catches the interactive config initialization failure, surfaces the exact conflict message on stderr and in the TUI initialization-error state, keeps input/background turn gates closed, and stops the initialization spinner.
Tests write session locks into the contributor's real ~/.qwen Deferred after review round 8 Valid test-hygiene issue, but non-production and non-Critical; it needs a separate scoped cleanup of test runtime-base setup rather than widening this PR again. Validation for this fix was run with an isolated QWEN_RUNTIME_DIR.
Headless conflict stack trace Deferred UX-only and non-Critical after the review-round limit.
Stale-lock sweep Not taking in this PR Cosmetic storage growth; reclaim-on-resume remains the intended P0 behavior.

Verification on the pushed commit: npm run build && npm run typecheck; AppContainer.test.tsx and Footer.test.tsx (147/147 passed).

yiliang114 pushed a commit to yiliang114/qwen-code that referenced this pull request Jul 19, 2026
…— soften the Request changes it rides (QwenLM#7191)

* fix(review): an unverified Critical must not become a public blocker -- soften the Request changes it rides

The module's header has stated the principle since the false
"leaks tokens" Critical: an unverified finding must not become a public
blocker. The mechanics only enforced it on the Approve row -- a verify
gap capped an Approve to Comment -- while the Request-changes row stood
on "a confirmed Critical earned that", with nothing checking CONFIRMED.
A real bot review shipped through the gap: a CHANGES_REQUESTED posted
onto an external contributor's PR (QwenLM#7166) over one Critical that the
review's own body disclosed as unverified, from a run whose verifier was
built and never launched.

verificationGaps now returns the structured bit (unverifiedFindings)
instead of leaving the verdict to parse gap prose, and composeReview
softens a Request changes to Comment when the non-deterministic
Criticals it would post cannot be shown verified -- verifier missing,
transcripts unreadable, or no plan to check against; fail closed at
every exit, because "could not show" and "was not" read the same to the
person the blocker is posted at. Deterministic [build]/[test] findings
stay pre-confirmed and keep their Request changes. The findings still
post either way -- the body copy of an unanchorable blocker survives the
softening exactly as it survives the presubmit carve-out -- and the
verdict line says why a Comment sits over visible Critical comments.

Manipulation check, both directions: a run that wants an Approve gains
nothing (the same gap already caps Approve), and a run that wants to
block without verifying now cannot.

* fix(review): keep presubmit reasons beside the unverified cap, sync the Step 7 restatement

Review follow-through: the Step 7 skill text still said a cap never
softens a REQUEST_CHANGES -- the exact one-restatement-behind drift the
module header warns about; it now carries the coverage qualifier and the
one exception. When the unverified cap and presubmit
downgradeRequestChanges both held, the softening ran first and the
presubmit reasons silently vanished from the body; the downgrade arm now
also fires on a softened Request-changes base, so the body's downgrade
clause carries the reasons while the verdict line keeps the unverified
sentence. Plus a pin that verify on record with the reverse audit absent
still blocks -- the softening gates on verify alone.

* fix(review): a deterministic Critical keeps its Request changes beside an unverified sibling

Review catch: the unverified-blockers softening dropped the whole
REQUEST_CHANGES even when the review also carried a pre-confirmed
[build]/[test] body Critical -- un-blocking a confirmed build failure
because its sibling lacked a verifier. The softening now requires zero
deterministic body Criticals; the unverified ones stay disclosed either
way, and the mixed case is pinned.

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

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Not reviewed: coverage — agents ran substantively but prompts were wrapped rather than passed verbatim from the CLI-built roster.

Not reviewed: chunk 4 — launched with a prompt that is not the one the CLI built.

Not reviewed: chunk 14 — launched with a prompt that is not the one the CLI built.

Not reviewed: chunk 26 — launched with a prompt that is not the one the CLI built.

Not reviewed: chunk 30 — launched with a prompt that is not the one the CLI built.

Not reviewed: chunk 33 — launched with a prompt that is not the one the CLI built.

Not reviewed: chunk 35 — launched with a prompt that is not the one the CLI built.

Not reviewed: chunk 27 — launched with a prompt that is not the one the CLI built.

Not reviewed: chunk 12 — launched with a prompt that is not the one the CLI built.

Not reviewed: chunk 43 — launched with a prompt that is not the one the CLI built.

Not reviewed: chunk 8 — launched with a prompt that is not the one the CLI built.

Not reviewed: chunk 29 — launched with a prompt that is not the one the CLI built.

Not reviewed: chunk 16 — launched with a prompt that is not the one the CLI built.

Not reviewed: chunk 38 — launched with a prompt that is not the one the CLI built.

Not reviewed: chunk 3 — launched with a prompt that is not the one the CLI built.

Not reviewed: chunk 18 — launched with a prompt that is not the one the CLI built.

Not reviewed: chunk 41 — launched with a prompt that is not the one the CLI built.

Not reviewed: chunk 7 — launched with a prompt that is not the one the CLI built.

Not reviewed: chunk 23 — launched with a prompt that is not the one the CLI built.

Not reviewed: chunk 15 — launched with a prompt that is not the one the CLI built.

Not reviewed: chunk 22 — launched with a prompt that is not the one the CLI built.

Not reviewed: chunk 34 — launched with a prompt that is not the one the CLI built.

Not reviewed: chunk 42 — launched with a prompt that is not the one the CLI built.

Not reviewed: chunk 39 — launched with a prompt that is not the one the CLI built.

Not reviewed: chunk 9 — launched with a prompt that is not the one the CLI built.

Not reviewed: chunk 25 — launched with a prompt that is not the one the CLI built.

Not reviewed: chunk 5 — launched with a prompt that is not the one the CLI built.

Not reviewed: chunk 24 — launched with a prompt that is not the one the CLI built.

Not reviewed: chunk 31 — launched with a prompt that is not the one the CLI built.

Not reviewed: chunk 19 — launched with a prompt that is not the one the CLI built.

Not reviewed: chunk 2 — launched with a prompt that is not the one the CLI built.

Not reviewed: chunk 37 — launched with a prompt that is not the one the CLI built.

Not reviewed: chunk 6 — launched with a prompt that is not the one the CLI built.

Not reviewed: chunk 21 — launched with a prompt that is not the one the CLI built.

Not reviewed: chunk 17 — launched with a prompt that is not the one the CLI built.

Not reviewed: chunk 13 — launched with a prompt that is not the one the CLI built.

Not reviewed: chunk 40 — launched with a prompt that is not the one the CLI built.

Not reviewed: chunk 36 — launched with a prompt that is not the one the CLI built.

Not reviewed: chunk 1 — launched with a prompt that is not the one the CLI built.

Not reviewed: chunk 11 — launched with a prompt that is not the one the CLI built.

Not reviewed: chunk 32 — launched with a prompt that is not the one the CLI built.

Not reviewed: chunk 28 — launched with a prompt that is not the one the CLI built.

Not reviewed: chunk 20 — launched with a prompt that is not the one the CLI built.

Not reviewed: chunk 10 — launched with a prompt that is not the one the CLI built.

Not reviewed: chunk 1 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 2 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 3 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 4 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 5 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 6 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 7 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 8 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 9 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 10 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 11 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 12 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 13 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 14 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 15 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 16 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 17 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 18 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 19 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 20 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 21 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 22 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 23 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 24 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 25 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 26 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 27 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 28 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 29 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 30 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 31 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 32 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 33 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 34 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 35 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 36 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 37 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 38 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 39 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 40 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 41 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 42 — its prompt was built, but no agent on record was launched with it.

Not reviewed: chunk 43 — its prompt was built, but no agent on record was launched with it.

Not reviewed: Test coverage matrix (whole-diff) — its prompt was built, but no agent on record was launched with it.

Not reviewed: Agent 1b: Removed-behavior audit — its prompt was built, but no agent on record was launched with it.

Not reviewed: Agent 1c: Cross-file tracer — its prompt was built, but no agent on record was launched with it.

Not reviewed: Agent 7: Build & test verification — its prompt was built, but no agent on record was launched with it.

Not reviewed: Invariant agent A: state, timers, collections — packages/cli/src/acp-integration/acpAgent.ts — its prompt was built, but no agent on record was launched with it.

Not reviewed: Invariant agent B: counters, return values, error taxonomies — packages/cli/src/acp-integration/acpAgent.ts — its prompt was built, but no agent on record was launched with it.

Not reviewed: Invariant agent C: config fields, early returns — packages/cli/src/acp-integration/acpAgent.ts — its prompt was built, but no agent on record was launched with it.

Not reviewed: Invariant agent A: state, timers, collections — packages/cli/src/ui/hooks/useBranchCommand.ts — its prompt was built, but no agent on record was launched with it.

Not reviewed: Invariant agent B: counters, return values, error taxonomies — packages/cli/src/ui/hooks/useBranchCommand.ts — its prompt was built, but no agent on record was launched with it.

Not reviewed: Invariant agent C: config fields, early returns — packages/cli/src/ui/hooks/useBranchCommand.ts — its prompt was built, but no agent on record was launched with it.

Not reviewed: reverse audit — no auditor was launched with a prompt this skill builds — the pass that hunts what the rest of the review missed ran, if at all, without the method its brief carries.

Not reviewed: verification — a verifier ran and opened its brief, but no agent was launched with the prompt the CLI built — the launch was written by hand, and the posted findings cannot be counted as verified against it.

— qwen3.7-max via Qwen Code /review

Comment thread packages/cli/src/acp-integration/acpAgent.ts Outdated
Comment on lines +429 to +431
return new SessionWriterUnavailableError();
}
return error;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Suggestion] normalizeMaintenanceError discards the original error when wrapping filesystem errors into SessionWriterUnavailableError, despite the constructor accepting ErrorOptions with cause. — Concrete cost: A maintenance operation (archive, remove, finalize) encounters EACCES, EIO, or ENOSPC. The original errno, path, and message are replaced by the generic "Session write ownership could not be verified." A maintainer debugging the failure has no way to determine the root cause from the thrown error.

Suggested change
return new SessionWriterUnavailableError();
}
return error;
return new SessionWriterUnavailableError({ cause: error });
}
return error;

— qwen3.7-max via Qwen Code /review

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.

[codex] Thanks — deferring this non-critical observability improvement because the PR is past the five-round review limit; only Critical fixes are being taken now.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
@doudouOUC

Copy link
Copy Markdown
Collaborator Author

Review round 10 summary for commit 39d1837

Item Decision Action
JSON-RPC code collision between transcript_page_too_large and session_writer_conflict Fixed Moved session writer errors to -32016 through -32019 and updated ACP, HTTP bridge, and regression expectations.
Preserve filesystem error as cause in maintenance normalization Deferred Non-critical observability improvement; this PR is past the five-round limit, so only Critical fixes are being accepted.
Review coverage prompt-launch report Informational No product-code defect identified.

Validation: 968 targeted tests passed; targeted ESLint passed; npm run build and npm run typecheck passed.

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

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Reviewed. Suggestions are inline. 3 Suggestion-level finding(s) could not be anchored to a changed line and were dropped; nothing further to act on here. Not reviewed: chunk 2, chunk 3, chunk 4, chunk 17, chunk 19, chunk 21, chunk 22, chunk 23, chunk 25, chunk 27, chunk 28, chunk 32, chunk 35, chunk 36, chunk 37, chunk 39, chunk 41 — no agent reported covering these; nobody read them. Not reviewed: chunk 26, chunk 33, chunk 38, chunk 11, chunk 40, chunk 29, chunk 34, chunk 6, chunk 24, chunk 20, chunk 42, chunk 13, chunk 18, chunk 5, chunk 10, chunk 43, chunk 1 — launched with a prompt that is not the one the CLI built. Not reviewed: Agent 0: Issue fidelity & root-cause ownership, chunk 2, chunk 3, chunk 4, chunk 7, chunk 8, chunk 9, chunk 12, chunk 14, chunk 15, chunk 16, chunk 17, chunk 19, chunk 21, chunk 22, chunk 23, chunk 25, chunk 27, chunk 28, chunk 30, chunk 31, chunk 32, chunk 35, chunk 36, chunk 37, chunk 39, chunk 41, Test coverage matrix (whole-diff), Agent 1b: Removed-behavior audit, Agent 1c: Cross-file tracer, Agent 7: Build & test verification, Invariant agent A: state, timers, collections — packages/cli/src/acp-integration/acpAgent.ts, Invariant agent B: counters, return values, error taxonomies — packages/cli/src/acp-integration/acpAgent.ts, Invariant agent C: config fields, early returns — packages/cli/src/acp-integration/acpAgent.ts, Invariant agent A: state, timers, collections — packages/cli/src/ui/hooks/useBranchCommand.ts, Invariant agent B: counters, return values, error taxonomies — packages/cli/src/ui/hooks/useBranchCommand.ts, Invariant agent C: config fields, early returns — packages/cli/src/ui/hooks/useBranchCommand.ts — its prompt was built, but no agent on record was launched with it. Not reviewed: reverse audit — no auditor was launched with a prompt this skill builds — the pass that hunts what the rest of the review missed ran, if at all, without the method its brief carries. Not reviewed: verification — a verifier ran and opened its brief, but no agent was launched with the prompt the CLI built — the launch was written by hand, and the posted findings cannot be counted as verified against it.

— qwen3.7-max via Qwen Code /review

Comment on lines +653 to +666
handle = await fs.open(temporaryPath, 'wx', 0o600);
if (bytes.byteLength > 0) await handle.writeFile(bytes);
await handle.sync();
await handle.close();
handle = undefined;
await this.assertOwnedAndUnchanged();
await fs.link(temporaryPath, this.transcriptPathValue);
this.expectedByteLengthValue = bytes.byteLength;
this.expectedTranscriptExistsValue = true;
} catch (error) {
failure =
(error as NodeJS.ErrnoException).code === 'EEXIST'
? new SessionTranscriptChangedError()
: error;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Suggestion] The catch block converts ALL EEXIST errors to SessionTranscriptChangedError, but EEXIST can come from two distinct calls: the temp file creation (fs.open(temporaryPath, 'wx', 0o600)) and the hard-link (fs.link). If a previous writeNewTranscript call failed and the await fs.unlink(temporaryPath) in cleanup also threw (no .catch(() => {}) unlike every other unlink in this file), the temp file is orphaned. A subsequent call hits EEXIST on temp file creation, misclassified as "transcript changed" when the transcript was never written. — Concrete cost: a retry after a transient filesystem error produces a misleading SessionTranscriptChangedError instead of surfacing the real cause.

Suggested change
handle = await fs.open(temporaryPath, 'wx', 0o600);
if (bytes.byteLength > 0) await handle.writeFile(bytes);
await handle.sync();
await handle.close();
handle = undefined;
await this.assertOwnedAndUnchanged();
await fs.link(temporaryPath, this.transcriptPathValue);
this.expectedByteLengthValue = bytes.byteLength;
this.expectedTranscriptExistsValue = true;
} catch (error) {
failure =
(error as NodeJS.ErrnoException).code === 'EEXIST'
? new SessionTranscriptChangedError()
: error;
try {
await fs.unlink(temporaryPath).catch(() => {});
handle = await fs.open(temporaryPath, 'wx', 0o600);

— qwen3.7-max via Qwen Code /review

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.

[codex] Thanks — deferring. Cleanup already suppresses unlink failures and the temporary filename is scoped by the lease owner; retry classification after a transient same-owner unlink failure is not Critical enough to expand review round 11.

@wenshao wenshao left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Reviewed. Suggestions are inline. Not reviewed: chunk 1, chunk 2, chunk 3, chunk 4, chunk 5, chunk 6, chunk 7, chunk 8, chunk 9, chunk 10, chunk 11, chunk 12, chunk 13, chunk 14, chunk 15, chunk 16, chunk 17, chunk 18, chunk 19, chunk 20, chunk 21, chunk 22, chunk 23, chunk 24, chunk 25, chunk 26, chunk 27, chunk 28, chunk 29, chunk 30, chunk 31, chunk 32, chunk 33, chunk 34, chunk 35, chunk 36, chunk 37, chunk 38, chunk 39, chunk 40, chunk 41, chunk 42, chunk 43 — no agent reported covering these; nobody read them. Not reviewed: coverage — agents ran substantively but the harness did not record them opening the diff file by path. Not reviewed: chunk 14, This PR introduces a process-level single-writer lease fo..., chunk 20, chunk 40, chunk 18, chunk 34, chunk 25, chunk 22, chunk 26, chunk 27, chunk 39, chunk 32, chunk 2, chunk 16, chunk 15, chunk 3, chunk 7, chunk 12, chunk 28, chunk 17, chunk 38, chunk 9, chunk 33, chunk 19, chunk 31, chunk 10, chunk 4, chunk 23, chunk 43, chunk 11, chunk 42, chunk 5, chunk 24, chunk 35, chunk 37, chunk 36, chunk 13, chunk 21, chunk 41, chunk 8, chunk 30, chunk 29, chunk 1, chunk 6 — pointed at diff lines it never opened: it made tool calls, but none of them read the diff. Not reviewed: reverse audit — no auditor was launched with a prompt this skill builds — the pass that hunts what the rest of the review missed ran, if at all, without the method its brief carries.

— qwen3.8-max-preview via Qwen Code /review

Comment on lines 4363 to 4365
// `session_closed` is terminal. Close the bus before ACP cancel so any
// late cancellation frames from the agent are intentionally dropped.
entry.events.close();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Suggestion] This comment now misdescribes the teardown ordering — the ACP cancel was moved to the top of closeSessionImpl (line 4294), so it runs before entry.events.close(), not after it. — Concrete cost: a maintainer relying on this comment would believe the bus is closed before cancel and that late cancel frames are dropped, when in fact the cancel now fires ~70 lines earlier with the bus open — an incorrect mental model of exactly the teardown-ordering invariant this PR is built around.

Suggested change
// `session_closed` is terminal. Close the bus before ACP cancel so any
// late cancellation frames from the agent are intentionally dropped.
entry.events.close();
// `session_closed` is terminal. The active-prompt cancel already ran at
// the top of closeSession; this closes the bus, dropping any later frames.
entry.events.close();

— qwen3.8-max-preview via Qwen Code /review

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.

Thanks — deferring this documentation-only correction because the PR is past the five-round review limit; only Critical fixes are being taken now.

Comment on lines +10063 to +10065
} catch (error) {
await this.discardStoredSessionIfCurrent(sessionId, session);
throw error;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Suggestion] If discardStoredSessionIfCurrent throws (e.g., SessionWriterUnavailableError from the writer lease release), the original setup error is silently replaced by the cleanup error. — Failure scenario: replayHistory throws (corrupt transcript), then closeStoredSession inside discardStoredSessionIfCurrent throws because the writer lease cannot be released. The caller receives the cleanup error with no trace of the original replay failure. The same file's shutdownConfigAfterFailure (line 509) already demonstrates the pattern of attaching the original error as cause.

Suggested change
} catch (error) {
await this.discardStoredSessionIfCurrent(sessionId, session);
throw error;
} catch (error) {
try {
await this.discardStoredSessionIfCurrent(sessionId, session);
} catch (cleanupError) {
if (cleanupError instanceof Error && cleanupError.cause === undefined) {
Reflect.defineProperty(cleanupError, 'cause', {
value: error,
configurable: true,
});
}
throw cleanupError;
}
throw error;

— qwen3.8-max-preview via Qwen Code /review

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.

Thanks — deferring. Preserving the setup failure as the cleanup error's cause would improve diagnostics, but it does not change the fail-closed cleanup behavior and is non-critical after the review-round limit.

typeof error === 'object' &&
typeof (error as NodeJS.ErrnoException).code === 'string'
) {
return new SessionWriterUnavailableError();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Suggestion] normalizeSessionWriterStorageError discards the original filesystem error instead of preserving it as cause, even though SessionWriterUnavailableError accepts ErrorOptions and other call sites in this same diff pass { cause: error }. — Failure scenario: a session activation fails because the lease directory has EACCES (or ENOSPC, ENOENT). The function wraps it in SessionWriterUnavailableError with no cause. A developer investigating a user's "session writer unavailable" report cannot distinguish a permission error from a missing directory from a full disk without reproducing the issue.

Suggested change
return new SessionWriterUnavailableError();
return new SessionWriterUnavailableError({ cause: error });

— qwen3.8-max-preview via Qwen Code /review

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.

Thanks — deferring this non-critical observability improvement because the PR is past the five-round review limit; only Critical fixes are being taken now.

Comment on lines 254 to +256
it('allows retry after a synchronous conversation-file failure', async () => {
const service = new ChatRecordingService(mockConfig);
vi.mocked(fs.writeFileSync).mockImplementationOnce(() => {
throw Object.assign(new Error('permission denied'), { code: 'EACCES' });
const service = createRecordingService(mockConfig);
vi.mocked(randomUUID).mockImplementationOnce(() => {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Suggestion] Test name says "synchronous conversation-file failure" but the mock now triggers a UUID-generation failure (randomUUID throws), not a file-write failure. — Concrete cost: a developer investigating conversation-file I/O failures would find this test and incorrectly conclude that path is covered, or a developer modifying the randomUUID call site would not realize this test's name promises something different from what it exercises.

Suggested change
it('allows retry after a synchronous conversation-file failure', async () => {
const service = new ChatRecordingService(mockConfig);
vi.mocked(fs.writeFileSync).mockImplementationOnce(() => {
throw Object.assign(new Error('permission denied'), { code: 'EACCES' });
const service = createRecordingService(mockConfig);
vi.mocked(randomUUID).mockImplementationOnce(() => {
it('allows retry after a synchronous record-creation failure', async () => {
const service = createRecordingService(mockConfig);
vi.mocked(randomUUID).mockImplementationOnce(() => {

— qwen3.8-max-preview via Qwen Code /review

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.

Thanks — deferring this non-critical test-name cleanup because the PR is past the five-round review limit; only Critical fixes are being taken now.

Comment on lines +1367 to +1369
await clearRuntimeStatus(
this.storage.getRuntimeStatusPath(sessionId),
);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Suggestion] removeSessionFiles now calls clearRuntimeStatus to clean up the runtime sidecar, but no test in the removeSession/removeSessions describe blocks asserts this happens. The archive and unarchive tests explicitly assert clearRuntimeStatus is NOT called, but the remove path has no positive assertion. — Failure scenario: if a future refactor accidentally drops the clearRuntimeStatus call, a removed session's runtime sidecar persists indefinitely. No test catches this regression.

Suggested fix: add expect(clearRuntimeStatus).toHaveBeenCalled() to the existing 'should remove session file' test.

— qwen3.8-max-preview via Qwen Code /review

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.

Thanks — deferring this non-critical test-coverage addition because the PR is past the five-round review limit; only Critical fixes are being taken now.

pull Bot pushed a commit to bhardwajRahul/qwen-code that referenced this pull request Jul 19, 2026
The first post-grouping body on QwenLM#7166 carried seventeen chunks twice:
once in "nobody read them" and once in the not-launched roster sentence
-- the consequence restated beside its cause. A chunk whose disclosure
entry already says WHY it went unread (launch never happened, or
happened on a rewritten prompt) now leaves the nobody-read sentence; the
cap and the remediation keep the full list, and a chunk with no
disclosed cause -- the 3A shape, where chunks are not roster
requirements -- keeps the sentence, because it is the only place the
author learns those lines went unread.
@doudouOUC

Copy link
Copy Markdown
Collaborator Author

已将当前事故所需的最小 P0a 独立拆到 #7237,便于先评审、合入和发布;以下分析已脱敏,不包含 session ID、用户输入、内部路径、模型内容或日志原文。

事故时序可以归纳为:

  1. writer A 已基于某个 parent 写入 tool result,并继续执行当前轮次。
  2. daemon 对同一持久化会话执行了一次真正的 fresh load,得到当时物理尾部对应的 parent,并构造了另一个可写 recorder。
  3. writer A 随后写入剩余工具结果和 final answer。
  4. daemon 中的新 recorder 又从先前缓存的 parent 追加下一条 user record,于是 transcript 中出现两个未标记的 sibling child。
  5. 重启只按物理尾重建 active chain,因此 writer A 已经展示给用户的完整回答不再位于恢复链上。重启是暴露分支的时点,不是制造分支的原因。

#7237 的 P0a 只覆盖本次 daemon/ACP 事故链路:按 (runtime base, session ID) 建立跨进程单 writer lease;取得 lease 后权威重载;每次 append 校验 owner token、文件身份和字节长度;在 user/cron/notification/teammate 轮次前做 admission;同 daemon 重复 load/resume 复用 live owner;live history read 经过 owner barrier;close 在 recorder drain 和 lease release 被 child 确认后才移除 bridge entry;对外返回稳定、脱敏的 409/503 错误。Desktop 遇到 writer 冲突会直接报错,不会静默创建 fresh session。

这版不新增通用 IPC/fork 协议,也不试图一次覆盖所有场景。Interactive/headless writer、完全事务化的 session switching、branch/fork/rewind 与 archive/delete maintenance、initializing-entry/load-close coalescing,以及已分支 transcript 的修复仍保留在 P0b/#7166 范围。逻辑 /cd 仍可用,但 persistence/runtime root 固定在该 session 的原始位置。

发布和回滚必须先 drain 旧 daemon/ACP 进程;新旧二进制混跑不安全,因为旧 writer 不识别 lease。若 runtime 文件系统不支持原子同目录 hard link,P0a 会以 session_writer_unavailable 失败关闭,而不是降级为无锁写入。

@wenshao

wenshao commented Jul 19, 2026

Copy link
Copy Markdown
Collaborator

✅ Maintainer verification — single-writer session persistence works as designed

I built this PR from source on Linux and verified it two ways: (1) a multi-process harness that drives the actual shipped compiled lease code across real OS processes, and (2) a live end-to-end run of two real qwen CLI processes on the same session (mock OpenAI backend). All the core guarantees hold. One non-blocking UX observation on the interactive path is noted at the end.

Net: the data-integrity goal is achieved — a second writer is rejected before any model turn, a crashed owner's stale lock is reclaimed, the authoritative transcript is fully restored, and history stays a single linear parent chain. Recommend merge with the interactive-surface follow-up tracked separately.

Environment

  • Head 39d183751 rebased scope vs origin/main merge-base 86ad53284 files, +9930 / −2418 (matches the PR).
  • Linux 6.12, Node v22.22.2, fresh npm ci + npm run build + npm run bundle (dist/cli.js), all clean.
  • CI on the PR is green (Test ubuntu, Serve A/B, web-shell E2E).

1) Changed-file unit tests — all green on Linux

packages/core   session-writer-lease.test.ts ....................  22 passed
packages/core   11 changed test files (recorder/session/config) . 740 passed
packages/cli    13 changed test files (config/resume/branch/acp) 1407 passed
packages/acp-bridge   bridge + status ..........................  433 passed
------------------------------------------------------------------------------
TOTAL                                                            2580 passed / 0 failed

2) Compiled-lease harness — 8/8 invariants across real OS processes

Spawns real child node processes that import the compiled packages/core/dist/.../session-writer-lease.js (not mocks; real PIDs, real Linux /proc start-time checks):

[PASS] INV1a holder acquired lease (process A)        :: owner=c300342d… pid=678917
[PASS] INV1b second live process (B) rejected         :: REJECTED:session_writer_conflict
[PASS] INV2a stale lock reclaimed after SIGKILL       :: staleLockPresent=true
[PASS] INV2b authoritative transcript fully restored  :: restoredLines=2 (expected 2)
[PASS] INV2c history linear after reclaim+restart     :: lines=3
[PASS] INV3  append fenced by expected byte length    :: errorKind=session_transcript_changed
[PASS] INV4  append rejected after ownership loss     :: errorKind=session_writer_lost
[PASS] INV5  graceful release → clean reopen          :: restoredLines=1
==== 8/8 invariants PASS ====

This directly validates invariants #1#3 and #5 from docs/design/session-writer-lease.md, including the byte-length fence catching an out-of-band ("old binary") append.

3) Live CLI E2E — two real qwen processes on one session (mock backend)

Step 1 — conflict (Reviewer Test Plan #1). Process A resumes the session interactively and holds the lease; process B resumes the same session and is rejected before any model turn, while A keeps running and the lock is unchanged:

# Terminal A (interactive) — resumed, input enabled, owns lock owner_pid=697355
# Terminal B (headless, SAME session):
An unexpected critical error occurred:
SessionWriterConflictError: This session is already open in another Qwen process.
    at SessionWriterLease.acquire (…/dist/chunks/chunk-O32IZHXP.js:39783:40)
    at async Config.activateChatRecording (…:153548:15)
    at async Config.initialize (…:153184:7)
process exit code = 1
lock unchanged → owner_pid=697355 (A)   |   process A still running ✓

Step 2 — stale reclaim + recovery (Reviewer Test Plan #2). SIGKILL A (no graceful release), then a fresh process C resumes: it reclaims the stale lock, restores the full transcript, and continues — leaving one linear chain:

kill -9 697355            → A procs remaining: 0   (stale lock left behind, pid 697355)
transcript before reclaim : 5 records
# Terminal C (interactive) restores "hello there" + reply, then a NEW "continue after reclaim" turn
new lock owner_pid = 698526 (C)               → stale lock reclaimed ✓
transcript after continuation : 11 records
divergent branches (parents with >1 child): 0 → SINGLE LINEAR CHAIN ✓

🟡 One non-blocking finding — interactive 2nd process fails closed but shows no on-screen reason

When the second process is interactive (not headless), the conflict is detected and it correctly fails closed — it never gets an input box and cannot append. However, the SessionWriterConflictError message only goes to stderr (hidden behind ink's alt-screen); the on-screen "Initialization Error" box never appears and the process does not exit — the user is left staring at a seemingly-frozen banner.

Root cause: Notifications (which renders initError) is mounted inside ink's <Static> region — MainContent.tsx:458-463. <Static> commits its items once, so the configInitializationError that AppContainer.tsx:743 sets after config.initialize() throws is never repainted. Headless handles this perfectly (prints + exit 1); only the interactive TUI is silent. This PR makes that path newly reachable for a normal action (opening the same session twice), so surfacing the conflict via a non-Static path (or exiting) would be a nice follow-up. Does not affect data integrity.

Verdict

Core single-writer guarantees are verified end-to-end on Linux (Linux was marked ⚠️ un-validated in the PR). LGTM / merge; suggest a small follow-up for the interactive conflict UX above.

🇨🇳 中文版(点击展开)

✅ 维护者验证 —— 会话单写者持久化按设计工作

我在 Linux 上从源码构建了本 PR,并用两种方式验证:(1) 一个驱动真正编译后 lease 代码的多进程 harness(跨真实操作系统进程);(2) 两个真实 qwen CLI 进程在同一会话上的端到端实测(mock OpenAI 后端)。所有核心保证都成立。结尾附一条不阻塞合并的交互层观察。

结论:数据完整性目标已达成 —— 第二个写者在任何模型轮次之前即被拒绝;owner 崩溃后其过期锁被回收;权威 transcript 被完整恢复;历史保持单一线性 parent 链。建议合并,交互层的小问题另行跟进。

环境

  • Head 39d183751,相对 origin/main merge-base 86ad532 的真实范围 = 84 文件,+9930 / −2418(与 PR 一致)。
  • Linux 6.12,Node v22.22.2;全新 npm ci + npm run build + npm run bundledist/cli.js)全部通过。
  • PR 的 CI 为绿(Test ubuntu、Serve A/B、web-shell E2E)。

1)变更文件单测 —— Linux 全绿

core  session-writer-lease.test.ts ......  22 passed
core  11 个变更测试文件 ................. 740 passed
cli   13 个变更测试文件 ................ 1407 passed
acp-bridge  bridge + status ...........  433 passed
合计 ................................. 2580 passed / 0 failed

2)编译后 lease 的多进程 harness —— 8/8 不变量全过

子进程 import 编译产物 packages/core/dist/.../session-writer-lease.js(非 mock;真实 PID、真实 Linux /proc 启动时间校验):

[PASS] INV1a  holder 取得 lease(进程 A)
[PASS] INV1b  第二个存活进程 B 被拒绝  :: session_writer_conflict
[PASS] INV2a  SIGKILL 后过期锁被回收
[PASS] INV2b  权威 transcript 完整恢复(2 行)
[PASS] INV2c  回收+重启后历史线性(3 行)
[PASS] INV3   按预期字节长度 fencing   :: session_transcript_changed
[PASS] INV4   失去所有权后拒绝追加     :: session_writer_lost
[PASS] INV5   正常释放 → 干净重开
==== 8/8 invariants PASS ====

直接验证了 docs/design/session-writer-lease.md 的不变量 #1#3#5,包括字节长度 fence 捕获“旧二进制”式的越权追加。

3)真实 CLI 端到端 —— 同一会话上的两个 qwen 进程(mock 后端)

第 1 步 —— 冲突(Reviewer 测试计划 #1:A 交互式恢复会话并持有 lease;B 恢复同一会话,在任何模型轮次之前被拒绝,A 继续正常运行、锁不变:

SessionWriterConflictError: This session is already open in another Qwen process.
    at SessionWriterLease.acquire → Config.activateChatRecording → Config.initialize
process exit code = 1     |     lock 仍属 A(owner_pid=697355),A 继续运行 ✓

第 2 步 —— 过期锁回收 + 恢复(Reviewer 测试计划 #2SIGKILL A(不做优雅释放),新进程 C 恢复:回收过期锁、恢复完整 transcript 并继续,历史保持单链:

kill -9 697355 → A 进程数 0;回收前 transcript 5 条
C 恢复出 “hello there”+回复,再追加 “continue after reclaim”
新锁 owner_pid=698526(C)→ 过期锁已回收 ✓
回收后 transcript 11 条;分叉 parent 数 = 0 → 单一线性链 ✓

🟡 一条不阻塞的发现 —— 交互式第二进程“安全失败”但界面无任何提示

当第二个进程是交互式(而非 headless)时,冲突被检测到并正确失败关闭(拿不到输入框、无法追加)。但 SessionWriterConflictError 只写到 stderr(被 ink 全屏覆盖),界面上的 “Initialization Error” 框始终不出现,进程也不退出——用户只看到一个像是“卡住”的启动横幅。

根因:渲染 initErrorNotifications 挂在 ink 的 <Static> 区域(MainContent.tsx:458-463)。<Static> 只提交一次,因此 AppContainer.tsx:743config.initialize() 抛错之后设置的 configInitializationError 不会被重绘。headless 处理完全正确(打印 + exit 1),只有交互式 TUI 静默。本 PR 让这条路径对“打开同一会话两次”这种正常操作变得可达,建议后续用非 <Static> 方式提示冲突(或直接退出)。不影响数据完整性。

结论

核心单写者保证已在 Linux 端到端验证通过(PR 中 Linux 标为 ⚠️ 未验证)。LGTM / 可合并;建议对上面的交互式冲突 UX 做一个小的后续修复。

@wenshao

wenshao commented Jul 19, 2026

Copy link
Copy Markdown
Collaborator

@qwen-code /triage

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

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM, looks ready to ship. ✅

@doudouOUC

Copy link
Copy Markdown
Collaborator Author

Closing this broad P0 proposal in favor of the smaller, independently landable P0a in #7237. PR #7237 carries the incident-critical ACP/daemon single-writer fencing and authoritative recovery path. The remaining interactive/headless transition and session-maintenance work from this PR will be handled separately as follow-up scope. Please continue review and validation on #7237.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Concurrent session writers can fork transcript history and hide responses

5 participants