Skip to content

fix(desktop): hide internal workspace during startup - #8988

Merged
yiliang114 merged 8 commits into
mainfrom
fix/desktop-startup-workspace-ux
Aug 12, 2026
Merged

fix(desktop): hide internal workspace during startup#8988
yiliang114 merged 8 commits into
mainfrom
fix/desktop-startup-workspace-ux

Conversation

@yiliang114

@yiliang114 yiliang114 commented Aug 12, 2026

Copy link
Copy Markdown
Collaborator

What this PR does

Replaces the normal Desktop loading page with a minimal centered Qwen icon and keeps the automatically selected internal workspace hidden while Qwen Code Desktop is starting, loading, or beginning a recovery action. If the runtime actually fails, the bootstrap page restores the detailed recovery UI and shows the attempted workspace so the user can diagnose the failure or choose another directory.

Runtime events now take precedence over an older bootstrap snapshot, and a snapshot taken after an early missed event reports the workspace currently being started rather than only the previously persisted workspace. An executable regression check covers startup, failure, and retry ordering.

Why it's needed

The Desktop app already starts with an internal primary workspace and does not require the user to select a directory. The card-style loading page looks interactive, and showing its internal path resembles a mandatory workspace picker. A centered brand mark communicates transient loading; the detailed screen and path are useful only when startup needs user action.

Reviewer Test Plan

How to verify

Launch the Desktop app with either fresh or persisted settings and confirm that no workspace path is shown while the bundled runtime starts. Force a runtime startup failure and confirm that the attempted workspace appears with the error. Start Retry while the initial bootstrap state request is still pending and confirm that an older state response does not restore the path or replace the retry status.

Evidence (Before & After)

Before: the normal “Starting Qwen Code” page displayed a large workspace card and the automatically selected local workspace path.

After: normal startup and retry show only a centered Qwen icon with a reduced-motion-safe animation; a runtime failure restores the detailed recovery screen and reveals the attempted path. This was visually checked at a 1440×900 viewport, and the executable bootstrap regression check confirms the state transitions. The full packaged build reached the runtime assembly stage but could not finish locally because two downloads of the official Node.js archive timed out after 120 seconds; no compile or test failure occurred.

Tested on

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

Environment (optional)

macOS arm64, Node.js 22.22.0. Desktop release helper checks, all 39 Rust tests, Prettier, ESLint, and diff checks passed.

Risk & Scope

  • Main risk or tradeoff: This changes only bootstrap presentation and event/snapshot ordering; the real automatic workspace remains unchanged.
  • Not validated / out of scope: A signed or notarized packaged app was not produced locally because the official Node.js runtime download timed out. Windows and Linux were not tested locally.
  • Breaking changes / migration notes: None.

Linked Issues

No linked issue.

中文说明

本 PR 做了什么

正常启动时改为只展示全局居中的 Qwen 图标,并且在启动、加载或开始恢复操作时不再展示自动选择的内部 workspace。只有运行时真正启动失败时,启动页才会恢复完整的排障界面并显示本次尝试启动的 workspace,方便用户排查失败或选择其他目录。

运行时事件现在会优先于较旧的启动状态快照;如果页面错过了较早的事件,后续快照也会返回当前正在启动的 workspace,而不只是之前持久化的 workspace。新增的可执行回归检查覆盖了启动、失败和重试的时序。

为什么需要

Desktop 已经会使用内部 primary workspace 自动启动,并不要求用户先选择目录。原来的卡片式加载页看起来像一个需要交互的界面,其中的内部路径也容易被理解成必须操作的 workspace 选择器。居中的品牌图标更适合表达短暂加载,完整界面和路径只在需要用户处理启动问题时有帮助。

Reviewer Test Plan

如何验证

分别使用全新设置和已有设置启动 Desktop,确认内置运行时启动期间不展示 workspace 路径。人为制造运行时启动失败,确认错误状态会展示本次尝试的 workspace。在初始启动状态请求尚未返回时点击 Retry,确认旧状态响应不会重新显示路径,也不会覆盖重试状态。

证据(修改前后)

修改前:正常的“Starting Qwen Code”页面会展示大型 workspace 卡片和自动选择的本地 workspace 路径。

修改后:正常启动和重试时只展示居中的 Qwen 图标,并提供遵循 reduced-motion 设置的轻量动画;运行时失败时恢复完整排障界面并展示本次尝试的路径。已在 1440×900 视口进行视觉检查,可执行的启动页回归检查也确认了这些状态切换。完整打包在本地已运行到运行时组装阶段,但两次下载官方 Node.js 压缩包都在 120 秒后超时,因此未能完成;没有出现编译或测试失败。

测试平台

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

环境(可选)

macOS arm64,Node.js 22.22.0。Desktop 发布辅助检查、全部 39 个 Rust 测试、Prettier、ESLint 和 diff 检查均通过。

风险与范围

  • 主要风险或取舍:只调整启动页展示和事件/快照时序;实际的自动 workspace 行为保持不变。
  • 未验证 / 范围外:由于官方 Node.js 运行时下载超时,本地没有产出签名或公证后的安装包;Windows 和 Linux 未在本地测试。
  • 破坏性变更 / 迁移说明:无。

关联 Issue

没有关联 Issue。

@qwen-code-ci-bot

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

Copy link
Copy Markdown
Collaborator

Qwen Triage finishedview run. See the stage comments in this thread for the result.

Qwen Triage 已完成 —— 查看运行。结果见本线程中的各阶段评论。

@qwen-code-ci-bot

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

Copy link
Copy Markdown
Collaborator

Re-run on the new head — full gate pass, prior comments updated in place.

  • Template: complete ✓ — all sections present, including the bilingual body.
  • Problem: real, and verifiable in the base code rather than claimed — base bootstrap/bootstrap.js calls setWorkspace(state.workspace) unconditionally in initialize(), so the automatically selected internal workspace path is shown during every normal startup, inside a card that reads like a mandatory picker. This is the shipping behavior before the PR, not a theoretical concern.
  • Direction: aligned. Desktop starts into an internal primary workspace on its own; the path and the detailed recovery UI only help once startup actually fails and the user must act. Product-direction escalation criteria don't apply (no auth/sandbox/model-selection/telemetry/release surface). No direct CHANGELOG reference signal, but the area is squarely qwen-code's own desktop surface.
  • Size: not applicable — all 5 changed files live in packages/desktop-shell (bootstrap page, release test script, Tauri main); no core paths, ~284 lines including tests.
  • Approach: scope feels right. Every edit serves the stated goal — a state-driven splash, an event-over-snapshot ordering guard, the snapshot reporting the workspace being started, and one executable regression covering the ordering. No drive-by changes, nothing I'd cut.
  • Risk: no elevated risk signals — none of the changed files match the revert-correlated high-risk paths.

Moving on to code review. 🔍

中文说明

新 head 上的重跑——完整门检查,历史评论就地更新。

  • **模板:**完整 ✓——包含中英文对照正文在内的所有部分齐全。
  • **问题:**真实存在,且可以直接在 base 代码里验证——base 版 bootstrap/bootstrap.jsinitialize() 无条件调用 setWorkspace(state.workspace),因此每次正常启动都会展示自动选择的内部 workspace 路径,而卡片样式看起来像必须操作的选择器。这是 PR 之前已上线的行为,不是理论性问题。
  • **方向:**对齐。Desktop 本来就会用内部 primary workspace 自动启动;路径和完整排障界面只有在启动真正失败、需要用户处理时才有用。不涉及产品方向升级条件(auth/sandbox/模型选择/遥测/release 面)。CHANGELOG 无直接参考信号,但该领域本来就是 qwen-code 自己的 desktop 范围。
  • **规模:**不适用——全部 5 个改动文件都在 packages/desktop-shell(启动页、发布测试脚本、Tauri main);未触及核心路径,含测试约 284 行。
  • **方案:**范围合理。每处改动都服务于目标——状态驱动的 splash、事件优先于快照的时序保护、快照返回正在启动的 workspace,以及一个覆盖时序的可执行回归。无顺手改动,没有可砍的部分。
  • **风险:**无升级风险信号——改动文件均未命中与 revert 相关的高风险路径。

进入代码审查。🔍

Qwen Code · qwen3.8-max

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

@qwen-code-ci-bot

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

Copy link
Copy Markdown
Collaborator

Code review

Independent proposal before reading the diff: hide the workspace UI behind a body state attribute, make live runtime events win over a stale bootstrap_state snapshot, and make the snapshot report the workspace being started rather than only the persisted one. The PR does exactly this, and the ordering guard lands as a single snapshotOverrideStatus flag — that is the minimal correct shape; I didn't find a simpler path it missed.

What I traced against the base blobs (they match the diff's parents exactly, so this is a review of the real delta):

  • start_runtime_async writes last_workspace before emitting runtime-starting, so the new bootstrap_workspace preference (attempted over persisted) always reports the workspace actually being started — that's what makes the missed-event snapshot show the right path.
  • Every flow walks correctly: cold start (splash from first paint via data-state="starting"), event arriving before the snapshot (early return keeps the fresh state), failure before any event (currentWorkspace ||= adopts the snapshot workspace and shows it), Retry clicked while the snapshot is still pending (the stale response cannot resurrect the path or overwrite the retry heading), and picker cancellation (idle shows the previously attempted path). version.textContent still updates from the snapshot on the early-return path — nice detail.
  • The reduced-motion CSS selectors (> :first-child, > div > :not(#title)) match the real .status DOM (#pulse plus the wrapper div holding title/detail/workspace/error), and in normal motion the status block stays announced via the visually-hidden pattern under the aria-live region.
  • The regression harness executes the real bootstrap.js in a vm context with a scriptable Tauri bridge and asserts ordering, not markup; the Rust unit test covers all four branches of bootstrap_workspace.

No blockers, no convention violations.

The one race this PR exists for, for reviewers validating the ordering fix:

sequenceDiagram
    participant P1 as User
    participant P2 as Bootstrap page
    participant P3 as Tauri backend
    P2->>P3: invoke bootstrap_state, still pending
    P1->>P2: click Retry
    P2->>P2: set override flag to starting
    P2->>P3: invoke restart_runtime
    P3-->>P2: stale snapshot resolves
    P2->>P2: override flag set, snapshot discarded, path stays hidden
Loading

Testing — the PR's own CI at d70101fc (this triage run executed no PR code)

The two Desktop Shell jobs — the package gate that actually exercises this change — are green on both OSes at the reviewed head. From the ubuntu job log: cargo test --manifest-path src-tauri/Cargo.tomltest result: ok. 38 passed; 0 failed, including the new tests::bootstrap_prefers_the_workspace_being_started (the author's "39 Rust tests" is the local count on a platform with one extra cfg-gated test — the windows job correspondingly reports 39 passed). node scripts/test-release.jsDesktop release helper checks passed., which includes the new bootstrap visibility harness.

The repo-wide Test (ubuntu-latest, Node 22.x) job finished red, and the failure is unrelated to this PR. All 19 vitest suite summaries elsewhere pass; the single failing file is packages/cli's src/serve/server.test.ts, 5 tests in the Live runtime / Appshot suites, each dying with the same teardown signature: Error: ENOTEMPTY: directory not empty, rmdir '/tmp/qwen-live-…/qwen-home/extension-store' — a tmp-dir cleanup race in test teardown. Classification as pre-existing noise, from the diff and the check identity: this PR changes 5 files, all in packages/desktop-shell (bootstrap page, release test script, Tauri main); the CLI serve suite imports none of it, and there is no mechanism by which a bootstrap splash change produces an ENOTEMPTY in a Live-runtime tmp cleanup. Repo context: today's main CI run is itself red on checkout network errors, so the suite is noisy independent of this PR. Not verified: pixel-level rendering (covered behaviorally by the sandboxed A/B run below).

Check Conclusion
Classify PR success
Desktop Shell (ubuntu-22.04) success
Desktop Shell (windows-2022) success
Test (ubuntu-latest, Node 22.x) failure (pre-existing flake, see prose)
Test (macos-latest, Node 22.x) skipped (CI classification)
Test (windows-latest, Node 22.x) skipped (CI classification)
Integration Tests (CLI, No Sandbox) skipped (CI classification)

Sandboxed verification

The central claim here is behavioural — path hidden during startup, events winning over stale snapshots — and a sandboxed @qwen-code /verify A/B run against the base build is already in flight for this exact head (run 31612096185); its report lands as a separate comment when done. The prior head's verify run already included a mutation matrix showing the harness fails when the guard is removed, so this run re-confirms rather than explores. Nothing further to trigger — and note /tmux is the wrong lane here (desktop GUI, not a TUI surface).

中文说明

代码审查

读 diff 之前的独立方案:用 body 状态属性隐藏 workspace 界面、让运行时事件优先于过期的 bootstrap_state 快照、让快照返回正在启动的 workspace 而不只是持久化的那个。PR 正是这么做的,而且时序保护收敛为一个 snapshotOverrideStatus 标志——这是最小正确形态,我没有找到更简单的路径。

对照 base blob 逐条追踪(blob 与 diff 父哈希完全一致,审的是真实增量):

  • start_runtime_async 在发出 runtime-starting 事件之前写入 last_workspace,因此新的 bootstrap_workspace 优先级(尝试启动的优先于持久化的)总能返回真正在启动的 workspace——这正是错过事件后快照仍能显示正确路径的原因。
  • 所有流程都走得通:冷启动(首屏即 splash)、事件先于快照到达(提前返回保留新状态)、任何事件之前先失败(currentWorkspace ||= 采用快照 workspace 并展示)、快照未返回时点击 Retry(过期响应不会复活路径、也不会覆盖重试标题)、取消目录选择(idle 展示上次尝试的路径)。早返回路径上 version.textContent 仍会从快照更新——细节到位。
  • reduced-motion 的 CSS 选择器与真实 .status DOM 一致,正常动效下状态块以视觉隐藏方式保留在 aria-live 区域内供读屏播报。
  • 回归 harness 在 vm 上下文里执行真实 bootstrap.js 并配可脚本化的 Tauri bridge,断言的是时序而非标记文本;Rust 单测覆盖 bootstrap_workspace 全部分支。

无阻塞项,无规范违规。

测试——d70101fc 上 PR 自己的 CI(本次 triage 未执行任何 PR 代码)

两个 Desktop Shell 作业(真正执行本改动的包级门槛)在受审 head 上双平台均为绿。ubuntu 日志:cargo test → 38 通过 0 失败(含新增测试;作者本地"39 个"是多一个平台 cfg 测试的计数,windows 作业相应报告 39 通过);node scripts/test-release.js → 通过(含新增启动页可见性 harness)。

仓库级 Test (ubuntu-latest) 作业最终为,但失败与本 PR 无关:唯一失败文件是 packages/clisrc/serve/server.test.ts(Live 运行时/Appshot 套件的 5 个用例),全部死于同一拆除期签名:ENOTEMPTY: directory not empty, rmdir '/tmp/qwen-live-…/qwen-home/extension-store'——测试拆除阶段临时目录清理竞态。判为既有噪声的依据来自 diff 与检查身份:本 PR 全部 5 个文件都在 packages/desktop-shell,CLI serve 套件不 import 其中任何内容,启动页改动不存在导致 Live 临时目录 ENOTEMPTY 的机制。另:今天 main 的 CI 本身也因 checkout 网络错误变红。未验证:像素级渲染(由沙箱 A/B 在行为层面覆盖)。

沙箱验证

核心主张是行为性的,针对该 head 的 @qwen-code /verify A/B 运行已在进行中,报告会另行发布;上一个 head 的验证已含变异矩阵(移除保护则 harness 失败),本次是复核而非探索。无需再触发——/tmux 不适用(桌面 GUI,不是 TUI)。

Qwen Code · qwen3.8-max

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

@qwen-code-ci-bot

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

Copy link
Copy Markdown
Collaborator

Confidence: 4/5 — clean, minimal fix whose tests actually pin the behavior; the only withholding is pixel-level rendering resting on the author's viewport check plus the A/B harness.

Stepping back: this is exactly the change I would have written. The problem is verifiable in the base code (the internal workspace path was displayed on every normal startup), the fix is the minimal shape of it — one state attribute, one ordering flag, one snapshot preference — and the regression harness runs the real bootstrap script against a scriptable bridge rather than asserting markup. I traced every state transition against the base blobs and found no flow where the path leaks back during startup or the stale snapshot wins. The reduced-motion and aria-live handling are correct against the actual DOM. Nothing in the diff is unrelated to the goal.

On the red CI: the only failing check is the repo-wide ubuntu suite, and its 5 failures are all the same ENOTEMPTY tmp-dir teardown race in packages/cli's Live-runtime tests — a subsystem this desktop-shell-only PR does not touch and cannot affect (full evidence in the Stage 2 comment). The Desktop Shell jobs that actually execute this change are green on both OSes. That red is pre-existing noise, not a reason to hold this PR; a maintainer re-running the flaky job should land it green.

Verdict: approve — pinned to the reviewed commit. (The earlier draft of this comment deferred approval pending CI while the suite was still running; CI has since settled, the one red is classified above, and the approval is posted explicitly rather than through the deferred marker.)

中文说明

置信度:4/5 —— 干净、最小的修复,且测试真正钉住了行为;唯一保留项是像素级渲染依赖作者的视口检查加 A/B harness。

整体看:这正是我会写的改法。问题可以在 base 代码中直接验证(内部 workspace 路径过去每次正常启动都会展示),修复是最小形态——一个状态属性、一个时序标志、一个快照优先级——回归 harness 用可脚本化的 bridge 执行真实启动脚本,而不是断言标记文本。逐条对照 base 追踪了所有状态流转,没有发现任何路径会在启动期间泄漏、或让过期快照胜出。reduced-motion 与 aria-live 处理与真实 DOM 一致。diff 中没有与目标无关的改动。

关于红色 CI:唯一失败的检查是仓库级 ubuntu 套件,其 5 个失败全部是 packages/cli Live 运行时测试中同一个 ENOTEMPTY 临时目录拆除竞态——本 PR 只改 desktop-shell,不触及也无法影响该子系统(完整证据见 Stage 2 评论)。真正执行本改动的 Desktop Shell 作业双平台均为绿。该红是既有噪声,不构成扣住本 PR 的理由;维护者重跑该 flaky 作业应能转绿。

结论:批准——绑定受审 commit。(本评论早前的版本在套件运行中时延迟批准;CI 现已出结果,唯一红色按上述归类,批准改为显式发布而非通过延迟标记。)

Qwen Code · qwen3.8-max

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

@github-actions

github-actions Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Summary

Package Lines Statements Functions Branches
CLI N/A% N/A% N/A% N/A%
Core 87.89% 87.89% 89.44% 86.41%
CLI Package - Full Text Report
CLI full-text-summary.txt not found at: coverage_artifact/cli/coverage/full-text-summary.txt
Core Package - Full Text Report
-------------------|---------|----------|---------|---------|-------------------
File               | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-------------------|---------|----------|---------|---------|-------------------
All files          |   87.89 |    86.41 |   89.44 |   87.89 |                   
 src               |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
 src/__mocks__/fs  |       0 |        0 |       0 |       0 |                   
  promises.ts      |       0 |        0 |       0 |       0 | 1-48              
 src/agents        |   90.38 |    84.54 |   94.85 |   90.38 |                   
  ...transcript.ts |   87.63 |    83.52 |     100 |   87.63 | ...80,588,594-598 
  ...ent-resume.ts |   85.59 |    77.55 |   83.33 |   85.59 | ...1793-1797,1800 
  ...ound-tasks.ts |   94.63 |    90.13 |   96.38 |   94.63 | ...1773,1793-1796 
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...ent-result.ts |    96.8 |    92.68 |     100 |    96.8 | 106,129-131       
  ...n-registry.ts |   94.79 |     87.7 |     100 |   94.79 | ...1067,1081-1083 
  ...w-snapshot.ts |   92.12 |    77.14 |     100 |   92.12 | ...65,189,196-198 
 src/agents/arena  |   76.32 |    67.71 |   78.94 |   76.32 |                   
  ...gentClient.ts |   79.47 |    88.88 |   81.81 |   79.47 | ...68-183,189-204 
  ArenaManager.ts  |   75.11 |    64.51 |   78.57 |   75.11 | ...1887,1893-1894 
  arena-events.ts  |   64.44 |      100 |      50 |   64.44 | ...71-175,178-183 
  diff-summary.ts  |    87.5 |    72.34 |     100 |    87.5 | ...32-133,137-138 
  index.ts         |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...gents/backends |   78.09 |    85.23 |   76.28 |   78.09 |                   
  ITermBackend.ts  |   97.97 |    93.93 |     100 |   97.97 | ...78-180,255,307 
  ...essBackend.ts |    90.9 |    85.36 |   93.33 |    90.9 | ...70,672,674-675 
  TmuxBackend.ts   |    90.7 |    76.55 |   97.36 |    90.7 | ...87,697,743-747 
  detect.ts        |   31.25 |      100 |       0 |   31.25 | 34-88             
  index.ts         |     100 |      100 |     100 |     100 |                   
  iterm-it2.ts     |     100 |     92.1 |     100 |     100 | 37-38,106         
  tmux-commands.ts |    6.64 |      100 |    3.03 |    6.64 | ...93-363,386-503 
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...agents/runtime |    91.1 |    86.68 |   89.23 |    91.1 |                   
  agent-context.ts |     100 |      100 |     100 |     100 |                   
  agent-core.ts    |   85.07 |     76.8 |   77.77 |   85.07 | ...2291,2337-2339 
  agent-events.ts  |     100 |      100 |     100 |     100 |                   
  ...t-headless.ts |   93.49 |    89.41 |   83.33 |   93.49 | ...96-497,500-501 
  ...nteractive.ts |   81.01 |    82.35 |   76.66 |   81.01 | ...33,535-538,541 
  ...statistics.ts |   98.29 |    82.55 |     100 |   98.29 | 141,165,206,239   
  agent-types.ts   |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...ool-policy.ts |   98.34 |      100 |    92.3 |   98.34 | 81-82             
  ...low-budget.ts |     100 |      100 |     100 |     100 |                   
  ...-scheduler.ts |   97.43 |    96.36 |     100 |   97.43 | 128-130           
  ...ow-journal.ts |   91.76 |    75.86 |     100 |   91.76 | ...38-139,179-181 
  ...chestrator.ts |    92.4 |       90 |   83.78 |    92.4 | ...1862,1911-1914 
  ...ow-prompts.ts |     100 |      100 |     100 |     100 |                   
  ...low-runner.ts |   94.85 |     87.5 |   92.85 |   94.85 | ...93,260,280-283 
  ...ow-sandbox.ts |   96.85 |    91.28 |     100 |   96.85 | ...1705,1711-1712 
  ...flow-saved.ts |   96.51 |    94.36 |     100 |   96.51 | 134-135,234-237   
  ...flow-stall.ts |    97.9 |    83.33 |     100 |    97.9 | 138-139,236       
 src/agents/tasks  |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/agents/team   |   82.04 |    84.17 |   88.97 |   82.04 |                   
  TeamManager.ts   |   72.02 |    79.41 |   79.24 |   72.02 | ...1632,1655-1656 
  identity.ts      |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...sionBridge.ts |     100 |      100 |     100 |     100 |                   
  mailbox.ts       |   96.02 |    87.23 |     100 |   96.02 | 352-358           
  ...ptAddendum.ts |     100 |      100 |     100 |     100 |                   
  tasks.ts         |   89.24 |    82.82 |     100 |   89.24 | ...-994,1038-1039 
  team-events.ts   |   60.52 |      100 |      50 |   60.52 | ...40-144,151-155 
  teamHelpers.ts   |   92.02 |    94.91 |   95.23 |   92.02 | ...31-332,368-378 
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...eam/test-utils |   94.39 |    94.26 |   98.21 |   94.39 |                   
  ...on-harness.ts |   96.49 |    84.21 |     100 |   96.49 | 128-129,141-142   
  fake-agent.ts    |   98.49 |    95.08 |     100 |   98.49 | 201-203           
  fake-backend.ts  |   86.46 |    97.61 |   95.83 |   86.46 | 124-146           
 src/config        |   84.81 |    87.18 |   75.53 |   84.81 |                   
  approval-mode.ts |     100 |      100 |     100 |     100 |                   
  ...xtDefaults.ts |     100 |      100 |     100 |     100 |                   
  config.ts        |   84.13 |    86.91 |   73.98 |   84.13 | ...8535,8539-8540 
  constants.ts     |     100 |      100 |     100 |     100 |                   
  models.ts        |     100 |      100 |     100 |     100 |                   
  storage.ts       |   94.39 |    91.57 |   88.23 |   94.39 | ...45-446,449-450 
 ...nfirmation-bus |   98.27 |    97.14 |     100 |   98.27 |                   
  message-bus.ts   |   98.14 |    97.05 |     100 |   98.14 | 42-43             
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/core          |   92.37 |    88.08 |   93.29 |   92.37 |                   
  baseLlmClient.ts |    88.4 |     83.8 |   81.81 |    88.4 | ...59,672,678-680 
  client.ts        |   92.05 |     87.4 |   91.66 |   92.05 | ...3987,4085-4086 
  ...tGenerator.ts |   86.34 |    87.34 |   84.61 |   86.34 | ...96-497,542-548 
  ...lScheduler.ts |   90.04 |    84.67 |   96.15 |   90.04 | ...6215,6243-6259 
  geminiChat.ts    |    94.7 |    90.12 |   95.53 |    94.7 | ...5052,5100-5101 
  geminiRequest.ts |     100 |      100 |     100 |     100 |                   
  genai-compat.ts  |     100 |      100 |     100 |     100 |                   
  ...MediaLimit.ts |     100 |       96 |     100 |     100 | 96                
  ...htProtocol.ts |    9.09 |      100 |       0 |    9.09 | ...9,62-66,69-110 
  ...ream-error.ts |     100 |      100 |     100 |     100 |                   
  logger.ts        |   87.41 |    87.02 |     100 |   87.41 | ...64-568,614-628 
  ...lay-buffer.ts |     100 |      100 |     100 |     100 |                   
  ...dispatcher.ts |     100 |      100 |     100 |     100 |                   
  ...tyDefaults.ts |     100 |      100 |     100 |     100 |                   
  ...olExecutor.ts |   93.54 |    83.33 |      50 |   93.54 | 49-50             
  ...on-helpers.ts |   93.49 |    78.57 |     100 |   93.49 | ...10-211,228-229 
  ...issionFlow.ts |   98.97 |    96.96 |     100 |   98.97 | 107               
  ...try-policy.ts |     100 |      100 |     100 |     100 |                   
  ...ell-policy.ts |   94.89 |    88.54 |     100 |   94.89 | ...51-252,297-298 
  prompts.ts       |   93.64 |    91.42 |   83.33 |   93.64 | ...1209,1412-1413 
  ...ing-effort.ts |     100 |      100 |     100 |     100 |                   
  ...n-recovery.ts |   95.13 |       80 |     100 |   95.13 | ...06-107,142-144 
  ...t-profiler.ts |    97.9 |    81.15 |   88.23 |    97.9 | 117,124-125,130   
  ...port-retry.ts |     100 |      100 |     100 |     100 |                   
  tokenLimits.ts   |     100 |    91.89 |     100 |     100 | 87,122-139        
  ...reparation.ts |     100 |      100 |     100 |     100 |                   
  ...tion-guard.ts |   90.38 |    94.73 |     100 |   90.38 | 68-72             
  ...allIdUtils.ts |   98.41 |    93.47 |     100 |   98.41 | 36,45             
  ...okTriggers.ts |   99.45 |    92.43 |     100 |   99.45 | 182,193           
  ...terruption.ts |     100 |     92.3 |     100 |     100 | 86,104            
  turn.ts          |   98.67 |    93.07 |     100 |   98.67 | ...79,707-708,755 
  ...l-fallback.ts |     100 |      100 |     100 |     100 |                   
 ...ntentGenerator |   96.33 |    88.12 |   96.15 |   96.33 |                   
  ...tGenerator.ts |   97.24 |    86.72 |   94.87 |   97.24 | ...1436,1465,1476 
  converter.ts     |   96.19 |    89.25 |     100 |   96.19 | ...1329,1550-1552 
  index.ts         |       0 |        0 |       0 |       0 | 1-21              
  usage.ts         |     100 |      100 |     100 |     100 |                   
 ...ntentGenerator |   88.78 |    72.36 |   89.47 |   88.78 |                   
  ...tGenerator.ts |   87.18 |    71.83 |   88.88 |   87.18 | ...58-364,382-383 
  index.ts         |     100 |       80 |     100 |     100 | 50                
 ...ntentGenerator |   95.88 |    90.34 |    92.3 |   95.88 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...tGenerator.ts |   95.81 |    89.63 |   91.89 |   95.81 | ...1221-1222,1250 
  ...tDetection.ts |     100 |      100 |     100 |     100 |                   
 ...ntentGenerator |   91.71 |    90.53 |   95.61 |   91.71 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  converter.ts     |    91.3 |    89.49 |   96.87 |    91.3 | ...1942,2111-2126 
  errorHandler.ts  |     100 |      100 |     100 |     100 |                   
  index.ts         |   60.31 |       75 |      50 |   60.31 | ...71,74-78,90-94 
  ...tGenerator.ts |    66.4 |    70.58 |   88.88 |    66.4 | ...51-157,168-169 
  pipeline.ts      |   95.48 |    91.27 |     100 |   95.48 | ...1309,1317,1416 
  ...ix-caching.ts |   95.23 |    92.85 |     100 |   95.23 | 45-46,69-70       
  ...ureContext.ts |     100 |      100 |     100 |     100 |                   
  ...ingOptions.ts |       0 |        0 |       0 |       0 | 1                 
  ...CallParser.ts |   92.24 |     92.4 |     100 |   92.24 | ...28-529,549-552 
  ...kingParser.ts |     100 |    96.87 |     100 |     100 | 42                
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 ...rator/provider |   97.36 |    92.19 |    98.5 |   97.36 |                   
  dashscope.ts     |   98.33 |    94.97 |   96.42 |   98.33 | ...91-692,834-835 
  deepseek.ts      |   94.91 |    89.36 |     100 |   94.91 | ...31-132,145-146 
  default.ts       |   99.18 |    97.05 |     100 |   99.18 | 208               
  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     |   87.71 |    84.62 |   92.57 |   87.71 |                   
  ...ive-safety.ts |     100 |      100 |     100 |     100 |                   
  ...-converter.ts |   80.55 |    73.66 |     100 |   80.55 | ...1133,1179-1180 
  corruptFile.ts   |     100 |       50 |     100 |     100 | 40-45             
  ...-converter.ts |     100 |      100 |     100 |     100 |                   
  ...me-refresh.ts |     100 |      100 |     100 |     100 |                   
  ...sion-store.ts |   90.94 |    86.26 |   97.91 |   90.94 | ...1230-1236,1280 
  ...ionManager.ts |   83.89 |    82.86 |   81.72 |   83.89 | ...2832,2861-2862 
  ...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 |    85.71 |   85.71 |    75.9 | ...98,202,214-248 
  github.ts        |   90.48 |    82.71 |     100 |   90.48 | ...4,994-995,1005 
  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       
  ...-converter.ts |   94.89 |    90.41 |     100 |   94.89 | ...50-151,222-224 
  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 |    84.21 |     100 |   88.95 | ...32-235,238-241 
  ...extraction.ts |   85.77 |       81 |   89.47 |   85.77 | ...02-205,260-261 
 ...ent-plugins-v1 |   84.94 |    79.51 |     100 |   84.94 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  manifest.ts      |   81.87 |    84.48 |     100 |   81.87 | ...55-156,161-174 
  mcp.ts           |   84.98 |    79.56 |     100 |   84.98 | ...88-389,419-420 
  paths.ts         |     100 |    94.44 |     100 |     100 | 59                
  skills.ts        |   82.31 |    63.88 |     100 |   82.31 | ...38-141,150-151 
 src/followup      |    79.9 |    78.92 |    90.9 |    79.9 |                   
  followupState.ts |   98.44 |    95.74 |     100 |   98.44 | 236-237           
  index.ts         |     100 |      100 |     100 |     100 |                   
  overlayFs.ts     |   96.29 |    88.88 |     100 |   96.29 | 78,108,122        
  speculation.ts   |   71.76 |    64.76 |   71.42 |   71.76 | ...53-654,661-662 
  ...onToolGate.ts |   97.97 |     87.5 |     100 |   97.97 | 105,110           
  ...nGenerator.ts |   72.03 |    81.15 |   83.33 |   72.03 | ...68-219,331-333 
 src/generated     |       0 |        0 |       0 |       0 |                   
  git-commit.ts    |       0 |        0 |       0 |       0 | 1-10              
 src/goals         |   93.25 |    88.99 |   93.68 |   93.25 |                   
  ...eGoalStore.ts |   87.61 |    88.88 |   86.66 |   87.61 | ...85-188,196-204 
  ...t-verifier.ts |   96.27 |     90.9 |     100 |   96.27 | ...20,143-146,163 
  ...checkpoint.ts |   81.48 |    76.19 |     100 |   81.48 | ...02-105,115-118 
  goal-evidence.ts |   88.79 |     88.5 |   96.42 |   88.79 | ...04-805,828-831 
  ...projection.ts |   66.66 |    72.97 |   33.33 |   66.66 | ...87,190,194-196 
  ...ersistence.ts |   87.73 |    84.84 |      80 |   87.73 | ...-94,97,101-106 
  goal-protocol.ts |      92 |    93.33 |      80 |      92 | 102-103,167-168   
  goal-reducer.ts  |    93.4 |    90.65 |   96.96 |    93.4 | ...27,501,519-520 
  goal-runtime.ts  |   97.44 |    89.68 |   97.67 |   97.44 | ...1216-1217,1338 
  goal-tools.ts    |   98.22 |    93.02 |      95 |   98.22 | ...46-147,248-249 
  ...rn-context.ts |     100 |      100 |     100 |     100 |                   
  goal-verifier.ts |   92.46 |    92.85 |     100 |   92.46 | ...69-172,185-187 
  goal-wire.ts     |       0 |        0 |       0 |       0 | 1-28              
  goalHook.ts      |   96.91 |    92.42 |     100 |   96.91 | 115-120,221-222   
  goalJudge.ts     |   95.84 |    87.09 |     100 |   95.84 | ...55-356,448-449 
  index.ts         |     100 |      100 |     100 |     100 |                   
 src/hooks         |   88.07 |    86.36 |   88.54 |   88.07 |                   
  ...okRegistry.ts |   86.48 |    77.08 |     100 |   86.48 | ...41-344,362-369 
  ...bortSignal.ts |     100 |      100 |     100 |     100 |                   
  context-usage.ts |     100 |      100 |     100 |     100 |                   
  ...terpolator.ts |   96.66 |    93.33 |     100 |   96.66 | 66-67             
  ...HookRunner.ts |   96.68 |    87.23 |     100 |   96.68 | 110-112,231-233   
  ...Aggregator.ts |   96.57 |    91.48 |     100 |   96.57 | ...20-321,402,404 
  ...entHandler.ts |   95.57 |    84.76 |   94.73 |   95.57 | ...1040-1041,1051 
  hookPlanner.ts   |   87.55 |    85.54 |   86.66 |   87.55 | ...22-226,233-244 
  hookRegistry.ts  |   92.53 |    85.43 |     100 |   92.53 | ...39,458,462,466 
  hookRunner.ts    |   62.65 |    72.34 |   66.66 |   62.65 | ...70-771,780-781 
  hookSystem.ts    |   87.64 |     98.5 |   70.83 |   87.64 | ...58-759,765-766 
  ...HookRunner.ts |   79.06 |    66.66 |      80 |   79.06 | ...33-434,452-456 
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...edCallback.ts |     100 |      100 |     100 |     100 |                   
  ...HookRunner.ts |   94.19 |    84.37 |   81.81 |   94.19 | ...76-384,458-459 
  ...SkillHooks.ts |   78.75 |       75 |   66.66 |   78.75 | 62-66,137-152     
  ...oksManager.ts |   94.87 |    88.88 |     100 |   94.87 | ...84,325,327-329 
  ssrfGuard.ts     |   86.45 |    89.13 |     100 |   86.45 | ...85,289-295,301 
  stopHookCap.ts   |     100 |      100 |     100 |     100 |                   
  trustedHooks.ts  |      90 |    52.63 |     100 |      90 | ...53,66-67,97-98 
  types.ts         |   94.25 |    96.12 |   88.88 |   94.25 | ...46-547,632-636 
  urlValidator.ts  |     100 |      100 |     100 |     100 |                   
  ...it-context.ts |     100 |      100 |     100 |     100 |                   
 src/ide           |   76.98 |    85.03 |   79.03 |   76.98 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  detect-ide.ts    |     100 |      100 |     100 |     100 |                   
  ide-client.ts    |   69.16 |    84.65 |   68.29 |   69.16 | ...1068,1097-1105 
  ide-installer.ts |   89.06 |    79.31 |     100 |   89.06 | ...36,143-147,160 
  ideContext.ts    |     100 |      100 |     100 |     100 |                   
  process-utils.ts |   84.84 |    71.79 |     100 |   84.84 | ...37,151,193-194 
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/lsp           |   58.96 |    70.57 |   66.14 |   58.96 |                   
  ...nfigLoader.ts |   80.55 |       72 |   95.45 |   80.55 | ...02-504,508-514 
  ...ionFactory.ts |   42.81 |    73.07 |      50 |   42.81 | ...76-427,433-450 
  ...Normalizer.ts |   23.09 |    13.72 |   30.43 |   23.09 | ...04-905,909-924 
  ...verManager.ts |   75.73 |     80.1 |   79.66 |   75.73 | ...1346,1352-1382 
  ...eLspClient.ts |   32.78 |       80 |   16.66 |   32.78 | ...89-293,299-300 
  ...LspService.ts |      60 |    73.36 |   78.26 |      60 | ...1575,1635-1645 
  configHash.ts    |     100 |      100 |     100 |     100 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/mcp           |    82.3 |    77.81 |   78.33 |    82.3 |                   
  configHash.ts    |     100 |      100 |     100 |     100 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  ...h-provider.ts |   86.95 |      100 |   33.33 |   86.95 | ...,93,97,101-102 
  ...h-provider.ts |   79.31 |    58.06 |     100 |   79.31 | ...26-933,940-942 
  ...en-storage.ts |   98.78 |    97.95 |     100 |   98.78 | 106-107           
  oauth-utils.ts   |   73.61 |    85.48 |    92.3 |   73.61 | ...46-366,392-421 
  ...n-provider.ts |   89.83 |       96 |   45.45 |   89.83 | ...43,147,151-152 
 .../token-storage |   82.12 |    88.19 |   89.28 |   82.12 |                   
  ...en-storage.ts |     100 |      100 |     100 |     100 |                   
  ...en-storage.ts |   87.08 |    87.03 |   95.23 |   87.08 | ...00-201,214-215 
  ...en-storage.ts |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...en-storage.ts |   68.14 |    82.35 |   64.28 |   68.14 | ...81-295,298-314 
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/memory        |   87.83 |    83.82 |   90.47 |   87.83 |                   
  ...y-document.ts |   89.52 |    84.61 |     100 |   89.52 | ...24-325,329-330 
  ...nel-memory.ts |   97.36 |    96.63 |   96.42 |   97.36 | ...91-293,367-368 
  const.ts         |   94.28 |     92.3 |     100 |   94.28 | 66-67             
  dream.ts         |    64.6 |    72.22 |      50 |    64.6 | ...04-109,124-165 
  ...entPlanner.ts |     100 |    83.33 |     100 |     100 | 136,146           
  entries.ts       |   75.59 |    84.84 |   83.33 |   75.59 | ...56-157,172-180 
  extract.ts       |   92.41 |    79.41 |     100 |   92.41 | 56-61,100,119-122 
  ...entPlanner.ts |   91.59 |    76.74 |     100 |   91.59 | ...05,114-117,293 
  ...ionPlanner.ts |       0 |        0 |       0 |       0 | 1                 
  forget.ts        |   81.83 |       75 |   83.33 |   81.83 | ...51,474,478-507 
  indexer.ts       |   94.14 |       84 |     100 |   94.14 | ...32-233,334,337 
  ...kill-agent.ts |   97.94 |    89.36 |     100 |   97.94 | 82-83,179-180     
  manager.ts       |    78.4 |    82.29 |   77.77 |    78.4 | ...1482,1495-1497 
  ...ent-config.ts |   86.99 |    82.69 |   86.36 |   86.99 | ...69,389,396-402 
  memoryAge.ts     |   90.47 |       80 |     100 |   90.47 | 50-51             
  paths.ts         |     100 |      100 |     100 |     100 |                   
  ...ing-skills.ts |     100 |       72 |     100 |     100 | 31-35,73-78,97    
  prompt.ts        |   97.26 |    87.03 |     100 |   97.26 | ...10-218,222,225 
  recall.ts        |   82.06 |       75 |    90.9 |   82.06 | ...59-364,395-406 
  refresh.ts       |   93.58 |    89.58 |     100 |   93.58 | ...75-176,183-184 
  ...ceSelector.ts |    93.1 |    81.81 |     100 |    93.1 | ...25,127-128,136 
  remember.ts      |   98.89 |    90.19 |     100 |   98.89 | 50,70             
  scan.ts          |   93.12 |    77.41 |     100 |   93.12 | ...08-109,154,157 
  scopes.ts        |     100 |      100 |     100 |     100 |                   
  ...et-scanner.ts |     100 |      100 |     100 |     100 |                   
  ...entPlanner.ts |   77.24 |    74.07 |   72.22 |   77.24 | ...52-456,459,465 
  status.ts        |   10.52 |      100 |       0 |   10.52 | 41-98             
  store.ts         |   92.92 |     82.6 |     100 |   92.92 | ...16-117,147-148 
  ...git-status.ts |     100 |     87.5 |     100 |     100 | 30                
  ...cret-guard.ts |     100 |      100 |     100 |     100 |                   
  ...emory-sync.ts |   94.24 |    82.85 |     100 |   94.24 | ...34-236,246-247 
  types.ts         |     100 |      100 |     100 |     100 |                   
  ...ontextFile.ts |   81.21 |     79.1 |   81.81 |   81.21 | ...63-277,291-296 
 src/mocks         |       0 |        0 |       0 |       0 |                   
  msw.ts           |       0 |        0 |       0 |       0 | 1-9               
 src/models        |   92.55 |    88.62 |   91.13 |   92.55 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  ...tor-config.ts |   97.77 |    91.83 |     100 |   97.77 | 155,161,171       
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...nfigErrors.ts |   74.22 |       44 |   84.61 |   74.22 | ...,67-74,106-117 
  ...igResolver.ts |   98.71 |    93.33 |     100 |   98.71 | 166,328,334       
  modelRegistry.ts |     100 |    98.11 |     100 |     100 | 177,261           
  modelsConfig.ts  |   89.36 |    86.93 |   88.09 |   89.36 | ...1404,1433-1434 
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/output        |     100 |      100 |     100 |     100 |                   
  ...-formatter.ts |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/permissions   |   83.79 |    91.16 |   71.07 |   83.79 |                   
  autoMode.ts      |   97.66 |    93.13 |     100 |   97.66 | ...82-589,635,712 
  ...transcript.ts |      98 |       84 |     100 |      98 | 200-201           
  classifier.ts    |      94 |    94.54 |     100 |      94 | 158-165,389-393   
  ...erousRules.ts |     100 |    89.36 |     100 |     100 | 110,133,147,175   
  ...alTracking.ts |     100 |      100 |     100 |     100 |                   
  ...e-commands.ts |   86.77 |     73.8 |     100 |   86.77 | 131-141,210-214   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...on-manager.ts |   86.63 |    89.01 |      80 |   86.63 | ...1111,1217-1221 
  rule-parser.ts   |   94.49 |     92.7 |     100 |   94.49 | ...1447,1481-1483 
  ...-semantics.ts |   70.44 |    91.07 |   46.66 |   70.44 | ...2237,2311-2314 
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...sifier-prompts |   99.04 |    95.23 |     100 |   99.04 |                   
  system-prompt.ts |   99.04 |    95.23 |     100 |   99.04 | 220               
 src/prompts       |   83.63 |      100 |    87.5 |   83.63 |                   
  mcp-prompts.ts   |   18.18 |      100 |       0 |   18.18 | 11-19             
  ...t-registry.ts |     100 |      100 |     100 |     100 |                   
 src/providers     |   83.71 |     78.6 |   81.25 |   83.71 |                   
  all-providers.ts |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  install.ts       |   93.11 |     84.5 |     100 |   93.11 | ...56-257,330-331 
  ...der-config.ts |   75.85 |    74.04 |   78.26 |   75.85 | ...73-474,502-503 
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 ...viders/presets |   97.82 |    91.66 |   63.63 |   97.82 |                   
  ...oding-plan.ts |   87.34 |      100 |       0 |   87.34 | 81-83,86-88,90-93 
  ...a-standard.ts |     100 |      100 |     100 |     100 |                   
  ...token-plan.ts |     100 |      100 |     100 |     100 |                   
  ...m-provider.ts |   97.05 |    81.25 |      75 |   97.05 | 118-119           
  deepseek.ts      |     100 |      100 |     100 |     100 |                   
  grok.ts          |     100 |      100 |     100 |     100 |                   
  idealab.ts       |     100 |      100 |     100 |     100 |                   
  minimax.ts       |     100 |      100 |     100 |     100 |                   
  modelscope.ts    |     100 |      100 |     100 |     100 |                   
  openrouter.ts    |     100 |      100 |     100 |     100 |                   
  requesty.ts      |     100 |      100 |     100 |     100 |                   
  zai.ts           |     100 |      100 |     100 |     100 |                   
 src/qwen          |   85.41 |    78.76 |   95.89 |   85.41 |                   
  ...tGenerator.ts |   98.64 |    98.18 |     100 |   98.64 | 105-106           
  qwenOAuth2.ts    |   82.79 |    73.75 |   90.62 |   82.79 | ...1205-1221,1251 
  ...kenManager.ts |   85.36 |    76.61 |     100 |   85.36 | ...52-757,778-783 
 src/resources     |     100 |      100 |     100 |     100 |                   
  ...e-registry.ts |     100 |      100 |     100 |     100 |                   
 src/services      |    89.8 |    84.74 |   96.92 |    89.8 |                   
  ...ionTrailer.ts |     100 |      100 |     100 |     100 |                   
  ...llRegistry.ts |    98.5 |     87.5 |     100 |    98.5 | 81-82,105,476-477 
  ...ionService.ts |   97.51 |    96.15 |     100 |   97.51 | ...,929,1072-1080 
  ...ingService.ts |   91.41 |    85.15 |   95.65 |   91.41 | ...2116,2143-2144 
  ...ttribution.ts |   91.73 |    87.71 |      90 |   91.73 | ...80-685,826-827 
  ...utSlimming.ts |    97.2 |    93.93 |     100 |    97.2 | ...39-340,378-381 
  cronScheduler.ts |   94.17 |    90.45 |      98 |   94.17 | ...1333,1736-1737 
  cronTasksFile.ts |   96.31 |    91.81 |     100 |   96.31 | ...11,336-337,483 
  cronTasksLock.ts |   94.44 |    89.47 |     100 |   94.44 | ...02-103,132-133 
  ...eryService.ts |   96.22 |    93.54 |      90 |   96.22 | 121,155-156,161   
  ...oryService.ts |   88.17 |    79.02 |    92.3 |   88.17 | ...1303,1344-1347 
  fileReadCache.ts |    97.5 |    96.07 |     100 |    97.5 | 349-350,363-364   
  ...temService.ts |    92.8 |    84.68 |   94.11 |    92.8 | ...53,479-486,531 
  ...ratedFiles.ts |      96 |    88.23 |     100 |      96 | 119-120,146-147   
  gitInit.ts       |     100 |      100 |     100 |     100 |                   
  ...reeService.ts |    73.7 |    68.49 |   95.83 |    73.7 | ...2196,2225-2226 
  ...on-service.ts |   87.38 |       72 |     100 |   87.38 | ...01-305,343-344 
  ...references.ts |   98.39 |    88.76 |     100 |   98.39 | 154-155,215-216   
  ...ionService.ts |   98.26 |    97.35 |     100 |   98.26 | ...13-714,761-762 
  ...ticsDumper.ts |   98.37 |    95.23 |     100 |   98.37 | 185-186           
  ...ureMonitor.ts |   95.82 |    90.52 |   97.05 |   95.82 | ...60,861,875-877 
  ...orRegistry.ts |    97.3 |    91.22 |     100 |    97.3 | ...53-454,611-612 
  ...ttachments.ts |   97.74 |    90.85 |     100 |   97.74 | 298-308,646       
  ...ersistence.ts |   90.95 |    78.75 |     100 |   90.95 | ...78,963-964,992 
  ...on-service.ts |   94.49 |    92.26 |   97.14 |   94.49 | ...98-600,656-664 
  ...ce-service.ts |    98.5 |    94.11 |    90.9 |    98.5 | 64-65             
  ...ipt-reader.ts |   94.55 |    89.78 |   96.66 |   94.55 | ...1353-1354,1422 
  ...est-helper.ts |       0 |        0 |       0 |       0 | 1-65              
  ...iter-lease.ts |   83.14 |    74.47 |   97.61 |   83.14 | ...2433,2445-2448 
  sessionRecap.ts  |   67.56 |    43.47 |     100 |   67.56 | ...60,178,180-183 
  ...ionService.ts |   89.08 |    84.71 |   97.18 |   89.08 | ...2514,2590-2610 
  sessionTitle.ts  |   94.26 |    73.21 |     100 |   94.26 | ...45-248,279-280 
  ...ionService.ts |    84.4 |    78.45 |   97.18 |    84.4 | ...2493,2499-2504 
  ...pInhibitor.ts |   97.42 |    92.77 |     100 |   97.42 | ...30,169,369-370 
  ...Estimation.ts |     100 |    88.23 |     100 |     100 | 118-119           
  ...ageService.ts |   97.76 |    91.59 |   93.75 |   97.76 | ...61-262,366,567 
  ...ite-origin.ts |     100 |    93.33 |     100 |     100 | 32                
  ...UseSummary.ts |   94.63 |    88.46 |     100 |   94.63 | ...62-164,214-215 
  ...rd-service.ts |     100 |    88.37 |     100 |     100 | ...29,145-146,241 
  ...oryService.ts |   90.72 |    84.07 |     100 |   90.72 | ...06-509,561-562 
  ...reeCleanup.ts |   14.42 |      100 |   33.33 |   14.42 | 58-186            
  ...ionService.ts |   88.36 |     87.8 |     100 |   88.36 | ...48-449,465-466 
 ...icrocompaction |    98.9 |    95.08 |     100 |    98.9 |                   
  microcompact.ts  |    98.9 |    95.08 |     100 |    98.9 | ...40,749,758-759 
 ...s/visionBridge |   98.81 |    92.12 |     100 |   98.81 |                   
  ...capability.ts |     100 |      100 |     100 |     100 |                   
  ...part-utils.ts |     100 |      100 |     100 |     100 |                   
  ...ion-bridge.ts |   98.72 |    82.35 |     100 |   98.72 | 65,71             
  ...-constants.ts |     100 |      100 |     100 |     100 |                   
  ...ge-service.ts |   98.61 |     94.7 |     100 |   98.61 | ...06,666,679-680 
 src/skills        |   89.29 |    85.89 |   93.61 |   89.29 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...activation.ts |     100 |    93.33 |     100 |     100 | 93,112            
  skill-curator.ts |   89.71 |    81.54 |     100 |   89.71 | ...01-902,904-907 
  skill-load.ts    |   94.84 |     87.5 |     100 |   94.84 | ...03,223,235-237 
  skill-manager.ts |   84.82 |    85.29 |   83.33 |   84.82 | ...1243,1250-1254 
  skill-paths.ts   |   90.42 |     87.5 |     100 |   90.42 | ...19-120,125-126 
  symlinkScope.ts  |     100 |      100 |     100 |     100 |                   
  types.ts         |   97.91 |    98.03 |     100 |   97.91 | 277-278           
 ...ataviz/scripts |   80.06 |    95.23 |   88.23 |   80.06 |                   
  ...te_palette.js |   80.06 |    95.23 |   88.23 |   80.06 | 261-296,306-328   
 ...s/bundled/loop |   97.48 |    95.77 |     100 |   97.48 |                   
  ...omous-loop.ts |     100 |      100 |     100 |     100 |                   
  ...-task-file.ts |   94.85 |     92.4 |     100 |   94.85 | ...56,367,375-376 
  ...k-resolver.ts |     100 |      100 |     100 |     100 |                   
 src/subagents     |   87.72 |    89.01 |   96.55 |   87.72 |                   
  ...ter-schema.ts |     100 |    98.07 |     100 |     100 | 99                
  ...tin-agents.ts |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...nt-manager.ts |   84.48 |    85.91 |   94.87 |   84.48 | ...1582,1659-1660 
  types.ts         |     100 |      100 |     100 |     100 |                   
  validation.ts    |   92.46 |    95.18 |     100 |   92.46 | 47-52,63-68,71-76 
 src/telemetry     |   81.83 |    83.71 |   84.92 |   81.83 |                   
  ...ty-tracker.ts |     100 |      100 |     100 |     100 |                   
  config.ts        |     100 |      100 |     100 |     100 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  ...on-metrics.ts |   99.08 |    80.95 |     100 |   99.08 | 185,199           
  ...on-tracing.ts |   76.31 |    74.62 |   73.68 |   76.31 | ...80,387-389,405 
  ...attributes.ts |   95.15 |    87.27 |     100 |   95.15 | ...97-198,216-217 
  ...ag-metrics.ts |     100 |    77.77 |     100 |     100 | 21,40             
  ...t-loop-lag.ts |   96.85 |    85.71 |     100 |   96.85 | 170-173           
  ...-exporters.ts |   65.78 |    83.33 |   55.55 |   65.78 | ...04-105,108-109 
  ...ai-content.ts |    74.5 |    66.41 |   91.66 |    74.5 | ...1480,1493-1502 
  ...i-provider.ts |     100 |       99 |     100 |     100 | 99                
  ...ai-request.ts |   87.52 |    92.79 |   83.78 |   87.52 | ...55-561,564-570 
  gen-ai-usage.ts  |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...t.circular.ts |       0 |        0 |       0 |       0 | 1-111             
  ...-processor.ts |    99.1 |    95.72 |      95 |    99.1 | 145,369-370       
  ...t.circular.ts |       0 |        0 |       0 |       0 | 1-128             
  loggers.ts       |   60.25 |    77.03 |   66.66 |   60.25 | ...1492,1509-1529 
  metrics.ts       |   80.37 |    82.35 |   80.95 |   80.37 | ...1150,1153-1164 
  otlp-urls.ts     |     100 |      100 |     100 |     100 |                   
  ...attributes.ts |     100 |      100 |     100 |     100 |                   
  ...ime-config.ts |       0 |        0 |       0 |       0 | 1                 
  sanitize.ts      |      80 |    83.33 |     100 |      80 | 35-36,41-42       
  ...rters-grpc.ts |     100 |      100 |     100 |     100 |                   
  ...rters-http.ts |     100 |      100 |     100 |     100 |                   
  sdk-impl.ts      |   91.06 |    87.15 |   68.75 |   91.06 | ...32,482-483,499 
  sdk.ts           |    82.7 |     90.9 |   66.66 |    82.7 | ...00-204,242-264 
  ...on-context.ts |     100 |      100 |     100 |     100 |                   
  ...ion-events.ts |     100 |      100 |     100 |     100 |                   
  ...on-tracing.ts |    91.1 |    88.68 |   96.77 |    91.1 | ...1737,1768-1771 
  ...etry-utils.ts |     100 |      100 |     100 |     100 |                   
  ...l-decision.ts |     100 |      100 |     100 |     100 |                   
  trace-context.ts |     100 |      100 |     100 |     100 |                   
  ...e-id-utils.ts |     100 |      100 |     100 |     100 |                   
  tracer.ts        |   98.56 |    88.63 |     100 |   98.56 | 52,101            
  types.ts         |   83.09 |    88.31 |   86.36 |   83.09 | ...1467,1471-1478 
  uiTelemetry.ts   |   97.18 |    93.93 |      88 |   97.18 | ...70,314,461-462 
 ...ry/qwen-logger |   74.23 |     80.7 |      70 |   74.23 |                   
  event-types.ts   |       0 |        0 |       0 |       0 |                   
  qwen-logger.ts   |   74.23 |    80.53 |   69.49 |   74.23 | ...1122,1160-1161 
 src/test-utils    |   96.38 |    98.61 |   83.33 |   96.38 |                   
  config.ts        |     100 |      100 |     100 |     100 |                   
  ...st-helpers.ts |   94.11 |       90 |     100 |   94.11 | 69-70             
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...mised-lock.ts |     100 |      100 |     100 |     100 |                   
  mock-tool.ts     |   94.85 |      100 |   78.78 |   94.85 | ...53,227-228,241 
  ...aceContext.ts |     100 |      100 |     100 |     100 |                   
 src/tools         |   86.25 |    85.07 |   88.72 |   86.25 |                   
  ...erQuestion.ts |   89.71 |    80.76 |   91.66 |   89.71 | ...66-367,374-375 
  ...-registrar.ts |    77.7 |    66.66 |   66.66 |    77.7 | ...72-277,292-294 
  ...ub-session.ts |   89.67 |     91.3 |   81.81 |   89.67 | ...03-304,315-322 
  cron-create.ts   |   90.64 |    92.85 |   72.72 |   90.64 | ...,73-74,223-231 
  cron-delete.ts   |   97.56 |      100 |   83.33 |   97.56 | 31-32             
  cron-list.ts     |   98.23 |    95.34 |    87.5 |   98.23 | 57-58             
  diffOptions.ts   |     100 |      100 |     100 |     100 |                   
  display-image.ts |   87.42 |    84.84 |   88.88 |   87.42 | ...29-134,194-195 
  edit.ts          |   82.76 |    86.77 |   81.25 |   82.76 | ...45-746,865-915 
  ...r-worktree.ts |   83.14 |    67.56 |    87.5 |   83.14 | ...84-187,278-279 
  enterPlanMode.ts |      85 |     82.6 |    87.5 |      85 | ...28-133,161-175 
  exit-worktree.ts |   83.29 |    83.65 |   94.44 |   83.29 | ...14-515,537-538 
  exitPlanMode.ts  |      95 |    85.29 |     100 |      95 | ...21-325,344,378 
  ...permission.ts |     100 |      100 |     100 |     100 |                   
  glob.ts          |   96.33 |     88.5 |     100 |   96.33 | ...24-225,373,376 
  grep.ts          |   90.73 |    86.61 |   85.71 |   90.73 | ...76-677,727-728 
  ...adTracking.ts |     100 |      100 |     100 |     100 |                   
  image-gen.ts     |   91.66 |    77.41 |    90.9 |   91.66 | ...13-214,221-222 
  list-agents.ts   |   94.02 |    82.35 |   83.33 |   94.02 | 31-32,47-48       
  loop-wakeup.ts   |   99.27 |    92.85 |     100 |   99.27 | 45                
  ls.ts            |   96.74 |    90.27 |     100 |   96.74 | 176-181,212,216   
  lsp.ts           |   72.71 |     59.5 |   90.32 |   72.71 | ...1212,1214-1215 
  ...nt-manager.ts |   82.13 |    80.47 |   85.71 |   82.13 | ...3234,3236-3237 
  mcp-client.ts    |   80.03 |    86.58 |   89.47 |   80.03 | ...2272,2276-2279 
  ...ry-timeout.ts |     100 |      100 |     100 |     100 |                   
  mcp-errors.ts    |     100 |      100 |     100 |     100 |                   
  ...pool-entry.ts |   79.21 |    85.71 |   81.57 |   79.21 | ...1341,1349-1350 
  ...ool-events.ts |       8 |      100 |       0 |       8 | 132-158           
  mcp-pool-key.ts  |   97.46 |    93.93 |     100 |   97.46 | 176-177           
  ...ce-content.ts |   96.55 |    91.17 |     100 |   96.55 | 80-82             
  mcp-retry.ts     |   97.67 |    95.65 |     100 |   97.67 | 131-132           
  ...ion-config.ts |     100 |      100 |     100 |     100 |                   
  mcp-status.ts    |     100 |      100 |     100 |     100 |                   
  mcp-tool.ts      |   98.35 |    93.71 |     100 |   98.35 | ...-990,1045-1046 
  ...sport-pool.ts |   83.98 |     80.3 |   88.46 |   83.98 | ...1409,1416-1420 
  ...ace-budget.ts |   87.27 |     82.6 |     100 |   87.27 | ...00-305,340-345 
  memory-config.ts |     100 |      100 |     100 |     100 |                   
  ...iable-tool.ts |     100 |    84.61 |     100 |     100 | 101,108           
  monitor.ts       |   91.82 |    83.09 |   88.46 |   91.82 | ...99,612,810-815 
  notebook-edit.ts |   85.71 |    77.08 |   81.25 |   85.71 | ...96-912,958-959 
  ...escendants.ts |   36.17 |    64.51 |   55.55 |   36.17 | ...46-310,385-390 
  ...nforcement.ts |   83.21 |    90.69 |     100 |   83.21 | 147-158,207-220   
  read-file.ts     |   95.49 |    88.52 |   86.66 |   95.49 | ...49,464,536-537 
  ...p-resource.ts |   96.85 |      100 |   91.66 |   96.85 | 92-96             
  ...d-artifact.ts |   91.18 |    86.71 |    87.5 |   91.18 | ...26-427,441-453 
  ripGrep.ts       |    94.6 |    87.26 |   95.23 |    94.6 | ...33-734,740-741 
  ...-transport.ts |   71.42 |    55.55 |   71.42 |   71.42 | ...36-137,143-144 
  send-message.ts  |   81.13 |    89.74 |    62.5 |   81.13 | ...80-286,363-371 
  ...n-mcp-view.ts |   94.07 |    91.89 |    90.9 |   94.07 | 131-139           
  shell.ts         |   78.81 |    84.22 |   91.91 |   78.81 | ...5036,5099-5100 
  skill-utils.ts   |     100 |      100 |     100 |     100 |                   
  skill.ts         |   91.39 |    92.55 |      90 |   91.39 | ...84,488,534-556 
  ...eticOutput.ts |   95.12 |      100 |      80 |   95.12 | 87-88             
  task-create.ts   |    94.4 |    93.33 |   81.81 |    94.4 | 45-49,63-64,95    
  task-list.ts     |   73.38 |    77.77 |   83.33 |   73.38 | ...02,105,109-116 
  task-stop.ts     |   93.14 |    96.15 |   85.71 |   93.14 | 39-40,54-64       
  task-update.ts   |   82.89 |    83.92 |    92.3 |   82.89 | ...14-422,454-465 
  team-create.ts   |   97.22 |    85.71 |   83.33 |   97.22 | 48-49,129-130     
  team-delete.ts   |   86.74 |    83.33 |   83.33 |   86.74 | 37-38,42-48,72-73 
  ...n-approval.ts |   92.14 |    96.77 |   77.77 |   92.14 | 38-39,42-43,93-99 
  todoWrite.ts     |   95.13 |    87.85 |   93.33 |   95.13 | ...23-527,540-545 
  tool-error.ts    |     100 |      100 |     100 |     100 |                   
  tool-names.ts    |     100 |      100 |     100 |     100 |                   
  tool-registry.ts |   78.57 |    79.59 |    82.6 |   78.57 | ...89-990,998-999 
  tool-search.ts   |   96.19 |    89.72 |   93.33 |   96.19 | ...09,259-264,426 
  tools.ts         |   93.11 |    92.53 |   91.66 |   93.11 | ...69-570,586-592 
  ...reapproved.ts |   99.27 |    94.11 |     100 |   99.27 | 170               
  web-fetch.ts     |   96.05 |    90.54 |   96.77 |   96.05 | ...85-786,800-801 
  web-search.ts    |   90.58 |    83.57 |      80 |   90.58 | ...1025,1083-1086 
  write-file.ts    |   86.72 |    84.92 |   88.88 |   86.72 | ...25-828,865-900 
  zoom-image.ts    |   95.76 |    93.75 |      90 |   95.76 | 54-59,203-204     
 src/tools/agent   |   87.22 |    87.68 |   88.69 |   87.22 |                   
  agent.ts         |   85.84 |    86.59 |   86.31 |   85.84 | ...4315,4337-4347 
  fork-profile.ts  |   93.65 |       90 |     100 |   93.65 | ...33-134,171-174 
  fork-subagent.ts |   98.73 |       95 |     100 |   98.73 | 101-102,173       
 ...tools/artifact |   95.78 |    92.51 |   88.63 |   95.78 |                   
  artifact-tool.ts |   91.46 |    88.46 |   71.42 |   91.46 | ...13-314,322-325 
  ...-publisher.ts |     100 |    85.71 |     100 |     100 | 32                
  ...-publisher.ts |   96.74 |    97.72 |    87.5 |   96.74 | 29-30,156-157     
  html.ts          |     100 |    96.77 |     100 |     100 | 122               
  ...-publisher.ts |     100 |       80 |     100 |     100 | 30                
  oss-publisher.ts |    98.1 |    91.48 |     100 |    98.1 | 43-45             
  publisher.ts     |     100 |      100 |     100 |     100 |                   
 ...s/computer-use |   90.21 |    82.17 |   78.08 |   90.21 |                   
  bootstrap.ts     |   59.42 |    80.95 |   41.66 |   59.42 | ...35-339,341-345 
  client.ts        |   80.11 |       90 |   77.77 |   80.11 | ...97,242-243,274 
  constants.ts     |     100 |    94.73 |     100 |     100 | 129,256           
  downloader.ts    |   65.29 |    52.77 |   58.33 |   65.29 | ...99-300,316-355 
  index.ts         |     100 |      100 |     100 |     100 |                   
  install-state.ts |   94.44 |    72.72 |     100 |   94.44 | 44-45             
  ...n-detector.ts |     100 |     87.5 |     100 |     100 | 50                
  schemas.ts       |     100 |      100 |     100 |     100 |                   
  tool.ts          |    96.3 |    85.71 |     100 |    96.3 | 75-76,184,252-258 
 ...tools/workflow |   86.51 |    84.81 |      75 |   86.51 |                   
  workflow.ts      |   86.51 |    84.81 |      75 |   86.51 | ...67,512,514-515 
 src/utils         |   92.89 |    89.63 |   96.88 |   92.89 |                   
  LruCache.ts      |     100 |      100 |     100 |     100 |                   
  ...Controller.ts |     100 |      100 |     100 |     100 |                   
  ...ssageQueue.ts |     100 |      100 |     100 |     100 |                   
  ...cFileWrite.ts |   94.94 |    92.47 |     100 |   94.94 | ...43-544,651-655 
  bareMode.ts      |   81.81 |      100 |      50 |   81.81 | 18-19             
  ...ry-content.ts |   98.45 |    95.45 |     100 |   98.45 | 132-133,159-160   
  browser.ts       |   86.84 |    78.94 |     100 |   86.84 | 34,36-37,65-66    
  btwUtils.ts      |   13.95 |      100 |       0 |   13.95 | 17-31,34-55       
  bundlePaths.ts   |     100 |      100 |     100 |     100 |                   
  ...on-context.ts |     100 |      100 |     100 |     100 |                   
  ...igResolver.ts |     100 |      100 |     100 |     100 |                   
  ...engthError.ts |   91.06 |    89.47 |     100 |   91.06 | ...46-147,154-155 
  ...n-branches.ts |   95.88 |    94.11 |      95 |   95.88 | ...98-499,511-524 
  ...tion-chain.ts |     100 |      100 |     100 |     100 |                   
  cronDisplay.ts   |     100 |    97.61 |     100 |     100 | 46                
  cronParser.ts    |   95.34 |    93.33 |     100 |   95.34 | 41-42,47-48,70-71 
  debugLogger.ts   |   96.66 |    96.61 |   88.88 |   96.66 | 192-196           
  editHelper.ts    |   93.63 |     83.9 |     100 |   93.63 | ...27-428,462-463 
  editor.ts        |   97.65 |    95.45 |     100 |   97.65 | ...35-336,338-339 
  encoding.ts      |     100 |      100 |     100 |     100 |                   
  env.ts           |     100 |      100 |     100 |     100 |                   
  ...arResolver.ts |   94.28 |    88.88 |     100 |   94.28 | 28-29,125-126     
  ...entContext.ts |   96.63 |    90.13 |   96.66 |   96.63 | ...42,444-445,512 
  errorParsing.ts  |     100 |      100 |     100 |     100 |                   
  ...rReporting.ts |   95.65 |    93.33 |     100 |   95.65 | 37-38             
  errors.ts        |   83.39 |    95.17 |    61.9 |   83.39 | ...81-397,401-407 
  fetch.ts         |   90.68 |    82.51 |     100 |   90.68 | ...72,483-484,503 
  file-identity.ts |     100 |      100 |     100 |     100 |                   
  fileUtils.ts     |   94.87 |    92.95 |   96.15 |   94.87 | ...1907,1915-1916 
  forkedAgent.ts   |   92.45 |    82.35 |   93.75 |   92.45 | ...34,642,647-654 
  formatters.ts    |     100 |      100 |     100 |     100 |                   
  ...eUtilities.ts |    92.4 |    86.95 |     100 |    92.4 | ...52-158,168-169 
  ...rStructure.ts |   94.39 |    94.28 |     100 |   94.39 | ...29-132,343-348 
  getPty.ts        |   31.57 |       50 |     100 |   31.57 | 26-38             
  git-branches.ts  |    91.6 |    84.21 |    92.3 |    91.6 | ...90,405-410,570 
  ...fig-safety.ts |   97.01 |       80 |     100 |   97.01 | 53-54             
  gitDiff.ts       |   95.19 |    81.36 |     100 |   95.19 | ...1073,1419-1420 
  gitDirect.ts     |   98.84 |    94.28 |     100 |   98.84 | 234,318           
  ...noreParser.ts |   94.48 |    93.22 |     100 |   94.48 | ...23-124,158-159 
  gitUtils.ts      |   78.02 |    81.25 |   85.71 |   78.02 | ...22-123,147-198 
  github-prs.ts    |   95.74 |    82.27 |     100 |   95.74 | 216,314-322       
  iconvHelper.ts   |     100 |      100 |     100 |     100 |                   
  ...rePatterns.ts |     100 |      100 |     100 |     100 |                   
  image-view.ts    |   95.12 |    93.33 |     100 |   95.12 | ...68-172,240-244 
  ...ionManager.ts |     100 |     90.9 |     100 |     100 | 27                
  ...lPromptIds.ts |     100 |      100 |     100 |     100 |                   
  ...on-context.ts |     100 |      100 |     100 |     100 |                   
  jsonl-utils.ts   |   95.41 |    93.54 |     100 |   95.41 | ...27-328,370-373 
  ...-detection.ts |     100 |      100 |     100 |     100 |                   
  ...iconv-lite.ts |     100 |      100 |     100 |     100 |                   
  ...simple-git.ts |   96.77 |    91.66 |     100 |   96.77 | 38                
  ...m-headless.ts |      96 |    88.88 |     100 |      96 | 34                
  ...iagnostics.ts |    96.4 |     94.2 |     100 |    96.4 | ...66,293-294,376 
  ...yDiscovery.ts |    92.4 |    89.13 |     100 |    92.4 | ...28,331,522-525 
  ...tProcessor.ts |   94.01 |       90 |     100 |   94.01 | ...47-353,445-446 
  ...Inspectors.ts |     100 |      100 |     100 |     100 |                   
  modelId.ts       |   98.96 |    98.21 |     100 |   98.96 | 153               
  ...kerChecker.ts |    90.9 |    91.66 |     100 |    90.9 | 73-79             
  notebook.ts      |   94.57 |    89.91 |   95.83 |   94.57 | ...21,333,385-387 
  openaiLogger.ts  |   91.66 |    89.74 |     100 |   91.66 | ...26-228,251-256 
  osc8.ts          |   54.26 |    64.86 |   83.33 |   54.26 | ...72-195,197-257 
  partUtils.ts     |     100 |    98.64 |     100 |     100 | 211               
  pathReader.ts    |     100 |      100 |     100 |     100 |                   
  paths.ts         |   93.61 |    92.42 |     100 |   93.61 | ...62-563,565-567 
  pdf.ts           |   92.17 |    85.81 |     100 |   92.17 | ...64-565,606-611 
  projectPath.ts   |     100 |      100 |     100 |     100 |                   
  projectRoot.ts   |   71.73 |    78.57 |     100 |   71.73 | 54-66             
  ...ectSummary.ts |   89.62 |    72.41 |     100 |   89.62 | ...40-145,196-199 
  ...tIdContext.ts |     100 |      100 |     100 |     100 |                   
  proxyUtils.ts    |     100 |      100 |     100 |     100 |                   
  ...rDetection.ts |   71.15 |       86 |     100 |   71.15 | ...-90,96-101,147 
  ...noreParser.ts |   92.63 |    91.66 |     100 |   92.63 | ...77-178,197-198 
  rateLimit.ts     |   93.75 |    89.62 |     100 |   93.75 | ...13,218-219,262 
  ...text-range.ts |   96.98 |    87.15 |     100 |   96.98 | ...87-688,763-764 
  readManyFiles.ts |   95.75 |    80.86 |     100 |   95.75 | ...05,558,568-572 
  retry.ts         |   96.09 |    92.52 |     100 |   96.09 | ...67,558-559,577 
  retryContext.ts  |     100 |      100 |     100 |     100 |                   
  ...sification.ts |   97.63 |    97.08 |     100 |   97.63 | ...17,251-252,278 
  retryPolicy.ts   |   97.72 |    90.56 |     100 |   97.72 | 130-131           
  ripgrepUtils.ts  |   90.04 |    93.43 |   95.45 |   90.04 | ...55-565,598-599 
  ...sDiscovery.ts |   97.46 |    93.05 |     100 |   97.46 | ...04,182-183,202 
  ...iagnostics.ts |   83.08 |     67.5 |   92.59 |   83.08 | ...23,543-544,550 
  ...tchOptions.ts |   84.87 |    86.71 |   96.29 |   84.87 | ...71,696,725-734 
  ...odelPrefix.ts |     100 |      100 |     100 |     100 |                   
  runtimeStatus.ts |   97.77 |    91.48 |     100 |   97.77 | 172-173           
  safe-mode.ts     |     100 |      100 |     100 |     100 |                   
  safeJsonParse.ts |     100 |      100 |     100 |     100 |                   
  ...nStringify.ts |     100 |      100 |     100 |     100 |                   
  ...-child-env.ts |     100 |      100 |     100 |     100 |                   
  ...aConverter.ts |   98.03 |    97.75 |     100 |   98.03 | 100,102-103       
  ...aValidator.ts |   92.09 |    83.65 |   90.47 |   92.09 | ...60,882-883,896 
  ...r-launcher.ts |   96.35 |    93.97 |   85.71 |   96.35 | ...35-336,347-348 
  sedEditParser.ts |   91.78 |    92.18 |     100 |   91.78 | ...66-569,645-646 
  ...nIdContext.ts |     100 |      100 |     100 |     100 |                   
  ...orageUtils.ts |   95.98 |    83.96 |     100 |   95.98 | ...70,386,466,485 
  ...-pager-env.ts |     100 |      100 |     100 |     100 |                   
  ...fety-rules.ts |     100 |     89.7 |     100 |     100 | ...01,304,309-311 
  shell-utils.ts   |   86.07 |    88.34 |     100 |   86.07 | ...2269,2276-2280 
  ...lAstParser.ts |   98.27 |    91.38 |     100 |   98.27 | ...1321-1323,1333 
  ...ContextEnv.ts |     100 |       92 |     100 |     100 | 50-52             
  ...nlyChecker.ts |   96.33 |    96.57 |     100 |   96.33 | ...83-284,292-293 
  sideQuery.ts     |   86.82 |    86.66 |     100 |   86.82 | ...79-185,187-193 
  ...pEventSink.ts |     100 |       80 |     100 |     100 | 61                
  ...tGenerator.ts |     100 |      100 |     100 |     100 |                   
  ...ameContext.ts |     100 |      100 |     100 |     100 |                   
  symlink.ts       |   77.77 |       50 |     100 |   77.77 | 44,54-59          
  ...e-encoding.ts |   85.96 |    76.47 |     100 |   85.96 | 58-61,64-65,78-79 
  ...emEncoding.ts |   96.36 |    91.17 |     100 |   96.36 | 59-60,124-125     
  terminalSafe.ts  |     100 |      100 |     100 |     100 |                   
  ...Serializer.ts |   98.72 |       90 |     100 |   98.72 | 42-43,134,201-203 
  testUtils.ts     |   53.33 |      100 |   33.33 |   53.33 | ...53,59-64,70-72 
  ...-constants.ts |     100 |      100 |     100 |     100 |                   
  textUtils.ts     |      65 |      100 |      75 |      65 | 56-75             
  thoughtUtils.ts  |     100 |    95.65 |     100 |     100 | 99                
  ...-converter.ts |   95.23 |    85.71 |     100 |   95.23 | 36-37             
  ...name-utils.ts |     100 |      100 |     100 |     100 |                   
  ...-finalizer.ts |   97.66 |     90.9 |     100 |   97.66 | 165-166,168-172   
  tool-utils.ts    |    95.2 |    93.61 |     100 |    95.2 | ...58-159,162-163 
  ...ultCleanup.ts |   54.62 |       64 |      75 |   54.62 | ...03-105,108-134 
  ...Compaction.ts |   96.13 |    96.42 |     100 |   96.13 | ...34-339,341-346 
  ...pt-records.ts |    87.5 |    86.13 |     100 |    87.5 | ...76-480,510-525 
  truncation.ts    |   90.56 |    90.43 |     100 |   90.56 | ...35-443,480-486 
  windowsPath.ts   |   89.47 |    79.31 |     100 |   89.47 | ...57-58,62,90-91 
  ...aceContext.ts |   95.39 |    89.47 |     100 |   95.39 | ...16-317,321-322 
  xml.ts           |    97.8 |    87.69 |     100 |    97.8 | 98-99             
  yaml-parser.ts   |   83.87 |    77.27 |     100 |   83.87 | ...31-234,239-240 
 ...ils/filesearch |   83.94 |    80.72 |   94.73 |   83.94 |                   
  crawlCache.ts    |     100 |      100 |     100 |     100 |                   
  crawler.ts       |    82.9 |    76.81 |   95.08 |    82.9 | ...1563,1597-1598 
  fileSearch.ts    |   93.78 |    87.67 |     100 |   93.78 | ...71-272,274-275 
  fzfWorker.ts     |       0 |        0 |       0 |       0 | 1-109             
  ...rkerHandle.ts |   84.05 |    75.43 |   89.47 |   84.05 | ...30-334,340-341 
  ignore.ts        |     100 |    97.36 |     100 |     100 | 187               
  result-cache.ts  |     100 |    93.75 |     100 |     100 | 49                
 ...uest-tokenizer |   69.76 |    75.47 |   85.29 |   69.76 |                   
  ...eTokenizer.ts |   65.72 |    74.02 |    92.3 |   65.72 | ...65-466,479-533 
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...tTokenizer.ts |   68.39 |    69.49 |    90.9 |   68.39 | ...24-325,327-328 
  ...ageFormats.ts |   76.92 |      100 |   33.33 |   76.92 | 46-49,56-57       
  textTokenizer.ts |     100 |      100 |     100 |     100 |                   
  types.ts         |       0 |        0 |       0 |       0 | 1                 
-------------------|---------|----------|---------|---------|-------------------

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

@qwen-code-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 explored to full depth (tool budget reached): You are review agent reverse-audit — Reverse audit agen...: could not compile/run the new Rust unit test bootstrap_prefers_the_workspace_being_started — cargo is present but cargo test fails building libdbus-sys …; This PR replaces the Desktop bootstrap loading page with ...: Rust compile/unit-test run ( cargo test bootstrap_prefers_the_workspace_being_started ) — cargo unavailable on this runner; verified by reading instead.; You are review agent reverse-audit — Reverse audit agen...: none — all planned checks completed within budget..

中文说明

已审查。 建议见行内评论。

未探索到全部深度(达到工具调用预算):You are review agent reverse-audit — Reverse audit agen...:could not compile/run the new Rust unit test bootstrap_prefers_the_workspace_being_started — cargo is present but cargo test fails building libdbus-sys …;This PR replaces the Desktop bootstrap loading page with ...:Rust compile/unit-test run ( cargo test bootstrap_prefers_the_workspace_being_started ) — cargo unavailable on this runner; verified by reading instead.;You are review agent reverse-audit — Reverse audit agen...:none — all planned checks completed within budget.

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

Comment thread packages/desktop-shell/bootstrap/bootstrap.js
Comment thread packages/desktop-shell/scripts/test-release.js Outdated
Comment thread packages/desktop-shell/scripts/test-release.js
@yiliang114

Copy link
Copy Markdown
Collaborator Author

Fixed the current startup-page regression where a secondary error, such as failed Open Logs, hid the failed workspace path again. Verified node packages/desktop-shell/scripts/test-release.js, Prettier, and diff check. Deferred the extra snapshot-only and fake-DOM selector harness Suggestions to avoid expanding this small startup UX fix.

@yiliang114

Copy link
Copy Markdown
Collaborator Author

@qwen-code-review-bot review this pr and approve if no blockers

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

Code Review Overview (AI Generated)

PR: #8988 fix(desktop): hide internal workspace during startup
Author: @yiliang114
Type: Bug fix (Desktop UX) + presentational change + test infra
Change size: +190/-21 across 5 files
HEAD reviewed: 0924d84 (fix(desktop): use Qwen logo on startup screen, 2026-08-12T11:31Z)
CI at HEAD: green (Desktop Shell (ubuntu-22.04), Desktop Shell (windows-2022), Test (ubuntu-latest) all pass). mergeable_state: blocked = awaiting required approval, not a failing check.

This is an independent blind review: Rounds 0-6 (incl. the 8 structural audits and the Pass E adversarial challenge) were completed before reading any existing review.

Findings Summary

  • Critical: 0
  • Major: 0
  • Minor: 4
  • Nit: 3

Key Observations

The core design is right and I reached the same conclusion independently: keep the attempted workspace in a JS variable, gate its display on the error state, let live runtime events win over a stale bootstrap_state snapshot, and make the backend report the workspace actually being started. The Rust side (bootstrap_workspace) is clean, correctly unit-tested, and provably has only two consumers.

My concerns are all fallout from the last two commits:

  1. 541a3b15 (which applied the previous reviewer's suggestion) moved the reveal into setStatus() but left the two now-redundant explicit setWorkspace(currentWorkspace) calls in place (bootstrap.js:148, :183) and silently regressed the idle recovery state, which used to show the path and no longer does.
  2. 0924d846 (the <img> logo swap + SVG + 2 asserts) landed ~3h after the only prior review and has had zero review coverage. My index.html and qwen-code-logo.svg findings all sit in that commit.

None of these block merge on their own; items 1 and 2 in the table below are the ones I would want addressed.

Cross-Validation

Finding Other Reviewer My Assessment
R1-1 setStatus() hides #workspace on unrelated errors qwen-code-ci-bot Obsolete at HEAD. Applied verbatim in 541a3b15; bootstrap.js:35 now reads setWorkspace(kind === 'error' ? currentWorkspace : ''). Verified against HEAD file content, not the author's claim. The fix is correct — but it produced Unique-1 and Unique-2 below.
R1-2 snapshot-only recovery path untested (test-release.js) qwen-code-ci-bot Valid, still open (author declined). Partial disagreement on the rationale: the mutation it cites — deleting "the two setWorkspace(currentWorkspace) reveal lines" — is a behavioural no-op after 541a3b15, so it no longer discriminates. The genuinely uncovered load-bearing lines are bootstrap.js:159 (currentWorkspace ||= backfill) and bootstrap.js:161 (if (runtimeStatus === 'failed') setWorkspace(...)). A future test should target those two.
R1-3 fake-DOM element() fabricates any selector qwen-code-ci-bot Valid, still open (author declined). Agree it is Nit-level for a fix this small; declining is defensible. A cheaper adjacent guard is Unique-4.
Triage stage-3: "catch-path display gap ... acceptable" qwen-code-ci-bot Superseded — R1-1's fix closed that gap entirely.
Unique-1: dead setWorkspace(currentWorkspace) at bootstrap.js:148 / :183 New (Minor)
Unique-2: idle recovery state lost the workspace path (bootstrap.js:35 vs :185) New (Minor) — behaviour regression vs main
Unique-3: no status text, version or "Open logs" for up to ~45s (index.html:93) New (Minor)
Unique-4: logo assertion never checks the SVG exists (test-release.js:63) New (Minor)
Unique-5: sr-only block missing border: 0 leaves a ~2px artifact (index.html:115) New (Nit)
Unique-6: mock assertion swallowed by retryRuntime catch; vm has no timeout (test-release.js:88) New (Nit)
Unique-7: runtimeStatus stays 'starting' after a cancelled picker (bootstrap.js:40) New (Nit)

Additional Audit Coverage

Areas I independently checked that go beyond the existing findings — all of these came back clean, recorded here so the author does not have to re-verify them:

  • Asset packaging: tauri.conf.json sets build.frontendDist: "../bootstrap", so the whole directory is bundled. The new qwen-code-logo.svg ships without a bundle.resources entry. No broken-image risk in the packaged app.
  • CSP: the page's img-src 'self' data: (duplicated in tauri.conf.json app.security.csp) permits the relative same-origin src="qwen-code-logo.svg" under both tauri://localhost (macOS/Linux) and http://tauri.localhost (Windows).
  • Asset duplication: the SVG path data is byte-identical to packages/desktop/apps/electron/resources/brands/qwen-code/icon.svg and packages/zed-extension/qwen-code.svg. Duplication is unavoidable here because frontendDist must be self-contained — not a finding.
  • Data-structure blast radius: BootstrapState.workspace has exactly two consumers repo-wide (main.rs, bootstrap.js); local-control.js does not read it. last_workspace is written only at main.rs:483 and read at main.rs:369 (restart_runtime) plus the new call site. No hidden consumer breaks.
  • Data provenance: the runtime-starting payload (main.rs:489) and bootstrap_workspace() both return the pre-canonicalisation workspace (resolve_workspace runs later, main.rs:501), so the event path and the snapshot path yield byte-identical strings. No optimistic/echo divergence.
  • Missed-event / replay divergence: setup() emits runtime-failed at main.rs:296 with last_workspace == None; bootstrap_workspace then correctly falls back to settings.workspace() and the JS state.error branch backfills currentWorkspace. The emit_runtime_failure generation guard (main.rs:592-598) also prevents a superseded start from poisoning the JS runtimeStatus machine. Both paths verified sound.
  • State-field init matrix: runtimeStatus ∈ {undefined, 'starting', 'failed'}; data-state ∈ {starting, error, idle}. Only starting has CSS; error/idle fall through to the full card. The initial <body data-state="starting"> matches the static "Starting Qwen Code" markup, so there is no flash-of-wrong-state. Only gap found is Unique-7.
  • Bounded worst case: runtime.rs:18 STARTUP_TIMEOUT = 45s caps the blank-splash window — this is what keeps Unique-3 at Minor rather than Major.
  • CI enforcement: .github/workflows/ci.yml:1214 runs node scripts/test-release.js whenever packages/desktop-shell/** changes, so the new check is genuinely gating.
  • Rust test correctness: bootstrap_prefers_the_workspace_being_started covers all three arms (Some/Some, None/Some, None/None). No clippy or_fun_call risk — .or() receives an already-materialised value.
  • Process (CONTRIBUTING.md): §1 asks every PR to link an issue and §6 asks for a screenshot/video; this PR states "No linked issue" and describes the visual check in prose only. Non-blocking, flagged for maintainer discretion.
  • AGENTS.md scope gate: confined to packages/desktop-shell/**, so the core-infrastructure two-tier gate does not apply.

Final Verdict

LGTM with minor follow-ups — recommend merge after Unique-1 and Unique-2 are addressed. The design is correct, the event/snapshot race is genuinely well handled, and CI is green at 0924d84. Unique-2 is the only real behaviour regression (idle state silently lost the workspace path) and it is a one-token fix; Unique-1 is a two-line deletion that removes the second, now-dead mechanism for the same DOM state. Everything else is optional polish.


This review was generated by QoderWork AI

Comment thread packages/desktop-shell/bootstrap/bootstrap.js Outdated
Comment thread packages/desktop-shell/bootstrap/bootstrap.js Outdated
Comment thread packages/desktop-shell/bootstrap/index.html
Comment thread packages/desktop-shell/scripts/test-release.js
Comment thread packages/desktop-shell/bootstrap/index.html
Comment thread packages/desktop-shell/scripts/test-release.js Outdated
Comment thread packages/desktop-shell/bootstrap/bootstrap.js Outdated

@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 explored to full depth (tool budget reached): 本 PR 将 Desktop 启动页改为居中的 Qwen 图标并在启动/加载/恢复期间隐藏内部 workspace...: cargo test for the new bootstrap_prefers_the_workspace_being_started Rust test was not run — no prebuilt target/ exists in this worktree and a cold Tauri/…; 本 PR 将 Desktop 启动页改为居中的 Qwen 图标并在启动/加载/恢复期间隐藏内部 workspace...: none — all planned checks completed within budget.; 本 PR 将 Desktop 启动页改为居中的 Qwen 图标并在启动/加载/恢复期间隐藏内部 workspace...: cargo is not installed on this runner — could not compile/run the new Rust unit test bootstrap_prefers_the_workspace_being_started ; the Rust change was review…; 本 PR 将 Desktop 启动页改为居中的 Qwen 图标并在启动/加载/恢复期间隐藏内部 workspace...: cargo test for src-tauri — cargo is not installed in this environment; the new Rust unit test ( bootstrap_prefers_the_workspace_being_started ) and the boo…; 本 PR 将 Desktop 启动页改为居中的 Qwen 图标并在启动/加载/恢复期间隐藏内部 workspace...: none — all checks I started were completed within budget..

中文说明

已审查。 建议见行内评论。

未探索到全部深度(达到工具调用预算):本 PR 将 Desktop 启动页改为居中的 Qwen 图标并在启动/加载/恢复期间隐藏内部 workspace...:cargo test for the new bootstrap_prefers_the_workspace_being_started Rust test was not run — no prebuilt target/ exists in this worktree and a cold Tauri/…;本 PR 将 Desktop 启动页改为居中的 Qwen 图标并在启动/加载/恢复期间隐藏内部 workspace...:none — all planned checks completed within budget.;本 PR 将 Desktop 启动页改为居中的 Qwen 图标并在启动/加载/恢复期间隐藏内部 workspace...:cargo is not installed on this runner — could not compile/run the new Rust unit test bootstrap_prefers_the_workspace_being_started ; the Rust change was review…;本 PR 将 Desktop 启动页改为居中的 Qwen 图标并在启动/加载/恢复期间隐藏内部 workspace...:cargo test for src-tauri — cargo is not installed in this environment; the new Rust unit test ( bootstrap_prefers_the_workspace_being_started ) and the boo…;本 PR 将 Desktop 启动页改为居中的 Qwen 图标并在启动/加载/恢复期间隐藏内部 workspace...:none — all checks I started were completed within budget.

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

Comment thread packages/desktop-shell/bootstrap/bootstrap.js
Comment thread packages/desktop-shell/bootstrap/bootstrap.js
Comment thread packages/desktop-shell/bootstrap/index.html
Comment thread packages/desktop-shell/src-tauri/src/main.rs
Comment thread packages/desktop-shell/bootstrap/index.html
Comment thread packages/desktop-shell/bootstrap/bootstrap.js Outdated
Comment thread packages/desktop-shell/scripts/test-release.js
@yiliang114

Copy link
Copy Markdown
Collaborator Author

@qwen-code /triage

@yiliang114
yiliang114 enabled auto-merge August 12, 2026 13:22
@qwen-code-ci-bot

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

Copy link
Copy Markdown
Collaborator

Sandboxed verification: ✅ passed — merge-ready (agent verdict) - workflow run

Ran the PR in an isolated, token-free container: A/B against the base build, mock-free harness assertions, targeted gates. Advisory evidence for human reviewers — not a review, an approval, or a CI check.

Scripted assertions: 98 passed · 0 failed · 98 total

中文 — 判定:✅ 通过 · 可合入(agent 判定)

沙箱验证在隔离、无凭证的容器中执行了该 PR 的代码(与 base 构建 A/B 对照、无 mock harness 断言、定向门禁)。仅作为评审证据,不构成评审、批准或 CI 检查

脚本断言:98 通过 · 0 失败 · 98 总计

Verification report

PR #8988 — fix(desktop): hide internal workspace during startup

Verdict: merge-ready — 98/98 scripted assertions passed, 0 unexpected failures. Verified head: 0924d8465366322a270540b611de0cd6b0856056 (git rev-parse HEAD^2; matches snapshot headRefOid). Base: a32ec1ee4a33323556ee5f9cd2dc66ff0282645b (HEAD^1).

中文摘要
  • 结论merge-ready。98/98 条脚本化断言通过,0 个意外失败。
  • A/B 结论:对 bootstrap.js 做了 head 与 base 的 9 场景 A/B。核心行为翻转成立:正常启动(snapshot starting/ready、或收到 runtime-starting 事件)时 head 隐藏内部 workspace 路径,base 显示(S1/S1b/S2 翻转);失败时(事件失败、snapshot 带 error)两个分支都正确显示本次尝试的 workspace 和 Retry(S3/S3b/S6/S7 控制组一致)。时序修复成立:Retry 点击后旧的 bootstrap_state 响应不再恢复路径或覆盖 "Restarting Qwen Code"(S4 翻转);早到的 runtime-failed 事件不再被后续 snapshot 降级(S5 翻转)。
  • 新回归测试testBootstrapWorkspaceVisibility 非空转——mutation 矩阵中删除 setStatus 的隐藏逻辑(M1)和删除 runtimeStatus 守卫(M2)都使真实套件按预期断言变红,注释型中性突变(M3)保持绿。npm run test:release 在 head 通过。
  • 未覆盖:Rust 侧(bootstrap_workspace 及 39 个 Rust 测试)——容器无 cargo/rustc,也无 webkit2gtk/浏览器,无法编译或渲染真实 Tauri 应用;Rust 改动仅经代码审阅验证。浅克隆(depth 2)只能到达 6 个 PR commit 中的 1 个,逐 commit 归因不可行,验证的是聚合 diff。

Central claim + A/B

Central claim: while the bundled runtime is starting/loading/restarting, the bootstrap page shows only the centered Qwen mark and never the auto-selected internal workspace path; the detailed recovery UI (error text, attempted workspace, Retry/Choose) returns exactly when startup fails. Secondary claims: (a) runtime events outrank an older bootstrap_state snapshot (the Retry-while-pending race), and the snapshot reports the workspace currently being started; (b) the new testBootstrapWorkspaceVisibility regression check pins these orderings and is not vacuous.

The unit under test is the real bootstrap.js source (head working tree, sha256-identical to the HEAD^2 blob; base extracted verbatim from the HEAD^1 blob) executed unmodified in Node vm. The shim fakes only the webview environment (DOM initial state taken from each arm's index.html, Tauri IPC scriptable) — never the code under test. Capture: evidence/01-ab-head-vs-base-workspace-visibility.png.

# Scenario (identical on both arms) Oracle base (a32ec1ee) head (0924d846) Cell
S1 snapshot starting, workspace = internal path, no events #workspace visible /data/internal/qwen hidden, data-state=starting FLIP
S1b snapshot ready (web shell connecting) #workspace visible hidden FLIP
S2 runtime-starting event, then snapshot #workspace visible (snapshot path wins) hidden FLIP
S3 runtime-starting then runtime-failed workspace+error+retry visible /evt/path, error boom, retry shown same CONTROL
S3b then Open-logs fails workspace retained visible visible CONTROL
S4 failed → Retry click → stale snapshot (starting, /snap/stale) resolves title + #workspace title clobbered to Starting Qwen Code, path restored title stays Restarting Qwen Code, hidden FLIP
S5 runtime-failed observed before snapshot; snapshot says starting title + retry + workspace error UI downgraded to starting, retry hidden error + retry preserved, workspace = snapshot path FLIP
S6 snapshot carries error (page missed all events) error + workspace visible + error shown same CONTROL
S7 snapshot idle, no error idle UI choose shown, workspace hidden same CONTROL

Five behavior flips, four controls holding on both arms: the hiding is load-bearing for exactly the starting/ready/retry paths, and failure visibility (the information the PR suppresses during startup) survives on every error path, including subsequent unrelated errors (S3b). Structural checks on the markup the minimal screen is built from all pass: <body data-state="starting"> gives the minimal first paint before any JS runs (base <body> had none), the logo is an <img alt="Qwen Code"> loading a same-origin SVG allowed by the CSP img-src 'self', .brand-copy/.actions/footer/::before are display:none while starting, .status stays screen-reader accessible via the a11y clip pattern (not display:none) inside the aria-live="polite" section, and prefers-reduced-motion disables the pulse.

Reviewer Test Plan walkthrough

  1. "Launch with fresh or persisted settings; no workspace path shown while the runtime starts" — S1/S1b/S2: head hides the path in all three startup shapes (snapshot-driven and event-driven). ✔
  2. "Force a runtime startup failure; the attempted workspace appears with the error" — S3/S6: the attempted path is shown from both the event path and the missed-events snapshot path. ✔
  3. "Start Retry while the initial bootstrap state request is still pending; the older response must not restore the path or replace the retry status" — S4: base demonstrably failed both halves of this (title clobbered, path restored); head holds. ✔

Findings

No blocking findings. Two informational notes, neither a defect:

  • The PR's own vm shim initializes element hidden as undefined while the real DOM starts #workspace hidden; this makes the test's first workspace assertion stricter than the real page, never looser. Harmless.
  • chooseWorkspace()/retryRuntime() set the module-level runtimeStatus even though only initialize() reads it; since the bootstrap page is re-created by every navigate_to_bootstrap (full navigation, fresh JS context — verified in main.rs), no state leaks across sessions. No observable effect.

Not covered

  • Rust side not executed. The container has no Rust toolchain (command -v cargo → empty; no ~/.cargo), so npm test in packages/desktop-shell (cargo test, the author's 39 Rust tests including the new bootstrap_prefers_the_workspace_being_started) could not run. The Rust change (bootstrap_workspace prefers last_workspace over the persisted settings workspace; start_runtime_async sets last_workspace before emitting runtime-starting, so a page that misses the event still gets the attempted workspace from bootstrap_state) was verified by inspection only. Environmental, not a regression: the toolchain is absent from the image.
  • No real webview rendering. No browser/webkit2gtk in the container (only Xvfb), and no cargo to build the Tauri binary, so the visual claims (centered logo, animation) are verified structurally (CSS/markup assertions above), not visually. The A/B reproduces the behavior of the bootstrap page's state machine, not a rendered frame.
  • Per-commit attribution out of reach. Shallow checkout (depth 2): git rev-list HEAD^1..HEAD^2 yields 1 commit while the metadata snapshot lists 6. The aggregate HEAD^1..HEAD diff (5 files, all in packages/desktop-shell) is what was verified.
  • Windows/macOS packaging/signing surfaces — untouched by this PR.
  • Repo-wide gates (full test suite, typecheck) — CI already ran build at HEAD; not re-run by choice.

Methodology

Environment: node:22-bookworm CI verify container, merge-ref checkout (HEAD 0e817206, HEAD^1 = base, HEAD^2 = PR head). harness-ab.mjs executes each arm's real bootstrap.js in vm.runInNewContext with a DOM shim initialized to each arm's index.html state and a scriptable Tauri bridge (bootstrap_state resolver held open to drive the races); 90 scripted assertions. harness-mutations.mjs copies packages/desktop-shell into scratch dirs mirroring the repo layout (with .github symlinked) and runs the real, unmodified scripts/test-release.js per mutant; 4 scripted outcomes. Gates: npm run test:release at head (exit 0), targeted npx eslint on both changed JS files (exit 0) with a planted-violation liveness probe (exit 1). Source provenance: working-tree bootstrap.js sha256 80424699… == HEAD^2 blob; base blob 24602bf2… from HEAD^1. Raw logs in logs/ (ab-run2.log, mutations-run1.log, test-release-head.log); captures in evidence/ (01-ab-head-vs-base-workspace-visibility.png, 02-mutation-matrix-new-test.png, 03-test-release-gate-at-head.png).

Evidence images

01-ab-head-vs-base-workspace-visibility

02-mutation-matrix-new-test

03-test-release-gate-at-head

Harness scripts and raw logs are in the workflow run artifacts (7-day retention).

Qwen Code · sandboxed verification

@yiliang114
yiliang114 requested review from qwen-code-review-bot and removed request for qwen-code-review-bot August 12, 2026 13:23
@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Triage re-run completed without a new review.

⚠️ The bot's only review on 0924d8465366322a270540b611de0cd6b0856056 is a COMMENTED one, which carries no vote — so it has no verdict of its own on this commit, and main needs two approving reviews: an approval left by another account is a separate vote and does not count as the bot's own. Two different things look like this, and the stage-3 comment above says which: the triage skill deferring on purpose at 3/5 — a fork refactor hitting the approval guardrail, or a core change escalated for maintainer awareness, both normal outcomes — or an earlier approval that a push dismissed, leaving only the comment behind, which needs a fresh review.

⚠️ 机器人在 0924d8465366322a270540b611de0cd6b0856056 上唯一的评审是 COMMENTED不带票 —— 因此它在该 commit 上没有自己的裁决,而 main 需要两个批准(其他账号的批准是另一张票)。有两种情况长这样,上方的 stage-3 评论会说明是哪一种:triage skill 在 3/5 时有意 defer(fork refactor 命中审批护栏,或核心改动被升级交由维护者把关,两者都是正常结果);或者更早的批准被一次推送作废、只剩下这条评论,此时需要重新评审。

The stage comments above were updated with the latest result. View workflow run.

上方各阶段评论已更新为最新结果。查看工作流运行

@yiliang114
yiliang114 requested a review from chiga0 August 12, 2026 15:14
@yiliang114

Copy link
Copy Markdown
Collaborator Author

@qwen-code /triage

@qwen-code-ci-bot

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

Copy link
Copy Markdown
Collaborator

Sandboxed verification: ✅ passed — merge-ready (agent verdict) - workflow run

Ran the PR in an isolated, token-free container: A/B against the base build, mock-free harness assertions, targeted gates. Advisory evidence for human reviewers — not a review, an approval, or a CI check.

Scripted assertions: 87 passed · 0 failed · 87 total

中文 — 判定:✅ 通过 · 可合入(agent 判定)

沙箱验证在隔离、无凭证的容器中执行了该 PR 的代码(与 base 构建 A/B 对照、无 mock harness 断言、定向门禁)。仅作为评审证据,不构成评审、批准或 CI 检查

脚本断言:87 通过 · 0 失败 · 87 总计

Verification report

PR 8276 — fix(core): preserve prompt cache across deferred tool discovery

Verdict: merge-ready — 87/87 scripted assertions passed (0 unexpected failures), verified head 14e93105f8bdedab712d90e7685762660f1c4bab (merge-ref checkout 78dfa313f3, base tip 3a59332361). Follow-up round 2 on an unchanged head: HEAD^2 and HEAD^1 are byte-identical to the OIDs verified in round 1, and every carried-forward measurement was rebuilt and re-executed at this head anyway (re-measure, never diff the old report).

中文 — 判定:✅ 通过 · 可合入(agent 判定)· 第 2 轮(head 未变化,全部重新测量)

第 2 轮验证。本轮 head(14e93105)与 base tip(3a593323)和上一轮完全相同;按规则未信任旧报告,全部测量在本 head 上重建并重跑。

  • 结论: merge-ready。87/87 脚本化断言通过,0 个意外失败。
  • A/B 结论(核心主张再次成立): head 构建在 tool_search 呈现 deferred 工具前后,三次模型请求的 tools 声明数组逐字节稳定(65/65/65,103,309 字节,与上轮完全一致);真实目标 schema 只出现在 tool result 中。base 构建把 mcp__calc__calc_add 声明插入下一次请求(64 → 65,+286 字节)。两侧 MCP 目标均恰好在 destination 执行一次。稳定集固定成本复测仍为恰好 +1 个声明(deferred_tool_call,+990 序列化字节)。证据:01-ab-head-tools-byte-stable.png02-ab-base-tools-mutate.png
  • Fail-closed 矩阵: 7 个攻击场景全部拒绝执行(MCP destination 成功执行计数 0;S5 非法参数甚至在 MCP 服务器侧 0 次 tools/call 尝试——客户端校验先于目标),provider 响应始终以 deferred_tool_call + 原始 call id 配对。30/30。
  • 变异矩阵: 3 个未变异对照绿(27/63/66),4 个单点变异全部被目标测试以行为断言杀死(M4 复测 15F/51P,与上轮完全一致)。
  • 门控(A/A): packages/core head 19,799 过 / 96 失败、base 19,696 过 / 85 失败;packages/cli head 19,034 过 / 14 失败、base 19,003 过 / 13 失败。两侧失败文件集合相同且均不在 PR diff 内;失败名差异全部来自两个文件(write-file.test.tsserver.test.ts),两者在单独运行时于两侧均全绿——系本轮 4 套件并行执行造成的负载抖动,非 PR 回归。环境性失败(HOME 路径类)以 file-token-storage 抽样证明在两侧逐名相同(5F/20P)。
  • 新增覆盖(上轮未覆盖项): oversized-schema 逃生通道 E2E(11/11):超预算 schema 直接声明、适配预算的 schema 留待后续 search 并经桥接调用、声明数组保持稳定;<functions> 包装器转义的 hostile-schema 探针(10/10):包含闭合标签、尖括号枚举、反斜杠+尖括号、CRLF/星光字符的 schema 均无原始 < 泄漏且 JSON 往返保真。
  • Findings: 无阻塞发现;上轮两条信息性记录复测后维持。
  • 未覆盖: provider 级缓存命中率/延迟(作者声明为 rollout 度量)、压缩/恢复/回退/MCP 重连的 E2E(单测绿)、subagent E2E(单测绿)、动态 catalog 变更的尾部 reminder 路径、逐 commit 归因(浅克隆)。

Previous-finding status (follow-up round)

Round 1 verified head 14e93105 against the same base tip and returned merge-ready (70/70). The head and base OIDs are unchanged this round; the input closure is therefore proven-identical by commit identity, but every measurement below was re-executed at this head rather than carried forward.

# Round-1 finding Severity Status at this head (re-measured)
1 Central claim: main-session declarations byte-stable across discovery; schema only in tool result; bridge routing with original call id load-bearing claim stands — re-measured A/B: head 13/13, base control 7/7; all wire numbers identical to round 1 (65/65/65 tools, 103,309 B)
2 Fail-closed matrix 7 scenarios, 0 destination executions load-bearing claim stands — 30/30 re-executed; S5 additionally shown to never reach the MCP server (0 tools/call attempts seen)
3 Mutation matrix: 4 guards each pinned by intended test, no survivors vacuity evidence stands — controls 27/63/66 green; M1–M4 all killed; M4 re-measured at 15F/51P, byte-identical to round 1
4 Targeted gates: failing suites environmental, byte-identical at base gate stands with re-attribution — same conclusion, but this round's container HOME differs, so the environmental set is larger (10 core / 4 cli files); A/A re-proven at name level incl. load-flake prove-out (see Targeted gates)
5 Fixed overhead: exactly +1 declaration (deferred_tool_call, +990 serialized bytes) informational stands — re-measured: head req0 103,309 B vs base req0 102,319 B = +990 B
6 Target validation surfaces verbatim under the bridge informational stands — S5 re-observed; rejection now proven client-side (MCP server saw 0 attempts)
7 Oversized-schema escape hatch not driven E2E not covered superseded — driven E2E this round, 11/11 (see Delta probes)

Central claim and A/B proof

Central claim: main-session provider function declarations stay byte-stable across deferred-tool discovery; the real schema reaches the model only in the tool_search tool result, and later execution goes through the stable deferred_tool_call bridge.

Harness (rebuilt this round): real bundled CLI (dist/cli.js, headless -p, --auth-type openai) against a loopback scripted OpenAI server (fake-openai.mjs, captures every raw request body as the wire oracle) and a real stdio MCP server (mcp-calc-server.mjs) that logs successful executions and every tools/call attempt to files, so execution is counted at the destination. The base control is a scratch worktree at HEAD^1 rebuilt (scripts/build.js --cli-only) and re-bundled on a symlinked node_modules farm; readlink -f node_modules/@qwen-code/qwen-code-core from inside it resolves to …/tmp/base-tree/packages/core (workspace links re-pointed, lockfile untouched by the PR), and grep -rl deferred_tool_call over the base dist/ returns 0 hits (6 in head) — the control contains no bridge code.

Cell build req0 tools req1 tools (after discovery) req2 tools MCP destination calls oracle verdict
head dist/cli.js @​ 14e93105 65 (incl. deferred_tool_call) 65, byte-identical (103,309 B) 65, byte-identical calc_add {a:2,b:3} → 5 stable ✔ (13/13)
base tmp/base-tree/dist/cli.js @​ 3a593323 64 (102,319 B) 65 (+mcp__calc__calc_add, +286 B in the serialized tools block) 65 calc_add → 5 mutates ✔ (expected control red, 7/7)

Witnesses: evidence/01-ab-head-tools-byte-stable.png, evidence/02-ab-base-tools-mutate.png. Raw wire bodies: raw/requests-head.ndjson, raw/requests-base.ndjson; per-cell CLI stdout/stderr in raw/cli-*.log|err.

Wire facts asserted on the head arm (in ab-harness.mjs): system-instruction hash identical across req0–req2; schema appears only in the tool_search tool result and in no tools array; the assistant's call uses deferred_tool_call with {name:"mcp__calc__calc_add",arguments:{a:2,b:3}}; the tool result carrying 5 is paired to the bridge's original call id. Stable-set delta vs base is exactly one declaration (+990 B) — the disclosed fixed cost, re-measured.

Delta probes (new coverage this round)

Oversized-schema escape hatch, driven E2E (oversized-harness.mjs, 11/11, witness evidence/05-oversized-escape-hatch.png). Round 1 listed this as not covered. With tools.toolOutputBatchBudget: 3000 in project settings and a real MCP server exposing a ~6.3 KB-description giant_tool plus a small small_tool:

  • the oversized batch is refused inline; the result names giant_tool as declared directly and asks for a follow-up for small_tool;
  • the escape hatch fires: giant_tool enters the provider declarations on the next request (the documented cache-invalidating exception) and executes by direct call (x:7 → 14 at destination);
  • small_tool (fits the budget alone) is not declared directly, its presentations are withheld from the oversized batch; a follow-up select: search presents it in the tool result, and it then executes through deferred_tool_call (x:5 → 15) while the declarations array stays free of it — stability preserved on the non-exceptional path.

Hostile-schema sweep of the <functions> wrapper (hostile-schema-probe.mjs against compiled dist, 10/10): descriptions containing the wrapper's own closing tags, </> enum values, backslash-before-angle sequences, pre-escaped \u003c, CRLF, and astral characters all produce payloads with no raw < (no premature close possible; raw > is intentionally left and harmless), and every payload JSON.parses back to the exact original schema. No production code parses these blocks back — they are model-facing text only; restore paths (restoreProxySchemasAfterCompaction, resume restore in client.ts) re-commit presentations by fingerprint comparison against the registry's current schema, so a changed schema rejects stale presentations (fail-closed by construction; exercised by the unit suite).

Fail-closed matrix (head, 30/30)

Seven scripted sessions (failclosed-harness.mjs, witness evidence/03-failclosed-matrix-head.png), each asserting exit 0, zero successful executions at the MCP destination, response paired to deferred_tool_call + original call id, and the expected rejection text:

Scenario Probe Observed rejection target executed MCP even saw attempt
S1 unrevealed target proxy → calc_mul without search "has not been fetched" no 0
S2 self-recursion proxy → deferred_tool_call "cannot target itself" no 0
S3 array arguments arguments: [1,2] "arguments must be an object matching the target tool schema" no 0
S4 empty name name: "" "must be the exact deferred tool name" no 0
S5 invalid target args a: "not-a-number" after search params/a must be number — client-side validation no 0 — rejected before the MCP server was called
S6 visible tool via proxy proxy → read_file "not eligible for deferred_tool_call" no 0
S7 parallel search+proxy same batch proxy rejected "has not been fetched" while the same-batch search succeeded and returned the schema no 0

S7 re-confirms the ordering invariant: a response cannot both present and authorize a new target in the same batch.

Mutation matrix (vacuity, re-measured)

Unmutated controls green first: normalization 27/27, tool-registry 63/63, tool-search 66/66 (registry and tool-search counts match round 1 exactly). Single-point mutants applied in a scratch worktree at HEAD, restored via git checkout after each run (mutation-matrix.mjs, witness evidence/04-mutation-matrix.png):

Mutant Guard deleted Suite Result killed by behavioral assertion
M1 presentation gate (hasPresentedProxySchema) deferred-tool-call-normalization.test.ts 1F/26P yes — expected true to be false
M2 self-recursion rejection deferred-tool-call-normalization.test.ts 1F/26P yes — expected 'execution_denied' to be 'invalid_tool_params'
M3 fingerprint compare-and-set in markProxySchemaPresented tool-registry.test.ts 1F/62P yes — expected true to be false
M4 no-reveal invariant (re-adds base revealDeferredTool) tool-search.test.ts 15F/51P yes — incl. the byte-identity tests; count byte-identical to round 1

No survivors. Every red run failed on expected-vs-actual behavioral assertions, not imports. Positive control: four planted deletions each turned the affected suite red, so the green suites cited in Targeted gates are live.

Targeted gates (re-measured, full A/A)

All four suites run this round (witness evidence/06-gates-aa-summary.png, raw logs in raw/gate-*.log):

Suite head base
packages/core 19,799 passed / 96 failed / 10 skipped (585 files) 19,696 passed / 85 failed / 10 skipped (582 files)
packages/cli 19,034 passed / 14 failed / 107 skipped (798 files) 19,003 passed / 13 failed / 107 skipped (798 files)

Attribution, at failing-name level (aa-compare.mjs, raw/aa-compare.out):

  • Failing files intersect the PR diff: none, on both arms, both packages.
  • Deterministic environmental failures (HOME-path expectations, container layout) fail with the same names on both arms: 75 common core names, 14 common cli names. Sampled file-token-storage.test.ts re-run isolated on both arms: byte-identical 5 failed / 20 passed — environmental and deterministic, as in round 1 (this container's HOME is /__w/_temp/verify-agent-home, which changes which environment-sensitive assertions trip vs round 1's container).
  • The only name-level deltas were in two files the PR does not touch — core write-file.test.ts (15 names only-on-head, 4 only-on-base) and cli server.test.ts (1 only-on-head). This round ran the four suites concurrently, so each delta file was re-run in isolation: write-file.test.ts 75/75 green on head and base; server.test.ts 922/922 green on head. Verdict: parallel-load flakes, not a PR effect — the deterministic cross-arm delta after prove-out is zero.
  • All test files added or modified by the PR are inside the passing sets (none appears in any failing list); deferred-tool-call-normalization.test.ts was additionally run green under the mutation controls (27/27), and the other two new suites (deferred-tool-call.test.ts, function-schema-rendering.test.ts) passed inside the full core gate.

Findings

No blocking findings. Informational (both carried from round 1, re-measured):

  1. Fixed overhead re-measured: the stable main-session declaration set costs exactly one extra declaration (deferred_tool_call): head req0 65 declarations / 103,309 B vs base req0 64 / 102,319 B = +990 B. Matches the PR's own disclosure.
  2. Target validation is client-side under the bridge: invalid target args are rejected by parameter validation before any MCP traffic (S5: the MCP server recorded 0 tools/call attempts; the rejection is the ajv-style params/a must be number), and the rejection still pairs to deferred_tool_call + original id.

Not covered

  • Provider-level cache-hit rate / latency: not measurable here; explicitly not a merge claim by the PR's own design doc.
  • Compression / rewind / resume / MCP-reconnect presentation lifecycle: unit suites green at head (client.test.ts, geminiChat.test.ts, Session.test.ts, loopDetectionService.test.ts, memoryPressureMonitor.test.ts); not driven E2E. The restore code paths were read and shown fail-closed by construction (fingerprint re-compare on every restore), which is a shape argument, not an E2E reproduction.
  • Dynamic MCP catalog updates delivered as tail reminders instead of system-instruction rewrites: the change path was not driven (requires a mid-session catalog change); system-instruction byte-stability was asserted for the no-change scenario only.
  • Subagent/teammate bridge exclusion: config/agent-core unit tests green; no E2E subagent run.
  • Per-commit attribution: depth-2 checkout — git rev-list HEAD^1..HEAD^2 returns 1 while the metadata lists 41 commits; intermediate commits unreachable. All evidence is for the aggregate HEAD^1..HEAD diff.
  • Model-side tool-use quality of the bridge protocol: author-declared rollout gate, untestable with a scripted model.
  • The 96 core + 14 cli environmental/load failures were attributed via A/A and isolated re-runs but not root-caused (they reproduce at base and outside the PR diff).
  • Windows/web-shell surfaces: additive map entries (toolFormatting.ts, i18n.tsx), covered by build only.

Methodology

Environment: CI verify container (node:22-bookworm, 64 cores), merge-ref checkout at depth 2; npm ci / npm run build pre-run at head. Round identity: HEAD^2/HEAD^1 byte-identical to round 1's verified OIDs; the metadata snapshot's baseRefOid (86a474ba…) had drifted behind the actual checkout base (3a593323…) and was not used. Harnesses (this artifact dir: ab-harness.mjs, failclosed-harness.mjs, oversized-harness.mjs, mutation-matrix.mjs, hostile-schema-probe.mjs, aa-compare.mjs, fake-openai.mjs, mcp-calc-server.mjs, mcp-big-server.mjs) drive the compiled dist/cli.js headless with --auth-type openai --openai-base-url http://127.0.0.1:<port>/v1 against a scripted loopback server that captures every request body, plus real stdio MCP servers whose execution logs are the destination oracle; each run uses an isolated QWEN_HOME/QWEN_RUNTIME_DIR scratch dir. Base control: worktree at HEAD^1 with a symlinked node_modules farm (workspace links asserted via readlink -f to resolve inside the base tree; lockfile unchanged by the PR), built with scripts/build.js --cli-only + npm run bundle (skips web-shell assets, which serve qwen serve UI only and are not on the headless path); bundle identity cross-checked by grep (0 bridge hits in base dist). Mutations applied in a second scratch worktree and restored after each run. Full gate suites ran concurrently (which is why two load-flake files needed isolated re-runs). Raw wire bodies, per-cell CLI output, gate logs, and harness stdout live in raw/; images in evidence/ (filenames are captions). Assertion counts: A/B head 13 + A/B base 7 + bundle identity 1 + workspace-realpath control 1 + fail-closed 30 + mutation controls 3 + mutant kills 4 + oversized 11 + hostile-schema 10 + A/A file-set comparisons 2 + isolated flake re-runs 3 + environmental determinism probe 1 + PR-diff intersection checks 2 = 87, all passing.

Evidence images

01-ab-head-tools-byte-stable

01-ab-head-vs-base-workspace-visibility

02-ab-base-tools-mutate

02-mutation-matrix-new-test

03-failclosed-matrix-head

04-mutation-matrix

05-oversized-escape-hatch

06-gates-aa-summary

1 additional image(s) did not pass the hosting checks (PNG magic, unique sanitized name, ≤2 MB, max 8) and remain in the run artifacts.

Harness scripts and raw logs are in the workflow run artifacts (7-day retention).

Qwen Code · sandboxed verification

@yiliang114
yiliang114 removed the request for review from qwen-code-review-bot August 12, 2026 15:44

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

@yiliang114
yiliang114 requested review from qwen-code-review-bot and removed request for qwen-code-review-bot August 12, 2026 15:44
@qwen-code-review-bot

Copy link
Copy Markdown
Collaborator

No blockers found. The current head preserves the intended startup, failure, retry, and snapshot/event ordering while keeping workspace details hidden until recovery UI is needed. Verified with node packages/desktop-shell/scripts/test-release.js; the Desktop Shell checks are also green.

@yiliang114

Copy link
Copy Markdown
Collaborator Author

@qwen-code-review-bot review this pr and approve if no blockers

@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 explored to full depth (tool budget reached): You are review agent reverse-audit — Reverse audit agen...: compile/run the new Rust unit test bootstrap_prefers_the_workspace_being_started (no cargo toolchain in this environment).

中文说明

已审查。 建议见行内评论。

未探索到全部深度(达到工具调用预算):You are review agent reverse-audit — Reverse audit agen...:compile/run the new Rust unit test bootstrap_prefers_the_workspace_being_started (no cargo toolchain in this environment)

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

});
}
if (command === 'open_logs') throw new Error('no file handler');
if (command === 'choose_workspace') return null;

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 changed success branch if (path) currentWorkspace = path; in chooseWorkspace() is never exercised: the harness mock hardcodes choose_workspace to resolve null here, so all three scenarios run only the no-selection branch — Failure scenario: deleting or breaking that assignment (the exact line this diff changed from setWorkspace(path)) leaves every assertion in testBootstrapWorkspaceVisibility green (mutation-proven), while the behaviour it guards — user picks a folder, the runtime then fails, and the recovery panel must show the folder the user chose — would silently regress to showing the stale auto-selected path (verified by probe: with choose_workspace resolving a path and a later runtime-failed, the mutated code shows the stale path). Suggested fix: parameterize the harness mock so choose_workspace can resolve a path, and add one picker-success scenario:

// createBootstrapHarness({ chooseResult: '/Users/example/Chosen' }) →
//   if (command === 'choose_workspace') return chooseResult ?? null;
const picker = await createBootstrapHarness({
  chooseResult: '/Users/example/Chosen',
});
await picker.element('#choose').listeners.click();
picker.listeners['runtime-failed']({ payload: 'runtime failed' });
picker.resolveBootstrapState({
  desktopVersion: '0.2.0',
  status: 'idle',
  workspace: '/Users/example/Auto',
  error: 'runtime failed',
});
await new Promise((resolve) => setImmediate(resolve));
assert.equal(
  picker.element('#workspace').textContent,
  '/Users/example/Chosen',
);
中文说明

[Suggestion] chooseWorkspace() 中被修改的成功分支 if (path) currentWorkspace = path; 从未被执行到:harness 的 mock 在这里把 choose_workspace 硬编码为返回 null,因此三个场景都只走到未选择目录的分支 — 失败场景:删除或破坏这行赋值(正是本 diff 从 setWorkspace(path) 改过来的那一行)后,testBootstrapWorkspaceVisibility 的所有断言仍然全绿(已通过变异验证),而它所保护的行为——用户选择了目录、运行时随后启动失败、排障面板必须展示用户选择的目录——会静默回退为展示旧的自动选择路径(已用探针验证:让 choose_workspace 返回一个路径、随后触发 runtime-failed,变异后的代码显示的是旧路径)。建议修复:让 harness 的 mock 可配置,使 choose_workspace 能返回路径,并新增一个“选择成功”场景(见上方代码)。

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

</style>
</head>
<body>
<body data-state="starting">

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 initial data-state="starting" attribute is load-bearing for the first paint but asserted nowhere: the static HTML checks only pin the logo <img> and the SVG's existence, and the vm harness injects body = { dataset: {} }, so the first-paint state is never verified — Failure scenario: removing or renaming the attribute keeps every check green, yet between page load and the first setStatus (which runs only after the async listen() registrations plus the bootstrap_state round trip) none of the body[data-state='starting'] rules apply and the page renders the full shell panel — brand copy, status card, actions row, footer — reintroducing exactly the loading UI this PR replaces (mutation-proven). Suggested fix: add this assertion next to the logo checks in testBootstrapWorkspaceVisibility:

assert.match(bootstrapHtml, /<body data-state="starting">/);
中文说明

[Suggestion] 初始的 data-state="starting" 属性对首屏渲染是承重的,但没有任何断言钉住它:静态 HTML 检查只钉住了 logo <img> 和 SVG 文件的存在,而 vm harness 注入的是 body = { dataset: {} },因此首屏状态从未被验证 — 失败场景:删除或改名该属性后所有检查仍然全绿,但在页面加载到第一次 setStatus(要等异步 listen() 注册加上 bootstrap_state 往返之后才会执行)之间,所有 body[data-state='starting'] 规则都不生效,页面会渲染出完整的外壳面板——品牌文案、状态卡片、操作按钮行、页脚——恰好把本 PR 要替换掉的加载界面又带了回来(已通过变异验证)。建议修复:在 testBootstrapWorkspaceVisibility 的 logo 检查旁加入上方断言。

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

@qwen-code-review-bot

Copy link
Copy Markdown
Collaborator

Reviewed the current head and found no blockers. The startup, failure, retry, and event/snapshot ordering paths look correct, and the Desktop release regression checks pass.

@doudouOUC doudouOUC left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM✅

@yiliang114
yiliang114 added this pull request to the merge queue Aug 12, 2026
Merged via the queue into main with commit 8cb416e Aug 12, 2026
140 of 142 checks passed
@QwenLM QwenLM deleted a comment Aug 12, 2026
@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Released in v0.21.11.

pull Bot pushed a commit to mcx/qwen-code that referenced this pull request Aug 13, 2026
…ion startup (QwenLM#9064)

* fix(desktop): hide the Windows runtime terminal and align reduced-motion startup

On Windows the bundled runtime (node.exe, a console application) was spawned
without CREATE_NO_WINDOW, so the desktop (a GUI application) allocated a
visible terminal window for it; closing that window stopped the runtime with
exit code 1 (QwenLM#9043). Route the spawn through a platform-specific helper that
sets CREATE_NO_WINDOW via the command-group builder (group_spawn would
overwrite creation flags set directly on the command). Add a Windows-only
regression test that asserts the spawned child receives no console window.

The reduced-motion bootstrap fallback showed the logo left-aligned inside the
shell while the newly visible status text was centered in a wider card, so the
two did not share a horizontal center. Stack and center both inside the shell
and drop the leftover card chrome, mirroring the simplified startup view from
QwenLM#8988, and extend the bootstrap release check to guard the centering rules.

* fix(desktop): simplify reduced-motion startup centering

* fix(core): hide daemon-side console spawns on Windows

With the bundled runtime spawned console-less, console-app children of
the daemon no longer inherit a console and each allocates a visible
window. Pass windowsHide at the git attribution, git notes, and
taskkill spawn sites in the shell tool, matching shellExecutionService.
Also loosen the reduced-motion bootstrap assertion so it no longer
hard-codes rule order inside the media block.

* fix(desktop): hide runtime descendant consoles

* test(desktop): pin the hidden-console spawn helper at the production call site

The Rust test exercises spawn_runtime_group directly; nothing guarded that
DesktopRuntime::start still routes through it. Assert the call site in the
release gate so a refactor reverting to group_spawn() fails the suite.
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.

5 participants