Skip to content

feat(web-shell): optimize session overview table - #10115

Merged
wenshao merged 19 commits into
mainfrom
worktree-session-overview-optimize
Aug 29, 2026
Merged

feat(web-shell): optimize session overview table#10115
wenshao merged 19 commits into
mainfrom
worktree-session-overview-optimize

Conversation

@ytahdn

@ytahdn ytahdn commented Aug 26, 2026

Copy link
Copy Markdown
Collaborator

What this PR does

Reworks Session Overview into a reusable, responsive data table with proportional columns on wide screens, horizontal scrolling and fixed edge columns on narrow screens, consistent hover backgrounds, fixed-column shadows, tooltips, sorting, workspace filtering, remembered pagination, row selection, and confirmation dialogs for destructive actions. Session rows retain rename, export, archive, delete, new-tab, and split-view workflows, including safe handling when the active session is renamed, archived, deleted, or cleared by navigating back.

Screenshot

Session Overview table

The shared table primitive owns column sizing, truncation, tooltip wrapping, fixed positioning, scroll shadows, empty states, and pagination so future Web Shell tables can reuse the same behavior. The sidebar archive action moves into the existing More menu.

Why it's needed

The previous card layout did not scale well for larger session catalogs and duplicated behavior that other tables may need. This change makes dense session management easier to scan and operate while preserving existing session actions and keeping narrow-window behavior usable.

Reviewer Test Plan

How to verify

Open Session Overview from the sidebar and confirm that wide layouts distribute non-fixed columns proportionally without horizontal scrolling. Narrow the window and confirm horizontal scrolling appears, the selection/title columns and action column remain fixed with synchronized row hover backgrounds, and edge shadows appear before scrolling when overflow exists.

Verify search, multi-select workspace filtering, time sorting, 10/50/100 page sizes with the last choice restored, row selection by clicking outside the title, title-only session switching, session ID copying, Worktree/PR details, and empty results rendered inside the table.

Verify rename, export, archive, and delete actions for supported primary and trusted workspace sessions. Archive and delete must require confirmation; operating on the active session or using Back from Session Overview must clear the active session into a new-task state without closing the overview during an in-panel mutation.

Evidence (Before & After)

Before: Session Overview used a card grid with limited dense-table behavior.

After: The screenshot in the summary shows the responsive table, fixed action controls, workspace filtering, Worktree and PR metadata, selection actions, and pagination.

Tested on

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

Environment (optional)

Local Web Shell daemon development environment. Verified 106 focused unit tests covering the table, Session Overview, tooltip, sidebar action visibility, and App integration flows; Web Shell TypeScript type checking and i18n consistency checks also pass.

Risk & Scope

  • Main risk or tradeoff: Responsive column sizing and sticky positioning depend on measured container width; regression tests cover fluid sizing and fixed-column offsets.
  • Not validated / out of scope: Browser automation and full-repository build/test suites were intentionally not run.
  • Breaking changes / migration notes: None.

Linked Issues

N/A

中文说明

本 PR 的改动

将会话总览重构为可复用的响应式数据表格:宽屏下按比例分配列宽,窄屏下启用水平滚动和两侧固定列,并统一行 Hover 背景、固定列阴影、Tooltip、排序、工作区筛选、记住的分页、行选择以及危险操作确认弹窗。会话行保留改名、导出、归档、删除、新标签页打开和分屏打开流程,并在当前会话被改名、归档、删除或通过返回操作清空时进行安全处理。

会话总览表格

通用表格基础组件统一承担列宽计算、内容缩略、Tooltip 包装、固定定位、滚动阴影、空状态和分页能力,便于后续 Web Shell 表格复用相同行为。侧边栏的归档操作收入已有的“更多”菜单。

改动原因

原有卡片布局不利于大量会话的展示,也无法复用其他表格可能需要的行为。本改动让高密度会话管理更容易浏览和操作,同时保留已有会话能力,并保证窄窗口下仍可使用。

Reviewer 测试计划

验证方式

从侧边栏打开会话总览,确认宽布局下非固定列按比例分配且不出现水平滚动。缩小窗口后确认出现水平滚动,选择/标题列和操作列保持固定,行 Hover 背景同步,并在存在溢出时于用户滚动前就显示边缘阴影。

验证搜索、工作区多选筛选、时间排序、10/50/100 分页并记住上次选择、点击标题外的行区域选中、仅点击标题切换会话、复制会话 ID、Worktree/PR 详情,以及在表格内展示空结果。

对受支持的主工作区和可信工作区会话验证改名、导出、归档和删除。归档和删除必须经过确认;对当前会话执行操作,或从会话总览点击返回时,必须清空当前会话并进入新建任务状态,而在面板内操作时不关闭会话总览。

证据(改动前后)

改动前:会话总览使用卡片网格,密集表格能力有限。

改动后:Summary 中的截图展示了响应式表格、固定操作区、工作区筛选、Worktree 和 PR 元数据、选择操作以及分页。

测试平台

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

环境(可选)

本地 Web Shell daemon 开发环境。已通过 106 个定向单元测试,覆盖表格、会话总览、Tooltip、侧边栏操作可见性和 App 集成流程;Web Shell TypeScript 类型检查和 i18n 一致性检查也已通过。

风险与范围

  • 主要风险或权衡:响应式列宽和粘性定位依赖容器宽度测量;回归测试已覆盖流式尺寸和固定列偏移。
  • 未验证/范围外:按要求未运行浏览器自动化和全仓库 build/测试套件。
  • 破坏性改动/迁移说明:无。

关联 Issue

@qwen-code-ci-bot

qwen-code-ci-bot commented Aug 26, 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 26, 2026

Copy link
Copy Markdown
Collaborator

Re-run at the author's request — gate re-checked at the current head, after five fix rounds since the first pass.

  • Template ✓ — bilingual body, reviewer test plan, tested-on matrix, and before/after screenshot all in place.
  • Problem: real and demonstrated — the card grid doesn't scale for larger session catalogs, and the PR shows the before/after. This is a UX improvement to an existing surface, not a theoretical fix, so no reproduction is required.
  • Direction: aligned. Session Overview is the established surface for operating on many sessions at once, and Web Shell UI is a product area with documented conventions. No direct CHANGELOG reference, but the area is clearly in scope.
  • Size: no core paths touched (everything is packages/web-shell/client/**), so the two-tier core gate doesn't apply. At the current head: ~3,200 production lines vs ~4,700 test lines vs ~110 docs/lockfile/NOTICES. That stays above the 1,000-line large-PR advisory — informational only, not a blocker. One hygiene note: a core-package formatting diff that crept in mid-flight was removed by a dedicated chore commit; the net diff against main carries no core changes.
  • Approach: the shape from the first pass is unchanged and still right — stock shadcn table primitive plus a DataTable behavior layer on @tanstack/react-table, confirmations through the existing AlertDialog, mutations routed per workspace scope. Since then, every finding from the maintainer's live verification was addressed in the fix rounds (split-selection truncation under sort, false archive error on already-removed sessions, mobile fixed-column overlap, Back resetting the workspace), and the newest commit adds two safeguards — live-state refresh only when every visible workspace is trusted, archive/delete only for idle sessions — both pinned by new tests.
  • Risk: no elevated risk signals — none of the changed files match the revert-correlated paths. The one red check at head is the bot's own review pipeline failing to complete, not the PR's CI; classified in the Stage 2 comment.

Moving on to code review. 🔍

中文说明

应作者请求重跑 —— 在首轮之后的五轮修复之上,于当前 head 重新过门禁。

  • 模板 ✓ —— 双语正文、Reviewer 测试计划、测试平台矩阵与改动前后截图齐全。
  • **问题:**真实且有证据 —— 卡片网格在会话较多时不易浏览,PR 提供了前后对比。这是对已有界面的 UX 改进,不是理论性修复,无需复现。
  • **方向:**对齐。会话总览本来就是批量管理会话的界面,Web Shell UI 也是有明确约定的产品区域。CHANGELOG 无直接引用,但该领域显然在范围内。
  • **规模:**未触及核心路径(全部在 packages/web-shell/client/**),两级核心门禁不适用。当前 head:生产代码约 3,200 行、测试约 4,700 行、文档/lock 文件/NOTICES 约 110 行。仍高于 1,000 行大 PR 提示线 —— 仅作提示、不构成阻塞。一处卫生说明:中途混入的核心包格式化差异已由专门的 chore 提交移除,对 main 的净差异不含核心改动。
  • **方案:**首轮的结构判断不变且依然合理 —— 标准 shadcn table 原语加基于 @tanstack/react-tableDataTable 行为层,确认弹窗复用现有 AlertDialog,变更操作按工作区作用域路由。此后维护者实机验证提出的每个问题都在修复轮中解决(排序下分屏选择被截断、归档已移除会话的假错误、移动端固定列重叠、返回按钮重置工作区),最新提交还增加了两项防护 —— 仅当所有可见工作区均可信时启用 live-state 刷新、仅对空闲会话允许归档/删除 —— 均有新测试钉住。
  • **风险:**无升级风险信号 —— 改动文件均未命中与 revert 相关的高风险路径。head 上唯一的红项是 bot 自身 review 流水线未跑完,不是 PR 的 CI;在 Stage 2 评论中分类说明。

进入代码审查 🔍

Qwen Code · qwen3.8-max

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

@ytahdn
ytahdn requested a review from wenshao August 26, 2026 09:17
@qwen-code-ci-bot

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

Copy link
Copy Markdown
Collaborator

Code review

Re-run: the table rework itself was reviewed in full at b64fba94 (that pass is in this comment's history — shape matched my independent sketch, no blockers). This pass re-read the load-bearing code at head and reviewed everything pushed since: five fix rounds, each a response to real review feedback.

What the delta does, round by round:

  • Round 1 — mutations now batch through the owning workspace client for every scope (primary included), which fixes the false "Operation did not complete" error when archiving an already-removed session and removes the per-id fan-out (up to 1,000 requests on select-all). Split selection is derived from the sorted row model and hard-capped at MAX_SPLIT_PANES with an explanatory tooltip instead of silently truncating. DataTable unpins the right column when the two fixed regions would overlap (the phone-width finding). Back preserves the viewed session's workspace. The sidebar test that went vacuous after the archive relocation now asserts through the More menu, and the sidebar-customization docs were updated to match (archive is dropdown-only, default inlineItems is ['pin']).
  • Catalog sync — mutations and renames refresh the session catalog store per owning workspace (finally, so failures converge too), so rows stay consistent even when the live channel misses an update.
  • Round 2 — explicit split exit and every overview navigation path cancel the pending shrink-fold split restore, so a resized window can't resurrect a split the user deliberately left; stale workspace exclusions are dropped when the filter options shrink (a stale exclusion could hide every remaining row); re-creating a task after removing the current session inherits the removed session's workspace.
  • Round 3 — the live-state channel replaces polling only when the panel owns it (liveStateActive = manageLiveState && liveStateEnabled). When the sidebar owns the channel its trusted-only coverage can miss workspaces the overview shows, so the panel keeps polling then — this closes the stale-rows gap that direction left open.
  • Navigation/scroll stabilization — sticky-footer hysteresis normalized against the viewport's padding, with the engage/release asymmetry documented; the overflow-class juggling replaced by a background-shadow mask; the table container clips vertical overflow.
  • Safeguards (head commit) — live-state is adopted only when every visible workspace is trusted (otherwise fall back to polling), and archive/delete require status === 'idle' (running/waiting sessions can't be destroyed from the overview). Both pinned by new tests (disables archive and delete actions for a running session, keeps polling when live state cannot cover an untrusted primary).

These increments are also corroborated from outside this review: the maintainer's scripted live-browser matrix (at b64fba94) measured the responsive layout, fixed-column offsets, edge shadows, and hover sync against the real DOM and its four findings are exactly what rounds 1–3 fix; a human reviewer then verified all C-level findings from the review rounds were fixed in 1c2f558b.

Remaining follow-ups (none blocking):

  • isNonPrimaryWorkspaceSession (utils/workspace.ts:56) and its test are now dead code — this PR removed the last consumer. Worth deleting here or in a follow-up.
  • The verify run's F1/F2: the mutateCards re-check and the page-size persistence write side have no direct tests pinning them. Optional coverage.
  • DataTable renders Radix Tooltip without a TooltipProvider and carries an unconsumed fixedOffset — unreachable from today's only consumer, already on the round-3 deferred list. Follow-up material for the next table.
  • Back clearing the active session without confirmation is intended per the PR body; the maintainer already weighed it.

Testing evidence

Unattended CI run — I did not build or execute PR code. The evidence below is the PR's own CI on the reviewed commit plus the sandboxed /verify run, both fetched via the API at this moment.

Check Conclusion
review-pr ❌ failure — bot review pipeline, classified below
Test (ubuntu-latest, Node 22.x) ✅ success
web-shell E2E Smoke (ubuntu-latest, Node 22.x) ✅ success
Capture web-shell visuals (ubuntu-latest, Node 22.x) ✅ success — scenario-level failure classified below
Desktop Shell (ubuntu-22.04) ✅ success
Desktop Shell (windows-2022) ✅ success
Real daemon E2E / Java 11 ✅ success
Integration Tests (no-AK, No Sandbox) ✅ success
Secret scan (TruffleHog) ✅ success
Dependency CVE audit ✅ success
SDK Java (ubuntu 11/17/21, macOS 21, windows 21) ✅ success
Classify PR · Post Coverage Comment ✅ success

One row per check name (latest run on the reviewed commit); skipped checks omitted. / 每个检查名一行(取被审提交的最新一次运行),省略 skipped。

All four of the PR's own CI workflows (pull_request events) completed green on the head commit — the ubuntu Node suite (web-shell unit tests + i18n consistency), the web-shell E2E smoke, desktop-shell builds, security scans, and the SDK matrix. macOS/windows Node test jobs are skipped by workflow configuration, not failures. Two red areas need classification, and neither is a PR defect:

  • review-pr failure — this is the bot's own review pipeline (pull_request_target), which failed before it could post a review on this head (the fallback comment is in this thread). That's bot infrastructure, not the PR's CI. The last substantive pipeline pass (round 5, at 1f9d5290) had already converged to Suggestion-level items it explicitly did not request, and every earlier C-level finding was verified fixed by a human reviewer.
  • Visuals "No preview" — the visuals check is green but its publisher reports a failed scenario on this head. Before attributing it: the failing scenario (workspace sidebar, dark and light) fails with an identical strict-mode violation (the mock renders two "Run auth migration" rows) when run against this PR's unmodified base tree in the same job — and it has failed identically since this PR's first visuals run on 08-26. Pre-existing on main, not a regression introduced here. What it does cost this PR: no before/after preview images, so pixel-level evidence at head comes from the sandboxed verify's DOM-level harnesses and the maintainer's earlier measurement matrix rather than the visuals lane. The scenario itself needs its own fix on main.

Sandboxed verification at exactly this head (/verify, run by maintainer trigger): ✅ merge-ready — 868/868 scripted assertions, typecheck clean, flakiness gate 6 files × 5 rounds with no divergence, and a mutation A/B matrix that proves the central safeguards are load-bearing: stripping the archive confirm, the delete confirm, the onCurrentSessionRemoved wiring, or reverting Back to base behavior each turns red exactly the intended tests (with a positive control going red on exactly one). The live-refresh/mutation-routing gap this comment flagged in the first run is now substantiated at head; no further /verify request. Not verified: browser rendering on Windows/Linux (author marks both ⚠️ — their claim, not independently re-run). A maintainer wanting pixel-level evidence at head can re-run the scripted live-browser matrix; the results above suggest it would hold.

中文说明

代码审查

重跑说明:表格重构本身已在 b64fba94 完整审过(本评论的历史版本,结构与我的独立构想一致、无阻塞)。本轮在 head 上重读了承重代码,并审查此后推送的全部内容:五轮修复,每轮都是对真实评审反馈的回应。

各轮要点:

  • 第 1 轮 —— 变更操作对所有作用域(含主工作区)统一走所属工作区 client 的批量接口,修复了归档已移除会话时的假错误,并消除逐条扇出(全选时最多 1000 个请求)。分屏选择改从排序后的行模型取,并以 MAX_SPLIT_PANES 硬上限加提示文案取代静默截断。DataTable 在两侧固定区会重叠时解除右列固定(手机宽度问题)。返回保留所查看会话的工作区。归档迁移后失效的侧边栏测试改为断言"更多"菜单,侧边栏自定义文档同步更新(归档改为仅下拉、默认 inlineItems['pin'])。
  • 目录同步 —— 变更与改名按所属工作区刷新会话目录存储(在 finally 中,失败也收敛),即使 live 通道漏掉更新,行状态也保持一致。
  • 第 2 轮 —— 显式退出分屏与所有总览导航路径都会取消待执行的收缩折叠恢复,避免窗口放大后把用户已主动离开的分屏复活;筛选选项减少时清除过期的工作区排除项(否则可能隐藏所有剩余行);移除当前会话后重建任务时继承被移除会话的工作区。
  • 第 3 轮 —— 仅当面板自己拥有 live-state 通道时(liveStateActive = manageLiveState && liveStateEnabled)才用它替代轮询;侧边栏拥有通道时其"仅可信"覆盖可能漏掉总览展示的工作区,面板此时继续轮询 —— 补上了该方向遗留的行状态过期缺口。
  • 导航/滚动稳定 —— 吸底页脚的滞回阈值按视口内边距归一,进入/退出不对称有注释说明;用背景色阴影遮罩替代 overflow 类切换;表格容器裁剪纵向溢出。
  • 防护(head 提交) —— 仅当所有可见工作区均可信时采用 live-state(否则回退轮询);归档/删除要求 status === 'idle'(运行中/等待中的会话不能从总览销毁)。两者均有新测试钉住。

这些增量也有外部佐证:维护者的脚本化实机验证(b64fba94)对真实 DOM 测量了响应式布局、固定列偏移、边缘阴影与 hover 同步,其四个发现正是第 1–3 轮修复的内容;随后有人工评审者逐条确认评审各轮的 C 级发现已在 1c2f558b 修复。

遗留跟进项(均不阻塞):

  • isNonPrimaryWorkspaceSessionutils/workspace.ts:56)及其测试现已是死代码 —— 本 PR 移除了最后一个使用方。建议在本 PR 或后续清理。
  • verify 报告的 F1/F2:mutateCards 复查与分页大小持久化的写入侧没有直接测试钉住。可选补充。
  • DataTable 渲染 Radix Tooltip 未带 TooltipProviderfixedOffset 无消费方 —— 当前唯一消费方触达不到,已在第 3 轮延期清单。留给下一张表格的跟进项。
  • 返回按钮无确认即清空当前会话为 PR 正文声明的预期行为,维护者已权衡过。

测试证据

无人值守 CI 运行 —— 未构建或执行 PR 代码。以上证据为被审提交上 PR 自身 CI 与沙箱 /verify 运行经 API 抓取的即时快照。

CI 表格见上方标记区。head 提交上 PR 自身的四个 CI 工作流(pull_request 事件)全部通过 —— ubuntu Node 套件(web-shell 单测 + i18n 一致性)、web-shell E2E 冒烟、桌面壳构建、安全扫描、SDK 矩阵。macOS/windows 的 Node 测试是工作流配置跳过,不是失败。两处红项需要分类,均非 PR 缺陷:

  • review-pr 失败 —— 这是 bot 自身的 review 流水线(pull_request_target),在该 head 上未能发出评审即失败(兜底评论在本帖)。属 bot 基础设施问题,不是 PR 的 CI。最近一次完整的流水线评审(第 5 轮,1f9d5290)已收敛到明确不要求处理的 Suggestion 级,且更早的 C 级发现已由人工评审者逐条确认修复。
  • 视觉预览"无预览" —— 视觉检查本身通过,但发布器报告该 head 上有场景渲染失败。先归因再定性:失败场景(workspace sidebar,深浅两色)在同一任务中对本 PR 未改动的 base 树运行时以完全相同的严格模式冲突失败(mock 渲染出两个 "Run auth migration" 行),且自 08-26 本 PR 首次视觉运行起就一直如此。属 main 上的既有问题,非本 PR 引入的回归。它对本 PR 的实际影响:没有前后对比预览图,head 上的像素级证据改由沙箱验证的 DOM 级断言与维护者此前的实测矩阵提供;该场景本身需要在 main 上单独修复。

该 head 上的沙箱验证(维护者触发的 /verify):✅ 可合入 —— 868/868 脚本断言、类型检查通过、抖动门 6 文件 × 5 轮无分歧,突变 A/B 矩阵证明核心防护均承重:去掉归档确认、删除确认、onCurrentSessionRemoved 接线,或把返回还原为 base 行为,都会让恰好对应的预期测试变红(阳性对照恰好红 1 个)。首轮评论指出的"实时刷新/变更路由"缺口已在该 head 上被证实,无需再次请求 /verify。未验证:Windows/Linux 上的浏览器渲染(作者两处均标 ⚠️ —— 作者声明,非独立复核)。如需 head 上的像素级证据,维护者可重跑脚本化实机矩阵;以上结果预示应当成立。

Qwen Code · qwen3.8-max

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

@qwen-code-ci-bot

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

Copy link
Copy Markdown
Collaborator

🖼️ web-shell visual preview

Rendered against a mock daemon (no real backend): the PR base vs this PR head 3baa229. Only screenshots that changed are shown (flows below, if any, are head-only) — refreshes on every push.

Screenshots · before / after

⚠️ No preview: one or more scenarios failed to render on this head — see the workflow run. This is not "no visual change" — a scenario that times out or throws produces no image. Fix the failing scenario (or a genuine regression it caught) and the preview returns on the next push.

Full-resolution recordings (.webm) are attached to the workflow run.

Qwen Code · web-shell visuals

@qwen-code-ci-bot

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

Copy link
Copy Markdown
Collaborator

Confidence: 4/5 — everything the gate can check at head checks out (CI green, sandboxed verify passes with load-bearing proof, maintainer findings converged); the last point stays off only because pixel-level rendering on Windows/Linux rests on the author's word and the bot review pipeline failed to complete a pass on this exact head.

Stepping back: my independent sketch for this problem (stock shadcn table primitive + thin behavior layer, sticky CSS columns, existing AlertDialog) is still what the PR does — and it keeps exceeding it in the places that matter. Five fix rounds landed since the first pass, and every one of them was a response to a real finding, not churn: the split-selection truncation, the false archive error, the phone-width fixed-column overlap, the stale-rows gap when the sidebar owns the live channel — each fixed with the matching test next to it. The newest commit hardens rather than patches: live-state only over fully trusted workspaces, archive/delete only on idle sessions.

Is it needed? Yes, more so than the first pass assumed — a maintainer drove the real UI against a real daemon with 29 sessions across 4 workspaces and measured the result, an independent E2E pass found no blockers, and the author engaged through five rounds plus a sandboxed verification instead of pushing back on volume. If I'm maintaining this in six months, the DataTable primitive and its test coverage are something I'd thank the author for.

Reservations, named so they don't get lost: the isNonPrimaryWorkspaceSession dead code and its test should go; the visuals lane's workspace sidebar scenario is broken on main and this PR merged without before/after preview images because of it (the verify harness and the maintainer's measurement matrix substitute, imperfectly); Back clearing the active session remains a deliberate design choice a maintainer has already weighed.

All of the PR's own CI completed green on the reviewed commit — no pending runs — and the approval guardrail does not apply (same-repository branch, feat title), so approval posts now, pinned to the reviewed commit.

中文说明

置信度:4/5 —— 门禁能在 head 上核验的一切均已通过(CI 全绿、沙箱验证以承重性证明通过、维护者提出的问题全部收敛);扣掉的一分仅因为 Windows/Linux 上的像素级渲染只有作者声明,且 bot review 流水线未能在该 head 上完成一轮完整评审。

退一步看:我为这个问题独立构想的方案(标准 shadcn table 原语 + 薄行为层、CSS 固定列、复用现有 AlertDialog)依然是本 PR 的做法 —— 且它在关键处持续超出预期。首轮之后落地的五轮修复,每一轮都是对真实发现的回应而非无效改动:分屏选择截断、归档假错误、手机宽度固定列重叠、侧边栏拥有 live 通道时的行状态过期 —— 每项修复旁都有对应测试。最新提交是加固而非补丁:仅对完全可信的工作区启用 live-state、仅对空闲会话允许归档/删除。

有必要吗?有,而且比首轮判断的更有必要:一位维护者用真实 daemon、4 个工作区的 29 个会话驱动真实 UI 并实测了结果,一次独立 E2E 未发现阻塞项,作者以五轮修复加一次沙箱验证持续投入而非以量压人。半年后维护这段代码,DataTable 原语与其测试覆盖是让人感谢作者的东西。

顾虑照实列出,避免被遗忘:isNonPrimaryWorkspaceSession 死代码及其测试应删除;视觉车道的 workspace sidebar 场景在 main 上就是坏的,本 PR 因此没有前后对比预览图(由验证 harness 与维护者的实测矩阵替代,但不完美);返回按钮清空当前会话是维护者已权衡过的有意设计。

PR 自身的 CI 在被审提交上全部通过且无进行中任务,批准护栏不适用(同仓库分支、feat 标题),因此立即提交批准,并固定在被审提交上。

Qwen Code · qwen3.8-max

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

@github-actions

github-actions Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Summary

Package Lines Statements Functions Branches
CLI 85.66% 85.66% 91.06% 84.62%
Core 88.75% 88.75% 90.51% 87.2%
CLI Package - Full Text Report
-------------------|---------|----------|---------|---------|-------------------
File               | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-------------------|---------|----------|---------|---------|-------------------
All files          |   85.66 |    84.62 |   91.06 |   85.66 |                   
 src               |   86.45 |    82.24 |   88.23 |   86.45 |                   
  cli.ts           |   95.68 |    84.11 |     100 |   95.68 | ...60-561,565-566 
  llm.tsx          |   73.22 |    77.73 |   80.76 |   73.22 | ...1345-1349,1476 
  ...ractiveCli.ts |   89.27 |    83.13 |   89.06 |   89.27 | ...3157,3163,3229 
  ...liCommands.ts |   89.71 |    84.17 |   81.81 |   89.71 | ...31-633,650,757 
  ...ActiveAuth.ts |     100 |     87.5 |     100 |     100 | 66-80             
 ...cp-integration |   74.57 |    77.36 |   93.65 |   74.57 |                   
  acpAgent.ts      |   73.63 |    77.23 |   92.93 |   73.63 | ...02,13080-13081 
  ...k-reporter.ts |     100 |       80 |     100 |     100 | 81,84,119,141     
  authMethods.ts   |      92 |       60 |     100 |      92 | 33-34             
  ...heap-probe.ts |   97.39 |    96.66 |     100 |   97.39 | 243,264-265       
  errorCodes.ts    |     100 |      100 |     100 |     100 |                   
  ...ion-skills.ts |     100 |     87.5 |     100 |     100 | 17,28             
  generation.ts    |    97.1 |    81.25 |     100 |    97.1 | 109,112           
  ...figuration.ts |     100 |    89.65 |     100 |     100 | 79,125,142        
  ...DirContext.ts |     100 |      100 |     100 |     100 |                   
  ...ersistence.ts |   94.95 |    92.24 |     100 |   94.95 | ...13-118,227-228 
  ...management.ts |   74.75 |     66.3 |     100 |   74.75 | ...92-496,505-509 
  ...e-download.ts |    64.7 |    62.24 |    87.5 |    64.7 | ...08-609,615-619 
 ...tegration/live |    97.5 |       88 |   92.85 |    97.5 |                   
  ...en-context.ts |   95.74 |    82.35 |     100 |   95.74 | ...0,66-67,99-100 
  ...structions.ts |     100 |      100 |     100 |     100 |                   
  ...ak-to-user.ts |   96.66 |      100 |    87.5 |   96.66 | 37-38             
  ...task-tools.ts |   98.97 |      100 |   88.88 |   98.97 | 201-202           
 ...ration/service |    97.1 |    95.89 |   93.75 |    97.1 |                   
  filesystem.ts    |    97.1 |    95.89 |   93.75 |    97.1 | ...22-123,246-247 
 ...ration/session |    90.9 |    86.48 |   95.67 |    90.9 |                   
  Session.ts       |   90.27 |    85.23 |   95.03 |   90.27 | ...85,13212-13216 
  ...entTracker.ts |   96.88 |    89.36 |      90 |   96.88 | 139-145,224       
  ...projection.ts |   98.85 |    91.59 |     100 |   98.85 | 234,250,262       
  ...stop-guard.ts |     100 |    98.07 |     100 |     100 | 37,127            
  ...eplay-page.ts |   94.19 |    86.53 |     100 |   94.19 | ...53,357,437,441 
  ...y-replayer.ts |   83.41 |    93.33 |   94.11 |   83.41 | ...30-148,266-268 
  index.ts         |       0 |        0 |       0 |       0 | 1-40              
  ...ssionUtils.ts |   89.19 |     87.8 |     100 |   89.19 | ...85-304,363-365 
  ...oal-update.ts |   98.61 |    97.29 |     100 |   98.61 | 64                
  ...lure-guard.ts |   98.32 |    97.72 |     100 |   98.32 | 294-295,340-341   
  tasksSnapshot.ts |    94.3 |     87.5 |     100 |    94.3 | 65-71             
  ...on-tracker.ts |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...ssion/emitters |   95.65 |    92.34 |   97.14 |   95.65 |                   
  ...ageEmitter.ts |   95.36 |    92.42 |     100 |   95.36 | ...16,129-130,223 
  PlanEmitter.ts   |     100 |       90 |     100 |     100 | 66                
  base-emitter.ts  |   78.26 |    77.77 |     100 |   78.26 | 23-24,26-28       
  index.ts         |       0 |        0 |       0 |       0 | 1-10              
  ...ll-emitter.ts |   98.57 |    94.84 |     100 |   98.57 | 75-76,394-395     
 ...ession/rewrite |   96.03 |    89.79 |   94.44 |   96.03 |                   
  LlmRewriter.ts   |   94.01 |    88.23 |     100 |   94.01 | 101-102,179-183   
  ...Middleware.ts |   96.99 |    88.37 |     100 |   96.99 | 145,153-155       
  TurnBuffer.ts    |     100 |      100 |     100 |     100 |                   
  config.ts        |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 src/agent-view    |   86.63 |     80.8 |   94.01 |   86.63 |                   
  attach-lease.ts  |     100 |    97.05 |     100 |     100 | 173               
  ...t-cli-argv.ts |     100 |     92.3 |     100 |     100 | 15                
  ...ged-detach.ts |     100 |     90.9 |     100 |     100 | 40,64             
  presentation.ts  |   94.13 |    88.72 |   94.73 |   94.13 | ...57-358,382-384 
  protocol.ts      |     100 |      100 |     100 |     100 |                   
  pty-host-env.ts  |     100 |      100 |     100 |     100 |                   
  ...st-process.ts |   88.43 |    78.79 |   94.44 |   88.43 | ...1294,1384-1386 
  pty-host.ts      |   85.25 |    87.03 |   90.69 |   85.25 | ...22-524,539-540 
  ...sor-client.ts |   80.38 |    72.81 |   77.41 |   80.38 | ...22-626,652-656 
  ...r-dispatch.ts |      98 |    85.18 |     100 |      98 | 117,173,190       
  ...or-process.ts |    83.5 |     77.3 |   98.72 |    83.5 | ...4479-4482,4485 
  ...sor-runner.ts |   82.43 |    76.82 |   80.95 |   82.43 | ...69,493,496-506 
  ...sor-server.ts |   84.39 |    83.56 |    93.1 |   84.39 | ...67-568,571-588 
  ...isor-store.ts |   94.76 |    84.95 |     100 |   94.76 | ...,966,1008,1023 
  ...nal-bridge.ts |   93.98 |    91.54 |   83.33 |   93.98 | 228-238           
  ...r-sideband.ts |   94.91 |    89.36 |     100 |   94.91 | ...75-276,299-304 
 src/commands      |   90.69 |    78.53 |   65.62 |   90.69 |                   
  auth.ts          |     100 |    83.33 |     100 |     100 | 11,14             
  channel.ts       |   55.55 |      100 |       0 |   55.55 | 18-22,30-40       
  extensions.tsx   |   96.77 |      100 |      50 |   96.77 | 39                
  hooks.tsx        |   66.66 |      100 |       0 |   66.66 | 20-24             
  mcp.ts           |   95.45 |      100 |      50 |   95.45 | 31                
  review.ts        |    98.9 |      100 |      50 |    98.9 | 102               
  serve.ts         |   89.46 |    76.02 |     100 |   89.46 | ...12-915,927,938 
  sessions.ts      |     100 |      100 |      50 |     100 |                   
  update.ts        |   98.13 |    94.44 |   66.66 |   98.13 | 82-83             
 ...mmands/channel |   89.55 |    88.77 |   90.68 |   89.55 |                   
  channel-cwd.ts   |     100 |      100 |     100 |     100 |                   
  ...l-registry.ts |   94.78 |    94.59 |      90 |   94.78 | ...32-335,380-383 
  ...entry-path.ts |      75 |       50 |     100 |      75 | 8-9               
  config-utils.ts  |   96.84 |    96.22 |     100 |   96.84 | ...40-245,303-306 
  configure.ts     |    14.7 |      100 |       0 |    14.7 | 18-21,23-84       
  daemon-worker.ts |   94.07 |    86.01 |   94.33 |   94.07 | ...1292,1299-1300 
  loop-runtime.ts  |   91.66 |      100 |      50 |   91.66 | 15,22             
  ...classifier.ts |   98.53 |    96.66 |     100 |   98.53 | 115-116,161       
  ...tact-store.ts |   93.51 |    87.65 |     100 |   93.51 | ...71,288-289,337 
  pairing.ts       |      75 |      100 |      50 |      75 | 22-28,59-70       
  pidfile.ts       |   95.55 |       90 |     100 |   95.55 | ...50-251,315-316 
  proxy.ts         |     100 |      100 |     100 |     100 |                   
  reload.ts        |    77.5 |    86.95 |      75 |    77.5 | 72-84,93-97       
  runtime.ts       |   82.43 |    86.44 |     100 |   82.43 | ...87-191,251-253 
  set.ts           |   75.72 |    85.71 |      50 |   75.72 | 65-83,111-116     
  start.ts         |    87.7 |    83.63 |      88 |    87.7 | ...95,601-604,616 
  ...ure-format.ts |   93.65 |    82.45 |     100 |   93.65 | ...42,48-49,74-75 
  status.ts        |   78.57 |    59.25 |   66.66 |   78.57 | ...36-137,150-161 
  stop.ts          |   57.83 |    82.35 |      50 |   57.83 | ...3,74-76,85-111 
 ...nds/extensions |   88.85 |    87.91 |   87.09 |   88.85 |                   
  consent.ts       |   72.53 |    90.32 |   42.85 |   72.53 | ...86-142,157-163 
  disable.ts       |     100 |       90 |     100 |     100 | 30                
  enable.ts        |     100 |    91.66 |     100 |     100 | 38                
  install.ts       |   82.95 |    81.57 |      75 |   82.95 | ...96-199,202-211 
  link.ts          |     100 |      100 |     100 |     100 |                   
  list.ts          |     100 |     90.9 |     100 |     100 | 18                
  new.ts           |     100 |      100 |     100 |     100 |                   
  settings.ts      |   99.15 |      100 |   83.33 |   99.15 | 151               
  sources.ts       |   93.42 |    87.09 |   92.85 |   93.42 | ...4-66,96-98,167 
  uninstall.ts     |   74.57 |       40 |   66.66 |   74.57 | 45-47,60-67,70-73 
  update.ts        |   96.71 |    97.05 |     100 |   96.71 | 114-118           
  utils.ts         |   75.63 |    57.14 |     100 |   75.63 | ...30-134,136-140 
 ...les/mcp-server |       0 |        0 |       0 |       0 |                   
  example.ts       |       0 |        0 |       0 |       0 | 1-60              
 ...amples/starter |       0 |        0 |       0 |       0 |                   
  example.ts       |       0 |        0 |       0 |       0 | 1-64              
 src/commands/mcp  |   91.19 |    88.76 |   85.71 |   91.19 |                   
  add.ts           |    99.3 |    96.07 |     100 |    99.3 | 154-155           
  approve.ts       |   76.19 |     87.5 |   66.66 |   76.19 | ...,89-99,114-124 
  list.ts          |    92.9 |    84.84 |      80 |    92.9 | ...79-181,199-200 
  reconnect.ts     |   85.54 |    86.76 |    90.9 |   85.54 | 45-58,337-359     
  remove.ts        |     100 |       80 |     100 |     100 | 21-25             
 ...ommands/review |   91.93 |    90.42 |    93.8 |   91.93 |                   
  ab-drive.ts      |   85.22 |    90.47 |   94.11 |   85.22 | ...50-926,969-972 
  agent-prompt.ts  |   94.89 |    92.99 |   97.95 |   94.89 | ...3289,3624-3704 
  base-tree.ts     |   77.02 |    80.76 |   77.77 |   77.02 | ...63-384,386-399 
  capture-local.ts |   94.72 |    97.61 |   94.11 |   94.72 | 271,1336-1374     
  ...k-coverage.ts |   50.71 |       35 |   66.66 |   50.71 | ...40-245,279-289 
  cleanup.ts       |   92.34 |     89.5 |    90.9 |   92.34 | ...1107,1109-1110 
  comment-body.ts  |   67.85 |    87.09 |   66.66 |   67.85 | ...30,157,159-164 
  ...ent-status.ts |   94.22 |    87.32 |    90.9 |   94.22 | ...96,462,738-758 
  ...ose-review.ts |   97.37 |    94.02 |   98.73 |   97.37 | ...6486-6530,6790 
  cost-ledger.ts   |   94.58 |     94.4 |   81.25 |   94.58 | ...53-654,694-704 
  drive.ts         |   97.12 |    89.85 |     100 |   97.12 | ...83-985,990-992 
  extract-step.ts  |   91.36 |    90.62 |   88.88 |   91.36 | ...90-707,714-729 
  fetch-diff.ts    |   73.75 |      100 |   66.66 |   73.75 | 77-97             
  fetch-pr.ts      |   97.29 |    92.25 |     100 |   97.29 | ...1566,1724-1729 
  findings.ts      |    96.3 |    93.68 |     100 |    96.3 | ...1418,1427-1428 
  issue-context.ts |   88.15 |     93.1 |   85.71 |   88.15 | 249-276           
  load-rules.ts    |   26.41 |      100 |   16.66 |   26.41 | ...41-153,155-156 
  match-remote.ts  |   85.55 |     92.3 |   66.66 |   85.55 | 74-79,144-150     
  meta.ts          |   79.43 |    93.75 |   66.66 |   79.43 | 123-128,147-162   
  mock-provider.ts |   95.44 |    90.25 |   89.47 |   95.44 | 145,690-709       
  parse-args.ts    |   99.48 |    95.74 |     100 |   99.48 | 665,990,1046,1082 
  plan-diff.ts     |   71.42 |      100 |   66.66 |   71.42 | 162-197           
  pr-context.ts    |   96.22 |    88.86 |     100 |   96.22 | ...2580,2681-2697 
  presubmit.ts     |   94.32 |    90.83 |   94.11 |   94.32 | ...1219,1254-1285 
  ...ish-assets.ts |    81.3 |    82.22 |   85.71 |    81.3 | ...75-479,506-552 
  ...r-findings.ts |   90.74 |    83.75 |     100 |   90.74 | ...17-422,429-430 
  repo-context.ts  |   94.62 |    90.75 |     100 |   94.62 | ...66-467,482-487 
  ...ve-anchors.ts |   78.34 |    89.28 |      75 |   78.34 | ...83-188,200-217 
  revert-hunk.ts   |   91.48 |    87.94 |     100 |   91.48 | ...1189,1236-1239 
  run.ts           |   84.47 |    87.58 |   95.45 |   84.47 | ...00,816-870,884 
  save-artifact.ts |    94.2 |    92.46 |   94.11 |    94.2 | ...14-617,710-713 
  scratch-tree.ts  |   95.93 |       86 |     100 |   95.93 | ...91-392,461-464 
  script-lint.ts   |   81.27 |    79.38 |   88.88 |   81.27 | ...69-783,785-807 
  submit.ts        |   94.21 |       89 |   94.44 |   94.21 | ...1710,1738-1775 
  test-delta.ts    |   95.75 |     92.3 |      75 |   95.75 | 470-478           
  test-efficacy.ts |   84.03 |    80.48 |   96.07 |   84.03 | ...3249,3257-3277 
  test-plan.ts     |   94.61 |    91.79 |      95 |   94.61 | ...29-832,873-874 
 ...w/__fixtures__ |     100 |      100 |     100 |     100 |                   
  ...r-default.mjs |     100 |      100 |     100 |     100 |                   
  ...der-empty.mjs |     100 |      100 |     100 |     100 |                   
  ...der-named.mjs |     100 |      100 |     100 |     100 |                   
 ...nds/review/lib |   97.37 |    94.75 |   98.68 |   97.37 |                   
  agent-briefs.ts  |   99.08 |      100 |      50 |   99.08 | 841-842           
  ...t-identity.ts |     100 |      100 |     100 |     100 |                   
  anchors.ts       |     100 |    97.04 |     100 |     100 | ...39,175,184,231 
  assets.ts        |     100 |      100 |     100 |     100 |                   
  audit-layers.ts  |   98.67 |    96.15 |     100 |   98.67 | 288-290           
  authorization.ts |    96.5 |    95.61 |     100 |    96.5 | ...54-255,629-630 
  budget.ts        |     100 |    97.95 |     100 |     100 | 887,940           
  build-budget.ts  |     100 |      100 |     100 |     100 |                   
  certification.ts |     100 |      100 |     100 |     100 |                   
  convergence.ts   |     100 |    97.94 |    92.3 |     100 | 52,515,620,716    
  coverage.ts      |   98.97 |    95.11 |     100 |   98.97 | ...1103,1648-1649 
  deadline.ts      |   98.03 |    91.66 |     100 |   98.03 | ...20,752,820,837 
  diff-flags.ts    |     100 |        0 |     100 |     100 | 75                
  diff-plan.ts     |   99.29 |    95.79 |     100 |   99.29 | 295-296,319       
  disk.ts          |     100 |      100 |     100 |     100 |                   
  effort.ts        |     100 |      100 |     100 |     100 |                   
  failing-files.ts |     100 |    93.33 |     100 |     100 | 41                
  gh.ts            |   89.53 |    95.52 |   78.94 |   89.53 | ...47,384-385,412 
  git.ts           |   96.92 |    94.11 |     100 |   96.92 | 264-265,302-303   
  heavy.ts         |     100 |      100 |     100 |     100 |                   
  import-graph.ts  |   96.68 |     95.6 |     100 |   96.68 | 180-182,211-212   
  ...ntal-scope.ts |     100 |      100 |     100 |     100 |                   
  inline-counts.ts |     100 |      100 |     100 |     100 |                   
  ...audit-gate.ts |     100 |     97.5 |     100 |     100 | 135               
  ledger.ts        |     100 |    99.45 |     100 |     100 | 828               
  local-anchor.ts  |   93.78 |    88.75 |     100 |   93.78 | ...61,594-595,745 
  local-diff.ts    |   86.77 |    94.28 |     100 |   86.77 | ...54-564,566-574 
  ...ry-context.ts |   96.61 |    95.48 |     100 |   96.61 | ...47-450,496-499 
  md-field.ts      |     100 |      100 |     100 |     100 |                   
  merge-base.ts    |     100 |      100 |     100 |     100 |                   
  narrow-diff.ts   |     100 |      100 |     100 |     100 |                   
  npm-toolchain.ts |   98.23 |    95.29 |     100 |   98.23 | ...,822,1203,1220 
  path-rules.ts    |     100 |      100 |     100 |     100 |                   
  paths.ts         |   98.05 |    88.57 |     100 |   98.05 | 33-34             
  prompt-record.ts |   98.03 |    94.23 |     100 |   98.03 | 293-294,300       
  receipt.ts       |     100 |      100 |     100 |     100 |                   
  remote-match.ts  |   98.03 |    94.73 |     100 |   98.03 | 109-110           
  report.ts        |   92.92 |    86.66 |     100 |   92.92 | 213-214,216-220   
  ...ry-context.ts |     100 |    98.66 |     100 |     100 | 187               
  resume.ts        |     100 |      100 |     100 |     100 |                   
  retirement.ts    |     100 |    94.36 |     100 |     100 | ...58-559,760,917 
  review-footer.ts |   99.55 |    98.09 |     100 |   99.55 | 548-549           
  ...w-settings.ts |     100 |    96.42 |     100 |     100 | 99                
  roster.ts        |     100 |    97.14 |     100 |     100 | 177,222           
  round-model.ts   |     100 |      100 |     100 |     100 |                   
  run-ledger.ts    |    98.2 |    93.87 |     100 |    98.2 | ...23,541,647,670 
  same-file.ts     |     100 |       95 |     100 |     100 | 36                
  ...boxed-exec.ts |   94.26 |    89.32 |   95.65 |   94.26 | ...49-550,728-729 
  shell-quote.ts   |     100 |      100 |     100 |     100 |                   
  stale-bundle.ts  |   98.18 |    94.38 |     100 |   98.18 | 431,472,512-513   
  test-utils.ts    |   99.04 |    91.66 |     100 |   99.04 | 75                
  toolchain.ts     |     100 |      100 |     100 |     100 |                   
  transcripts.ts   |   98.09 |    95.07 |     100 |   98.09 | ...92,438,707-708 
  ...pace-scope.ts |     100 |    96.96 |     100 |     100 | 186               
  workspaces.ts    |     100 |    96.85 |     100 |     100 | 222,452,499,512   
  ...ree-reader.ts |     100 |      100 |     100 |     100 |                   
  worktree.ts      |   89.39 |    81.78 |     100 |   89.39 | ...1813-1814,1827 
 ...w/lib/platform |   94.71 |    87.89 |   97.05 |   94.71 |                   
  aone-client.ts   |   94.94 |     87.3 |     100 |   94.94 | ...92-293,299-302 
  aone.ts          |   93.06 |    89.86 |   94.73 |   93.06 | ...34,598-603,655 
  github.ts        |   99.08 |     75.8 |     100 |   99.08 | 249-250           
  registry.ts      |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...mands/sessions |   94.11 |    89.06 |   89.47 |   94.11 |                   
  common.ts        |     100 |      100 |     100 |     100 |                   
  list.ts          |   90.96 |    86.66 |   81.81 |   90.96 | 208-219,221-222   
  ps.ts            |     100 |    94.44 |     100 |     100 | 58                
 src/config        |   94.26 |    90.56 |   95.02 |   94.26 |                   
  ...l-fallback.ts |     100 |      100 |     100 |     100 |                   
  auth.ts          |   93.36 |    88.37 |     100 |   93.36 | ...06-307,330-331 
  ...eMcpImport.ts |   87.91 |    81.52 |     100 |   87.91 | ...63-371,453-454 
  compile-cache.ts |     100 |      100 |     100 |     100 |                   
  config.ts        |   89.62 |    91.05 |   83.78 |   89.62 | ...2515,2517-2525 
  ...cy-monitor.ts |      90 |    77.27 |     100 |      90 | ...72-73,90-92,98 
  ...ust-policy.ts |   83.02 |    88.88 |     100 |   83.02 | ...02-209,232-240 
  ...heme-names.ts |     100 |      100 |     100 |     100 |                   
  ...ScopeUtils.ts |   97.56 |    88.88 |     100 |   97.56 | 67                
  environment.ts   |   94.51 |    92.55 |   95.23 |   94.51 | ...24-625,679-680 
  ...le-watcher.ts |   90.86 |    83.65 |   95.83 |   90.86 | ...23-325,370,418 
  ...resh-state.ts |   90.57 |    97.29 |   93.75 |   90.57 | 137-142,146-152   
  ...ime-reload.ts |     100 |    69.69 |     100 |     100 | ...12-113,122-123 
  hot-reload.ts    |     100 |    89.13 |     100 |     100 | 47,172-178,238    
  keyBindings.ts   |    97.4 |       50 |     100 |    97.4 | 240-243           
  ...ngsAdapter.ts |     100 |    94.11 |     100 |     100 | 64                
  ...ig-watcher.ts |   95.17 |    83.05 |     100 |   95.17 | ...78,200,292-293 
  ...er-secrets.ts |   98.97 |    96.87 |     100 |   98.97 | 85                
  mcpApprovals.ts  |   78.57 |       92 |   86.66 |   78.57 | ...18-319,324-326 
  mcpJson.ts       |     100 |      100 |     100 |     100 |                   
  mcpServers.ts    |   92.85 |     87.5 |     100 |   92.85 | 46-47             
  ...idersScope.ts |      95 |    94.73 |     100 |      95 | 11-12             
  ...abledTools.ts |     100 |      100 |     100 |     100 |                   
  ...comparison.ts |     100 |      100 |     100 |     100 |                   
  ...n-settings.ts |   99.15 |    93.93 |     100 |   99.15 | 63                
  sandboxConfig.ts |   93.33 |    93.33 |     100 |   93.33 | ...42-147,216-217 
  session-id.ts    |     100 |      100 |     100 |     100 |                   
  ...ings-cache.ts |   96.52 |    93.93 |     100 |   96.52 | 90-91,201-202     
  settings.ts      |   91.16 |    93.02 |      90 |   91.16 | ...1026,1028-1029 
  ...ingsSchema.ts |     100 |      100 |     100 |     100 |                   
  settingsUtils.ts |   80.92 |     89.2 |   85.18 |   80.92 | ...87-605,612-620 
  ...ngsWatcher.ts |   95.54 |    88.34 |     100 |   95.54 | ...28,277-278,293 
  ...d-env-keys.ts |     100 |      100 |     100 |     100 |                   
  ...l-settings.ts |     100 |      100 |     100 |     100 |                   
  ...paths-lite.ts |   89.47 |       88 |     100 |   89.47 | 43-44,53-54,56-57 
  ...precedence.ts |   98.79 |     92.3 |     100 |   98.79 | 62                
  ...tedFolders.ts |   92.53 |    93.54 |     100 |   92.53 | ...36-337,373-384 
 ...nfig/migration |   95.23 |    78.94 |   85.71 |   95.23 |                   
  index.ts         |   95.65 |     87.5 |     100 |   95.65 | 117-118           
  scheduler.ts     |   96.55 |       80 |     100 |   96.55 | 19-20             
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 ...ation/versions |   94.91 |      100 |     100 |   94.91 |                   
  ...-v2-shared.ts |     100 |      100 |     100 |     100 |                   
  v1-to-v2.ts      |   81.75 |      100 |     100 |   81.75 | ...28-229,231-247 
  v2-to-v3.ts      |     100 |      100 |     100 |     100 |                   
  v3-to-v4.ts      |     100 |      100 |     100 |     100 |                   
  v5-to-v4.ts      |      96 |      100 |     100 |      96 | 94-95,99          
 src/core          |     100 |      100 |     100 |     100 |                   
  auth.ts          |     100 |      100 |     100 |     100 |                   
  initializer.ts   |     100 |      100 |     100 |     100 |                   
  theme.ts         |     100 |      100 |     100 |     100 |                   
 src/dualOutput    |   75.08 |    67.64 |   71.42 |   75.08 |                   
  ...tputBridge.ts |   75.33 |    68.18 |   73.68 |   75.33 | ...09-410,418-421 
  ...utContext.tsx |     100 |      100 |     100 |     100 |                   
  index.ts         |       0 |        0 |       0 |       0 | 1-8               
 src/export        |       0 |        0 |       0 |       0 |                   
  index.ts         |       0 |        0 |       0 |       0 | 1-7               
 src/generated     |     100 |      100 |     100 |     100 |                   
  git-commit.ts    |     100 |      100 |     100 |     100 |                   
 src/hooks         |     100 |      100 |     100 |     100 |                   
  ...elete-hook.ts |     100 |      100 |     100 |     100 |                   
 src/i18n          |   89.68 |    88.66 |   93.02 |   89.68 |                   
  index.ts         |   73.45 |    77.77 |      90 |   73.45 | ...70-271,294-299 
  languageUtils.ts |   98.88 |    97.01 |     100 |   98.88 | 184-185           
  languages.ts     |   93.07 |     92.3 |   85.71 |   93.07 | ...35,164-169,184 
  ...nslateKeys.ts |     100 |      100 |     100 |     100 |                   
  ...lationDict.ts |   93.33 |    66.66 |     100 |   93.33 | 15                
 src/i18n/locales  |     100 |      100 |     100 |     100 |                   
  ca.js            |     100 |      100 |     100 |     100 |                   
  de.js            |     100 |      100 |     100 |     100 |                   
  en.js            |     100 |      100 |     100 |     100 |                   
  fr.js            |     100 |      100 |     100 |     100 |                   
  ja.js            |     100 |      100 |     100 |     100 |                   
  pt.js            |     100 |      100 |     100 |     100 |                   
  ru.js            |     100 |      100 |     100 |     100 |                   
  zh-TW.js         |     100 |      100 |     100 |     100 |                   
  zh.js            |     100 |      100 |     100 |     100 |                   
 ...nonInteractive |   87.37 |    83.73 |   89.32 |   87.37 |                   
  ...ng-failure.ts |     100 |      100 |     100 |     100 |                   
  ...iveHelpers.ts |   94.95 |    91.05 |     100 |   94.95 | ...30-431,529,542 
  ...uggestions.ts |   84.29 |    70.83 |     100 |   84.29 | 70-76,92-103      
  session.ts       |   84.97 |    76.31 |   96.07 |   84.97 | ...1048,1057-1067 
  ...iagnostics.ts |    95.8 |     87.5 |   93.75 |    95.8 | ...03,277-278,289 
  types.ts         |    42.5 |      100 |   33.33 |    42.5 | ...33-634,637-638 
 ...active/control |   75.54 |    89.83 |      80 |   75.54 |                   
  ...rolContext.ts |    6.06 |        0 |       0 |    6.06 | 57-99             
  ...Dispatcher.ts |   91.95 |    92.98 |   88.88 |   91.95 | ...54-372,392,395 
  ...rolService.ts |    6.89 |        0 |       0 |    6.89 | 46-188            
 ...ol/controllers |   57.47 |     66.3 |   73.68 |   57.47 |                   
  ...Controller.ts |    42.4 |      100 |   83.33 |    42.4 | 101-105,140-223   
  ...Controller.ts |       0 |        0 |       0 |       0 | 1-56              
  ...Controller.ts |   70.04 |    62.92 |   91.66 |   70.04 | ...11-620,635-640 
  ...Controller.ts |   49.23 |       60 |      50 |   49.23 | ...07-108,111-121 
  ...Controller.ts |   53.96 |    67.08 |   66.66 |   53.96 | ...78-690,699-728 
 .../control/types |       0 |        0 |       0 |       0 |                   
  serviceAPIs.ts   |       0 |        0 |       0 |       0 | 1                 
 ...Interactive/io |   98.18 |    94.11 |   95.34 |   98.18 |                   
  ...putAdapter.ts |   98.07 |    93.21 |   98.11 |   98.07 | ...1448,1464-1465 
  ...putAdapter.ts |   96.22 |    91.66 |   85.71 |   96.22 | 52-53             
  ...nputReader.ts |     100 |    94.73 |     100 |     100 | 67                
  ...putAdapter.ts |   98.51 |      100 |   90.47 |   98.51 | 90-91,131-132     
  ...projection.ts |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
 src/patches       |       0 |        0 |       0 |       0 |                   
  is-in-ci.ts      |       0 |        0 |       0 |       0 | 1-17              
 src/peerMessaging |   90.64 |    85.29 |      96 |   90.64 |                   
  ...ngContext.tsx |     100 |      100 |     100 |     100 |                   
  ...-messaging.ts |   90.45 |    85.07 |   95.83 |   90.45 | ...01-306,347-352 
 src/remoteInput   |   87.31 |    75.32 |   88.23 |   87.31 |                   
  ...utContext.tsx |     100 |      100 |     100 |     100 |                   
  ...putWatcher.ts |   88.01 |       76 |   93.33 |   88.01 | ...49-350,361-364 
  index.ts         |       0 |        0 |       0 |       0 | 1-8               
 src/runtime       |    99.7 |    96.32 |     100 |    99.7 |                   
  ...livery-ipc.ts |     100 |    91.17 |     100 |     100 | 94,106,134        
  ...l-delivery.ts |     100 |      100 |     100 |     100 |                   
  cpu-percent.ts   |     100 |      100 |     100 |     100 |                   
  ...ion-source.ts |     100 |      100 |     100 |     100 |                   
  ...erver-name.ts |     100 |      100 |     100 |     100 |                   
  ...-constants.ts |     100 |      100 |     100 |     100 |                   
  ...-summaries.ts |   86.66 |       50 |     100 |   86.66 | 11,19             
  ...ber-errors.ts |     100 |    95.32 |     100 |     100 | 53,93-94,172,192  
  ...ls-mapping.ts |     100 |      100 |     100 |     100 |                   
 src/serve         |   87.42 |    84.98 |   90.73 |   87.42 |                   
  ...extra-args.ts |     100 |      100 |     100 |     100 |                   
  ...tp-enabled.ts |     100 |      100 |     100 |     100 |                   
  ...ion-bridge.ts |     100 |      100 |     100 |     100 |                   
  auth.ts          |   93.99 |     91.5 |     100 |   93.99 | ...29-430,433-435 
  ...em-adapter.ts |     100 |      100 |     100 |     100 |                   
  capabilities.ts  |     100 |    98.18 |     100 |     100 | 717               
  ...cp-command.ts |     100 |      100 |     100 |     100 |                   
  ...horization.ts |   92.79 |    93.54 |    87.5 |   92.79 | 75-80,135-136     
  ...op-mcp-ipc.ts |   81.06 |    73.68 |   94.11 |   81.06 | ...37-242,267,289 
  ...nt-service.ts |    94.1 |    86.98 |     100 |    94.1 | ...75-477,484,486 
  ...-selection.ts |     100 |      100 |     100 |     100 |                   
  ...ings-store.ts |   89.61 |    94.37 |   96.55 |   89.61 | ...64-276,528-531 
  ...ebhook-ipc.ts |    98.5 |     87.5 |     100 |    98.5 | 47                
  ...iagnostics.ts |     100 |      100 |     100 |     100 |                   
  ...worker-env.ts |     100 |      100 |     100 |     100 |                   
  ...rker-group.ts |   87.32 |    85.33 |     100 |   87.32 | ...14,820-824,842 
  ...er-manager.ts |   89.39 |    83.88 |   93.33 |   89.39 | ...98,711,722-724 
  ...horization.ts |     100 |      100 |     100 |     100 |                   
  ...tartup-ipc.ts |   97.72 |    96.66 |     100 |   97.72 | 88-89             
  ...supervisor.ts |   93.24 |    85.42 |    97.4 |   93.24 | ...1765,1819-1823 
  ...e-grouping.ts |     100 |    94.28 |     100 |     100 | 71,137            
  core-runtime.ts  |     100 |      100 |     100 |     100 |                   
  ...ub-session.ts |   90.75 |    80.47 |   94.73 |   90.75 | ...1091,1112-1117 
  ...tree-guard.ts |   93.87 |    89.81 |     100 |   93.87 | ...3227,3297-3301 
  daemon-logger.ts |   82.82 |    78.68 |   92.04 |   82.82 | ...1775,1802-1808 
  ...y-pressure.ts |     100 |    96.96 |     100 |     100 | 135               
  ...trics-ring.ts |     100 |      100 |     100 |     100 |                   
  ...s-provider.ts |   68.04 |    52.77 |     100 |   68.04 | ...44-249,282-290 
  daemon-status.ts |   98.69 |    91.96 |     100 |   98.69 | ...1590,1592-1593 
  debug-mode.ts    |     100 |      100 |     100 |     100 |                   
  env-snapshot.ts  |   93.37 |    85.18 |     100 |   93.37 | 114-117,195-202   
  ...-scheduler.ts |   87.34 |    83.87 |     100 |   87.34 | 33-36,48-50,79-81 
  ...d-provider.ts |   92.06 |    87.09 |     100 |   92.06 | ...72,287-293,316 
  ...h-settings.ts |   94.94 |    90.45 |     100 |   94.94 | ...30,708,724,734 
  fast-path.ts     |   91.38 |       82 |   95.45 |   91.38 | ...46-555,633-634 
  ...ration-sse.ts |   42.55 |    33.33 |     100 |   42.55 | 23-24,30,33-56    
  health-query.ts  |     100 |      100 |     100 |     100 |                   
  index.ts         |       0 |        0 |       0 |       0 | 1-149             
  ...e-observer.ts |   89.89 |    83.24 |      96 |   89.89 | ...11-512,541-543 
  ...back-binds.ts |     100 |    88.88 |     100 |     100 | 32                
  ...-workspace.ts |   91.58 |    86.48 |     100 |   91.58 | ...44-145,156-157 
  ...pp-sandbox.ts |   96.72 |    95.23 |     100 |   96.72 | 41-42             
  ...iders-edit.ts |     100 |    82.14 |     100 |     100 | 58-60,65,81       
  ...ory-picker.ts |     100 |    86.95 |     100 |     100 | 36,66,92          
  ...-with-auth.ts |     100 |      100 |     100 |     100 |                   
  ...ate-blocks.ts |   99.03 |    94.73 |     100 |   99.03 | 133               
  ...sion-audit.ts |     100 |      100 |   93.33 |     100 |                   
  ...nal-ledger.ts |    94.9 |    84.78 |     100 |    94.9 | ...81,302,361-362 
  rate-limit.ts    |   92.68 |    88.29 |     100 |   92.68 | ...89-291,303-305 
  ...qwen-serve.ts |   84.69 |    81.44 |   76.99 |   84.69 | ...9116,9134-9138 
  ...tup-errors.ts |     100 |      100 |     100 |     100 |                   
  sandbox.ts       |   45.52 |    59.42 |   76.92 |   45.52 | ...1050,1062-1085 
  ...-keepalive.ts |   94.31 |    88.28 |     100 |   94.31 | ...37,541-542,581 
  ...-lifecycle.ts |     100 |      100 |     100 |     100 |                   
  ...-lifecycle.ts |   89.16 |    90.29 |   86.95 |   89.16 | ...24-325,330-334 
  serve-token.ts   |     100 |      100 |     100 |     100 |                   
  server.ts        |   89.07 |    91.03 |   70.31 |   89.07 | ...3165,3196-3197 
  ...-admission.ts |   99.13 |    95.94 |     100 |   99.13 | 308-309           
  ...on-helpers.ts |     100 |      100 |     100 |     100 |                   
  ...-redaction.ts |     100 |      100 |     100 |     100 |                   
  ...t-event-id.ts |     100 |    95.23 |     100 |     100 | 12                
  ...-admission.ts |   98.71 |    89.65 |     100 |   98.71 | 68                
  types.ts         |     100 |      100 |     100 |     100 |                   
  ...ion-limits.ts |     100 |      100 |     100 |     100 |                   
  ...t-sessions.ts |   93.72 |    77.93 |     100 |   93.72 | ...51,854,867-869 
  ...l-resolver.ts |   90.32 |    66.66 |     100 |   90.32 | 16,45-46          
  ...ell-static.ts |   93.45 |    86.88 |     100 |   93.45 | ...77-280,323-326 
  ...ace-agents.ts |   66.13 |    70.57 |   92.68 |   66.13 | ...2246,2256-2266 
  ...generation.ts |    95.4 |    82.35 |   66.66 |    95.4 | 55-56,78,92       
  ...-git-state.ts |     100 |    91.93 |    90.9 |     100 | 161,172,202,265   
  ...ace-inputs.ts |     100 |      100 |     100 |     100 |                   
  ...ace-memory.ts |      83 |    74.54 |     100 |      83 | ...30-537,597-604 
  ...ers-status.ts |   98.63 |       80 |     100 |   98.63 | 108,136,186,189   
  ...tion-store.ts |   89.67 |    88.27 |   92.59 |   89.67 | ...91-400,411-414 
  ...e-registry.ts |   94.09 |    90.57 |     100 |   94.09 | ...90-591,598-599 
  ...e-remember.ts |   98.23 |    92.56 |     100 |   98.23 | ...36,340-345,386 
  ...te-runtime.ts |   89.88 |     90.9 |     100 |   89.88 | ...05-206,274-295 
  ...me-storage.ts |     100 |      100 |     100 |     100 |                   
  ...visibility.ts |     100 |      100 |     100 |     100 |                   
  ...management.ts |   72.63 |    72.83 |   96.15 |   72.63 | ...88-889,896-900 
  ...lls-status.ts |     100 |    95.45 |     100 |     100 | 152               
  ...reconciler.ts |   91.63 |    84.09 |     100 |   91.63 | ...71-273,306-307 
 ...serve/acp-http |    80.4 |    80.03 |   94.53 |    80.4 |                   
  ...r-registry.ts |   96.92 |    94.87 |     100 |   96.92 | 184-187           
  client-mcp-ws.ts |   54.85 |    58.62 |   72.72 |   54.85 | ...99-300,304-305 
  ...n-registry.ts |   93.03 |    84.13 |   98.52 |   93.03 | ...1624,1671-1682 
  dispatch.ts      |   75.71 |    76.82 |   93.44 |   75.71 | ...5649,5706-5712 
  index.ts         |   82.81 |    79.92 |   91.22 |   82.81 | ...2434,2520-2521 
  json-rpc.ts      |     100 |    96.96 |     100 |     100 | 92                
  ...ach-budget.ts |     100 |      100 |     100 |     100 |                   
  safe-ws-send.ts  |   52.94 |    71.42 |     100 |   52.94 | 33-42,47-55       
  sse-stream.ts    |   98.26 |    88.75 |     100 |   98.26 | 87-88,117         
  ...ort-stream.ts |       0 |        0 |       0 |       0 | 1                 
  ws-stream.ts     |   94.06 |    89.09 |     100 |   94.06 | 50,55,134,138-141 
 src/serve/auth    |   86.86 |     79.7 |   93.87 |   86.86 |                   
  device-flow.ts   |   96.35 |    80.57 |   97.61 |   96.35 | ...1358,1453,1519 
  ...w-provider.ts |   44.24 |    74.07 |   71.42 |   44.24 | ...23-284,297,301 
 ...rve/cdp-tunnel |   87.73 |    76.21 |    97.5 |   87.73 |                   
  ...r-emulator.ts |   93.27 |    77.77 |     100 |   93.27 | ...53-256,282-283 
  ...verse-link.ts |      88 |    76.19 |     100 |      88 | ...28-329,420-423 
  ...l-registry.ts |     100 |      100 |     100 |     100 |                   
  cdp-ws.ts        |   76.28 |    61.29 |    87.5 |   76.28 | ...13-217,223-228 
 ...nel/acceptance |    6.12 |    57.89 |   46.15 |    6.12 |                   
  ...helpers.d.mts |       0 |        0 |       0 |       0 | 1                 
  ...e-helpers.mjs |   97.64 |    70.96 |     100 |   97.64 | 22-23             
  ...mcp-smoke.mjs |       0 |        0 |       0 |       0 | 1-124             
  ...cceptance.mjs |       0 |        0 |       0 |       0 | 1-473             
  ...re-server.mjs |       0 |        0 |       0 |       0 | 1-59              
  ...ols-smoke.mjs |       0 |        0 |       0 |       0 | 1-268             
  real-tab.mjs     |       0 |        0 |       0 |       0 | 1-218             
  ...al-chrome.mjs |       0 |        0 |       0 |       0 | 1-223             
 .../conversations |   86.32 |    78.72 |   93.33 |   86.32 |                   
  ...e-activity.ts |     100 |      100 |     100 |     100 |                   
  ...ime-errors.ts |     100 |      100 |     100 |     100 |                   
  ...me-manager.ts |   97.88 |    94.91 |     100 |   97.88 | 64-65,92          
  ...-ownership.ts |   87.33 |    83.58 |   88.46 |   87.33 | ...57-558,601-602 
  ...-workspace.ts |   89.21 |    76.37 |     100 |   89.21 | ...52-554,568-572 
  ...on-journal.ts |   91.69 |    80.86 |     100 |   91.69 | ...46-747,753-755 
  ...on-service.ts |   83.22 |    75.11 |   89.01 |   83.22 | ...3014,3023-3025 
 src/serve/fs      |   87.77 |    82.34 |     100 |   87.77 |                   
  audit.ts         |     100 |    96.29 |     100 |     100 | 211               
  errors.ts        |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...x-registry.ts |     100 |      100 |     100 |     100 |                   
  paths.ts         |   77.64 |    74.01 |     100 |   77.64 | ...65,594-598,611 
  policy.ts        |   90.52 |    89.18 |     100 |   90.52 | 172-180           
  text-cursor.ts   |   88.23 |       90 |     100 |   88.23 | 74-77,92-95       
  ...ile-system.ts |   88.02 |    81.85 |     100 |   88.02 | ...3027,3037-3038 
 src/serve/live    |    76.6 |    70.53 |    90.2 |    76.6 |                   
  discovery.ts     |   85.89 |    82.05 |    91.3 |   85.89 | ...73-579,592-593 
  ...oordinator.ts |   82.67 |    76.63 |   97.01 |   82.67 | ...1319,1351-1353 
  ...-installer.ts |    64.3 |    82.35 |   80.76 |    64.3 | ...45-446,460-472 
  ...oordinator.ts |    76.7 |    67.47 |   85.71 |    76.7 | ...1885,1976-1977 
  ...controller.ts |   67.82 |    79.66 |      75 |   67.82 | ...66-278,287-295 
  ...sk-service.ts |   82.71 |    66.15 |   93.61 |   82.71 | ...1270,1283,1290 
  ...redentials.ts |   96.26 |    93.47 |     100 |   96.26 | 91-94             
  ...me-session.ts |   65.63 |    57.24 |   88.88 |   65.63 | ...2270,2275-2282 
  ...up-context.ts |   94.85 |    77.39 |     100 |   94.85 | ...18,327-330,350 
  types.ts         |     100 |      100 |     100 |     100 |                   
 .../local-control |   82.89 |    88.77 |      90 |   82.89 |                   
  credentials.ts   |   96.42 |    95.45 |     100 |   96.42 | 109-110           
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...interfaces.ts |   43.58 |    82.75 |   42.85 |   43.58 | ...09-117,130-142 
  ...r-identity.ts |     100 |    85.71 |     100 |     100 | 61                
  service.ts       |    93.4 |       90 |     100 |    93.4 | ...20-222,313-315 
 src/serve/routes  |   86.39 |    81.71 |   95.73 |   86.39 |                   
  a2ui-action.ts   |   96.84 |     88.5 |    87.5 |   96.84 | ...70-272,309-311 
  capabilities.ts  |   98.73 |    96.15 |     100 |   98.73 | 82                
  ...nel-notify.ts |   79.16 |    85.18 |     100 |   79.16 | ...03-104,120-126 
  ...l-webhooks.ts |   93.56 |    84.09 |     100 |   93.56 | ...42,292,332,334 
  daemon-status.ts |   85.71 |    83.33 |     100 |   85.71 | 101-108           
  goals.ts         |   98.94 |    91.17 |     100 |   98.94 | 143               
  health.ts        |   99.09 |    91.42 |     100 |   99.09 | 147               
  live-setup.ts    |   33.33 |     37.5 |      50 |   33.33 | ...18-123,130-135 
  live.ts          |   84.61 |    76.47 |     100 |   84.61 | ...04,106-111,131 
  permission.ts    |   96.03 |    87.87 |     100 |   96.03 | 81-84             
  ...uled-tasks.ts |   87.95 |    84.38 |   94.59 |   87.95 | ...1730,1775-1776 
  ...r-backfill.ts |   98.53 |    94.51 |     100 |   98.53 | ...48-249,616-617 
  ...on-runtime.ts |   91.42 |       90 |     100 |   91.42 | 56-64             
  session.ts       |   86.69 |    83.06 |    94.3 |   86.69 | ...7149,7151-7152 
  sse-events.ts    |   87.01 |    84.95 |   94.44 |   87.01 | ...40-951,954,961 
  ...e-sessions.ts |    86.9 |    80.57 |     100 |    86.9 | ...81-483,486-491 
  terminal.ts      |   92.81 |    90.35 |     100 |   92.81 | ...10-313,332-335 
  usage-stats.ts   |     100 |    95.45 |     100 |     100 | 118               
  ...space-auth.ts |   85.55 |    75.64 |     100 |   85.55 | ...21-326,331,345 
  ...el-control.ts |   86.26 |    78.94 |     100 |   86.26 | ...17-318,339-347 
  ...management.ts |   90.35 |    78.94 |     100 |   90.35 | ...52-553,576-577 
  ...d-contacts.ts |   83.62 |    94.59 |     100 |   83.62 | 123,125-142       
  ...controller.ts |   83.33 |    80.47 |      90 |   83.33 | ...1056,1061,1068 
  ...extensions.ts |    89.9 |    79.35 |   93.93 |    89.9 | ...2348,2393-2394 
  ...-file-read.ts |      91 |    80.91 |     100 |      91 | ...20-621,624-625 
  ...file-write.ts |   89.72 |    79.35 |     100 |   89.72 | ...05,719-726,807 
  ...t-branches.ts |   75.04 |     66.4 |     100 |   75.04 | ...99-604,613-620 
  ...e-git-diff.ts |   97.19 |    89.58 |     100 |   97.19 | 157-158,185-187   
  ...ce-git-log.ts |     100 |       95 |     100 |     100 | 48,73             
  workspace-git.ts |   74.71 |     87.5 |     100 |   74.71 | 83-104            
  ...github-prs.ts |   88.26 |    63.46 |     100 |   88.26 | ...38-239,264-265 
  ...-lifecycle.ts |   95.23 |    75.75 |     100 |   95.23 | ...50-151,186-187 
  ...al-control.ts |   74.17 |    69.23 |     100 |   74.17 | ...18,220-226,231 
  ...management.ts |   87.14 |    84.21 |     100 |   87.14 | ...1802,1812-1817 
  ...cp-control.ts |    73.2 |    67.54 |   85.71 |    73.2 | ...27-633,644-645 
  ...ace-models.ts |   95.53 |    89.74 |     100 |   95.53 | ...52-157,296-297 
  ...ermissions.ts |    77.9 |    72.41 |     100 |    77.9 | ...69-277,298-316 
  ...e-settings.ts |   75.67 |       75 |     100 |   75.67 | ...15-726,732-733 
  ...tup-github.ts |   77.97 |    70.58 |   84.21 |   77.97 | ...46-352,397-398 
  ...ace-skills.ts |   76.41 |    86.11 |     100 |   76.41 | ...29-354,360-394 
  ...ace-status.ts |   82.57 |    74.48 |     100 |   82.57 | ...71-473,477-478 
  ...pace-tools.ts |   75.94 |    69.69 |   66.66 |   75.94 | ...59-164,193-194 
  ...pace-trust.ts |   76.92 |     67.1 |      80 |   76.92 | ...38-343,351-352 
  ...pace-voice.ts |   91.33 |    81.02 |     100 |   91.33 | ...70-673,676-678 
 src/serve/server  |   93.06 |    91.22 |   97.39 |   93.06 |                   
  access-log.ts    |   98.73 |    97.26 |     100 |   98.73 | 119,196           
  ...-timestamp.ts |     100 |      100 |     100 |     100 |                   
  ...er-helpers.ts |   63.82 |    78.15 |   81.81 |   63.82 | ...16,330,332-347 
  ...w-registry.ts |    98.8 |    81.81 |     100 |    98.8 | 107               
  ...r-handlers.ts |   97.87 |       80 |     100 |   97.87 | 27                
  ...r-response.ts |   88.75 |    82.25 |     100 |   88.75 | ...61,878,941-950 
  fs-factory.ts    |     100 |    95.52 |     100 |     100 | 77,144,200        
  ...branch-ops.ts |     100 |      100 |     100 |     100 |                   
  ...list-cache.ts |   99.01 |    95.52 |     100 |   99.01 | 184-185           
  ...t-deadline.ts |     100 |      100 |     100 |     100 |                   
  ...iter-setup.ts |      65 |       80 |   33.33 |      65 | 30-35,38-43,47-48 
  ...st-helpers.ts |   95.13 |    95.14 |     100 |   95.13 | ...66-168,423-428 
  self-origin.ts   |   76.19 |       80 |     100 |   76.19 | 45-54             
  ...e-features.ts |   95.13 |     87.5 |     100 |   95.13 | 188-194           
  ...on-archive.ts |   91.29 |    89.33 |   97.61 |   91.29 | ...1133,1196-1197 
  ...ion-export.ts |   98.57 |    90.47 |     100 |   98.57 | 85                
  session-list.ts  |   97.27 |    93.89 |     100 |   97.27 | ...1183,1392-1396 
  ...pr-refresh.ts |   98.71 |    98.57 |     100 |   98.71 | 267-270           
  ...ry-context.ts |    87.5 |       50 |     100 |    87.5 | 49-50             
  telemetry.ts     |   99.06 |    97.26 |     100 |   99.06 | ...04,873,952-954 
 src/serve/voice   |    92.7 |    91.53 |   97.72 |    92.7 |                   
  ...ice-config.ts |   84.81 |       30 |     100 |   84.81 | 91-100,104-105    
  voice-ws.ts      |   91.58 |    93.44 |      96 |   91.58 | ...68,483,521-523 
  ...oordinator.ts |     100 |    98.24 |     100 |     100 | 176               
 ...kspace-service |   89.85 |    86.73 |    91.3 |   89.85 |                   
  index.ts         |   89.49 |    86.34 |      90 |   89.49 | ...1393-1397,1400 
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/services      |    92.7 |    89.68 |   98.13 |    92.7 |                   
  ...mandLoader.ts |     100 |       95 |     100 |     100 | 107               
  ...killLoader.ts |   97.19 |    85.71 |     100 |   97.19 | 142,153-154       
  ...andService.ts |   98.73 |      100 |     100 |   98.73 | 107               
  ...mandLoader.ts |   87.09 |    83.07 |     100 |   87.09 | ...35-340,345-350 
  ...omptLoader.ts |   79.55 |    88.42 |   85.71 |   79.55 | ...48,178,245-246 
  ...mandLoader.ts |   97.77 |    92.45 |     100 |   97.77 | 176,183-184       
  ...nd-factory.ts |   91.42 |    91.66 |     100 |   91.42 | 128,137-144       
  ...ation-tool.ts |     100 |    95.45 |     100 |     100 | 125               
  ...ndMetadata.ts |   98.23 |    96.72 |     100 |   98.23 | 83,87             
  commandUtils.ts  |      96 |     90.9 |     100 |      96 | 48                
  ...and-parser.ts |   90.69 |    85.71 |     100 |   90.69 | 63-66             
  ...ionService.ts |     100 |      100 |     100 |     100 |                   
  prompt-stash.ts  |   96.66 |    92.85 |     100 |   96.66 | 34-35             
  ...tree-lease.ts |   92.14 |    92.42 |     100 |   92.14 | ...91-296,329-330 
  ...low-loader.ts |     100 |    96.29 |     100 |     100 | 88                
  setup-github.ts  |    90.8 |    80.95 |     100 |    90.8 | ...49-450,457-458 
  ...-args-file.ts |   93.93 |    91.66 |    87.5 |   93.93 | 208-210,224-230   
  types.ts         |     100 |      100 |     100 |     100 |                   
  ...e-keyterms.ts |   98.64 |    95.77 |     100 |   98.64 | 116,142-143       
  voice-model.ts   |     100 |      100 |     100 |     100 |                   
  voice-service.ts |    90.4 |    87.87 |     100 |    90.4 | ...81,288,353-358 
  ...e-settings.ts |     100 |    95.23 |     100 |     100 | 19                
  ...ranscriber.ts |   91.77 |    87.11 |   97.22 |   91.77 | ...96-898,901-903 
 ...s/housekeeping |      93 |    88.34 |      95 |      93 |                   
  scheduler.ts     |      93 |    88.34 |      95 |      93 | ...57-359,411-415 
 ...rvices/insight |     100 |      100 |     100 |     100 |                   
  dates.ts         |     100 |      100 |     100 |     100 |                   
 ...ght/generators |   88.94 |    86.86 |   96.29 |   88.94 |                   
  DataProcessor.ts |   88.31 |    86.84 |      95 |   88.31 | ...1368,1372-1379 
  ...tGenerator.ts |   98.24 |    85.71 |     100 |   98.24 | 47                
  ...teRenderer.ts |     100 |      100 |     100 |     100 |                   
 .../insight/types |       0 |       50 |      50 |       0 |                   
  ...sightTypes.ts |       0 |        0 |       0 |       0 |                   
  ...sightTypes.ts |       0 |        0 |       0 |       0 | 1                 
 ...mpt-processors |   97.27 |    94.25 |     100 |   97.27 |                   
  ...tProcessor.ts |     100 |      100 |     100 |     100 |                   
  ...eProcessor.ts |   94.52 |       85 |     100 |   94.52 | 46-47,93-94       
  ...tionParser.ts |     100 |      100 |     100 |     100 |                   
  ...lProcessor.ts |   97.41 |    95.83 |     100 |   97.41 | 96-99             
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/services/tips |   97.27 |    84.61 |     100 |   97.27 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  tipHistory.ts    |   92.59 |       70 |     100 |   92.59 | ...24,146,153,162 
  tipRegistry.ts   |     100 |      100 |     100 |     100 |                   
  tipScheduler.ts  |     100 |    91.66 |     100 |     100 | 55                
 src/startup       |   88.99 |    83.47 |    90.9 |   88.99 |                   
  ...p-prefetch.ts |   98.09 |    94.23 |    87.5 |   98.09 | 50,209,225-226    
  ...reeStartup.ts |   80.53 |     74.6 |     100 |   80.53 | ...94,403,409-412 
 src/test-utils    |    94.6 |    76.66 |      80 |    94.6 |                   
  ci-env.ts        |      88 |     62.5 |     100 |      88 | 22-23,28          
  ...omMatchers.ts |   69.69 |       50 |      50 |   69.69 | 32-35,37-39,45-47 
  ...mised-lock.ts |     100 |      100 |   66.66 |     100 |                   
  ...lot-client.ts |     100 |    66.66 |     100 |     100 | 31,39             
  ...andContext.ts |     100 |      100 |     100 |     100 |                   
  render.tsx       |     100 |      100 |     100 |     100 |                   
 src/ui            |   71.09 |    78.17 |   70.65 |   71.09 |                   
  App.tsx          |   33.33 |       75 |   33.33 |   33.33 | 32-86             
  AppContainer.tsx |   76.62 |    73.37 |   71.05 |   76.62 | ...4465,4581-4587 
  ...tionNudge.tsx |    9.58 |      100 |       0 |    9.58 | 24-94             
  ...ackDialog.tsx |    30.3 |      100 |       0 |    30.3 | 26-76             
  ...tionNudge.tsx |    7.69 |      100 |       0 |    7.69 | 25-103            
  colors.ts        |   63.63 |      100 |   41.17 |   63.63 | ...52,54-55,60-61 
  constants.ts     |     100 |      100 |     100 |     100 |                   
  ...AutoUpdate.ts |   93.54 |    94.64 |      90 |   93.54 | 126,131,202-213   
  keyMatchers.ts   |   95.91 |    97.14 |     100 |   95.91 | 25-26             
  ...tic-colors.ts |     100 |      100 |     100 |     100 |                   
  ...one-update.ts |   39.81 |    77.44 |   62.16 |   39.81 | ...1193,1196-1215 
  ...ractiveUI.tsx |   68.33 |    77.27 |   41.66 |   68.33 | ...63-465,495-500 
  ...inePresets.ts |   96.27 |    83.87 |     100 |   96.27 | ...97,402,410-412 
  systemInfo.ts    |   95.09 |    90.27 |     100 |   95.09 | ...54-255,260-264 
  ...InfoFields.ts |    87.5 |    65.85 |     100 |    87.5 | ...24-125,146-147 
  textConstants.ts |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
  ...e-relaunch.ts |   89.61 |    86.66 |      50 |   89.61 | 56-61,83-84       
 src/ui/auth       |   69.23 |    72.03 |   61.22 |   69.23 |                   
  AuthDialog.tsx   |   59.01 |     42.1 |   16.66 |   59.01 | ...25,332-354,358 
  ...nProgress.tsx |       0 |        0 |       0 |       0 | 1-64              
  ...etupSteps.tsx |   74.93 |    78.62 |   71.42 |   74.93 | ...92-902,918,921 
  useAuth.ts       |   94.83 |       75 |     100 |   94.83 | ...33-234,253-259 
  ...rSetupFlow.ts |   59.79 |    58.33 |     100 |   59.79 | ...82-403,420-463 
 src/ui/commands   |    84.6 |    84.46 |   91.68 |    84.6 |                   
  aboutCommand.ts  |     100 |      100 |     100 |     100 |                   
  ...or-command.ts |     100 |    95.65 |     100 |     100 | 104,182           
  agentsCommand.ts |   83.78 |      100 |      60 |   83.78 | 30-32,42-44       
  ...odeCommand.ts |    93.1 |    95.23 |     100 |    93.1 | 77-82             
  arenaCommand.ts  |   63.89 |    65.71 |   65.21 |   63.89 | ...01-606,691-699 
  authCommand.ts   |     100 |      100 |     100 |     100 |                   
  branchCommand.ts |     100 |      100 |     100 |     100 |                   
  btwCommand.ts    |   94.32 |    77.41 |     100 |   94.32 | 35-36,114-119     
  bugCommand.ts    |     100 |    77.77 |     100 |     100 | 28,62             
  cdCommand.ts     |    92.3 |    82.75 |     100 |    92.3 | ...,94-99,178,187 
  clearCommand.ts  |    80.9 |    70.83 |     100 |    80.9 | ...28-129,137-146 
  commands.ts      |   97.45 |    96.66 |     100 |   97.45 | 153-155           
  ...essCommand.ts |   80.71 |     64.7 |     100 |   80.71 | ...05-206,220-223 
  ...astCommand.ts |   84.75 |    76.47 |     100 |   84.75 | ...96-102,130-135 
  ...ig-command.ts |   93.12 |    88.42 |     100 |   93.12 | ...07-315,321-323 
  ...extCommand.ts |   73.75 |    74.02 |   83.33 |   73.75 | ...72-605,616-617 
  copyCommand.ts   |    98.7 |    96.29 |     100 |    98.7 | 66-67,172,272,323 
  ...or-command.ts |   85.95 |    80.55 |   88.88 |   85.95 | ...68-274,298-309 
  deleteCommand.ts |     100 |      100 |     100 |     100 |                   
  diffCommand.ts   |     100 |    87.87 |     100 |     100 | ...63,231-232,245 
  ...ryCommand.tsx |   90.56 |    87.83 |    90.9 |   90.56 | ...75-280,327-334 
  docsCommand.ts   |     100 |     90.9 |     100 |     100 | 26                
  doctorChecks.ts  |   70.31 |    74.57 |     100 |   70.31 | ...95-301,325-341 
  doctorCommand.ts |   70.16 |    84.61 |      95 |   70.16 | ...29-679,682-816 
  dreamCommand.ts  |   85.45 |    88.88 |     100 |   85.45 | 58-65             
  editorCommand.ts |     100 |      100 |     100 |     100 |                   
  ...rt-command.ts |   80.95 |       80 |     100 |   80.95 | 49-54,69-72,93-98 
  effort-utils.ts  |     100 |      100 |     100 |     100 |                   
  exportCommand.ts |   98.25 |    91.02 |     100 |   98.25 | ...81,198-199,364 
  ...onsCommand.ts |   52.31 |    56.25 |   69.23 |   52.31 | ...09,277-329,390 
  forgetCommand.ts |     100 |       90 |     100 |     100 | 59                
  forkCommand.ts   |     100 |    94.11 |     100 |     100 | 95,146            
  goalCommand.ts   |     100 |    96.49 |     100 |     100 | 139,192           
  helpCommand.ts   |     100 |      100 |     100 |     100 |                   
  ...oryCommand.ts |     100 |      100 |     100 |     100 |                   
  hooksCommand.ts  |   81.25 |    65.71 |   85.71 |   81.25 | ...,86-93,131-132 
  ideCommand.ts    |   60.75 |    64.28 |   41.17 |   60.75 | ...05-306,310-324 
  ...figCommand.ts |    58.5 |    74.07 |      80 |    58.5 | ...21-331,334-343 
  initCommand.ts   |   91.86 |       80 |     100 |   91.86 | 48,83-88          
  ...ghtCommand.ts |   77.87 |    71.42 |     100 |   77.87 | ...44-245,250-272 
  ...ageCommand.ts |   94.63 |    90.66 |     100 |   94.63 | ...25-226,253-263 
  learn-command.ts |     100 |      100 |     100 |     100 |                   
  lspCommand.ts    |     100 |    86.95 |     100 |     100 | 31,102-103        
  mcpCommand.ts    |     100 |      100 |     100 |     100 |                   
  memoryCommand.ts |     100 |      100 |     100 |     100 |                   
  modelCommand.ts  |   86.28 |    86.29 |     100 |   86.28 | ...1112,1146-1151 
  peers-command.ts |     100 |    94.36 |     100 |     100 | 59,70,223,228     
  ...onsCommand.ts |     100 |      100 |     100 |     100 |                   
  planCommand.ts   |   78.82 |    76.92 |     100 |   78.82 | 30-35,51-56,68-73 
  quitCommand.ts   |     100 |      100 |     100 |     100 |                   
  recapCommand.ts  |   21.81 |      100 |      50 |   21.81 | 24-73             
  ...ns-command.ts |   98.83 |    81.81 |     100 |   98.83 | 100               
  ...berCommand.ts |     100 |     87.5 |     100 |     100 | 46                
  renameCommand.ts |    89.6 |       90 |     100 |    89.6 | ...72-176,212-219 
  ...oreCommand.ts |   90.96 |    86.04 |     100 |   90.96 | ...41-146,177-178 
  resumeCommand.ts |     100 |      100 |     100 |     100 |                   
  rewindCommand.ts |   81.25 |      100 |      50 |   81.25 | 20-22             
  ...ngsCommand.ts |     100 |      100 |     100 |     100 |                   
  ...hubCommand.ts |   89.47 |       75 |      80 |   89.47 | 54-59             
  skillsCommand.ts |   78.82 |    81.81 |     100 |   78.82 | 37-52,78,97       
  statsCommand.ts  |   90.65 |    76.73 |     100 |   90.65 | ...30-733,825-832 
  ...ineCommand.ts |     100 |      100 |     100 |     100 |                   
  ...aryCommand.ts |   73.04 |     82.3 |      90 |   73.04 | ...20-547,561-565 
  tasksCommand.ts  |   77.33 |    72.13 |     100 |   77.33 | ...46-150,173-178 
  ...tupCommand.ts |     100 |      100 |     100 |     100 |                   
  themeCommand.ts  |     100 |      100 |     100 |     100 |                   
  toolsCommand.ts  |     100 |      100 |     100 |     100 |                   
  trustCommand.ts  |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
  ...te-command.ts |     100 |    94.11 |     100 |     100 | 74,148            
  vimCommand.ts    |     100 |      100 |     100 |     100 |                   
  voice-command.ts |   93.63 |       88 |     100 |   93.63 | 36,98-103         
  ...owsCommand.ts |   94.38 |    85.29 |     100 |   94.38 | ...78-183,282-287 
 src/ui/components |   73.25 |    80.22 |    77.7 |   73.25 |                   
  AboutBox.tsx     |     100 |      100 |     100 |     100 |                   
  AnsiOutput.tsx   |   65.57 |      100 |      50 |   65.57 | 69-90             
  ApiKeyInput.tsx  |       0 |        0 |       0 |       0 | 1-97              
  AppHeader.tsx    |    88.7 |       75 |     100 |    88.7 | 36,38-43,45       
  ...odeDialog.tsx |   87.24 |    72.22 |   33.33 |   87.24 | ...85,233-238,245 
  AsciiArt.ts      |     100 |      100 |     100 |     100 |                   
  ...Indicator.tsx |   95.65 |    66.66 |     100 |   95.65 | 27,52             
  ...TextInput.tsx |   89.06 |    90.78 |     100 |   89.06 | ...87-289,303-305 
  Composer.tsx     |   94.54 |    66.66 |     100 |   94.54 | ...-76,88,143,158 
  ...entPrompt.tsx |     100 |      100 |     100 |     100 |                   
  ...ryDisplay.tsx |   75.89 |    62.06 |     100 |   75.89 | ...,88,93-108,113 
  ...geDisplay.tsx |   68.42 |    57.14 |     100 |   68.42 | 16-17,31-32,42-50 
  CronPill.tsx     |     100 |    93.75 |     100 |     100 | 19                
  ...ification.tsx |      84 |       60 |     100 |      84 | 23-24,40-42       
  ...gProfiler.tsx |       0 |        0 |       0 |       0 | 1-36              
  ...ogManager.tsx |   11.28 |      100 |       0 |   11.28 | 71-598            
  DiffDialog.tsx   |    53.5 |     37.5 |   69.23 |    53.5 | ...32-737,747-760 
  ...ngsDialog.tsx |    8.44 |      100 |       0 |    8.44 | 37-195            
  EffortDialog.tsx |   97.36 |      100 |     100 |   97.36 | 55-56             
  ExitWarning.tsx  |     100 |      100 |     100 |     100 |                   
  ...hProgress.tsx |    87.8 |    33.33 |     100 |    87.8 | 28-31,56          
  ...gsDisplay.tsx |     100 |    96.87 |   83.33 |     100 | 69                
  ...ustDialog.tsx |     100 |      100 |     100 |     100 |                   
  Footer.tsx       |   81.27 |    69.23 |      50 |   81.27 | ...06,245,267-272 
  GoalPill.tsx     |   93.51 |    81.81 |     100 |   93.51 | 37-38,106-109,123 
  Header.tsx       |   98.65 |    94.73 |     100 |   98.65 | 173,175           
  Help.tsx         |   98.33 |       90 |     100 |   98.33 | ...25,382,448-449 
  ...emDisplay.tsx |   79.69 |    67.61 |     100 |   79.69 | ...17,520,523-529 
  ...ngeDialog.tsx |     100 |      100 |     100 |     100 |                   
  InputPrompt.tsx  |   86.26 |     83.3 |      80 |   86.26 | ...2231,2252,2348 
  ...Shortcuts.tsx |     100 |       88 |     100 |     100 | 98,119            
  ...Indicator.tsx |   98.18 |    97.82 |     100 |   98.18 | 161-162           
  ...firmation.tsx |   91.42 |      100 |      50 |   91.42 | 26-31             
  MainContent.tsx  |   95.88 |    96.03 |   46.15 |   95.88 | ...20,523-527,530 
  MemoryDialog.tsx |   86.59 |    80.15 |     100 |   86.59 | ...34-435,485,553 
  ...geDisplay.tsx |       0 |        0 |       0 |       0 | 1-41              
  ModelDialog.tsx  |   85.22 |    74.17 |     100 |   85.22 | ...1042,1098,1100 
  ...tsDisplay.tsx |     100 |    97.22 |     100 |     100 | 270               
  ...fications.tsx |   16.66 |      100 |       0 |   16.66 | 14-56             
  ...onsDialog.tsx |    2.13 |      100 |       0 |    2.13 | 62-133,148-1004   
  ...ryDisplay.tsx |     100 |      100 |     100 |     100 |                   
  ...icePrompt.tsx |   92.64 |    85.71 |     100 |   92.64 | 102-106,134-139   
  PrepareLabel.tsx |   91.66 |    77.27 |     100 |   91.66 | 73-75,77-79,110   
  ...atePrompt.tsx |    8.57 |      100 |       0 |    8.57 | 24-55,58-134      
  ...geDisplay.tsx |     100 |      100 |     100 |     100 |                   
  ...ngDisplay.tsx |   21.42 |      100 |       0 |   21.42 | 13-39             
  ...hProgress.tsx |   85.25 |    88.46 |     100 |   85.25 | 121-147           
  ...ngSpinner.tsx |   67.85 |    85.71 |      50 |   67.85 | 33-50,71,78-79    
  ...dSelector.tsx |   92.79 |    82.65 |     100 |   92.79 | ...19-323,354-370 
  ...ionPicker.tsx |   83.66 |    72.13 |     100 |   83.66 | ...96,402,444-466 
  ...onPreview.tsx |   93.58 |    83.78 |     100 |   93.58 | ...,70-71,195-197 
  ...ryDisplay.tsx |     100 |      100 |     100 |     100 |                   
  ...putPrompt.tsx |   92.06 |    86.36 |   83.33 |   92.06 | ...,70-72,120-123 
  ...tedDialog.tsx |     100 |      100 |     100 |     100 |                   
  ...ngsDialog.tsx |   71.55 |    73.89 |   69.23 |   71.55 | ...1252,1258-1259 
  ...ionDialog.tsx |    92.3 |    96.15 |   33.33 |    92.3 | 60-63,68-75,164   
  ...putPrompt.tsx |    15.9 |      100 |       0 |    15.9 | 20-63             
  ...Indicator.tsx |   57.14 |      100 |       0 |   57.14 | 12-15             
  ...MoreLines.tsx |      28 |      100 |       0 |      28 | 18-40             
  ...iewDialog.tsx |   97.77 |    87.67 |     100 |   97.77 | ...97,305-307,324 
  ...tsDisplay.tsx |   95.86 |       75 |     100 |   95.86 | 67-71             
  ...ionPicker.tsx |       0 |        0 |       0 |       0 | 1-171             
  ...tivityTab.tsx |    3.94 |      100 |       0 |    3.94 | 27-275            
  StatsDialog.tsx  |    8.64 |      100 |       0 |    8.64 | ...76-111,130-322 
  StatsDisplay.tsx |     100 |      100 |     100 |     100 |                   
  ...ciencyTab.tsx |    78.9 |    56.52 |     100 |    78.9 | ...26,213,262-288 
  ...atmapView.tsx |    8.98 |      100 |       0 |    8.98 | 20-107            
  ...essionTab.tsx |      80 |    66.66 |     100 |      80 | ...70-277,283-300 
  ...ineDialog.tsx |    93.9 |    86.88 |     100 |    93.9 | ...20,282,302-304 
  ...yTodoList.tsx |   96.36 |    88.23 |     100 |   96.36 | 138-141           
  ...nsDisplay.tsx |   95.62 |    87.09 |     100 |   95.62 | ...24-125,273-275 
  ...inalImage.tsx |     100 |    93.93 |     100 |     100 | 75,129            
  ThemeDialog.tsx  |   89.95 |    46.15 |      75 |   89.95 | ...71-173,243-245 
  Tips.tsx         |   93.54 |       75 |     100 |   93.54 | 39-40             
  TodoDisplay.tsx  |     100 |      100 |     100 |     100 |                   
  ...tsDisplay.tsx |     100 |     87.5 |     100 |     100 | 31-32             
  TrustDialog.tsx  |     100 |    83.33 |     100 |     100 | 72-87             
  ...ification.tsx |   36.36 |      100 |       0 |   36.36 | 15-22             
  ...Indicator.tsx |    92.5 |     87.5 |     100 |    92.5 | 50-53             
  ...ackDialog.tsx |    7.84 |      100 |       0 |    7.84 | 24-134            
  ...xitDialog.tsx |   80.36 |    43.47 |      60 |   80.36 | ...24-238,248-251 
  ...odeVisuals.ts |   97.22 |    85.71 |     100 |   97.22 | 25                
  ...s-helpers.tsx |   66.25 |    81.25 |      50 |   66.25 | 25-32,46-53,62-72 
 ...nts/agent-view |    61.5 |    75.57 |    62.5 |    61.5 |                   
  ...atContent.tsx |    9.09 |      100 |       0 |    9.09 | 54-275,281-283    
  ...tChatView.tsx |     100 |    81.81 |     100 |     100 | 82                
  ...tComposer.tsx |   78.35 |     64.7 |   66.66 |   78.35 | ...64,277,303-305 
  AgentFooter.tsx  |   15.38 |      100 |       0 |   15.38 | 28-65             
  AgentHeader.tsx  |   15.38 |      100 |       0 |   15.38 | 27-64             
  AgentTabBar.tsx  |    87.9 |    63.88 |     100 |    87.9 | ...88,110-118,136 
  ...oryAdapter.ts |     100 |    91.83 |     100 |     100 | 103,109-110,138   
  index.ts         |       0 |        0 |       0 |       0 | 1-12              
 ...mponents/arena |   45.51 |    70.53 |   60.86 |   45.51 |                   
  ArenaCards.tsx   |   73.06 |    71.79 |   85.71 |   73.06 | ...83-185,321-326 
  ...ectDialog.tsx |   83.48 |    69.86 |   88.88 |   83.48 | ...88-392,409-410 
  ...artDialog.tsx |    9.77 |      100 |       0 |    9.77 | 27-166            
  ...tusDialog.tsx |    5.63 |      100 |       0 |    5.63 | 33-75,80-288      
  ...topDialog.tsx |    6.17 |      100 |       0 |    6.17 | 33-213            
 ...ackground-view |   85.86 |     85.1 |   92.98 |   85.86 |                   
  ...sksDialog.tsx |   82.66 |    83.09 |   85.71 |   82.66 | ...1854,1977-1983 
  ...TasksPill.tsx |   78.84 |    94.28 |     100 |   78.84 | 64,109-129        
  ...gentPanel.tsx |   97.08 |    86.31 |     100 |   97.08 | 132,442-446,520   
  agent-forest.ts  |    99.2 |    93.93 |     100 |    99.2 | 258               
  ...Visibility.ts |     100 |      100 |     100 |     100 |                   
  ...e-overlay.tsx |    88.2 |    76.47 |     100 |    88.2 | ...36-138,140-142 
 ...nts/extensions |   84.32 |    76.78 |   83.33 |   84.32 |                   
  ...gerDialog.tsx |   82.15 |    76.08 |     100 |   82.15 | ...91-198,258,260 
  TabBar.tsx       |   97.29 |    88.88 |     100 |   97.29 | 33                
  index.ts         |       0 |        0 |       0 |       0 | 1-12              
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...tensions/steps |   46.26 |       85 |   58.82 |   46.26 |                   
  ...ctionStep.tsx |   95.12 |    92.85 |   85.71 |   95.12 | 84-86,89          
  ...etailStep.tsx |       0 |        0 |       0 |       0 | 1-145             
  ...nListStep.tsx |   75.26 |    88.37 |   66.66 |   75.26 | ...53,174,203-209 
  ...electStep.tsx |       0 |        0 |       0 |       0 | 1-83              
  ...nfirmStep.tsx |   16.32 |      100 |       0 |   16.32 | 28-74             
  index.ts         |       0 |        0 |       0 |       0 | 1-11              
 ...xtensions/tabs |   71.92 |    68.21 |   70.83 |   71.92 |                   
  DiscoverTab.tsx  |   68.22 |    67.66 |   55.55 |   68.22 | ...93,656-660,664 
  InstalledTab.tsx |   75.49 |    67.44 |   83.33 |   75.49 | ...77,782-783,820 
  SourcesTab.tsx   |   71.67 |    70.47 |   77.77 |   71.67 | ...28,547,621-633 
 ...tensions/views |    50.7 |    52.38 |   20.83 |    50.7 |                   
  ...tionsView.tsx |   73.75 |    56.36 |   66.66 |   73.75 | ...30,353,369-374 
  ...tionsView.tsx |   43.45 |    44.82 |    6.66 |   43.45 | ...98-405,408-420 
  ...etailView.tsx |    9.24 |      100 |       0 |    9.24 | 40-67,70-163      
 ...mponents/hooks |   87.11 |    81.37 |   91.89 |   87.11 |                   
  ...rListBody.tsx |   95.29 |    85.18 |     100 |   95.29 | 95-98             
  ...etailStep.tsx |   75.32 |    71.42 |      60 |   75.32 | ...56-169,173-186 
  ...etailStep.tsx |     100 |      100 |     100 |     100 |                   
  ...rListStep.tsx |     100 |      100 |     100 |     100 |                   
  ...entHeader.tsx |     100 |    85.71 |     100 |     100 | 47                
  ...rListStep.tsx |     100 |      100 |     100 |     100 |                   
  ...etailStep.tsx |     100 |      100 |     100 |     100 |                   
  ...abledStep.tsx |     100 |      100 |     100 |     100 |                   
  ...sListStep.tsx |     100 |      100 |     100 |     100 |                   
  ...entDialog.tsx |   72.29 |    70.49 |     100 |   72.29 | ...51,563-568,572 
  constants.ts     |     100 |      100 |     100 |     100 |                   
  index.ts         |       0 |        0 |       0 |       0 | 1-13              
  ...erGrouping.ts |     100 |      100 |     100 |     100 |                   
  sourceLabels.ts  |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...components/mcp |   40.91 |    63.44 |   70.58 |   40.91 |                   
  ...ealthPill.tsx |     100 |      100 |     100 |     100 |                   
  ...entDialog.tsx |   32.09 |    26.19 |      40 |   32.09 | ...12,914,927-933 
  ...valDialog.tsx |   15.06 |      100 |       0 |   15.06 | 40-109            
  constants.ts     |     100 |      100 |     100 |     100 |                   
  index.ts         |       0 |        0 |       0 |       0 | 1-35              
  types.ts         |     100 |      100 |     100 |     100 |                   
  utils.ts         |      97 |       95 |     100 |      97 | 24,113-114        
 ...ents/mcp/steps |   53.94 |    73.51 |   57.14 |   53.94 |                   
  ...icateStep.tsx |    5.65 |      100 |       0 |    5.65 | 40-66,69-308      
  ...electStep.tsx |   10.95 |      100 |       0 |   10.95 | 16-88             
  ...etailStep.tsx |     100 |      100 |     100 |     100 |                   
  ...eListStep.tsx |   99.09 |    97.36 |     100 |   99.09 | 71                
  ...etailStep.tsx |   62.83 |       60 |   33.33 |   62.83 | ...87-296,307-332 
  ...rListStep.tsx |   88.53 |    81.25 |     100 |   88.53 | ...64,170,175-180 
  ...etailStep.tsx |    10.3 |      100 |       0 |    10.3 | ...1,67-79,82-140 
  ToolListStep.tsx |   69.29 |       50 |     100 |   69.29 | ...23,126,135-144 
 ...nents/messages |   90.78 |    87.65 |   86.79 |   90.78 |                   
  ...orMessage.tsx |     100 |      100 |     100 |     100 |                   
  ...ionDialog.tsx |   89.23 |     84.9 |   81.81 |   89.23 | ...75,593,611-613 
  BtwMessage.tsx   |     100 |      100 |     100 |     100 |                   
  ...upDisplay.tsx |     100 |    94.73 |     100 |     100 | ...43,289,402,432 
  ...onMessage.tsx |   93.24 |       85 |     100 |   93.24 | 73-75,77,79       
  ...nMessages.tsx |   94.11 |    95.91 |   76.92 |   94.11 | ...47-349,352-355 
  DiffRenderer.tsx |   93.17 |    86.02 |     100 |   93.17 | ...07,235-236,302 
  ...tsDisplay.tsx |   97.08 |    77.77 |     100 |   97.08 | 95,97,106         
  ...usMessage.tsx |   81.73 |     65.9 |      75 |   81.73 | ...10-214,222,245 
  ...tsDisplay.tsx |   95.52 |    88.31 |     100 |   95.52 | ...40,142,175-180 
  ...ssMessage.tsx |    12.5 |      100 |       0 |    12.5 | 18-59             
  ...edMessage.tsx |   21.05 |      100 |       0 |   21.05 | 23-39             
  ...sMessages.tsx |   59.04 |       50 |    37.5 |   59.04 | ...21-126,147-159 
  ...ryMessage.tsx |   13.63 |      100 |       0 |   13.63 | 23-64             
  ...onMessage.tsx |   91.87 |    82.51 |     100 |   91.87 | ...49-651,658-660 
  ...upMessage.tsx |   98.38 |    95.38 |     100 |   98.38 | 188-191,422       
  ToolMessage.tsx  |   95.04 |    89.55 |     100 |   95.04 | ...1075,1120-1122 
 ...ponents/shared |    86.4 |    82.05 |    86.6 |    86.4 |                   
  ...ctionList.tsx |     100 |      100 |      75 |     100 |                   
  ...tonSelect.tsx |     100 |      100 |     100 |     100 |                   
  ...rBoundary.tsx |     100 |      100 |     100 |     100 |                   
  MaxSizedBox.tsx  |   84.71 |    86.95 |      90 |   84.71 | ...67-568,685-686 
  MultiSelect.tsx  |   93.58 |       75 |     100 |   93.58 | ...43,199-201,211 
  ...tonSelect.tsx |     100 |      100 |     100 |     100 |                   
  ...ontroller.tsx |     100 |    83.33 |     100 |     100 | 73,93-95          
  ...eSelector.tsx |     100 |       60 |     100 |     100 | 40-45             
  ...lableList.tsx |   90.37 |    82.85 |   18.18 |   90.37 | ...60-63,65,73-76 
  StaticRender.tsx |     100 |      100 |     100 |     100 |                   
  TextInput.tsx    |    80.8 |    67.79 |      80 |    80.8 | ...36-240,252-258 
  ...ontroller.tsx |     100 |    81.81 |     100 |     100 | 59-62             
  ...apsedTime.tsx |     100 |      100 |     100 |     100 |                   
  ...Indicator.tsx |     100 |      100 |     100 |     100 |                   
  ...lizedList.tsx |   91.49 |    86.66 |   83.33 |   91.49 | ...18-846,859,959 
  text-buffer.ts   |   85.98 |    81.78 |   97.91 |   85.98 | ...2664,2762-2763 
  ...er-actions.ts |   73.93 |    67.22 |     100 |   73.93 | ...32-733,934-936 
 ...ponents/skills |    3.99 |      100 |       0 |    3.99 |                   
  ...gerDialog.tsx |    3.99 |      100 |       0 |    3.99 | 79-137,140-678    
 ...ents/subagents |   30.87 |        0 |       0 |   30.87 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  index.ts         |       0 |        0 |       0 |       0 | 1-11              
  reducers.tsx     |    12.1 |      100 |       0 |    12.1 | 33-190            
  types.ts         |     100 |      100 |     100 |     100 |                   
  utils.ts         |   10.95 |      100 |       0 |   10.95 | ...1,56-57,60-102 
 ...bagents/create |    9.13 |      100 |       0 |    9.13 |                   
  ...ionWizard.tsx |    7.28 |      100 |       0 |    7.28 | 34-299            
  ...rSelector.tsx |   14.75 |      100 |       0 |   14.75 | 26-85             
  ...onSummary.tsx |    4.26 |      100 |       0 |    4.26 | 27-331            
  ...tionInput.tsx |    8.63 |      100 |       0 |    8.63 | 23-177            
  ...dSelector.tsx |   33.33 |      100 |       0 |   33.33 | 20-21,26-27,36-63 
  ...nSelector.tsx |    37.5 |      100 |       0 |    37.5 | 20-21,26-27,36-58 
  ...EntryStep.tsx |   12.76 |      100 |       0 |   12.76 | 34-78             
  ToolSelector.tsx |    4.16 |      100 |       0 |    4.16 | 31-253            
 ...bagents/manage |    21.6 |    59.52 |   27.27 |    21.6 |                   
  ...ctionStep.tsx |   10.25 |      100 |       0 |   10.25 | 21-103            
  ...eleteStep.tsx |   20.93 |      100 |       0 |   20.93 | 23-62             
  ...tEditStep.tsx |   25.53 |      100 |       0 |   25.53 | ...2,37-38,51-124 
  ...ctionStep.tsx |   35.61 |    59.52 |     100 |   35.61 | ...21-433,438-440 
  ...iewerStep.tsx |   13.72 |      100 |       0 |   13.72 | 18-73             
  ...gerDialog.tsx |    6.74 |      100 |       0 |    6.74 | 35-341            
 ...mponents/views |    70.1 |    72.89 |   61.11 |    70.1 |                   
  ContextUsage.tsx |   71.49 |    64.86 |      80 |   71.49 | ...30-436,473-567 
  DoctorReport.tsx |     9.8 |      100 |       0 |     9.8 | 25-54,57-131      
  ...sionsList.tsx |   88.05 |       75 |     100 |   88.05 | 70-77             
  McpStatus.tsx    |   92.01 |     73.8 |     100 |   92.01 | ...36,175-177,262 
  SkillsList.tsx   |   20.51 |      100 |       0 |   20.51 | 17-20,27-57       
  ToolsList.tsx    |     100 |      100 |     100 |     100 |                   
 src/ui/contexts   |   86.47 |    82.34 |   86.48 |   86.47 |                   
  ...ewContext.tsx |   91.66 |       90 |      75 |   91.66 | ...89-193,279-289 
  AppContext.tsx   |      80 |       50 |     100 |      80 | 19-20             
  ...ewContext.tsx |   93.83 |    68.51 |   42.85 |   93.83 | ...44,281-285,317 
  ...igContext.tsx |   81.81 |       50 |     100 |   81.81 | 15-16             
  ...ssContext.tsx |   85.65 |    84.85 |     100 |   85.65 | ...1612-1614,1620 
  ...owContext.tsx |   91.07 |    81.81 |     100 |   91.07 | 47-48,60-62       
  ...deContext.tsx |     100 |      100 |      50 |     100 |                   
  ...onContext.tsx |   80.77 |       80 |    92.3 |   80.77 | ...31-434,443-446 
  ...gsContext.tsx |     100 |      100 |     100 |     100 |                   
  ...usContext.tsx |     100 |      100 |     100 |     100 |                   
  ...ngContext.tsx |   71.42 |       50 |     100 |   71.42 | 17-20             
  ...utContext.tsx |   85.71 |      100 |   66.66 |   85.71 | 13-14             
  ...edContext.tsx |     100 |      100 |      50 |     100 |                   
  ...nsContext.tsx |   88.88 |       50 |     100 |   88.88 | 156-157           
  ...teContext.tsx |   86.66 |       50 |     100 |   86.66 | 237-238           
  ...deContext.tsx |      80 |     87.5 |      75 |      80 | ...11-112,118-120 
  ...rtContext.tsx |     100 |      100 |     100 |     100 |                   
 src/ui/daemon     |   89.51 |    76.92 |   95.65 |   89.51 |                   
  ...ui-adapter.ts |   89.51 |    76.92 |   95.65 |   89.51 | ...59,877-878,964 
 src/ui/editors    |   93.33 |    85.71 |   66.66 |   93.33 |                   
  ...ngsManager.ts |   93.33 |    85.71 |   66.66 |   93.33 | 49,63-64          
 src/ui/hooks      |   86.03 |    84.19 |   87.53 |   86.03 |                   
  ...dProcessor.ts |   85.53 |    85.13 |     100 |   85.53 | ...-970,1017-1018 
  ...ention-ref.ts |   97.72 |       84 |     100 |   97.72 | 65                
  keyToAnsi.ts     |    3.92 |      100 |       0 |    3.92 | 19-77             
  ...esourceRef.ts |     100 |      100 |     100 |     100 |                   
  ...completion.ts |     100 |    95.45 |     100 |     100 | 95                
  ...ention-ref.ts |     100 |      100 |     100 |     100 |                   
  ...dProcessor.ts |   94.55 |    73.58 |     100 |   94.55 | ...87-288,293-294 
  ...dProcessor.ts |   86.83 |    71.86 |   83.33 |   86.83 | ...1536,1565-1569 
  ...rt-command.ts |     100 |      100 |     100 |     100 |                   
  ...sced-flush.ts |     100 |      100 |     100 |     100 |                   
  ...llm-stream.ts |   87.63 |    84.43 |   78.72 |   87.63 | ...5813-5815,5817 
  ...ng-enabled.ts |     100 |      100 |     100 |     100 |                   
  ...oice-input.ts |   92.41 |    82.08 |   66.66 |   92.41 | ...12,514-515,670 
  ...ke-repaint.ts |     100 |      100 |     100 |     100 |                   
  ...amingState.ts |   12.22 |      100 |       0 |   12.22 | 54-157            
  ...agerDialog.ts |   88.23 |      100 |     100 |   88.23 | 20,24             
  ...dScrollbar.ts |     100 |      100 |     100 |     100 |                   
  ...ationFrame.ts |      42 |       75 |     100 |      42 | 42-44,53-59,62-87 
  ...odeCommand.ts |   58.82 |      100 |     100 |   58.82 | 28,33-48          
  ...enaCommand.ts |      85 |      100 |     100 |      85 | 23-24,29          
  ...aInProcess.ts |   27.92 |       80 |      25 |   27.92 | ...69-170,173-175 
  ...Completion.ts |   86.44 |    88.48 |     100 |   86.44 | ...14-515,525-541 
  ...ifications.ts |   87.82 |    96.77 |     100 |   87.82 | 138-152           
  ...tIndicator.ts |   88.28 |    81.57 |     100 |   88.28 | ...66,175,179-187 
  ...waySummary.ts |   96.26 |       75 |     100 |   96.26 | 126-128,170       
  ...ndTaskView.ts |   94.89 |    77.55 |     100 |   94.89 | 164-168,257,263   
  ...chedScroll.ts |     100 |      100 |     100 |     100 |                   
  ...ketedPaste.ts |    23.8 |      100 |       0 |    23.8 | 19-37             
  ...nchCommand.ts |   96.03 |    88.75 |     100 |   96.03 | ...04-205,362-365 
  ...ompletion.tsx |   97.09 |    87.23 |     100 |   97.09 | ...23-324,334-335 
  ...dMigration.ts |    92.1 |    88.88 |     100 |    92.1 | 42-44             
  useCompletion.ts |   96.29 |    90.56 |     100 |   96.29 | ...17-218,222-223 
  ...nitMessage.ts |     100 |      100 |     100 |     100 |                   
  ...extualTips.ts |   78.26 |       50 |     100 |   78.26 | ...2,75-79,96-104 
  ...eteCommand.ts |   89.52 |    90.69 |     100 |   89.52 | ...98-106,114-115 
  ...ialogClose.ts |   36.11 |       10 |     100 |   36.11 | ...89-195,202-207 
  useDiffData.ts   |   11.62 |      100 |       0 |   11.62 | 44-87             
  ...oublePress.ts |   53.12 |       75 |     100 |   53.12 | 33-35,41-54       
  ...orSettings.ts |     100 |      100 |     100 |     100 |                   
  ...Completion.ts |   99.12 |    97.67 |     100 |   99.12 | 182-183           
  ...ionUpdates.ts |   93.72 |    92.98 |     100 |   93.72 | ...87-291,314-320 
  ...agerDialog.ts |   88.88 |      100 |     100 |   88.88 | 21,25             
  ...backDialog.ts |   57.89 |    71.42 |      50 |   57.89 | ...66-168,190-191 
  useFocus.ts      |     100 |      100 |     100 |     100 |                   
  ...olderTrust.ts |     100 |    93.33 |     100 |     100 | 62                
  ...ggestions.tsx |   96.47 |    78.94 |     100 |   96.47 | 121,155-156       
  ...BranchName.ts |     100 |    94.44 |     100 |     100 | 54                
  ...oryManager.ts |   98.44 |     98.9 |     100 |   98.44 | 157-160           
  ...ooksDialog.ts |    87.5 |      100 |     100 |    87.5 | 19,23             
  ...stListener.ts |     100 |      100 |     100 |     100 |                   
  ...nAuthError.ts |   76.19 |       50 |     100 |   76.19 | 39-40,43-45       
  ...putHistory.ts |   92.59 |    85.71 |     100 |   92.59 | 63-64,72,94-96    
  useKeypress.ts   |     100 |      100 |     100 |     100 |                   
  ...rdProtocol.ts |   36.36 |      100 |       0 |   36.36 | 24-31             
  ...unchEditor.ts |   22.58 |      100 |      50 |   22.58 | 11-32,44-85       
  ...gIndicator.ts |     100 |    96.66 |     100 |     100 | 109               
  useLogger.ts     |      16 |      100 |       0 |      16 | 15-45             
  useMCPHealth.ts  |   10.52 |      100 |       0 |   10.52 | 36-75             
  ...cpApproval.ts |   93.12 |    86.11 |     100 |   93.12 | ...24-127,139-140 
  useMcpDialog.ts  |    87.5 |      100 |     100 |    87.5 | 19,23             
  ...moryDialog.ts |    87.5 |      100 |     100 |    87.5 | 19,23             
  ...oryMonitor.ts |   83.14 |    78.57 |     100 |   83.14 | 54-63,74-79       
  ...ssageQueue.ts |     100 |    94.94 |     100 |     100 | ...43,279,349,359 
  ...delCommand.ts |     100 |       96 |     100 |     100 | 61                
  ...ouseEvents.ts |   94.89 |       95 |   83.33 |   94.89 | 78-82             
  ...raseCycler.ts |   84.74 |    76.47 |     100 |   84.74 | ...49,52-53,69-71 
  ...rredEditor.ts |   58.33 |    22.22 |     100 |   58.33 | 23-27,29-33       
  ...derUpdates.ts |   85.29 |    80.28 |    92.3 |   85.29 | ...36,351-361,441 
  useQwenAuth.ts   |     100 |      100 |     100 |     100 |                   
  ...lScheduler.ts |   89.13 |     86.9 |     100 |   89.13 | ...61-463,496-506 
  ...oryCommand.ts |       0 |        0 |       0 |       0 | 1-7               
  ...umeCommand.ts |   96.51 |    90.19 |     100 |   96.51 | 279,306-311       
  ...ompletion.tsx |   90.67 |    83.33 |     100 |   90.67 | ...02,105,138-141 
  ...ectionList.ts |   97.12 |    96.19 |     100 |   97.12 | ...92-193,247-250 
  ...sionPicker.ts |   92.87 |    90.35 |     100 |   92.87 | ...99-501,503-505 
  ...earchInput.ts |     100 |    97.29 |     100 |     100 | 82                
  ...ngsCommand.ts |   18.75 |      100 |       0 |   18.75 | 10-25             
  ...ellHistory.ts |   93.28 |    80.95 |     100 |   93.28 | ...96,153-154,164 
  ...oryCommand.ts |   85.48 |    58.33 |     100 |   85.48 | 22-28,40,71       
  ...agerDialog.ts |   88.23 |      100 |     100 |   88.23 | 20,24             
  ...Completion.ts |   82.79 |    85.33 |   94.73 |   82.79 | ...86-688,696-732 
  ...tateAndRef.ts |     100 |      100 |     100 |     100 |                   
  ...tatsDialog.ts |     100 |      100 |     100 |     100 |                   
  useStatusLine.ts |   97.32 |    93.93 |     100 |   97.32 | ...18-422,518-525 
  ...eateDialog.ts |   88.23 |      100 |     100 |   88.23 | 14,18             
  ...mInProcess.ts |   27.35 |       80 |      25 |   27.35 | ...82-183,186-188 
  ...tification.ts |     100 |     87.5 |     100 |     100 | 50                
  ...alProgress.ts |   67.34 |    58.82 |   66.66 |   67.34 | 52-53,61-68,79-85 
  ...rminalSize.ts |     100 |      100 |     100 |     100 |                   
  ...emeCommand.ts |    79.2 |    35.29 |     100 |    79.2 | ...15-116,120-121 
  useTimer.ts      |   97.59 |    94.73 |     100 |   97.59 | 17-18             
  ...lMigration.ts |       0 |        0 |       0 |       0 |                   
  ...rustModify.ts |     100 |    90.47 |     100 |     100 | 112,134           
  useTurnDiffs.ts  |   95.12 |    78.57 |     100 |   95.12 | 133-134,156-157   
  ...elcomeBack.ts |   87.36 |     90.9 |     100 |   87.36 | ...,94-96,114-115 
  ...reeSession.ts |   93.75 |       70 |     100 |   93.75 | 47-48,72          
  vim.ts           |      74 |    67.56 |   69.23 |      74 | ...1854-1861,1869 
 src/ui/layouts    |   91.25 |    89.47 |     100 |   91.25 |                   
  ...AppLayout.tsx |   90.99 |     87.5 |     100 |   90.99 | 61-63,111-116,152 
  ...AppLayout.tsx |   91.66 |    92.85 |     100 |   91.66 | 75-80             
 src/ui/model      |   97.91 |    98.36 |     100 |   97.91 |                   
  ...ggregation.ts |     100 |      100 |     100 |     100 |                   
  ...ming-model.ts |   97.43 |    97.72 |     100 |   97.43 | 261-265           
 src/ui/models     |   80.72 |       80 |   71.42 |   80.72 |                   
  ...ableModels.ts |   80.72 |       80 |   71.42 |   80.72 | ...,61-71,125-127 
 ...noninteractive |     100 |      100 |    6.66 |     100 |                   
  ...eractiveUi.ts |     100 |      100 |    6.66 |     100 |                   
 src/ui/selection  |   93.56 |    86.19 |     100 |   93.56 |                   
  screen-buffer.ts |   94.73 |    66.66 |     100 |   94.73 | 51-52             
  ...ion-coords.ts |     100 |      100 |     100 |     100 |                   
  ...ction-span.ts |   93.81 |     92.1 |     100 |   93.81 | ...1,45-46,99-100 
  ...tion-state.ts |     100 |      100 |     100 |     100 |                   
  ...ction-text.ts |   93.85 |    93.44 |     100 |   93.85 | 30-34,130-131     
  ...selection.tsx |   91.88 |    78.57 |     100 |   91.88 | ...16-417,446-447 
 src/ui/state      |      95 |    81.81 |     100 |      95 |                   
  extensions.ts    |      95 |    81.81 |     100 |      95 | 69-70,89          
 src/ui/themes     |    98.5 |    73.17 |     100 |    98.5 |                   
  ansi-light.ts    |     100 |      100 |     100 |     100 |                   
  ansi.ts          |     100 |      100 |     100 |     100 |                   
  atom-one-dark.ts |     100 |      100 |     100 |     100 |                   
  ayu-light.ts     |     100 |      100 |     100 |     100 |                   
  ayu.ts           |     100 |      100 |     100 |     100 |                   
  color-utils.ts   |   99.23 |    97.05 |     100 |   99.23 | 277-278           
  default-light.ts |     100 |      100 |     100 |     100 |                   
  default.ts       |     100 |      100 |     100 |     100 |                   
  ...inal-theme.ts |   88.59 |    85.96 |     100 |   88.59 | ...57-261,266-270 
  dracula.ts       |     100 |      100 |     100 |     100 |                   
  github-dark.ts   |     100 |      100 |     100 |     100 |                   
  github-light.ts  |     100 |      100 |     100 |     100 |                   
  googlecode.ts    |     100 |      100 |     100 |     100 |                   
  no-color.ts      |     100 |      100 |     100 |     100 |                   
  qwen-dark.ts     |     100 |      100 |     100 |     100 |                   
  qwen-light.ts    |     100 |      100 |     100 |     100 |                   
  ...tic-tokens.ts |     100 |      100 |     100 |     100 |                   
  ...-of-purple.ts |     100 |      100 |     100 |     100 |                   
  theme-manager.ts |   88.68 |    84.52 |     100 |   88.68 | ...83-392,397-398 
  theme.ts         |     100 |    38.02 |     100 |     100 | ...34-449,457-461 
  xcode.ts         |     100 |      100 |     100 |     100 |                   
 src/ui/utils      |   87.98 |    86.07 |    96.1 |   87.98 |                   
  ...Colorizer.tsx |   80.31 |    85.41 |     100 |   80.31 | ...00-201,313-339 
  ...nRenderer.tsx |   80.07 |     75.6 |     100 |   80.07 | ...70,274,332-333 
  ...wnDisplay.tsx |   92.87 |     93.5 |     100 |   92.87 | ...,955,1002-1020 
  ...idDiagram.tsx |   87.79 |    95.34 |     100 |   87.79 | 156-179           
  ...eRenderer.tsx |   93.63 |    81.77 |   95.23 |   93.63 | ...47-750,803-808 
  ...odeDisplay.ts |   94.28 |    85.71 |     100 |   94.28 | 23,40             
  asciiCharts.ts   |    96.7 |     87.5 |     100 |    96.7 | 170-177,278       
  ...dWorkUtils.ts |     100 |      100 |     100 |     100 |                   
  ...boardUtils.ts |    52.9 |    74.15 |    92.3 |    52.9 | ...29,632-641,644 
  commandUtils.ts  |   98.61 |    93.27 |     100 |   98.61 | 189,217-218,424   
  computeStats.ts  |     100 |      100 |     100 |     100 |                   
  customBanner.ts  |   90.68 |    91.22 |     100 |   90.68 | ...13,324-327,334 
  displayUtils.ts  |   73.84 |    73.91 |     100 |   73.84 | ...34,36-40,42-46 
  ...coalescing.ts |     100 |      100 |     100 |     100 |                   
  formatters.ts    |   94.87 |    98.24 |     100 |   94.87 | 116-119           
  goal-runtime.ts  |   94.44 |    96.29 |     100 |   94.44 | 32-34             
  gradientUtils.ts |     100 |      100 |     100 |     100 |                   
  highlight.ts     |     100 |      100 |     100 |     100 |                   
  ...gap-notice.ts |     100 |      100 |     100 |     100 |                   
  ...oryMapping.ts |     100 |    95.65 |     100 |     100 | 45,151            
  historyUtils.ts  |   96.07 |     97.1 |     100 |   96.07 | 104-107           
  ...mage-parts.ts |   97.75 |       95 |     100 |   97.75 | 82-83             
  inline-math.ts   |   98.48 |    95.23 |     100 |   98.48 | 129-130           
  input-mouse.ts   |     100 |    85.71 |     100 |     100 | 48,93             
  isNarrowWidth.ts |     100 |      100 |     100 |     100 |                   
  ...olDetector.ts |   68.81 |       75 |   66.66 |   68.81 | ...27-132,160-161 
  latexRenderer.ts |   94.95 |     73.8 |     100 |   94.95 | ...76-178,184-187 
  layoutUtils.ts   |     100 |      100 |     100 |     100 |                   
  list-mouse.ts    |     100 |      100 |     100 |     100 |                   
  ...ightLoader.ts |     100 |       95 |     100 |     100 | 81                
  ...nUtilities.ts |   98.72 |    94.36 |     100 |   98.72 | 145-146           
  ...t-position.ts |     100 |     87.5 |     100 |     100 | 85                
  ...geRenderer.ts |   86.51 |    70.16 |   95.12 |   86.51 | ...1286,1326-1332 
  ...alRenderer.ts |   86.69 |     71.9 |     100 |   86.69 | ...1476,1513-1519 
  ...lsBySource.ts |     100 |    95.23 |     100 |     100 | 84                
  mouse.ts         |   92.85 |    74.19 |     100 |   92.85 | ...38,145,149-152 
  osc8.ts          |   91.33 |    79.03 |     100 |   91.33 | ...73,273,277-278 
  ...red-height.ts |   98.38 |    97.14 |     100 |   98.38 | 195-197           
  ...mConstants.ts |     100 |      100 |     100 |     100 |                   
  restoreGoal.ts   |     100 |      100 |     100 |     100 |                   
  ...storyUtils.ts |   84.37 |    81.09 |     100 |   84.37 | ...03-625,759-760 
  ...ickerUtils.ts |     100 |      100 |     100 |     100 |                   
  ...evel-label.ts |   77.77 |    66.66 |     100 |   77.77 | 18,22-24          
  ...are-cursor.ts |   89.47 |    85.71 |     100 |   89.47 | 39-44             
  ...ataService.ts |   93.17 |     79.1 |     100 |   93.17 | ...14,227,254-256 
  suggestions.ts   |     100 |      100 |     100 |     100 |                   
  ...izedOutput.ts |   95.19 |      100 |   88.88 |   95.19 | 121-126           
  ...nal-buffer.ts |     100 |      100 |     100 |     100 |                   
  ...e-renderer.ts |   90.61 |    83.44 |     100 |   90.61 | ...80,482-484,607 
  ...ize-reflow.ts |     100 |     92.3 |     100 |     100 | 57,62,209,217,347 
  ...wOptimizer.ts |     100 |    94.73 |     100 |     100 | 35,78             
  terminalSetup.ts |    4.37 |      100 |       0 |    4.37 | 44-393            
  textUtils.ts     |   98.71 |    95.72 |     100 |   98.71 | 292-293,478-479   
  ...background.ts |     100 |      100 |     100 |     100 |                   
  todoSnapshot.ts  |   95.81 |     92.3 |     100 |   95.81 | ...09-210,243-244 
  ...isplay-map.ts |     100 |      100 |     100 |     100 |                   
  updateCheck.ts   |     100 |    92.75 |     100 |     100 | 227-239,331       
  windowTitle.ts   |   96.55 |    94.73 |     100 |   96.55 | 56-57             
  ...ow-keyword.ts |     100 |      100 |     100 |     100 |                   
 ...i/utils/export |   75.03 |     60.1 |   94.59 |   75.03 |                   
  collect.ts       |   71.27 |    65.81 |      96 |   71.27 | ...90-633,655-656 
  index.ts         |     100 |      100 |     100 |     100 |                   
  normalize.ts     |   80.42 |    51.35 |     100 |   80.42 | ...59-364,376-378 
  types.ts         |       0 |        0 |       0 |       0 | 1                 
  utils.ts         |     100 |      100 |     100 |     100 |                   
 ...ort/formatters |   52.92 |    47.22 |   71.42 |   52.92 |                   
  html.ts          |   84.61 |       50 |     100 |   84.61 | ...53,57-58,62-63 
  json.ts          |     100 |      100 |     100 |     100 |                   
  jsonl.ts         |   82.45 |     37.5 |     100 |   82.45 | ...48,50-51,65-66 
  markdown.ts      |   36.32 |    47.05 |      50 |   36.32 | ...16-219,233-295 
 src/ui/voice      |   81.24 |    79.78 |   81.69 |   81.24 |                   
  ...d-recorder.ts |     6.2 |      100 |       0 |     6.2 | ...33-159,162-163 
  ...o-recorder.ts |   84.61 |    93.33 |   57.14 |   84.61 | ...16-117,131-136 
  ...me-session.ts |   91.09 |     92.1 |     100 |   91.09 | ...99,305,316-319 
  sox-recorder.ts  |    92.7 |    71.87 |     100 |    92.7 | ...34-135,153-154 
  ...ailability.ts |     100 |      100 |     100 |     100 |                   
  ...e-keyterms.ts |     100 |      100 |     100 |     100 |                   
  voice-model.ts   |     100 |      100 |     100 |     100 |                   
  ...e-recorder.ts |   88.29 |    67.74 |   81.81 |   88.29 | ...,98-99,112,115 
  voice-refine.ts  |     100 |    93.33 |     100 |     100 | 92                
  ...ream-retry.ts |   86.79 |       70 |     100 |   86.79 | 16-18,48-49,59-60 
  ...am-session.ts |   88.02 |    66.66 |   84.61 |   88.02 | ...26,343-345,363 
  ...ranscriber.ts |     100 |      100 |     100 |     100 |                   
 src/utils         |   92.23 |    89.82 |   96.12 |   92.23 |                   
  ...p-profiler.ts |   98.39 |    92.59 |     100 |   98.39 | 141,185,235       
  acpModelUtils.ts |   97.36 |    95.09 |     100 |   97.36 | ...09-210,214-215 
  apiPreconnect.ts |   96.74 |    94.59 |     100 |   96.74 | 167-170           
  ...ol-call-id.ts |   84.61 |       60 |     100 |   84.61 | 26-27,37-38       
  checks.ts        |   33.33 |      100 |       0 |   33.33 | 23-28             
  ...-api-error.ts |     100 |    96.42 |     100 |     100 | 14                
  cleanup.ts       |   84.05 |    94.11 |      80 |   84.05 | 80,111-121        
  ...y-identity.ts |   89.22 |    85.18 |     100 |   89.22 | ...23-424,431-432 
  ...Calculator.ts |     100 |      100 |     100 |     100 |                   
  cpuProfiler.ts   |   70.73 |    73.23 |   88.88 |   70.73 | ...27,430-431,438 
  deepMerge.ts     |     100 |       90 |     100 |     100 | 50-52,58          
  ...re-runtime.ts |     100 |      100 |     100 |     100 |                   
  ...putCapture.ts |   90.65 |    86.31 |     100 |   90.65 | ...73,371,373-374 
  ...arResolver.ts |   97.14 |    96.55 |     100 |   97.14 | 125-126           
  errors.ts        |   97.56 |    94.64 |     100 |   97.56 | 69-70,304-305     
  events.ts        |     100 |      100 |     100 |     100 |                   
  ...on-mention.ts |   88.48 |     82.6 |     100 |   88.48 | ...56-160,164-168 
  gitUtils.ts      |   92.85 |    86.66 |     100 |   92.85 | ...13-116,164-167 
  ...tyWarnings.ts |     100 |      100 |     100 |     100 |                   
  ...lationInfo.ts |   97.81 |    94.69 |     100 |   97.81 | ...03,420-421,466 
  ...projection.ts |   95.27 |    95.58 |     100 |   95.27 | 140-145           
  jsonc-editor.ts  |   93.18 |    92.66 |     100 |   93.18 | ...80-381,384-385 
  load-undici.ts   |     100 |      100 |     100 |     100 |                   
  ...npm-update.ts |   86.64 |    77.02 |     100 |   86.64 | ...03-304,335-345 
  math.ts          |       0 |        0 |       0 |       0 | 1-15              
  ...er-mention.ts |     100 |    66.66 |     100 |     100 | 14,30,44-46       
  ...iagnostics.ts |   94.57 |    83.01 |   88.88 |   94.57 | ...05,311,315-317 
  ...serMessage.ts |     100 |      100 |     100 |     100 |                   
  ...onfigUtils.ts |   94.25 |    91.17 |     100 |   94.25 | ...30,436,439-443 
  ...-part-list.ts |     100 |      100 |     100 |     100 |                   
  osc.ts           |   97.18 |      100 |    87.5 |   97.18 | 182-183           
  package.ts       |   88.88 |    85.71 |     100 |   88.88 | 31-32             
  paths.ts         |     100 |      100 |     100 |     100 |                   
  processUtils.ts  |    92.3 |       80 |     100 |    92.3 | 45-46             
  readStdin.ts     |   93.67 |    94.11 |   85.71 |   93.67 | 79-83             
  relaunch.ts      |   95.87 |    89.28 |     100 |   95.87 | 103-105,131       
  resolvePath.ts   |     100 |      100 |     100 |     100 |                   
  runBudget.ts     |   99.35 |    96.77 |     100 |   99.35 | 119               
  sandbox-path.ts  |     100 |      100 |     100 |     100 |                   
  ...xImageName.ts |     100 |    77.77 |     100 |     100 | 10,18             
  sandboxMounts.ts |     100 |      100 |     100 |     100 |                   
  ...-path-argv.ts |     100 |      100 |     100 |     100 |                   
  sessionPaths.ts  |   90.84 |    90.56 |     100 |   90.84 | ...81-182,185-186 
  shell-args.ts    |     100 |      100 |     100 |     100 |                   
  spawnWrapper.ts  |     100 |      100 |     100 |     100 |                   
  ...ate-verify.ts |     100 |      100 |     100 |     100 |                   
  ...upProfiler.ts |   98.47 |    94.66 |     100 |   98.47 | 132-133,308       
  ...upWarnings.ts |     100 |      100 |     100 |     100 |                   
  stdioHelpers.ts  |   76.66 |       90 |   83.33 |   76.66 | 93-99             
  ...alSequence.ts |     100 |    97.61 |     100 |     100 | 60                
  ...iffPreview.ts |   76.47 |       25 |     100 |   76.47 | 13,17,23-24       
  ...on-handler.ts |    73.8 |       75 |     100 |    73.8 | 17-18,25-26,67-73 
  ...entEmitter.ts |     100 |      100 |     100 |     100 |                   
  ...ansionHook.ts |     100 |      100 |     100 |     100 |                   
  ...upWarnings.ts |   87.75 |       75 |     100 |   87.75 | 47-48,53-54,57-58 
  version.ts       |     100 |    66.66 |     100 |     100 | 11                
  ...ingHandler.ts |     100 |      100 |     100 |     100 |                   
  ...WithBackup.ts |   65.04 |    77.77 |     100 |   65.04 | 97,112,133-172    
 ...s/housekeeping |   94.35 |    94.11 |     100 |   94.35 |                   
  cleanup.ts       |   92.59 |    93.75 |     100 |   92.59 | ...02-205,209-211 
  ...eractionAt.ts |     100 |      100 |     100 |     100 |                   
  throttledOnce.ts |   95.95 |    93.93 |     100 |   95.95 | 77-78,153-154     
-------------------|---------|----------|---------|---------|-------------------
Core Package - Full Text Report
-------------------|---------|----------|---------|---------|-------------------
File               | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-------------------|---------|----------|---------|---------|-------------------
All files          |   88.75 |     87.2 |   90.51 |   88.75 |                   
 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.26 |    84.51 |   94.55 |   90.26 |                   
  ...transcript.ts |   88.49 |    84.09 |     100 |   88.49 | ...32,640,646-650 
  ...ent-resume.ts |   85.74 |       78 |    85.1 |   85.74 | ...1803-1807,1810 
  ...ound-tasks.ts |   95.19 |    90.75 |   96.42 |   95.19 | ...1889,1897-1898 
  forkedAgent.ts   |   93.21 |    83.47 |   94.44 |   93.21 | ...94,702,707-714 
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...ent-result.ts |    96.8 |    92.68 |     100 |    96.8 | 106,129-131       
  ...n-registry.ts |   95.27 |    88.23 |   98.33 |   95.27 | ...1478,1492-1494 
  ...w-snapshot.ts |   75.73 |    72.22 |    87.5 |   75.73 | ...21,445,452-454 
  worktree-pin.ts  |     100 |    88.23 |     100 |     100 | 78,99             
 src/agents/arena  |   76.87 |    68.43 |   78.94 |   76.87 |                   
  ...gentClient.ts |   79.47 |    88.88 |   81.81 |   79.47 | ...68-183,189-204 
  ArenaManager.ts  |    75.8 |    65.46 |   78.57 |    75.8 | ...1879,1885-1886 
  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 |   77.32 |    86.38 |   75.52 |   77.32 |                   
  ITermBackend.ts  |   97.97 |    93.93 |     100 |   97.97 | ...78-180,255,307 
  ...essBackend.ts |   91.45 |    90.21 |   96.87 |   91.45 | ...66-467,586-592 
  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 |   93.37 |    87.56 |   92.44 |   93.37 |                   
  agent-context.ts |     100 |      100 |     100 |     100 |                   
  agent-core.ts    |   90.39 |    80.91 |   81.25 |   90.39 | ...2551,2597-2599 
  agent-events.ts  |     100 |      100 |     100 |     100 |                   
  ...t-headless.ts |   93.57 |    89.41 |   83.33 |   93.57 | ...04-505,508-509 
  ...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.38 |      100 |    92.3 |   98.38 | 85-86             
  ...low-budget.ts |     100 |      100 |     100 |     100 |                   
  ...-scheduler.ts |   97.43 |    96.36 |     100 |   97.43 | 128-130           
  ...ow-journal.ts |   92.78 |    78.12 |     100 |   92.78 | ...49-150,192-194 
  ...ta-literal.ts |   95.96 |    92.68 |     100 |   95.96 | ...78-379,395-396 
  ...chestrator.ts |   93.85 |    90.47 |     100 |   93.85 | ...2206,2299-2302 
  ...ow-prompts.ts |     100 |      100 |     100 |     100 |                   
  ...low-runner.ts |   95.77 |    84.16 |      95 |   95.77 | ...88,356,376-379 
  ...ow-sandbox.ts |   97.29 |    88.84 |     100 |   97.29 | ...1835,1841-1842 
  ...flow-saved.ts |    96.7 |     93.9 |     100 |    96.7 | 153-154,261-264   
  ...flow-stall.ts |    97.9 |    83.33 |     100 |    97.9 | 170-171,270       
 src/agents/tasks  |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/agents/team   |   84.84 |    85.82 |   91.09 |   84.84 |                   
  TeamManager.ts   |   78.24 |    83.83 |   84.12 |   78.24 | ...1907,1930-1931 
  identity.ts      |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...sionBridge.ts |     100 |      100 |     100 |     100 |                   
  mailbox.ts       |   96.02 |     87.5 |     100 |   96.02 | 352-358           
  ...ptAddendum.ts |     100 |      100 |     100 |     100 |                   
  tasks.ts         |   89.29 |       83 |     100 |   89.29 | ...1000,1044-1045 
  team-events.ts   |   73.68 |      100 |   66.66 |   73.68 | 140-144,151-155   
  teamHelpers.ts   |    92.5 |    95.45 |      95 |    92.5 | ...29-330,393-403 
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...eam/test-utils |   95.28 |    95.34 |   98.24 |   95.28 |                   
  ...on-harness.ts |   96.49 |    85.71 |     100 |   96.49 | 128-129,141-142   
  fake-agent.ts    |     100 |    96.96 |     100 |     100 | 189,198           
  fake-backend.ts  |   86.46 |    97.61 |   95.83 |   86.46 | 124-146           
 src/config        |   86.21 |    88.39 |   78.34 |   86.21 |                   
  approval-mode.ts |     100 |      100 |     100 |     100 |                   
  ...xtDefaults.ts |     100 |      100 |     100 |     100 |                   
  config.ts        |   84.91 |    87.81 |   76.32 |   84.91 | ...9653,9657-9659 
  ...ionManager.ts |     100 |     90.9 |     100 |     100 | 27                
  models.ts        |     100 |      100 |     100 |     100 |                   
  ...sDiscovery.ts |   97.46 |    93.05 |     100 |   97.46 | ...04,182-183,202 
  storage.ts       |   96.05 |    93.43 |   89.47 |   96.05 | ...34-735,738-739 
 ...nfirmation-bus |   98.27 |    97.22 |     100 |   98.27 |                   
  message-bus.ts   |   98.14 |    97.14 |     100 |   98.14 | 42-43             
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/core          |   92.83 |    88.65 |   93.87 |   92.83 |                   
  ...on-restore.ts |   88.23 |    85.41 |     100 |   88.23 | ...60,63-64,67-68 
  baseLlmClient.ts |    88.4 |    83.68 |   81.81 |    88.4 | ...59,672,678-680 
  client.ts        |   92.36 |    88.22 |   91.83 |   92.36 | ...4537,4635-4636 
  ...tGenerator.ts |   87.45 |    88.09 |   88.88 |   87.45 | ...08-509,554-560 
  ...lScheduler.ts |   90.23 |    85.01 |   94.73 |   90.23 | ...6512,6540-6556 
  ...entContext.ts |   96.63 |    90.13 |   96.66 |   96.63 | ...42,444-445,512 
  geminiChat.ts    |     100 |      100 |     100 |     100 |                   
  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 |                   
  llm-chat.ts      |   95.21 |    90.81 |   96.69 |   95.21 | ...5744,5789-5790 
  llm-request.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 | 46-47             
  output-styles.ts |     100 |      100 |     100 |     100 |                   
  ...on-helpers.ts |   95.38 |    84.31 |     100 |   95.38 | ...87,215,217-218 
  ...issionFlow.ts |   98.98 |    96.96 |     100 |   98.98 | 109               
  ...try-policy.ts |     100 |      100 |     100 |     100 |                   
  ...ell-policy.ts |   94.89 |    88.54 |     100 |   94.89 | ...51-252,297-298 
  prompts.ts       |   93.89 |    91.12 |      85 |   93.89 | ...1272,1475-1476 
  ...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        
  ...-arguments.ts |     100 |      100 |     100 |     100 |                   
  ...reparation.ts |     100 |      100 |     100 |     100 |                   
  ...tion-guard.ts |   90.38 |    94.73 |     100 |   90.38 | 83-87             
  ...allIdUtils.ts |   98.81 |    91.22 |     100 |   98.81 | 43,52             
  ...okTriggers.ts |   99.45 |     92.5 |     100 |   99.45 | 182,193           
  ...terruption.ts |     100 |     92.3 |     100 |     100 | 86,104            
  turn.ts          |   99.19 |    94.48 |     100 |   99.19 | 765-766,835       
  ...l-fallback.ts |     100 |      100 |     100 |     100 |                   
 ...ntentGenerator |   96.58 |    89.11 |   97.43 |   96.58 |                   
  ...tGenerator.ts |   97.66 |    88.91 |   97.43 |   97.66 | ...1494,1523,1534 
  converter.ts     |   96.19 |    89.25 |     100 |   96.19 | ...1334,1555-1557 
  index.ts         |       0 |        0 |       0 |       0 | 1-21              
  usage.ts         |     100 |      100 |     100 |     100 |                   
 ...ntentGenerator |     100 |      100 |     100 |     100 |                   
  ...tGenerator.ts |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
 ...tent-generator |   89.24 |    72.72 |   94.11 |   89.24 |                   
  index.ts         |     100 |    85.71 |     100 |     100 | 51                
  ...-generator.ts |   87.54 |    71.42 |   93.75 |   87.54 | ...93-294,356-362 
 ...ntentGenerator |   95.78 |    90.51 |   96.22 |   95.78 |                   
  ...e-snapshot.ts |   97.39 |    89.65 |     100 |   97.39 | ...,49-50,151-152 
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...tGenerator.ts |   95.38 |    90.14 |   95.12 |   95.38 | ...1345-1346,1374 
  ...tDetection.ts |     100 |      100 |     100 |     100 |                   
 ...ntentGenerator |   92.33 |    90.93 |   96.58 |   92.33 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  converter.ts     |   91.25 |    89.66 |   96.87 |   91.25 | ...1946,2115-2130 
  errorHandler.ts  |     100 |      100 |     100 |     100 |                   
  index.ts         |   76.19 |    88.88 |      50 |   76.19 | 44-53,90-94       
  ...tGenerator.ts |      70 |    73.33 |     100 |      70 | ...07-112,121-127 
  pipeline.ts      |   95.38 |    91.56 |     100 |   95.38 | ...1461-1462,1569 
  ...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.11 |    92.25 |     100 |   92.11 | ...21-522,542-545 
  ...kingParser.ts |     100 |    96.87 |     100 |     100 | 42                
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 ...rator/provider |   97.24 |       92 |   98.64 |   97.24 |                   
  dashscope.ts     |   98.42 |    95.27 |   96.55 |   98.42 | ...51-752,894-895 
  deepseek.ts      |   95.34 |    90.56 |     100 |   95.34 | ...54-155,168-169 
  default.ts       |   98.87 |       96 |     100 |   98.87 | 178,304           
  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 |                   
  openrouter.ts    |     100 |      100 |     100 |     100 |                   
  types.ts         |       0 |        0 |       0 |       0 |                   
  utils.ts         |     100 |      100 |     100 |     100 |                   
  zai.ts           |      90 |    76.31 |     100 |      90 | ...,72-73,173-175 
 src/extension     |   88.79 |    86.22 |   93.46 |   88.79 |                   
  ...ive-safety.ts |   97.77 |    93.75 |     100 |   97.77 | 100-101           
  ...-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 |                   
  ...git-client.ts |     100 |      100 |     100 |     100 |                   
  ...redentials.ts |   95.33 |    89.47 |     100 |   95.33 | ...21-122,173-175 
  ...me-refresh.ts |     100 |      100 |     100 |     100 |                   
  ...sion-store.ts |   92.82 |    89.27 |    98.3 |   92.82 | ...1641-1647,1691 
  ...ionManager.ts |   84.52 |    83.52 |      83 |   84.52 | ...3139,3177-3178 
  ...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        |   92.43 |    87.52 |     100 |   92.43 | ...1293-1294,1304 
  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.16 |     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.54 |     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.33 |     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      |   84.78 |    82.27 |   86.84 |   84.78 |                   
  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   |   76.53 |    71.96 |   58.33 |   76.53 | ...48-749,756-757 
  ...onToolGate.ts |   97.97 |     87.5 |     100 |   97.97 | 105,110           
  ...nGenerator.ts |   86.11 |    87.17 |     100 |   86.11 | ...39-244,356-358 
 src/generated     |       0 |        0 |       0 |       0 |                   
  git-commit.ts    |       0 |        0 |       0 |       0 | 1-10              
 src/goals         |   93.59 |    90.38 |      95 |   93.59 |                   
  ...eGoalStore.ts |   87.61 |    88.88 |   86.66 |   87.61 | ...85-188,196-204 
  ...t-verifier.ts |   99.45 |    97.05 |     100 |   99.45 | 155               
  ...checkpoint.ts |   86.08 |    85.18 |     100 |   86.08 | ...29-132,142-145 
  ...ion-prompt.ts |     100 |      100 |     100 |     100 |                   
  goal-evidence.ts |    88.7 |     88.2 |   97.67 |    88.7 | ...1219,1242-1245 
  ...projection.ts |   66.66 |    72.97 |   33.33 |   66.66 | ...87,190,194-196 
  ...ersistence.ts |   87.36 |    85.96 |    87.5 |   87.36 | ...53-154,185-190 
  goal-protocol.ts |   97.56 |    96.42 |     100 |   97.56 | 322-323           
  goal-reducer.ts  |   95.75 |    93.82 |   97.36 |   95.75 | ...76,666,684-685 
  goal-runtime.ts  |   96.51 |    90.64 |   96.49 |   96.51 | ...1645-1646,1777 
  ...provenance.ts |     100 |      100 |     100 |     100 |                   
  goal-tools.ts    |   98.58 |     95.2 |   96.15 |   98.58 | ...41-242,350-351 
  ...rn-context.ts |     100 |      100 |     100 |     100 |                   
  goal-verifier.ts |   92.46 |    93.02 |     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         |   89.12 |     87.1 |    89.8 |   89.12 |                   
  ...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    |   75.58 |    83.23 |   87.87 |   75.58 | ...25-927,937-940 
  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 |   82.47 |    84.21 |      75 |   82.47 | 63-67,169-184     
  ...oksManager.ts |   94.87 |    90.12 |     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.09 |   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/ipc           |   92.72 |    90.15 |    97.5 |   92.72 |                   
  inbound-gate.ts  |   98.93 |     89.1 |     100 |   98.93 | 522-524           
  peer-envelope.ts |     100 |      100 |     100 |     100 |                   
  peer-frames.ts   |   97.45 |    93.65 |     100 |   97.45 | 235-237           
  socket-path.ts   |   85.71 |    93.33 |     100 |   85.71 | 83-88             
  uds-client.ts    |   85.71 |    94.11 |      80 |   85.71 | 162-175           
  uds-inbox.ts     |   82.42 |    81.81 |     100 |   82.42 | ...33,240-250,282 
 src/lsp           |   58.96 |    70.67 |   66.49 |   58.96 |                   
  ...nfigLoader.ts |   80.55 |    72.22 |   95.65 |   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 |    81.81 |   21.05 |   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.48 |   89.28 |   82.12 |                   
  ...en-storage.ts |     100 |      100 |     100 |     100 |                   
  ...en-storage.ts |   87.08 |    87.71 |   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        |   88.82 |    85.24 |    90.9 |   88.82 |                   
  ...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 
  dream.ts         |    64.6 |    72.22 |      50 |    64.6 | ...04-109,124-165 
  ...entPlanner.ts |     100 |    83.33 |     100 |     100 | 135,145           
  entries.ts       |   75.59 |    84.84 |   83.33 |   75.59 | ...56-157,172-180 
  extract.ts       |   93.82 |    84.09 |     100 |   93.82 | 78-83,122,154-157 
  ...entPlanner.ts |   91.55 |    76.74 |     100 |   91.55 | ...05,118-121,296 
  ...ionPlanner.ts |       0 |        0 |       0 |       0 | 1                 
  forget.ts        |   90.16 |    78.76 |   94.44 |   90.16 | ...06,629,642-648 
  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.51 |    83.16 |   77.77 |   78.51 | ...1487,1500-1502 
  ...ent-config.ts |   87.64 |    83.62 |      88 |   87.64 | ...08,411-425,437 
  memoryAge.ts     |   90.47 |    83.33 |     100 |   90.47 | 50-51             
  ...yDiscovery.ts |   93.48 |    90.09 |     100 |   93.48 | ...42,401,629-632 
  paths.ts         |     100 |      100 |     100 |     100 |                   
  ...ing-skills.ts |     100 |       72 |     100 |     100 | 31-35,73-78,97    
  prompt.ts        |   97.26 |    86.79 |     100 |   97.26 | ...10-218,222,225 
  recall.ts        |   86.86 |    86.23 |   92.85 |   86.86 | ...33-538,571-582 
  refresh.ts       |   93.58 |    89.58 |     100 |   93.58 | ...75-176,183-184 
  ...ceSelector.ts |    93.2 |    85.71 |     100 |    93.2 | ...45-146,148-149 
  remember.ts      |   98.88 |    90.38 |     100 |   98.88 | 50,70             
  scan.ts          |   93.75 |       80 |     100 |   93.75 | ...08-109,154,157 
  scopes.ts        |     100 |      100 |     100 |     100 |                   
  ...et-scanner.ts |     100 |      100 |     100 |     100 |                   
  ...entPlanner.ts |   73.92 |       75 |   66.66 |   73.92 | ...78-482,485,491 
  status.ts        |   10.52 |      100 |       0 |   10.52 | 41-98             
  store.ts         |   92.92 |    81.81 |     100 |   92.92 | ...16-117,147-148 
  ...git-status.ts |     100 |    85.71 |     100 |     100 | 27                
  ...cret-guard.ts |     100 |      100 |     100 |     100 |                   
  ...emory-sync.ts |   94.24 |    82.85 |     100 |   94.24 | ...34-236,246-247 
  types.ts         |     100 |      100 |     100 |     100 |                   
  ...ontextFile.ts |   81.21 |    81.53 |   81.81 |   81.21 | ...66-280,294-299 
 src/mocks         |       0 |        0 |       0 |       0 |                   
  msw.ts           |       0 |        0 |       0 |       0 | 1-9               
 src/models        |   92.82 |    89.39 |   91.35 |   92.82 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  ...tor-config.ts |   97.77 |    91.83 |     100 |   97.77 | 155,161,171       
  ...capability.ts |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...nfigErrors.ts |   79.43 |    64.51 |   85.71 |   79.43 | ...,89-96,131-142 
  ...igResolver.ts |   98.71 |    93.33 |     100 |   98.71 | 166,328,334       
  modelRegistry.ts |     100 |    98.11 |     100 |     100 | 177,262           
  modelsConfig.ts  |   89.36 |    86.93 |   88.09 |   89.36 | ...1407,1436-1437 
  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   |   84.45 |    91.47 |    72.4 |   84.45 |                   
  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.79 |     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 |      89 |    90.99 |   86.84 |      89 | ...1461,1567-1571 
  rule-parser.ts   |   94.89 |    92.83 |     100 |   94.89 | ...1550,1584-1586 
  ...-semantics.ts |   70.44 |    91.09 |   46.66 |   70.44 | ...2237,2311-2314 
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...sifier-prompts |   99.05 |    95.23 |     100 |   99.05 |                   
  system-prompt.ts |   99.05 |    95.23 |     100 |   99.05 | 226               
 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     |   85.14 |    80.63 |   82.85 |   85.14 |                   
  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 
  ...-discovery.ts |    95.4 |    94.44 |     100 |    95.4 | 31-32,42-43       
  ...der-config.ts |   75.91 |    73.48 |   78.26 |   75.91 | ...74-475,503-504 
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 ...viders/presets |   98.04 |    91.66 |   63.63 |   98.04 |                   
  ...oding-plan.ts |    87.5 |      100 |       0 |    87.5 | 82-84,87-89,91-94 
  ...a-standard.ts |     100 |      100 |     100 |     100 |                   
  ...token-plan.ts |     100 |      100 |     100 |     100 |                   
  ...m-provider.ts |   97.05 |    81.25 |      75 |   97.05 | 118-119           
  deepseek.ts      |     100 |      100 |     100 |     100 |                   
  grok.ts          |     100 |      100 |     100 |     100 |                   
  idealab.ts       |     100 |      100 |     100 |     100 |                   
  minimax.ts       |     100 |      100 |     100 |     100 |                   
  modelscope.ts    |     100 |      100 |     100 |     100 |                   
  moonshot.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.36 |    78.82 |   95.94 |   85.36 |                   
  ...tGenerator.ts |    98.6 |    98.14 |     100 |    98.6 | 103-104           
  qwenOAuth2.ts    |   82.79 |    73.91 |    90.9 |   82.79 | ...1205-1221,1251 
  ...kenManager.ts |   85.36 |     76.8 |     100 |   85.36 | ...52-757,778-783 
 src/resources     |     100 |      100 |     100 |     100 |                   
  ...e-registry.ts |     100 |      100 |     100 |     100 |                   
 src/services      |   90.64 |    86.19 |   96.55 |   90.64 |                   
  ...ionTrailer.ts |     100 |      100 |     100 |     100 |                   
  ...llRegistry.ts |   98.48 |    87.28 |     100 |   98.48 | 81-82,105,474-475 
  branch-points.ts |     100 |    95.23 |     100 |     100 | ...20,211,224,327 
  ...ionService.ts |   97.72 |    96.53 |     100 |   97.72 | ...1081,1224-1232 
  ...ingService.ts |    92.6 |    88.12 |   94.73 |    92.6 | ...2856,2871-2872 
  ...ttribution.ts |   91.73 |    87.71 |      90 |   91.73 | ...80-685,826-827 
  ...utSlimming.ts |    97.2 |    94.23 |     100 |    97.2 | ...39-340,378-381 
  cronScheduler.ts |   94.17 |    90.45 |      98 |   94.17 | ...1333,1736-1737 
  cronTasksFile.ts |   95.52 |    90.99 |     100 |   95.52 | ...37,346-347,483 
  cronTasksLock.ts |   94.44 |    89.47 |     100 |   94.44 | ...02-103,132-133 
  ...eryService.ts |   96.22 |    93.54 |      90 |   96.22 | 121,155-156,161   
  ...oryService.ts |   88.17 |    79.02 |    92.3 |   88.17 | ...1303,1344-1347 
  fileReadCache.ts |    97.5 |    96.07 |     100 |    97.5 | 349-350,363-364   
  ...temService.ts |    92.8 |    84.68 |   94.11 |    92.8 | ...53,479-486,531 
  ...ratedFiles.ts |      96 |    88.23 |     100 |      96 | 119-120,146-147   
  gitInit.ts       |     100 |      100 |     100 |     100 |                   
  ...reeService.ts |   74.75 |    70.76 |   96.07 |   74.75 | ...2296,2325-2326 
  ...on-service.ts |   86.58 |    74.39 |     100 |   86.58 | ...56-460,498-499 
  ...references.ts |   98.57 |    91.42 |     100 |   98.57 | 156-157,217-218   
  ...ionService.ts |   98.26 |    97.23 |     100 |   98.26 | ...65-866,889-890 
  ...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.22 |    90.99 |     100 |   97.22 | ...55-456,609-610 
  ...ttachments.ts |   97.74 |     90.9 |     100 |   97.74 | 298-308,646       
  ...pi-history.ts |   98.94 |    89.13 |     100 |   98.94 | 43                
  ...ersistence.ts |   91.88 |    81.19 |     100 |   91.88 | ...1073-1074,1119 
  ...tory-state.ts |     100 |    95.23 |     100 |     100 | 31                
  ...on-service.ts |   94.61 |    92.44 |   97.22 |   94.61 | ...11-613,669-677 
  ...pr-service.ts |   96.04 |    89.74 |     100 |   96.04 | 72,98-101,190-191 
  ...ce-service.ts |    98.5 |    94.11 |    90.9 |    98.5 | 64-65             
  ...n-registry.ts |   98.74 |    94.92 |     100 |   98.74 | 601,655-656,714   
  ...ken-counts.ts |     100 |       96 |     100 |     100 | 58                
  ...ipt-reader.ts |    93.7 |    91.22 |    97.8 |    93.7 | ...2791-2792,2869 
  ...turn-state.ts |   94.11 |     90.9 |   91.66 |   94.11 | 108-112,129-130   
  ...est-helper.ts |       0 |        0 |       0 |       0 | 1-65              
  ...iter-lease.ts |   84.57 |    75.18 |   97.72 |   84.57 | ...2567,2589,2603 
  sessionRecap.ts  |   67.56 |    43.47 |     100 |   67.56 | ...60,178,180-183 
  ...ionService.ts |   88.82 |    85.68 |    91.4 |   88.82 | ...4049-4050,4091 
  sessionTitle.ts  |   96.35 |    79.71 |     100 |   96.35 | ...08-311,342-343 
  ...ContextEnv.ts |     100 |    94.73 |     100 |     100 | 76,111            
  ...ionService.ts |   84.43 |    78.45 |   97.18 |   84.43 | ...2496,2502-2507 
  ...pInhibitor.ts |   97.42 |    92.77 |     100 |   97.42 | ...30,169,369-370 
  ...e-encoding.ts |   85.96 |    76.47 |     100 |   85.96 | 58-61,64-65,78-79 
  ...Estimation.ts |     100 |    95.83 |     100 |     100 | 139               
  ...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.77 |    84.92 |     100 |   90.77 | ...43-546,598-599 
  ...l-registry.ts |   92.99 |    83.19 |     100 |   92.99 | ...66-367,377-378 
  ...reeCleanup.ts |   14.42 |      100 |   33.33 |   14.42 | 58-186            
  ...ionService.ts |   88.36 |     87.7 |     100 |   88.36 | ...48-449,465-466 
 ...icrocompaction |   98.91 |    95.08 |     100 |   98.91 |                   
  microcompact.ts  |   98.91 |    95.08 |     100 |   98.91 | ...60,769,778-779 
 ...s/visionBridge |    98.8 |    92.12 |     100 |    98.8 |                   
  ...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             
  ...ge-service.ts |   98.61 |     94.7 |     100 |   98.61 | ...06,666,679-680 
 src/skills        |   89.78 |    86.08 |   94.73 |   89.78 |                   
  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.69 |     100 |   94.84 | ...03,223,235-237 
  skill-manager.ts |   86.11 |    85.71 |   86.11 |   86.11 | ...1244,1251-1255 
  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.07 |     100 |   97.91 | 286-287           
 ...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     |   88.58 |    89.46 |    98.3 |   88.58 |                   
  ...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 |   85.54 |    86.59 |   97.43 |   85.54 | ...1588,1665-1666 
  types.ts         |     100 |      100 |     100 |     100 |                   
  validation.ts    |   92.46 |    95.18 |     100 |   92.46 | 47-52,63-68,71-76 
 src/telemetry     |   83.23 |    84.98 |   86.51 |   83.23 |                   
  ...ty-tracker.ts |     100 |      100 |     100 |     100 |                   
  config.ts        |     100 |      100 |     100 |     100 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  context-usage.ts |   96.85 |    91.07 |     100 |   96.85 | ...26-127,199-200 
  ...on-metrics.ts |   99.08 |    80.95 |     100 |   99.08 | 185,199           
  ...on-tracing.ts |   80.71 |    81.91 |   79.16 |   80.71 | ...92,499-501,517 
  ...attributes.ts |   96.98 |    91.37 |     100 |   96.98 | ...47-348,366-367 
  ...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.38 |    83.33 |      50 |   65.38 | ...08-109,112-113 
  ...ai-content.ts |    74.5 |    66.41 |   91.66 |    74.5 | ...1480,1493-1502 
  ...i-provider.ts |     100 |    99.02 |     100 |     100 | 106               
  ...ai-request.ts |   87.88 |    92.79 |   83.78 |   87.88 | ...55-561,564-568 
  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.12 |    96.03 |      95 |   99.12 | 150,379-380       
  ...t.circular.ts |       0 |        0 |       0 |       0 | 1-128             
  loggers.ts       |   60.83 |    77.77 |   66.66 |   60.83 | ...1523,1540-1560 
  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      |   94.13 |    86.66 |      75 |   94.13 | ...45,496-497,513 
  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.29 |    88.88 |    97.5 |   91.29 | ...1946,1975-1978 
  ...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.26 |    88.81 |   86.36 |   83.26 | ...1467,1471-1478 
  uiTelemetry.ts   |   98.87 |     95.1 |   97.05 |   98.87 | ...59,696,786-787 
 ...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.64 |   84.09 |   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 |      80 |   94.85 | ...53,227-228,241 
  ...aceContext.ts |     100 |      100 |     100 |     100 |                   
 src/tools         |   87.55 |    86.06 |   90.21 |   87.55 |                   
  ...erQuestion.ts |   89.71 |    81.13 |    92.3 |   89.71 | ...66-367,374-375 
  ...-registrar.ts |    77.7 |    66.66 |   66.66 |    77.7 | ...72-277,292-294 
  ...ub-session.ts |   89.72 |    91.48 |   83.33 |   89.72 | ...06-307,318-325 
  cron-create.ts   |   92.26 |    97.72 |      75 |   92.26 | ...,76-77,272-281 
  cron-delete.ts   |   97.56 |      100 |   85.71 |   97.56 | 31-32             
  cron-list.ts     |   98.23 |    95.45 |   88.88 |   98.23 | 57-58             
  diffOptions.ts   |     100 |      100 |     100 |     100 |                   
  display-image.ts |   87.42 |    85.71 |    90.9 |   87.42 | ...29-134,194-195 
  edit.ts          |   82.76 |    86.88 |   82.35 |   82.76 | ...45-746,865-915 
  ...r-worktree.ts |   83.14 |    68.42 |   88.88 |   83.14 | ...84-187,278-279 
  enterPlanMode.ts |      85 |       84 |      90 |      85 | ...28-133,161-175 
  exit-worktree.ts |   83.29 |     83.8 |   94.73 |   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.71 |   86.36 |   90.73 | ...76-677,727-728 
  ...adTracking.ts |     100 |      100 |     100 |     100 |                   
  image-gen.ts     |   91.66 |    78.12 |   91.66 |   91.66 | ...13-214,221-222 
  list-agents.ts   |   94.11 |    83.33 |   85.71 |   94.11 | 31-32,47-48       
  loop-wakeup.ts   |   99.27 |     93.1 |     100 |   99.27 | 45                
  ls.ts            |   96.74 |    90.54 |     100 |   96.74 | 176-181,212,216   
  lsp.ts           |   72.71 |     59.9 |    90.9 |   72.71 | ...1212,1214-1215 
  ...nt-manager.ts |   82.07 |    80.15 |   85.71 |   82.07 | ...3243,3245-3246 
  mcp-client.ts    |   86.25 |    87.61 |   93.93 |   86.25 | ...2552,2556-2559 
  ...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 | ...1342,1350-1351 
  ...ool-events.ts |       8 |      100 |       0 |       8 | 132-158           
  mcp-pool-key.ts  |    97.5 |    93.93 |     100 |    97.5 | 178-179           
  ...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.1 |       93 |     100 |    98.1 | ...1233,1288-1289 
  ...sport-pool.ts |   83.98 |     80.3 |   88.46 |   83.98 | ...1411,1418-1422 
  ...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.39 |   82.35 |   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.61 |    87.5 |   95.49 | ...49,464,536-537 
  ...p-resource.ts |   96.85 |      100 |   91.66 |   96.85 | 92-96             
  readManyFiles.ts |   96.04 |    82.25 |     100 |   96.04 | ...41,594,604-608 
  ...d-artifact.ts |   85.68 |    81.59 |   94.73 |   85.68 | ...1071,1095-1096 
  ...t-findings.ts |   99.13 |    93.93 |    92.3 |   99.13 | 256-258           
  ...t-shutdown.ts |    87.2 |    86.66 |   77.77 |    87.2 | ...,75-79,162-165 
  ripGrep.ts       |    94.6 |    87.34 |   95.45 |    94.6 | ...33-734,740-741 
  ...-transport.ts |   71.42 |    55.55 |   71.42 |   71.42 | ...36-137,143-144 
  send-message.ts  |    81.5 |    90.69 |   66.66 |    81.5 | ...80-286,354-361 
  ...n-mcp-view.ts |   94.07 |    91.89 |    90.9 |   94.07 | 131-139           
  shell.ts         |   78.96 |    84.29 |      93 |   78.96 | ...5036,5111-5112 
  skill-utils.ts   |     100 |      100 |     100 |     100 |                   
  skill.ts         |   93.56 |    90.78 |   91.66 |   93.56 | ...49,653,701-723 
  ...-constants.ts |     100 |      100 |     100 |     100 |                   
  ...eticOutput.ts |   95.12 |      100 |      80 |   95.12 | 87-88             
  task-create.ts   |    94.4 |    93.75 |   83.33 |    94.4 | 45-49,63-64,95    
  task-list.ts     |   80.43 |    86.95 |   85.71 |   80.43 | ...67,121,125-132 
  task-stop.ts     |   93.14 |    96.29 |    87.5 |   93.14 | 39-40,54-64       
  task-update.ts   |   82.87 |     86.5 |   92.85 |   82.87 | ...54-564,588-599 
  team-create.ts   |   97.24 |     87.5 |   85.71 |   97.24 | 48-49,129-130     
  team-delete.ts   |   86.74 |    84.61 |   85.71 |   86.74 | 37-38,42-48,72-73 
  ...n-approval.ts |   92.14 |    96.96 |   81.81 |   92.14 | 38-39,42-43,93-99 
  todoWrite.ts     |   95.73 |    90.47 |   93.75 |   95.73 | ...48-552,565-570 
  ...repeat-key.ts |     100 |      100 |     100 |     100 |                   
  tool-error.ts    |     100 |      100 |     100 |     100 |                   
  tool-names.ts    |     100 |      100 |     100 |     100 |                   
  tool-registry.ts |   80.48 |    82.45 |   86.53 |   80.48 | ...1099,1107-1108 
  ...-finalizer.ts |    98.1 |    92.36 |   93.33 |    98.1 | ...34-235,237-241 
  ...iagnostics.ts |   99.06 |    97.69 |   91.66 |   99.06 | 133-134,205       
  ...-retention.ts |     100 |    95.83 |     100 |     100 | 116               
  tool-search.ts   |   96.19 |    89.79 |   93.75 |   96.19 | ...09,259-264,426 
  tool-utils.ts    |   97.46 |    96.55 |     100 |   97.46 | 26-27             
  tools.ts         |   92.93 |    92.18 |      92 |   92.93 | ...64-565,581-587 
  truncation.ts    |   90.61 |    90.35 |     100 |   90.61 | ...53-461,498-504 
  ...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    |   87.29 |    86.15 |   89.47 |   87.29 | ...53-856,893-928 
  zoom-image.ts    |   95.76 |    93.93 |    90.9 |   95.76 | 54-59,203-204     
 src/tools/agent   |   87.26 |    88.51 |   89.71 |   87.26 |                   
  agent.ts         |   85.88 |    87.64 |   87.35 |   85.88 | ...4265,4299-4309 
  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.83 |    92.51 |   88.63 |   95.83 |                   
  artifact-tool.ts |   91.69 |    88.46 |   71.42 |   91.69 | ...20-321,329-332 
  ...-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 |                   
 ...tools/workflow |   89.33 |    87.68 |   82.75 |   89.33 |                   
  workflow.ts      |   89.33 |    87.68 |   82.75 |   89.33 | ...33,878,880-881 
 src/utils         |   92.78 |    89.75 |   96.89 |   92.78 |                   
  ...Controller.ts |     100 |      100 |     100 |     100 |                   
  ...ssageQueue.ts |     100 |      100 |     100 |     100 |                   
  ...cFileWrite.ts |      95 |    92.76 |     100 |      95 | ...49-550,657-661 
  auth-type.ts     |     100 |      100 |     100 |     100 |                   
  bareMode.ts      |   81.81 |      100 |      50 |   81.81 | 18-19             
  ...ry-content.ts |   98.45 |    95.79 |     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.89 |    94.11 |      95 |   95.89 | ...99-500,512-525 
  ...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   |     100 |    97.18 |     100 |     100 | 79,86             
  ...qwen-model.ts |     100 |      100 |     100 |     100 |                   
  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     
  errorParsing.ts  |     100 |      100 |     100 |     100 |                   
  ...rReporting.ts |   95.65 |    93.33 |     100 |   95.65 | 37-38             
  errors.ts        |   88.92 |    93.03 |      68 |   88.92 | ...92,394,410-411 
  fetch.ts         |   90.68 |    82.63 |     100 |   90.68 | ...72,483-484,503 
  ...ng-options.ts |     100 |      100 |     100 |     100 |                   
  file-identity.ts |     100 |      100 |     100 |     100 |                   
  fileUtils.ts     |   94.79 |    92.16 |   96.29 |   94.79 | ...2076,2084-2085 
  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             
  git-ignore.ts    |     100 |      100 |     100 |     100 |                   
  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.83 |    82.35 |    87.5 |   78.83 | ...22-123,164-215 
  github-prs.ts    |   96.06 |    84.09 |     100 |   96.06 | 251,350-358       
  iconvHelper.ts   |     100 |      100 |     100 |     100 |                   
  ...rePatterns.ts |     100 |      100 |     100 |     100 |                   
  image-view.ts    |   95.08 |    93.47 |     100 |   95.08 | ...62-166,234-238 
  ...lPromptIds.ts |     100 |      100 |     100 |     100 |                   
  ...on-context.ts |     100 |      100 |     100 |     100 |                   
  is-tool.ts       |     100 |      100 |     100 |     100 |                   
  jsonl-utils.ts   |   96.15 |    93.51 |     100 |   96.15 | ...86-387,429-432 
  ...-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                
  ...-constants.ts |   94.73 |     92.3 |     100 |   94.73 | 66-67             
  ...iagnostics.ts |    96.4 |     94.2 |     100 |    96.4 | ...66,293-294,376 
  ...tProcessor.ts |   94.01 |     90.1 |     100 |   94.01 | ...47-353,445-446 
  ...Inspectors.ts |     100 |      100 |     100 |     100 |                   
  modelId.ts       |   98.96 |    98.18 |     100 |   98.96 | 154               
  ...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         |   90.88 |    90.66 |     100 |   90.88 | ...28-629,631-633 
  pdf.ts           |   92.17 |    85.81 |     100 |   92.17 | ...64-565,606-611 
  ...s-liveness.ts |     100 |    93.47 |     100 |     100 | 62,72,108         
  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.36 |     100 |   96.98 | ...87-688,763-764 
  retry.ts         |   96.09 |    92.52 |     100 |   96.09 | ...72,563-564,582 
  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 
  ...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.22 |    98.01 |     100 |   98.22 | 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 |       90 |     100 |     100 | 95                
  ...orageUtils.ts |   96.21 |     86.2 |     100 |   96.21 | ...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.37 |    88.59 |     100 |   86.37 | ...2361,2368-2372 
  ...lAstParser.ts |    98.3 |    91.59 |     100 |    98.3 | ...1340-1342,1352 
  ...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 |    57.14 |     100 |   77.77 | 44,54-59          
  ...emEncoding.ts |   96.36 |    91.17 |     100 |   96.36 | 59-60,124-125     
  terminal-env.ts  |      50 |      100 |       0 |      50 | 18-19             
  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             
  ...error-type.ts |     100 |      100 |     100 |     100 |                   
  ...name-utils.ts |     100 |      100 |     100 |     100 |                   
  ...ultCleanup.ts |   54.62 |       64 |      75 |   54.62 | ...03-105,108-134 
  ...Compaction.ts |   96.83 |     92.7 |     100 |   96.83 | ...37-342,344-349 
  ...pt-records.ts |   87.61 |    86.23 |     100 |   87.61 | ...80-484,514-529 
  ...-constants.ts |     100 |      100 |     100 |     100 |                   
  windowsPath.ts   |   89.47 |    79.31 |     100 |   89.47 | ...57-58,62,90-91 
  ...-directory.ts |    83.7 |    80.95 |    87.5 |    83.7 | ...37-238,252-253 
  ...ifact-path.ts |   94.11 |    92.85 |     100 |   94.11 | 32-33             
  ...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.75 |   94.78 |   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.86 |      90 |   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 |    92.3 |      100 |   88.88 |    92.3 |                   
  ...ageFormats.ts |   81.81 |      100 |   66.66 |   81.81 | 56-61             
  textTokenizer.ts |     100 |      100 |     100 |     100 |                   
-------------------|---------|----------|---------|---------|-------------------

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.

LGTM, looks ready to ship — CI landed green after the review. ✅

@wenshao

wenshao commented Aug 26, 2026

Copy link
Copy Markdown
Collaborator

Local verification report — real daemon + real Web Shell

I built a live environment for this PR and drove the actual UI in Chromium rather than reasoning from the diff. Summary up front: the responsive table works, and every claim in the Reviewer Test Plan that I could measure holds. I found one regression I'd fix before merge, plus three smaller issues worth a decision.

Verified atb64fba948f (merge of origin/main into worktree-session-overview-optimize), merge-base ba657c0678
EnvironmentLinux · a real qwen serve daemon on an isolated HOME/QWEN_HOME, bearer auth on, serving packages/web-shell/dist built from this branch
Data29 real sessions with real transcripts across 4 registered workspaces, one of which is a real git worktree. Titles include a 100-char title and a CJK title; two sessions deliberately have no turns (null updatedAt); three carry PR metadata.
DriverPlaywright/Chromium against the live daemon — no mocks, no fixtures. All assertions are measurements of the rendered DOM (getComputedStyle, getBoundingClientRect, scrollWidth), not screenshot eyeballing.

Static checks

Check Result
tsc -p tsconfig.json --noEmit clean
eslint packages/web-shell clean
vitest run (whole web-shell package) 199 files / 4323 tests pass
the 6 test files this PR touches 748 tests pass
prettier --check 5 pre-existing failures (GitModePopover.module.css, GitDialog.module.css, PlanExecutionView.module.css, client/index.html) — none touched by this PR

I also chased two things that looked like diff noise and both are fine: the packages/vscode-ide-companion lockfile entry for @qwen-code/web-shell repairs pre-existing drift (that package.json already declared the dep at the merge-base; the base lockfile was the stale side), and the +54 NOTICES.txt lines are mandatory — ci.yml regenerates and diffs that file, so omitting them would have gone red.


What the live run confirms

Every one of these was measured against the real DOM, not asserted from source.

Responsive sizing. At 1600px and 1280px the table reports data-layout="fluid", the seven column widths sum to the container width to within 1px, and scrollWidth === clientWidth (no horizontal scroll). At 1024px and below it flips to data-layout="scroll" with genuine overflow.

Fixed columns and their offsets. In scroll mode the select column pins at left: 0px, the Title column at left: 40px (exactly the select column's width — the offset accumulator is correct), and Actions at right: 0px. Their getBoundingClientRect().left is byte-identical before and after scrolling to the far end, so they really are pinned and not just initially aligned.

Edge shadows, including the "before scrolling" claim in the PR body. Measured via getComputedStyle(th, '::after').boxShadow through a full cycle: at scrollLeft = 0 the right shadow is on and the left is off; mid-scroll both are on; scrolled fully right the left is on and the right is off; with no overflow neither appears. The claim that the shadow shows before the user scrolls holds.

Hover synchronisation across the fixed and scrolling cells, at every scroll-mode width.

Functional matrix, all passing against the live daemon: search; the empty result rendering inside <table> ([data-slot="data-table-empty"] is a real descendant of [data-slot="table"]); the workspace multi-select (all-checked by default, unchecking excludes, two-at-once works, unchecking All yields the in-table "No data" state); the Time sort cycling ascending → descending → unsorted with correct aria-sort and the ascending order being the exact reverse of descending; page sizes 10/50/100 with correct page counts; Next/Previous; filtering while on page 3 resets to page 1 instead of showing an empty page; the page size surviving a full browser reload; row-click selection outside the title; the header checkbox selecting every filtered row across pages; confirmation dialogs for both archive and delete, with cancel as a true no-op; and inline rename writing through to the daemon (I confirmed the new displayName on the daemon's own session list, not just in the DOM).

Localisation. Under zh-CN every new key resolves — no raw sessionsOverview.* key leaks into the rendered text — and the fixed-width Actions column still contains its content (−8px spill, i.e. room to spare). "Worktree" staying untranslated matches the existing sidebar.newWorktreeTask precedent, so that's deliberate, not a gap.

Mobile. The panel is now genuinely reachable from the drawer at 760/600/414px and scrolls correctly there.


Finding 1 — "Open in split" silently drops selections, and under a sort it drops the wrong ones (recommend fixing before merge)

SessionOverviewPanel.tsx:1442-1464

const splitIds = selectedCards.map((card) => card.sessionId).slice(0, MAX_SPLIT_PANES);

Two problems in that one line, both reproduced live.

a) The cap is silent. I selected 8 rows. The footer read 8 of 29 row(s) selected., the button tooltip read "Show the selected sessions side by side in this window", and clicking it opened 6 panes. Nothing anywhere told the user that two of their selections were discarded. The comment directly above the line says the cap exists so "the in-window path doesn't silently open fewer than were checked" — which is what it now does. Note this PR also deletes the sessionsOverview.splitCap key ("Only the first 6 selected sessions will open in the split.") that used to carry exactly this warning.

b) Under an active sort it drops the rows at the top of the screen. selectedCards comes from getSelectedRowModel(), which returns core order (the status/recency ranking), not the sorted order the user is looking at. So .slice(0, 6) takes the first six in a ranking that is invisible on screen.

Reproduced: sorted by Time ascending, selected the top 8 visible rows, clicked Open in split. The six that opened were selections #3 through #8 — the ones at the bottom of the selection. Probe: rename via metadata and Refactor session catalogue pagination, the two rows sitting at the very top of the screen, were the ones thrown away.

Open in new tab uses the same splitIds, so it behaves identically.

Suggested fix: cap against table.getSortedRowModel() order so the six that open are the six at the top of the view, and either restore an over-cap notice or disable the button above the cap.

The test that should have caught this can never fail. SessionOverviewPanel.test.tsx:988, inside the test named "caps the split to 6 sessions":

expect(container!.textContent).not.toContain('Only the first 6');

That string was deleted by this same PR and appears nowhere in packages/, so the assertion is unconditionally true. Three sibling assertions have the same shape — :1159 ('No sessions matching'), :1359 ('border-r'), :1370 ('group-hover:bg-muted/50') — none of those strings is produced by any product code.

To be fair to the rest of the file: SessionOverviewPanel.test.tsx genuinely renders the real component with real TanStack Table and real Radix primitives, and its other 77 tests are meaningful. This is a small pocket of dead assertions, not a mirrored test file.


Finding 2 — Archiving an already-removed session reports a false error, but only on the primary workspace

SessionOverviewPanel.tsx:696 vs :662-672

The workspace-qualified branch explicitly counts notFound as success. The primary-workspace branch tests result.status === 'fulfilled' && result.value, and actions.archiveSession (packages/webui/src/daemon/workspace/actions.ts:164) returns archived.length > 0 || alreadyArchived.length > 0notFound is excluded. Delete's sibling does include it.

Live A/B on the same action, same daemon, one session in each workspace, each removed out-of-band first (exactly what a second tab or the TUI does while the overview's list is stale):

archive result UI
ws-api (non-primary → batch path) notFound clean, row removed
ws-main (primary → per-id path) notFound Failed to archive session: Operation did not complete, row removed anyway

I want to be clear about what this does not do. The obvious escalation is that onCurrentSessionRemoved never fires for a "failed" archive, leaving the shell attached to a session the daemon has destroyed. I tested that directly — archived the active session on the primary path, left the panel, and sent a prompt — and the shell ran the turn normally. It is not wedged. So this is a false error message and a primary-vs-secondary inconsistency, not a correctness bug. Worth aligning the two predicates; not a blocker.


Finding 3 — Below ~430px the two fixed regions cover the entire scroll port

Before this PR the Session Overview entry point was gated on isLargeScreen (≥1024px) and the panel auto-closed on shrink. This PR removes both (App.tsx:12182, and the deleted if (activePanel === 'sessions') setActivePanel(null) block), which is deliberate and matches the test plan. The consequence at phone widths is measurable:

viewport scroll-port width left fixed right fixed free space middle columns
360px 316 264 128 −76 0 visible px at any scrollLeft
390px 348 264 128 −44 0 visible px
414px 372 264 128 −20 0 visible px
430px 388 264 128 −4 0 visible px
460px 418 264 128 +26 reachable
600px 558 264 128 +166 reachable

Under 460px the Title and Actions columns overlap, so Worktree, Session ID, Workspace and Time can never be brought into view no matter how far you scroll — I verified this by scrolling to scrollWidth and measuring each non-sticky cell's visible width after subtracting the sticky rectangles. iPhone SE (375), iPhone 14 (390) and 14 Pro Max (430) all sit in that band.

The table stays operable there — Title plus the four actions is arguably the right mobile subset — so this may be an acceptable trade. But it is currently accidental rather than designed. Dropping the Title column's fixed width or unpinning Actions below a breakpoint would make it intentional.


Finding 4 — Back from the Session Overview discards the open conversation

App.tsx:12430-12459 special-cases the shared panel-back button when activePanel === 'sessions' and calls createNewSession().

Reproduced: opened a session with a transcript, opened the Session Overview, pressed Back — the transcript is gone and the shell is in the "Welcome to Qwen Code" new-task state. No confirmation, and it fires even if the user opened the overview and touched nothing.

The PR body says clearing on Back is intended, so this is a design question rather than a defect, but two things about it look unconsidered:

  • Every other panel's Back is a plain closePanel(), and the sidebar's own current-session row still closes this same panel non-destructively. Two affordances that both read as "leave this panel" now have different outcomes.
  • createNewSession() is called with no workspaceCwd, so on a multi-workspace daemon it also resets the workspace selection to the primary — while the sidebar's New-task path passes the workspace explicitly.

Smaller notes

  • Bulk archive fans out one request per session on the primary workspace (:687-707, Promise.allSettled over ids). The header checkbox selects every filtered row across all pages and SESSION_LIST_PAGE_SIZE is 1000, so "select all → Archive" can fire up to 1000 concurrent requests. Batch endpoints already exist and are used by the other branch (archiveSessionsData / deleteSessions).
  • A sidebar test went vacuous. WebShellSidebar.workspace-removal.test.tsx:3249 (hides archive UI when session_archive is absent) asserts through a selector for the inline hover button this PR deletes, so it now matches nothing under any capability state and the assertion is unconditionally true. I mutation-proved it: removing the per-row session_archive gate from canMutateSessionArchive survives all 87 sidebar tests at this HEAD, and is killed at the merge-base. One line fixes it — assert the More menu's contents instead.
  • react18-ref-compat.test.tsx is weaker than its name. The $$typeof === forward_ref matrix is a real guard, but only 10 of its 25 rows concern this PR (the other 15 were already forwardRef at the merge-base). All 4 behavioral ref tests pass with this PR fully reverted, because React 19 delivers ref as an ordinary prop that {...props} forwards — and the suite never actually runs React 18, even though peerDependencies allows it.
  • Docs are stale. docs/developers/daemon-ui/sidebar-customization.md:125 still marks sessionsOverview "large screens only"; :213-242 still lists 'archive' as a legal inlineItems value with a default of ['pin','archive'], and its example { inlineItems: ['archive', 'export'] } is now a TypeScript error for embedders.
  • ui/data-table.tsx has rough edges as a shared primitive, none reachable from this consumer (all seven columns declare width): a column with no width contributes 0 to the layout minimum, so the scroll fallback never engages for it; if every column sets fixedWidth the fluidWeight === 0 guard returns min widths but leaves width: 100% with no min-width, and the browser spreads the surplus anyway; meta.truncate is a no-op on a fixedWidth column; and meta.tooltip throws without an ambient TooltipProvider (works today only because the panel happens to wrap). fixedOffset has no consumers and folds into the offset accumulator in a surprising way. Follow-up material, not merge-blocking.
  • The Worktree column rendered its - placeholder correctly, but I could not populate it — the daemon's session summaries carry no worktree/branch in this setup even for sessions in a real git worktree, which is daemon-side and pre-existing. So that column's populated state is unverified here; the PR badges next to it (#10115, #9987, #10101) do render.

Verdict

The table itself is solid and the responsive engineering is better than the PR body claims — the shadow-before-scroll behaviour, the offset accumulator and the fluid/scroll flip all measure correctly, and 4323 tests pass. Finding 1 is the one I'd want fixed first: it silently discards user selections, and under a sort it discards specifically the rows the user is looking at, in a path whose guard-rail notice this PR removed. Findings 2–4 are judgement calls for the maintainers; the rest are follow-ups.

Happy to re-run the whole matrix against a new push — the harness is scripted end to end.

中文版

本地验证报告 —— 真实 daemon + 真实 Web Shell

我为这个 PR 搭建了一套真实环境,在 Chromium 里驱动真正的 UI,而不是只读 diff 推理。结论先说:响应式表格是可用的,Reviewer Test Plan 里我能测量的每一条主张都成立。 我发现了一个建议合并前修掉的回归,外加三个需要维护者拍板的小问题。

验证提交b64fba948forigin/main 合入 worktree-session-overview-optimize),merge-base ba657c0678
环境Linux · 真实 qwen serve daemon,隔离的 HOME/QWEN_HOME,开启 bearer 鉴权,直接服务本分支构建出的 packages/web-shell/dist
数据4 个已注册工作区中的 29 个真实会话(含真实对话记录),其中一个工作区是真实的 git worktree。标题覆盖 100 字符超长标题和中文标题;两个会话故意没有任何轮次(updatedAt 为空);三个带 PR 元数据。
驱动方式Playwright/Chromium 直连真实 daemon —— 无 mock、无 fixture。所有断言都是对渲染后 DOM 的测量(getComputedStylegetBoundingClientRectscrollWidth),而非肉眼看截图。

静态检查

检查项 结果
tsc -p tsconfig.json --noEmit 通过
eslint packages/web-shell 通过
vitest run(整个 web-shell 包) 199 个文件 / 4323 个用例全部通过
本 PR 修改的 6 个测试文件 748 个用例通过
prettier --check 5 个既有失败(GitModePopover.module.cssGitDialog.module.cssPlanExecutionView.module.cssclient/index.html)—— 均与本 PR 无关

另外我追查了两处看起来像 diff 噪音的改动,结论都是没问题:packages/vscode-ide-companion 锁文件里新增的 @qwen-code/web-shell 条目是在修复既有漂移(该 package.json 在 merge-base 上就已声明该依赖,反而是基线锁文件过时了);NOTICES.txt 的 +54 行是必需的 —— ci.yml 会重新生成并比对该文件,不加反而会红。


实机验证通过的部分

以下每一条都是对真实 DOM 的测量,不是从源码推断的。

响应式列宽。 1600px 和 1280px 下表格上报 data-layout="fluid",七列宽度之和与容器宽度误差在 1px 内,且 scrollWidth === clientWidth(无横向滚动)。1024px 及以下切换为 data-layout="scroll" 并产生真实溢出。

固定列及其偏移。 滚动模式下选择列固定在 left: 0px,标题列固定在 left: 40px(恰好等于选择列宽度 —— 偏移累加逻辑正确),操作列固定在 right: 0px。滚动到最右端前后,它们的 getBoundingClientRect().left 完全一致,说明是真正的钉住,而不只是初始对齐。

边缘阴影,含 PR 描述中"滚动前就出现"这一条。 通过 getComputedStyle(th, '::after').boxShadow 测了完整循环:scrollLeft = 0 时右侧阴影开、左侧关;滚动中两侧都开;滚到最右端左侧开、右侧关;无溢出时两侧都不出现。"用户滚动之前阴影就已显示"这一主张成立。

Hover 背景同步 —— 在所有滚动模式宽度下,固定列与滚动列均保持一致。

功能矩阵(全部通过,均针对真实 daemon):搜索;空结果渲染在 <table> 内部[data-slot="data-table-empty"] 确实是 [data-slot="table"] 的后代节点);工作区多选筛选(默认全选,取消勾选即排除,可同时选两个,取消 All 得到表内 "No data" 状态);时间列排序在升序 → 降序 → 取消之间循环且 aria-sort 正确,升序结果恰好是降序的逆序;10/50/100 分页且页数正确;上一页/下一页;在第 3 页时进行筛选会重置回第 1 页,而不是显示空页;分页大小在整页刷新后仍被记住;点击标题以外的行区域可选中;表头复选框跨页选中全部筛选结果;归档和删除都有确认弹窗,取消是真正的空操作;行内改名会写穿到 daemon(我是在 daemon 自己的会话列表里确认了新的 displayName,不只是看 DOM)。

本地化。 zh-CN 下所有新增 key 均能解析 —— 渲染文本中没有泄漏任何原始 sessionsOverview.* key —— 且固定宽度的操作列仍能容纳内容(溢出 −8px,即还有余量)。"Worktree" 保持不翻译与既有的 sidebar.newWorktreeTask 惯例一致,属于有意为之,不是遗漏。

移动端。 该面板现在确实能从抽屉里在 760/600/414px 下打开,并能正常滚动。


问题 1 —— "分屏打开"会静默丢弃选择,且在排序状态下丢错了对象(建议合并前修复)

SessionOverviewPanel.tsx:1442-1464

const splitIds = selectedCards.map((card) => card.sessionId).slice(0, MAX_SPLIT_PANES);

这一行里有两个问题,均已实机复现。

a) 截断是无声的。 我选中了 8 行。底部显示 8 of 29 row(s) selected.,按钮提示写着"在本窗口内并排显示选中的会话",点击后打开了 6 个面板。没有任何地方告诉用户有两个选择被丢弃了。这一行正上方的注释写的是:设置上限是为了让"窗口内路径不会静默地打开比勾选数量更少的会话"—— 而现在它做的恰恰就是这件事。另外,本 PR 同时删除了 sessionsOverview.splitCap 这个 key("仅前 6 个选中的会话会在分屏中打开"),而它正是承载这条提示的。

b) 在排序状态下,被丢掉的是屏幕最上方的行。 selectedCards 来自 getSelectedRowModel(),返回的是核心顺序(状态/最近使用排名),而不是用户正在看的排序顺序。于是 .slice(0, 6) 取的是一个屏幕上根本看不见的排名的前六个。

复现过程:按时间升序排序,选中可见的前 8 行,点击"分屏打开"。真正打开的是选择项 #3#8 —— 也就是选择中靠下的那些。而 Probe: rename via metadataRefactor session catalogue pagination,正是屏幕最顶部的两行,被丢弃了。

"新标签页打开"使用同一个 splitIds,行为完全相同。

建议修法:按 table.getSortedRowModel() 的顺序截断,使打开的六个就是视图顶部的六个;同时恢复超限提示,或在超过上限时禁用按钮。

本该拦住这个问题的测试永远不会失败。 SessionOverviewPanel.test.tsx:988,位于名为 "caps the split to 6 sessions" 的用例内:

expect(container!.textContent).not.toContain('Only the first 6');

该字符串正是被本 PR 删除的,在 packages/ 下已不存在,所以这条断言恒为真。另有三条同样形态的断言::1159'No sessions matching')、:1359'border-r')、:1370'group-hover:bg-muted/50')—— 这些字符串都不由任何产品代码产生。

公平地说,该文件其余部分是扎实的:SessionOverviewPanel.test.tsx 确实渲染了真实组件,用的是真实的 TanStack Table 和真实的 Radix 基础组件,另外 77 个用例都有实际意义。这只是一小撮失效断言,不是"逻辑镜像"式的测试文件。


问题 2 —— 归档一个已被移除的会话会报假错误,且只在主工作区发生

SessionOverviewPanel.tsx:696 对比 :662-672

带工作区限定的分支明确把 notFound 计为成功。主工作区分支判断的是 result.status === 'fulfilled' && result.value,而 actions.archiveSessionpackages/webui/src/daemon/workspace/actions.ts:164)返回 archived.length > 0 || alreadyArchived.length > 0 —— 不包含 notFound。而删除那一侧的同类实现是包含它的。

同一操作、同一 daemon、每个工作区各取一个会话,事先在带外删除(这正是第二个标签页或 TUI 在总览列表尚未刷新时会造成的情况)的实机 A/B:

归档返回 UI 表现
ws-api(非主 → 批量路径) notFound 干净,行被移除
ws-main(主 → 逐条路径) notFound Failed to archive session: Operation did not complete,但行照样被移除

我想明确说明这个问题不会导致什么。 最容易想到的升级路径是:归档被判为"失败"后 onCurrentSessionRemoved 不会触发,于是 shell 仍挂在一个已被 daemon 销毁的会话上。我直接测了这一条 —— 在主路径上归档当前活动会话,离开面板,然后发一条 prompt —— shell 正常跑完了这一轮,并没有卡死。所以这是一条错误的报错信息加上主/非主路径不一致,而不是正确性缺陷。值得把两处判定对齐,但不构成阻塞。


问题 3 —— 约 430px 以下,两侧固定列会盖满整个滚动区

在本 PR 之前,会话总览入口受 isLargeScreen(≥1024px)限制,且窗口变窄时面板会自动关闭。本 PR 移除了这两点(App.tsx:12182,以及被删除的 if (activePanel === 'sessions') setActivePanel(null) 代码块),这是有意为之,也符合测试计划。其在手机宽度下的后果是可测量的:

视口 滚动区宽度 左固定 右固定 剩余空间 中间列
360px 316 264 128 −76 任何 scrollLeft 下可见 0 像素
390px 348 264 128 −44 可见 0 像素
414px 372 264 128 −20 可见 0 像素
430px 388 264 128 −4 可见 0 像素
460px 418 264 128 +26 可触达
600px 558 264 128 +166 可触达

460px 以下标题列与操作列相互重叠,因此 Worktree、会话 ID、工作区、时间四列无论怎么滚动都无法进入视野 —— 我通过滚动到 scrollWidth 并在扣除各 sticky 矩形后测量每个非 sticky 单元格的可见宽度来验证了这一点。iPhone SE(375)、iPhone 14(390)和 14 Pro Max(430)都落在这个区间内。

在那些宽度下表格仍然可操作 —— 只保留标题加四个操作,作为移动端子集其实也说得通 —— 所以这可能是可接受的取舍。但目前它是偶然形成的,而非设计出来的。去掉标题列的固定宽度,或在某个断点以下取消操作列的钉住,可以把它变成有意的设计。


问题 4 —— 从会话总览点击"返回"会丢弃已打开的对话

App.tsx:12430-12459activePanel === 'sessions' 时对共享的 panel-back 按钮做了特殊处理,调用 createNewSession()

复现:打开一个有对话记录的会话,进入会话总览,点击返回 —— 对话记录消失,shell 进入 "Welcome to Qwen Code" 新建任务状态。没有确认,且即使用户只是打开总览什么都没做也会触发。

PR 描述说返回时清空是有意设计,所以这更像是一个设计问题而非缺陷,但其中两点看起来没有被考虑到:

  • 其他所有面板的返回都是普通的 closePanel(),而侧边栏当前会话行关闭这同一个面板时仍然是非破坏性的。两个读起来都像"离开这个面板"的操作,现在结果不同。
  • createNewSession() 调用时没有传 workspaceCwd,因此在多工作区 daemon 上还会把工作区选择重置为主工作区 —— 而侧边栏自己的新建任务路径是显式传入工作区的。

其他较小的问题

  • 主工作区上的批量归档是一个会话一个请求:687-707,对 id 数组做 Promise.allSettled)。表头复选框会跨所有页选中全部筛选结果,而 SESSION_LIST_PAGE_SIZE 是 1000,所以"全选 → 归档"最多可以并发发出 1000 个请求。批量接口已经存在,并且另一个分支已经在用(archiveSessionsData / deleteSessions)。
  • 一个侧边栏测试失效了。 WebShellSidebar.workspace-removal.test.tsx:3249hides archive UI when session_archive is absent)断言用的选择器指向的是本 PR 删除的行内 hover 按钮,因此现在无论 capability 处于什么状态都匹配不到任何元素,断言恒为真。我用变异测试证明了这一点:把 canMutateSessionArchive 中的每行 session_archive 门禁移除后,在当前 HEAD 上 87 个侧边栏测试全部通过,而在 merge-base 上会被杀死。一行即可修复 —— 改为断言"更多"菜单的内容。
  • react18-ref-compat.test.tsx 比它的名字要弱。 $$typeof === forward_ref 矩阵确实是有效防护,但其 25 行中只有 10 行与本 PR 相关(其余 15 个在 merge-base 上就已经是 forwardRef)。4 个行为性 ref 测试在完全回退本 PR 后依然通过,因为 React 19 把 ref 作为普通 prop 传递,{...props} 会自动转发 —— 而且这套测试从未真正在 React 18 下运行过,尽管 peerDependencies 是允许 18 的。
  • 文档过时。 docs/developers/daemon-ui/sidebar-customization.md:125 仍标注 sessionsOverview 为"仅大屏";:213-242 仍把 'archive' 列为合法的 inlineItems 取值、默认值仍写作 ['pin','archive'],其示例 { inlineItems: ['archive', 'export'] } 对接入方而言现在已是 TypeScript 编译错误。
  • ui/data-table.tsx 作为通用基础组件还有些毛刺,当前这个使用方都碰不到(七列全部声明了 width):没有 width 的列对布局最小宽度贡献 0,导致该列永远不会触发滚动回退;如果所有列都设了 fixedWidthfluidWeight === 0 的保护会返回最小宽度,但仍保留 width: 100% 且没有 min-width,浏览器照样会把富余宽度摊开;meta.truncatefixedWidth 列上是空操作;meta.tooltip 在没有外层 TooltipProvider 时会抛错(现在能用只是因为该面板恰好包了一层)。fixedOffset 无任何使用方,且会以令人意外的方式并入偏移累加器。属于后续跟进项,不阻塞合并。
  • Worktree 列正确渲染了 - 占位符,但我无法填充它 —— 在这套环境下,即使会话位于真实的 git worktree 中,daemon 的会话摘要也不携带 worktree/branch,这属于 daemon 侧的既有行为。因此该列有数据时的表现在此未被验证;不过它旁边的 PR 徽章(#10115#9987#10101)是能正常渲染的。

结论

表格本身是扎实的,响应式部分的工程质量比 PR 描述所称的还要好 —— 滚动前阴影、偏移累加器、流式/滚动模式切换全部测量正确,4323 个测试通过。问题 1 是我希望优先修掉的:它会静默丢弃用户的选择,而在排序状态下丢掉的恰恰是用户正在看的那几行,且本 PR 还顺手删除了这条路径上原有的提示护栏。问题 2 到 4 需要维护者判断;其余属于后续跟进。

如果有新的推送,我可以重跑整套矩阵 —— 这套 harness 是全程脚本化的。

@qqqys

qqqys commented Aug 27, 2026

Copy link
Copy Markdown
Collaborator

tmux E2E test report (head 6659d77d9a)

Independent review of the diff found no blocking (Critical) issues; per review policy, here is the functional verification pass. Scope: the session-overview table rework and the UI primitives it introduces.

Static review. The highest-risk surface for this package — React 18/19 ref compatibility — is handled per the repo convention: every new Table primitive (Table/TableHeader/TableBody/TableFooter/TableRow/TableHead/TableCell/TableCaption) is React.forwardRef, and TooltipTrigger/TooltipContent are converted to forwardRef with React.ComponentRef typing, with the whole set pinned by $$typeof === forward_ref checks plus runtime ref-forwarding tests (Table ref → DOM element; asChild TooltipTrigger ref → button). The new DataTable wrapper keeps refs on plain DOM (viewport div), guards ResizeObserver availability, and renders through the existing portal-root-aware TooltipContent. Session mutations route through the existing batch daemon-client APIs (archiveSessionsData/deleteSessionsData) with error surfacing and best-effort reloads.

Functional verification at this head (tmux). Built the PR head in a worktree (npm ci + prepare) and ran the affected suites in a tmux pane:

  • data-table.test.tsx + react18-ref-compat.test.tsx + SessionOverviewPanel.test.tsx + session-action-visibility.test.ts: 121/121 pass.
  • WebShellSidebar.workspace-removal.test.tsx (regression sweep for the sidebar changes): 80/80 pass.

Honest limits. Pixel-level rendering (fluid/scroll table layout, sticky-column shadows, tooltips) needs a real browser and was not captured here — that surface is covered by the repo's web-shell visuals lane and the live-refresh/mutation freshness the bot's stage-3 notes rests on mocked-client tests for. Not approving in this pass (no bot/maintainer approval has landed on this head yet — its finalize lane is still pending).


tmux E2E 测试报告(head 6659d77d9a

对 diff 的独立审查未发现阻塞性(Critical)问题;按评审规则,这里给出功能性验证。范围:会话总览表重构及其引入的 UI 原语。

静态审查。 本包最高风险面——React 18/19 ref 兼容——按仓库约定处理:全部新 Table 原语(Table/TableHeader/TableBody/TableFooter/TableRow/TableHead/TableCell/TableCaption)均为 React.forwardRefTooltipTrigger/TooltipContent 转为 forwardRef 并使用 React.ComponentRef 类型;整套由 $$typeof === forward_ref 检查加运行时 ref 转发测试钉住(Table ref → DOM 元素;asChild TooltipTrigger ref → button)。新 DataTable 封装的 ref 仅落在普通 DOM(视口 div)上,ResizeObserver 可用性有守卫,且经由既有的 portal-root 感知的 TooltipContent 渲染。会话变更走既有批量 daemon 客户端 API(archiveSessionsData/deleteSessionsData),带错误呈现与尽力重载。

本 head 上的功能验证(tmux)。 在 worktree 中构建 PR head(npm ci + prepare),在 tmux 面板中运行受影响套件:

  • data-table.test.tsx + react18-ref-compat.test.tsx + SessionOverviewPanel.test.tsx + session-action-visibility.test.ts121/121 通过
  • WebShellSidebar.workspace-removal.test.tsx(侧栏改动的回归扫描):80/80 通过

如实说明的局限。 像素级渲染(流式/滚动表格布局、固定列阴影、工具提示)需要真实浏览器,未在此截取——该面由仓库的 web-shell 视觉通道覆盖;机器人 stage-3 所注明的活动刷新/变更时效仍依赖 mocked-client 测试。本轮不予 approve(本 head 尚无机器人/维护者批准——其 finalize 通道仍在 pending)。

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

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Not explored to full depth (tool budget reached): chunk 8: none — but note I could not run typecheck/tests locally (no node_modules in the review worktree), so runtime/type verification of these tests rests on the aut…; "agent 1b": none — no check was cut short.; chunk 7: none — CI's ubuntu test job was still pending at check time, so I could not use it as evidence and instead verified behavior directly against the component an…; chunk 4: executing SessionOverviewPanel.test.tsx via vitest (no node_modules in worktree; install+build not feasible in budget).

中文说明

未探索到全部深度(达到工具调用预算):chunk 8:none — but note I could not run typecheck/tests locally (no node_modules in the review worktree), so runtime/type verification of these tests rests on the aut…"agent 1b"none — no check was cut short.;chunk 7:none — CI's ubuntu test job was still pending at check time, so I could not use it as evidence and instead verified behavior directly against the component an…;chunk 4:executing SessionOverviewPanel.test.tsx via vitest (no node_modules in worktree; install+build not feasible in budget)

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

Comment thread packages/web-shell/client/components/SessionOverviewPanel.tsx
Comment thread packages/web-shell/client/App.tsx
Comment thread packages/web-shell/client/App.test.tsx
Comment thread packages/web-shell/client/components/ui/tooltip.tsx
Comment thread packages/web-shell/client/components/SessionOverviewPanel.test.tsx
Comment thread packages/web-shell/client/components/SessionOverviewPanel.tsx
Comment thread packages/web-shell/client/components/SessionOverviewPanel.tsx Outdated
Comment thread packages/web-shell/client/components/SessionOverviewPanel.tsx
Comment thread packages/web-shell/client/components/SessionOverviewPanel.tsx Outdated
@ytahdn

ytahdn commented Aug 27, 2026

Copy link
Copy Markdown
Collaborator Author

@qwen-code /takeover

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

Copy link
Copy Markdown
Collaborator

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

中文说明

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

@qwen-code-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.

Deferred under the convergence posture (round 2, not a blocker) — recorded, not requested in this round:

  • packages/web-shell/client/components/SessionOverviewPanel.tsx:1090 — [review] actionable statuses render identically to running (uniform spinner)
  • packages/web-shell/client/App.tsx:12649 — [review] manageLiveState is only witnessed in the false direction
  • packages/web-shell/client/App.tsx:12183 — [review] canOpenSessionsOverview un-gating has no witness
  • packages/web-shell/client/components/SessionOverviewPanel.tsx:398 — [review] panel/sidebar live-state workspace predicates diverge
  • packages/web-shell/client/App.test.tsx:17755 — [probe] post-clear guards' === undefined disjuncts are unwitnessed
  • packages/web-shell/client/App.test.tsx:17799 — [probe] pre-guard sessionId-mismatch half is unwitnessed
  • packages/web-shell/client/components/SessionOverviewPanel.test.tsx:2441 — [probe] live-state channel enabled:true direction never asserted
  • packages/web-shell/client/App.test.tsx:18009 — [probe] panel-back race test passes via the invocation guard alone
  • packages/web-shell/client/App.tsx:12609 — [probe] Open in split is reachable below the breakpoint and folds silently
  • packages/web-shell/client/components/SessionOverviewPanel.test.tsx:2415 — [probe] useStatusReport autoLoad pinned only in the false direction
  • packages/web-shell/client/App.test.tsx:17740 — [probe] onCurrentSessionRemoved success-path return never asserted
  • packages/web-shell/client/components/SessionOverviewPanel.test.tsx:1671 — [probe] onCurrentSessionRemoved payload unwitnessed from both ends
  • packages/web-shell/client/App.test.tsx:1285 — [probe] locked-workspace prop handoff to the overview is unwitnessed
  • packages/web-shell/client/components/SessionOverviewPanel.test.tsx:1324 — [probe] workspace filter re-inclusion branch never exercised
中文说明

收敛姿态下延后(第 2 轮,非阻断)——已记录,本轮不要求修改:共 14 条(原文未翻译,列表见上方英文部分)。

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

// away. Standalone/uncontrolled only — a controlled host owns its split
// lifecycle and re-opens it itself.
if (splitFoldedByShrinkRef.current) {
if (splitFoldedByShrinkRef.current && !activePanel) {

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.

[Critical] R1-3: (fix-induced) The && !activePanel deferral this commit added to the grow-restore branch (answering the round-1 finding) leaves splitFoldedByShrinkRef.current set while the Session Overview is open, so any later panel close — including closes that are explicit navigation — restores the folded split over the user's navigation. Shrink folds an open split (the flag is set at line ~5419); the user opens the Session Overview; the viewport grows back and this branch is skipped because the panel is open — without clearing the flag (this line is its only clear site). The user then clicks a session title (handleOpenSessionFromOverviewloadSidebarSessionclosePanel()) or Back (createNewSessionclosePanel()); closing the panel re-runs the effect, which sees the stale flag and calls setMainView('split') — the user lands on the stale split instead of the clicked session (which loads into the hidden chat connection) or the fresh chat. Before this commit the flag was always cleared immediately on grow, so this window did not exist. (The explicit-split-exit-then-Escape variant does not reproduce — openSplitView itself clears the flag.)

Witness (probe on this commit):

PROBE-F1-back  split-view-page: PRESENT  inline-panel: absent  -> FAILED
PROBE-F1-load  split-view-page: PRESENT                         -> FAILED
with the flag cleared on navigation: both absent -> passed
(committed Escape-restore test still passes)

Clear splitFoldedByShrinkRef.current = false; whenever the user takes explicit ownership of the view — in handleSplitExit next to clearSplitSessions(), and in handleOpenSessionFromOverview / the sessions Back handler before navigation — so the deferred restore only fires for a plain dismiss (Escape/close). Please add a variant of the deferral test that leaves the overview via panel-back or a session open and asserts split-view-page stays absent; removing the flag-clear must turn it red (the probe verified both directions).

中文说明

本次提交为回应上一轮发现而在 grow-restore 分支加入的 && !activePanel 延迟恢复,会在会话总览打开期间一直保留 splitFoldedByShrinkRef.current,导致之后任何关闭面板的操作——包括明确属于导航的关闭——都会恢复已被折叠的分屏,覆盖用户的导航。收缩时折叠分屏(约 5419 行置位);用户打开会话总览;视口恢复变大时因面板打开而跳过本分支——但没有清除标志(本行是该标志唯一的清除点)。随后用户点击会话标题(handleOpenSessionFromOverviewloadSidebarSessionclosePanel())或点击返回(createNewSessionclosePanel()),关闭面板会重新触发该 effect,读到过期标志并调用 setMainView('split')——用户落在过期的分屏上,而不是被点击的会话(它被加载进隐藏的聊天连接)或新聊天。本次提交之前标志在 grow 时总是立即清除,因此不存在这个窗口。(先显式退出分屏再按 Esc 的变体不复现——openSplitView 自身会清除标志。)

探针见上方输出。修复:在用户明确接管视图时清除标志——handleSplitExitclearSplitSessions() 旁,以及 handleOpenSessionFromOverview/会话面板返回处理器的导航之前——使延迟恢复只在普通关闭(Esc/关闭)时触发。请新增一个从面板返回或打开会话离开总览、并断言 split-view-page 保持不出现的变体测试;移除清标志逻辑后该测试应变红(探针已双向验证)。

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

Comment thread packages/web-shell/client/App.tsx Outdated
Comment on lines +12625 to +12628
const cleared = await createNewSession(undefined, {
keepView: true,
keepPanel: true,
});

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Critical] onCurrentSessionRemoved passes undefined as the workspace to createNewSession, silently bouncing the user's next chat to the primary workspace when the deleted/archived current session lived in a trusted secondary workspace. Multi-workspace daemon, no workspace locked, current session in /wsB: the user deletes/archives it from the Session Overview, the guard passes, but createNewSession(undefined, …) clears selectedWorkspaceCwd; at the next prompt prepareSubmit resolves targetWorkspaceCwd = locked ?? selectedWorkspaceCwdRef.current ?? primaryWorkspaceCwd — the user's next prompt, tool calls, and file access silently run against the wrong project. This contradicts the workspace-preserving semantics the same diff pins for the sibling panel-back handler (expect(selectedWorkspaceCwd).toBe('/work/secondary')); all existing delete-flow tests use the primary workspace, where undefined and the current workspace coincide.

Witness (probe on this commit):

BASE: AssertionError: expected undefined to be '/work/secondary'
PR + fix below: 15/15 tests pass
Suggested change
const cleared = await createNewSession(undefined, {
keepView: true,
keepPanel: true,
});
const cleared = await createNewSession(removed.workspaceCwd, {
keepView: true,
keepPanel: true,
});

If bouncing to the primary workspace after a delete is intentional product behavior, say so in a comment instead. The witness is a new App.test.tsx case mirroring the panel-back secondary-workspace test for the delete flow — with the fix reverted to undefined, it must go red.

中文说明

onCurrentSessionRemovedcreateNewSession 传入 undefined 作为工作区:当被删除/归档的当前会话位于可信的次要工作区时,用户的下一个聊天会被悄悄切回主工作区。多工作区、未锁定场景下,当前会话在 /wsB:用户从会话总览删除/归档它,守卫通过,但 createNewSession(undefined, …) 清掉了 selectedWorkspaceCwd;下一次提交时 prepareSubmit 解析 targetWorkspaceCwd = locked ?? selectedWorkspaceCwdRef.current ?? primaryWorkspaceCwd——用户的下一条消息、工具调用与文件访问会悄悄跑在错误的项目里。这与同一 diff 为面板返回处理器钉住的工作区保持语义相矛盾(expect(selectedWorkspaceCwd).toBe('/work/secondary'));现有删除流程测试全部使用主工作区,那里 undefined 与当前工作区恰好重合。探针输出见上。若删除后切回主工作区是刻意的产品行为,请改用注释说明。见证测试:仿照面板返回的次要工作区测试新增删除流程用例;将修复还原为 undefined 后该测试应变红。

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

Comment on lines +501 to +502
const workspaceOptions = useMemo(() => {
if (workspaceCwd || !multiWorkspace) return [];

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.

[Critical] excludedWorkspaceCwds is never reconciled against the visible workspaces and never reset when the panel becomes locked to a workspaceCwd, so a stale exclusion can hide every row with the filter UI removed — no recovery short of a remount. Daemon advertising 2+ trusted workspaces: the user unchecks /wsB in the funnel filter; the host then locks the shell to /wsB while mounted (index.test.tsx re-renders the same root with a changed lockWorkspaceCwd, and nothing in App.tsx remounts the panel). The panel re-renders locked: workspaceOptions collapses to [] so the filter popover disappears, but filteredCards still excludes every /wsB card — the table shows the empty state even though sessions exist, and there is no visible control left to clear the exclusion.

Witness (probe on this commit):

BASE: rows [""]  empty: "No data"  funnel: ABSENT   -> FAILED
with a reconcile effect: rows ["Alpha"]              -> passed (91 panel tests green)

Reconcile the exclusions with the currently listed options — e.g. an effect keyed on workspaceOptions that filters excludedWorkspaceCwds down to the option cwds (this also drops them when locked, when the UI to manage them is hidden). The witness is a panel test that excludes /wsB via the filter, re-renders with workspaceCwd: '/wsB', and asserts the /wsB row is still listed; removing the reconcile effect must turn it red.

中文说明

excludedWorkspaceCwds 从不与可见工作区做对账,面板被锁定到某个 workspaceCwd 时也不会重置,因此过期的排除项会在筛选 UI 消失的同时隐藏所有行——除了重新挂载别无恢复手段。守护进程通告 2 个以上可信工作区时:用户在漏斗筛选中取消勾选 /wsB;宿主在已挂载状态下把 shell 锁定到 /wsBindex.test.tsx 会在同一 root 上以变更后的 lockWorkspaceCwd 重新渲染,App.tsx 中没有任何逻辑重挂载面板)。面板以锁定状态重新渲染:workspaceOptions 收敛为 [],筛选弹层消失,但 filteredCards 仍排除所有 /wsB 卡片——会话明明存在,表格却显示空状态,且没有任何可见控件能清除该排除项。探针输出见上。修复:用当前可选项对排除集对账——例如一个以 workspaceOptions 为依赖的 effect,把 excludedWorkspaceCwds 过滤到可选项的 cwd(锁定时 UI 已隐藏,顺便清除)。见证测试:先通过筛选排除 /wsB,再以 workspaceCwd: '/wsB' 重新渲染,断言 /wsB 行仍然列出;移除对账 effect 后应变红。

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

Comment on lines +1706 to +1709
expect(workspaceClient.deleteSessionsData).toHaveBeenCalledWith(['s1']);
expect(sessionCatalogController.refreshWorkspace).toHaveBeenCalledWith(
'/w',
);

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 round-2 guarantee 'refresh the owning catalog workspace even when a mutation fails' is pinned only on the resolved-with-errors path: none of the rejection-path tests assert refreshWorkspace, so the finally refresh in mutateCards (SessionOverviewPanel.tsx:692-697) and the catch refresh in saveRename (SessionOverviewPanel.tsx:787-789) are unwitnessed. The only failing-path assertion ('clears a deleted current session after a partial batch failure') uses a client that RESOLVES with errors: [...], so its try-block completes normally and still triggers the refresh. A refactor moving refreshWorkspace out of the finally into the success branch (or dropping it from the rename catch) keeps the whole suite green — verified by mutation (90/90 pass under both mutants; deleting the refresh outright fails 4 tests, proving the wiring is live). On a daemon advertising workspace_session_live_state the panel disables its catalog-poll fallback, so after a rejected mutation (network error, daemon busy) with no refresh, overview rows stay stale indefinitely — exactly the staleness this fix commit set out to eliminate.

Add expect(sessionCatalogController.refreshWorkspace).toHaveBeenCalledWith('/w'); to the it.each('does not clear the current session when %s fails') cases and to the archive/rename failure tests. Those extended tests must go red if the finally block in mutateCards or the refreshWorkspace call in saveRename's catch is removed — today removing either keeps every test green.

中文说明

第二轮引入的保证“即使变更失败也刷新所属 catalog 工作区”只在 resolve-with-errors 路径上被钉住:所有 reject 路径测试都没有断言 refreshWorkspace,因此 mutateCardsfinally 刷新与 saveRenamecatch 刷新没有见证。唯一的失败路径断言使用的客户端是 RESOLVE 出 errors: [...],try 块正常完成,刷新照常触发。把 refreshWorkspace 移出 finally 到成功分支(或从改名 catch 中删掉)整个套件仍然绿——已用突变验证(两种突变均 90/90 通过;彻底删除刷新则 4 个测试失败,证明接线是活的)。在通告 workspace_session_live_state 的守护进程上面板禁用了 catalog 轮询兜底,变更后若失败且不刷新,总览行将无限期保持过期——正是本次修复要消除的过期问题。请在失败用例中补充断言;移除对应刷新后这些测试应变红。

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

Comment on lines +19493 to +19496
expect(panel).not.toBeNull();
expect(
container.querySelector('[data-testid="split-view-page"]'),
).toBeNull();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Suggestion] This new deferral test witnesses only the Escape exit from the Session Overview; the navigation exits — the exact paths the confirmed Critical above (R1-3) is broken on — have no witness, so the forthcoming fix lands unpinned. A probe leaving via panel-back or load-session shows split-view-page PRESENT on this commit (the folded split is restored over the navigation) while this Escape-only test stays green. When R1-3 is fixed by clearing the flag on navigation, no test pins that clearing — a later refactor removing it regresses the fix with the entire suite green.

Add a variant reusing this setup (shrink → open overview → grow) that leaves the overview via [data-testid="panel-back"] or a session open instead of Escape, and asserts [data-testid="split-view-page"] stays absent. The proposed test is red on current code (probe-verified) and passes once the R1-3 fix clears the flag on navigation.

中文说明

这个新的延迟恢复测试只见证了按 Esc 离开会话总览;导航式离开——正是上面已确认 Critical(R1-3)出问题的路径——没有任何见证,即将到来的修复将落地即无钉。探针显示:在本提交上从面板返回或打开会话离开时 split-view-page 会出现(折叠的分屏越过导航被恢复),而这个仅 Esc 的测试依旧绿。R1-3 通过“导航时清标志”修复后,没有任何测试钉住该清除——后续重构删掉它将在套件全绿的情况下复发。请新增一个复用该场景、改从面板返回或打开会话离开并断言 split-view-page 保持不出现的变体;该测试在当前代码上为红(探针已验证),在 R1-3 修复后变绿。

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

Comment on lines +778 to +782
sessionCatalogController.renamed(
ownerCwd,
card.sessionId,
result?.displayName || nextName,
);

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 || nextName fallback in this new catalog sync call has no witness — both rename mocks always resolve a displayName ({ displayName: 'Renamed' } at test lines 203 and 230), so dropping the fallback ships green. Mutation check: replacing result?.displayName || nextName with result?.displayName keeps 90/90 green, because the inline rename test types 'Renamed' (coinciding with the mock echo) and the qualified-client test asserts the echoed value. The void shape is real — the panel itself types let result: SessionMetadataResult | void (line ~762), and the sidebar's mirrored path handles it with an explicit fallback and comment (WebShellSidebar.tsx:2610-2618). If the fallback regresses, any rename resolving void writes undefined into the catalog cache, blanking/wronging that session's label in the sidebar and overview until the next full reconcile.

Add a test that sets workspaceActions.renameSession.mockResolvedValueOnce(undefined), renames to a distinct name (e.g. 'Void Name'), and asserts sessionCatalogController.renamed was called with '/w', 's1', 'Void Name'. That test must go red if the || nextName fallback is removed — the probe observed renamed called with ['/w', 's1', undefined] under that mutant.

中文说明

这个新 catalog 同步调用里的 || nextName 兜底没有见证——两个改名 mock 总是返回 displayName(测试 203、230 行的 { displayName: 'Renamed' }),删掉兜底依旧全绿。突变验证:把 result?.displayName || nextName 换成 result?.displayName,90/90 仍绿(内联改名测试恰好输入 'Renamed' 与 mock 回显重合;qualified 客户端测试断言的也是回显值)。void 形态是真实存在的——面板自身就把 result 标为 SessionMetadataResult | void(约 762 行),侧边栏的镜像路径也用显式兜底加注释处理了它。若兜底回归丢失,任何解析为 void 的改名都会把 undefined 写进 catalog 缓存,侧边栏/总览里该会话的名字会空白或错误,直到下一次完整对账。请补充 void 场景测试;移除兜底后应变红(探针在该突变下观察到 renamed 收到 ['/w','s1', undefined])。

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

workspaceLiveStateOptions = { enabled: false };
statusReportOptions = {};
sessionCatalogController.refreshWorkspace.mockReset();
sessionCatalogController.renamed.mockReset();

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 new renamed() catalog-sync call has no negative witness on the rename-failure path: 'surfaces a rename failure in the notice area' (line ~2353) runs saveRename's catch branch via workspaceActions.renameSession.mockRejectedValue(new Error('locked')) but only asserts the error text, never expect(sessionCatalogController.renamed).not.toHaveBeenCalled(). saveRename already calls refreshWorkspace(ownerCwd) on BOTH the success and catch paths (SessionOverviewPanel.tsx:783 and 788), so a cleanup that consolidates the two sync calls — e.g. moving renamed(...) into the shared finally/catch next to refreshWorkspace — ships with the suite green (verified: adding renamed to the catch keeps 90/90 green). A failed rename would then overwrite the catalog's cached display name with the value the daemon rejected, showing a stale label until the next full reconcile.

Add expect(sessionCatalogController.renamed).not.toHaveBeenCalled(); after flushAsync() in the rename-failure test. That assertion must go red if the renamed(...) call is moved into the failure path of saveRename — the probe observed it called once with ['/w', 's1', 'Renamed'] under that mutant.

中文说明

新的 renamed() catalog 同步调用在改名失败路径上没有负向见证:'surfaces a rename failure in the notice area'(约 2353 行)通过 mockRejectedValue 走到 saveRename 的 catch 分支,但只断言错误文案,从不断言 expect(sessionCatalogController.renamed).not.toHaveBeenCalled()saveRename 在成功与 catch 两条路径都已调用 refreshWorkspace(ownerCwd)(783、788 行),因此把两个同步调用合并的清理——例如把 renamed(...) 挪到与 refreshWorkspace 并列的共享 finally/catch——会在套件全绿的情况下通过(已验证:把 renamed 加进 catch 仍 90/90 绿)。失败的改名将用守护进程拒绝的值覆盖 catalog 缓存的显示名,标签一直错误直到下一次完整对账。请在失败测试中补上负向断言;把 renamed(...) 移入失败路径后该断言应变红(探针在该突变下观察到它被调用一次,参数 ['/w','s1','Renamed'])。

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

@qwen-code-dev-bot

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

Copy link
Copy Markdown
Collaborator

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

中文说明

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

钉萁 and others added 2 commits August 27, 2026 13:29
…view-optimize

# Conflicts:
#	packages/web-shell/client/App.test.tsx
#	packages/web-shell/client/components/sidebar/SessionDetailsTooltip.tsx
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

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

Round summary — PR #10115 (session overview optimize)

Base-conflict resolution was required this round: origin/main (65 commits) was merged in. Two conflicts were resolved by understanding both sides:

  • packages/web-shell/client/App.test.tsx — both sides added different tests at the same insertion point; kept both groups (8 branch tests + main's sidebar-customization test).
  • packages/web-shell/client/components/sidebar/SessionDetailsTooltip.tsx — main added PR-state icons (SessionPrStateIcon + sr-only state label); the branch wraps the status/id rows in the worktreeOnly gate. Kept both features combined.

Feedback dispositions

Round-2 Critical findings — fixed this round

  • [rc:3870807244] (Critical, fix-induced fold-restore over navigation) — Fixed. The && !activePanel deferral left splitFoldedByShrinkRef set while the Session Overview is open, so any later panel close restored the folded split over the user's navigation. The flag is now cleared whenever the user takes explicit ownership of the view: handleSplitExit, handleOpenSessionFromOverview, and the sessions-panel Back handler. The plain-dismiss (Escape) deferred restore is unchanged. Two new tests reproduce the defect on the pre-fix code (probe-verified: split-view-page present over navigation) and pin the fix: leaving via Back and opening a session from the overview both keep split-view-page absent. Mutation probe: removing either flag-clear turns the matching test red.
  • [rc:3870807251] (Critical, workspace bounce on delete/archive of current session) — Fixed. onCurrentSessionRemoved now calls createNewSession(removed.workspaceCwd || undefined, …) instead of createNewSession(undefined, …), so the next chat stays in the deleted/archived session's trusted secondary workspace instead of silently resolving to the primary on the next prompt. New witness test mirrors the panel-back secondary-workspace test for the delete flow; it fails with expected undefined to be '/work/secondary' when the fix is reverted (mutation-verified).
  • [rc:3870807273] (Critical, stale workspace exclusion hides every row when locked) — Fixed. Added a reconcile effect keyed on excludedWorkspaceCwds/workspaceOptions that drops exclusions no longer present in the visible options — including all of them when the panel becomes locked to a workspace and the filter popover disappears. New test: exclude /wsB via the funnel, re-render locked to /wsB, assert the row is listed; the test fails on pre-fix code with the reported [""] empty shape and goes red again when the effect is deleted (mutation-verified).

Round-2 suggestions — implemented this round

  • [rc:3870807284] (R2-3, rejected-mutation refresh unwitnessed) — The finally refresh in mutateCards and the catch refresh in saveRename already existed; they are now pinned: expect(refreshWorkspace).toHaveBeenCalledWith('/w') added to the does not clear the current session when %s fails it.each, the archive-failure test, and the rename-failure test. Mutation probes: moving the refresh out of finally (or out of the rename catch) turns those tests red.
  • [rc:3870807292] (R2-4, navigation exits unwitnessed) — Implemented together with the rc:3870807244 fix as the two navigation-exit variant tests described above.
  • [rc:3870807295] (R2-5, || nextName fallback unwitnessed) — New test: rename resolving undefined asserts renamed('/w', 's1', 'Void Name'). Dropping the fallback makes it red (mutation-verified).
  • [rc:3870807304] (R2-6, rename-failure negative witness) — The rename-failure test now also asserts renamed was NOT called. Moving renamed(...) into the failure path makes it red (mutation-verified).

Round-1 findings — verified as already resolved in code (prior fix commits 6659d77d9a / bb7d84c0cf), re-verified against this head

All 23 round-1 inline findings were checked against the current code and each confirmed resolved:

  • rc:3868956975 (R1-1 catalog invalidation): mutateCards refreshes the owning catalog workspace in finally, saveRename calls renamed(...) + refreshWorkspace(...) on success and refreshWorkspace(...) on catch; now additionally pinned by the R2-3/5/6 witnesses above.
  • rc:3868956978 (JSDoc), rc:3868956982 (grow-restore deferral, Escape witness exists), rc:3868956987 ('Unlocked pinned' archive assertion), rc:3868956992 (TooltipContent DOM ref test), rc:3868956999 (data-table fixedWidth + distinct-weight cases), rc:3868957006 (workspaceCwds asserted ['/w','/wsB'] / ['/wsB']), rc:3868957010 (recency tie-break test), rc:3868957013 (hasActivePrompt status-report fallback test), rc:3868957016 (panel-level status-report ranking test), rc:3868957021 (not.toContain('opacity-0')), rc:3868957024 (workspaceByCwd called-with assertion), rc:3868957027 (qualified mocks echo ids), rc:3868957031 (pruning test second half restored), rc:3868957036 (exactly-6 boundary test opens all 6 sessions at the split limit), rc:3868957038 (page-clamp test), rc:3868957040 (primary folder cell assertion), rc:3868957044 (clear-failure mislabel fixed — cleared === false surfaces newSessionFailed directly, tests for both delete and archive), rc:3868957046 (two-phase status-poll shape restored), rc:3868957048 (cross-workspace status isolation test), rc:3868957050 (dead memo removed), rc:3868957057 (status-poll cost rationale restored in the comment), rc:3868957064 (archive clear-failure test).

Maintainer report [ic:5426366182] (@wenshao)

  • Finding 1 (split cap silent + wrong order) — already fixed in 6659d77d9a before this round: selectedCards derives from getSortedRowModel() (visible sort order) and both open buttons are disabled above the cap with a splitLimit tooltip. Witnessed by opens the selected sessions in the visible sort order, disables split actions when more than 6 sessions are selected, and opens all 6 sessions at the split limit. This round additionally removed the three remaining dead assertions the report flagged ('No sessions matching', 'border-r', 'group-hover:bg-muted/50' — none of these strings is produced by any product code; the surviving positive assertions in the same tests pin the real behavior).
  • Finding 2 (primary-path archive notFound false error) — left for a maintainer decision (report classifies findings 2–4 as maintainer judgement calls). Recommendation: align the primary-workspace predicate with the qualified branch and the delete side (count notFound as success) — the report's live A/B shows the inconsistency is real but not a correctness bug.
  • Finding 3 (fixed regions cover the viewport below ~430px) — left for a maintainer decision (product/design tradeoff; the table stays operable).
  • Finding 4 (Back discards the open conversation) — design question left for maintainers (the PR body says clearing on Back is intended). Its workspace-reset sub-point is already resolved: panel-back passes currentWorkspaceCwd to createNewSession, pinned by starts a new session when leaving the Session Overview with Back asserting selectedWorkspaceCwd === '/work/secondary'.
  • Bulk archive fan-out — no longer present: mutateCards routes every group (primary included) through the batch archiveSessionsData/deleteSessionsData endpoints.
  • Stale docs — already fixed in 6659d77d9a (sessionsOverview no longer "large screens only"; inlineItems docs updated, 'archive' documented as dropdown-only).
  • Vacuous sidebar test — already fixed (hides archive UI when session_archive is absent now asserts through openSessionMenuItems).
  • Follow-ups recorded in deferred-findings.json: the ui/data-table.tsx shared-primitive rough edges and the react18-ref-compat.test.tsx harness weakness (both verified-real per the report, explicitly follow-up material, larger than this round).

Other issue comments

  • [ic:5423234169] web-shell visual preview — the lane reported one or more scenarios failed to render at the previous head bb7d84c. Which scenario failed is not identifiable from here (no access to the run's artifacts, and no Playwright browser is installable on this runner). The lane is non-blocking by design (continue-on-error) and refreshes on every push; it will re-run against this round's push.
  • [ic:5434715006] tmux E2E report (@qqqys) — informational, no blocking issues reported; no action needed.

Verification

  • npm ci — failed against the default cache (root-owned files in ~/.npm, pre-existing runner issue); re-ran as npm ci --cache /tmp/npm-autofix-cache — passed.
  • Reproduction-first: all three new Critical-fix tests were written first and confirmed RED on the pre-fix code with the exact reported failure shapes ([""] empty rows; split-view-page present over navigation; expected undefined to be '/work/secondary').
  • Mutation probes (each guard removed/negated → focused tests go red → restored → green):
    1. reconcile effect deleted → drops stale workspace exclusions… red.
    2. removed.workspaceCwd || undefined reverted to undefined → workspace witness red.
    3. either navigation flag-clear removed → matching navigation-exit variant red.
    4. finally refresh in mutateCards removed → both does not clear the current session when %s fails cases + archive-failure test red (3).
    5. rename catch refresh removed → rename-failure test red.
    6. || nextName fallback removed → void-rename test red.
    7. renamed(...) added to the rename failure path → rename-failure test red.
  • npx vitest run for the touched files — SessionOverviewPanel.test.tsx 92 passed; App.test.tsx 560 passed; data-table.test.tsx 4 passed; react18-ref-compat.test.tsx + WebShellSidebar.workspace-removal.test.tsx + SessionDetailsTooltip.test.tsx all passed.
  • npx vitest run whole packages/web-shell package — 202 files / 4424 tests passed.
  • npm run build — passed.
  • npm run typecheck — passed.
  • npm run lint — passed (no errors/warnings).
  • npx prettier --check on the four changed files — passed.
  • Integration tests: not applicable (web-shell client behavior, exercised through the package's own vitest suites; nothing in the change is only reachable through the bundled CLI).
  • npm run generate:settings-schema: not applicable (no settings source changed).
中文说明

本轮总结 — PR #10115(会话总览优化)

本轮需要先解决与基线的冲突:已合入 origin/main(65 个提交)。两处冲突均通过理解双方语义后解决:

  • packages/web-shell/client/App.test.tsx —— 双方在同一插入点各自新增了不同的测试;两组全部保留(分支上的 8 个测试 + main 的侧边栏定制测试)。
  • packages/web-shell/client/components/sidebar/SessionDetailsTooltip.tsx —— main 新增了 PR 状态图标(SessionPrStateIcon + sr-only 状态文本);分支侧把状态/ID 行包在 worktreeOnly 门控里。两个特性合并保留。

反馈处理

第二轮 Critical 发现 — 本轮已修复

  • [rc:3870807244](Critical,延迟恢复覆盖用户导航,系修复引入) —— 已修复。&& !activePanel 延迟逻辑在会话总览打开期间一直保留 splitFoldedByShrinkRef,导致之后任何关闭面板的操作都会把折叠的分屏恢复到用户导航之上。现在凡是用户明确接管视图时都会清除该标志:handleSplitExithandleOpenSessionFromOverview、会话面板返回按钮。普通关闭(Esc)的延迟恢复行为保持不变。新增两个测试在修复前复现缺陷(探针验证:导航之上出现 split-view-page)并钉住修复:从返回按钮离开、从总览打开会话,split-view-page 均保持不出现。变异探针:移除任一清标志逻辑,对应测试变红。
  • [rc:3870807251](Critical,删除/归档当前会话后工作区被弹回主工作区) —— 已修复。onCurrentSessionRemoved 现在调用 createNewSession(removed.workspaceCwd || undefined, …) 而非 createNewSession(undefined, …),使下一个聊天保持在被删除/归档会话所在的可信次要工作区,而不是在下一条消息时悄悄解析为主工作区。新增见证测试仿照面板返回的次要工作区测试覆盖删除流程;将修复还原为 undefined 后测试以 expected undefined to be '/work/secondary' 失败(变异验证)。
  • [rc:3870807273](Critical,锁定后过期排除项隐藏所有行) —— 已修复。新增一个以 excludedWorkspaceCwds/workspaceOptions 为依赖的对账 effect,把不再出现在可见选项中的排除项丢弃——面板被锁定到某个工作区、筛选弹层消失时则全部清除。新增测试:先通过漏斗筛选排除 /wsB,再以锁定 /wsB 重新渲染,断言行仍列出;该测试在修复前以报告的 [""] 空形态失败,删除对账 effect 后再次变红(变异验证)。

第二轮建议 — 本轮已实现

  • [rc:3870807284](R2-3,失败路径刷新无见证) —— mutateCardsfinally 刷新与 saveRenamecatch 刷新本就存在,现已钉住:does not clear the current session when %s fails 参数化测试、归档失败测试、改名失败测试均补充 expect(refreshWorkspace).toHaveBeenCalledWith('/w')。变异探针:把刷新移出 finally(或移出改名 catch)后这些测试变红。
  • [rc:3870807292](R2-4,导航式离开无见证) —— 与 rc:3870807244 的修复一并实现,即上述两个导航离开变体测试。
  • [rc:3870807295](R2-5,|| nextName 兜底无见证) —— 新增测试:改名解析为 undefined 时断言 renamed('/w', 's1', 'Void Name')。移除兜底后变红(变异验证)。
  • [rc:3870807304](R2-6,改名失败负向见证) —— 改名失败测试补充断言 renamed 未被调用。把 renamed(...) 移入失败路径后变红(变异验证)。

第一轮发现 — 已在代码中确认解决(先前修复提交 6659d77d9a / bb7d84c0cf),本轮在当前 head 上逐一复核

23 条第一轮 inline 发现已全部对照当前代码核实为已解决:

  • rc:3868956975(R1-1 catalog 失效):mutateCardsfinally 中刷新所属工作区,saveRename 成功路径调用 renamed(...) + refreshWorkspace(...)、catch 路径调用 refreshWorkspace(...);本轮又由上述 R2-3/5/6 见证进一步钉住。
  • rc:3868956978(JSDoc)、rc:3868956982(grow 恢复延迟,Esc 见证已存在)、rc:3868956987('Unlocked pinned' 归档断言)、rc:3868956992(TooltipContent DOM ref 测试)、rc:3868956999(data-table fixedWidth 与不同权重用例)、rc:3868957006(workspaceCwds 断言 ['/w','/wsB'] / ['/wsB'])、rc:3868957010(同状态按最近排序测试)、rc:3868957013(hasActivePrompt 状态报告兜底测试)、rc:3868957016(面板级状态报告排序测试)、rc:3868957021(not.toContain('opacity-0'))、rc:3868957024(workspaceByCwd 调用参数断言)、rc:3868957027(qualified mock 回显 id)、rc:3868957031(裁剪测试后半段恢复)、rc:3868957036(恰好 6 个的边界测试 opens all 6 sessions at the split limit)、rc:3868957038(页码钳制测试)、rc:3868957040(主工作区文件夹单元格断言)、rc:3868957044(清空失败误标已修——cleared === false 直接提示 newSessionFailed,删除与归档均有测试)、rc:3868957046(两段式状态轮询形态恢复)、rc:3868957048(跨工作区状态隔离测试)、rc:3868957050(无用 memo 已删)、rc:3868957057(状态轮询成本理由已恢复到注释)、rc:3868957064(归档清空失败测试)。

维护者报告 [ic:5426366182](@wenshao

  • 问题 1(分屏上限无声截断 + 排序下丢错对象) —— 已在本轮之前的 6659d77d9a 修复:selectedCards 取自 getSortedRowModel()(可见排序),超限时两个打开按钮禁用并显示 splitLimit 提示。由 opens the selected sessions in the visible sort orderdisables split actions when more than 6 sessions are selectedopens all 6 sessions at the split limit 三个测试见证。本轮另外删除了报告指出的剩余三条失效断言('No sessions matching''border-r''group-hover:bg-muted/50'——这些字符串均不由任何产品代码产生;同一测试中存活的正向断言已钉住真实行为)。
  • 问题 2(主工作区归档 notFound 假错误) —— 留给维护者决定(报告将问题 2–4 归为维护者判断项)。建议:把主工作区判定与 qualified 分支及删除侧对齐(把 notFound 计为成功)——报告的实机 A/B 证明该不一致真实存在但非正确性缺陷。
  • 问题 3(约 430px 以下固定列盖满视口) —— 留给维护者决定(产品/设计取舍;表格仍可操作)。
  • 问题 4(返回按钮丢弃已打开对话) —— 设计问题留给维护者(PR 描述说明返回时清空是有意设计)。其中的工作区重置子问题已解决:面板返回会向 createNewSession 传入 currentWorkspaceCwd,由 starts a new session when leaving the Session Overview with Back 断言 selectedWorkspaceCwd === '/work/secondary' 钉住。
  • 主工作区批量归档逐条请求 —— 已不存在:mutateCards 的所有分组(含主工作区)均走批量接口 archiveSessionsData/deleteSessionsData
  • 文档过时 —— 已在 6659d77d9a 修复(sessionsOverview 不再标注"仅大屏";inlineItems 文档已更新,'archive' 标注为仅下拉菜单)。
  • 失效的侧边栏测试 —— 已修复(hides archive UI when session_archive is absent 现通过 openSessionMenuItems 断言)。
  • 后续跟进项已记录到 deferred-findings.jsonui/data-table.tsx 通用组件的毛刺、react18-ref-compat.test.tsx 测试用具偏弱(均按报告验证属实、明确属于后续项,且超出本轮范围)。

其他 issue 评论

  • [ic:5423234169] web-shell 视觉预览 —— 该通道报告上一个 head bb7d84c 上有一个或多个场景渲染失败。具体哪个场景失败在此无法定位(无法访问该运行的产物,且本运行器无法安装 Playwright 浏览器)。该通道按设计为非阻塞(continue-on-error)且每次推送自动刷新;本轮推送后会重新运行。
  • [ic:5434715006] tmux E2E 报告(@qqqys —— 信息性评论,未报告阻塞问题;无需处理。

验证

  • npm ci —— 默认缓存失败(~/.npm 含 root 所有文件,属运行器既有问题);改用 npm ci --cache /tmp/npm-autofix-cache 重跑 —— 通过。
  • 复现优先:三个 Critical 修复测试均先编写并在修复前确认为红,失败形态与报告完全一致([""] 空行;导航之上出现 split-view-pageexpected undefined to be '/work/secondary')。
  • 变异探针(逐项移除/取反新守卫 → 对应测试变红 → 恢复 → 变绿):
    1. 删除对账 effect → drops stale workspace exclusions… 变红。
    2. removed.workspaceCwd || undefined 还原为 undefined → 工作区见证变红。
    3. 移除任一导航清标志 → 对应导航离开变体变红。
    4. 移除 mutateCardsfinally 刷新 → 两个 does not clear the current session when %s fails 用例 + 归档失败测试变红(3 个)。
    5. 移除改名 catch 刷新 → 改名失败测试变红。
    6. 移除 || nextName 兜底 → void 改名测试变红。
    7. renamed(...) 加进改名失败路径 → 改名失败测试变红。
  • 对修改文件运行 npx vitest —— SessionOverviewPanel.test.tsx 92 通过;App.test.tsx 560 通过;data-table.test.tsx 4 通过;react18-ref-compat.test.tsx + WebShellSidebar.workspace-removal.test.tsx + SessionDetailsTooltip.test.tsx 全部通过。
  • 整个 packages/web-shellnpx vitest run —— 202 个文件 / 4424 个用例全部通过
  • npm run build —— 通过。
  • npm run typecheck —— 通过。
  • npm run lint —— 通过(无错误/警告)。
  • 对四个改动文件运行 npx prettier --check —— 通过。
  • 集成测试:不适用(web-shell 客户端行为,由该包自身的 vitest 套件覆盖;改动内容不存在只能经打包 CLI 触达的路径)。
  • npm run generate:settings-schema:不适用(未改动任何 settings 源)。

Base-conflict check · 基分支冲突检查: conflicted with main — resolved in this push. · 与 main 有冲突——已在本次推送中解决。

Re-review when you have a moment. After round 100 this bot stops and leaves the PR for a human. · 有空请复审;第 100 轮后本 bot 停止并将 PR 交给人工。


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

@qwen-code-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.

2 Suggestion-level finding(s) this review confirmed are already reported on this PR and are not repeated:

  • manageLiveState=true (panel-owned channel) direction unwitnessed — already reported in the round-2 deferred list (review 5039666410: 'App.tsx:12649 — manageLiveState is only witnessed in the false direction' and 'SessionOverviewPanel.test.t…
  • canOpenSessionsOverview un-gating unwitnessed — already reported in the round-2 deferred list (review 5039666410: 'App.tsx:12183 — canOpenSessionsOverview un-gating has no witness')

Not explored to full depth (tool budget reached): chunk 6: execute SessionOverviewPanel.test.tsx under vitest to confirm the chunk's tests pass at the reviewed commit.

Deferred under the convergence posture (round 3, not a blocker) — recorded, not requested in this round:

  • packages/web-shell/client/components/SessionOverviewPanel.test.tsx:36 — [probe] capabilities mock typed as full DaemonCapabilities envelope; every fixture omits required fields (TS2739 invisible to CI)
  • packages/web-shell/client/components/SessionOverviewPanel.tsx:171 — [review] readPageSize hand-lists the page sizes PAGE_SIZES already declares — remembered pagination silently resets if the list drifts
  • packages/web-shell/client/components/ui/data-table.tsx:34 — [review] fixedOffset is a dead switch: declared and read at three sites, never set by any caller
  • packages/web-shell/client/components/ui/data-table.tsx:267 — [probe] hardcoded overflow-hidden beats the caller's overflow-y:auto only by CSS concatenation order (measured on the built bundle)
  • packages/web-shell/client/components/SessionOverviewPanel.tsx:865 — [probe] export-failure notice branch has no witness; emptying the catch keeps 92/92 green
  • packages/web-shell/client/components/SessionOverviewPanel.tsx:989 — [probe] filter-change page/selection reset effect unwitnessed; deleting it keeps 92/92 green
  • packages/web-shell/client/App.test.tsx:18133 — [probe] onCurrentSessionRemoved entry-guard sessionId arm has no witness; removing it keeps 560/560 green
  • packages/web-shell/client/App.test.tsx:18216 — [probe] panel-Back created && failure-path guard has no witness; dropping it keeps 560/560 green
  • packages/web-shell/client/components/SessionOverviewPanel.test.tsx:2532 — [probe] other-workspaces poll suppression under live-state unwitnessed; always-LIST_POLL_MS mutant keeps 92/92 green
  • packages/web-shell/client/components/SessionOverviewPanel.test.tsx:86 — [probe] removed useSessions mock export leaves a dangling reference for the real useWebShellSessions
  • packages/web-shell/client/components/ui/table.tsx:10 — [review] scroll axes split across nested containers: horizontal scrollbar renders at the bottom of full-height content, not the visible viewport
  • packages/web-shell/client/App.test.tsx:18133 — [probe] overview completion-guard workspace arm has no witness; removing it keeps all nine tests green
  • packages/web-shell/client/App.tsx:5516 — [probe] approval effect force-closing the panel re-triggers the deferred split restore, replacing the approval overlay with the split notice
  • packages/web-shell/client/App.tsx:5516 — [probe] fold flag consumed by Goals/Scheduled-Tasks transitions silently discards the deferred restore
  • packages/web-shell/client/components/SessionOverviewPanel.tsx:882 — [probe] batch daemon error swallowed when the current-session clear fails; only newSessionFailed is shown
  • packages/web-shell/client/components/sidebar/WebShellSidebar.workspace-removal.test.tsx:2773 — [probe] archive enabled-state pin lost for pinned sessions in the dropdown migration; isPinned mutant keeps 82/83 green

Convergence: round 3 posted 5 inline comment(s), 4 of them reported for the first time; the previous round posted 7 (7 new). Findings keep coming back to the same files: packages/web-shell/client/components/SessionOverviewPanel.tsx (findings in round 2; 3 more now); packages/web-shell/client/App.tsx (findings in rounds 1, 2; 1 more now). A cluster that keeps producing siblings usually means the fixes are treating instances of a shared root cause — triaging that cause before the next round, or splitting an independent cluster into its own pull request, tends to end the loop faster than fixing them one at a time. (Observation only — nothing was withheld from this review because of this observation.)

中文说明

本轮确认的 2 条建议级发现已在 PR 上报告过,不再重复发布(列表见上方英文部分)。

未探索到全部深度(达到工具调用预算):chunk 6:execute SessionOverviewPanel.test.tsx under vitest to confirm the chunk's tests pass at the reviewed commit

收敛姿态下延后(第 3 轮,非阻断)——已记录,本轮不要求修改:共 16 条(原文未翻译,列表见上方英文部分)。

收敛情况:第 3 轮发布了 5 条行内评论,其中 4 条是首次提出;上一轮发布了 7 条(其中 7 条首次提出)。发现反复回到同一批文件:packages/web-shell/client/components/SessionOverviewPanel.tsx(第 2 轮已出过发现,本轮又有 3 条);packages/web-shell/client/App.tsx(第 1、2 轮已出过发现,本轮又有 1 条)。一个不断再生兄弟发现的簇,通常意味着逐条修复只在处理同一根因的实例——先定位并处理该根因,或把独立的簇拆成单独的 PR,通常比逐条修复更快结束循环。(仅为观察——本轮评审未因此扣留任何内容。)

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

Comment on lines +5516 to 5517
if (splitFoldedByShrinkRef.current && !activePanel) {
splitFoldedByShrinkRef.current = false;

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.

[Critical] R1-3: The stale-flag restore this thread was filed for still stands via sibling navigation paths. The round-2 fix cleared splitFoldedByShrinkRef only in handleSplitExit, handleOpenSessionFromOverview, and the panel-Back handler; the shared entry points createNewSession (New chat, workspace switch) and loadSidebarSession (sidebar session click) — plus onSelectCurrentSession — still close the panel without clearing it. With a split open, shrink below 1024px (the fold sets the flag), keep the overview open, grow back (restore deferred by !activePanel), then click New chat or a sidebar session: closePanel() runs, this effect re-runs on the activePanel dep with the stale flag, and mainView flips back to 'split' — the user lands on the old split while the fresh chat/session loads invisibly in the background.

Witness (probe on this commit):

× does not restore a folded split when the sidebar starts a new chat
  → expected <div class="_fullPage_cdbed7" …> to be null   (split-view-page present after navigation)
× sidebar loads a session → same failure shape
with the flag cleared in createNewSession/loadSidebarSession: 18 passed (fold family green)

Clear the flag at the two shared entry points instead of enumerating call sites:

// in createNewSession, beside closePanel()
splitFoldedByShrinkRef.current = false;
// in loadSidebarSession, beside closePanel()
splitFoldedByShrinkRef.current = false;

Leave the Escape dismiss-restore path untouched so the existing 'defers split restoration' test still pins it. Fix witness: add fold-family tests that leave the overview via sidebar New chat / session open and assert split-view-page stays absent — removing either flag-clear must turn the matching test red (the probe verified both directions).

中文说明

R1-3 仍然存在:本线程所报的过期标志恢复问题仍可通过其他导航路径触发。第二轮修复只在 handleSplitExithandleOpenSessionFromOverview 和面板返回处理器中清除了 splitFoldedByShrinkRef;共享入口 createNewSession(新建聊天、切换工作区)与 loadSidebarSession(点击侧边栏会话)以及 onSelectCurrentSession 关闭面板时依然不清除该标志。分屏打开时收缩到 1024px 以下(折叠置位标志),保持总览打开,窗口恢复变大(!activePanel 延迟恢复),然后点击新建聊天或侧边栏会话:closePanel() 执行后,该 effect 因 activePanel 依赖重新运行,读到过期标志,把 mainView 翻回 'split'——用户落在旧分屏上,而新聊天/会话在后台无声加载。

修复:在两个共享入口处清标志(见上方代码),而不是逐一枚举调用点;保留 Esc 普通关闭的延迟恢复路径,以维持现有 'defers split restoration' 测试。见证测试:新增从侧边栏新建聊天/打开会话离开总览的用例,断言 split-view-page 保持不出现;移除任一清标志逻辑后该测试应变红(探针已双向验证)。

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

Comment on lines 515 to +517
useEffect(() => {
setSelected((prev) => {
if (prev.size === 0) return prev;
const present = new Set(cards.map((card) => card.sessionId));
let changed = false;
const next = new Set<string>();
for (const id of prev) {
if (present.has(id)) next.add(id);
else changed = true;
}
return changed ? next : prev;
if (excludedWorkspaceCwds.size === 0) return;
const optionCwds = new Set(workspaceOptions.map((option) => option.cwd));

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.

[Critical] R2-2: (fix-induced) The round-2 fix closed the reported input — locking the panel to the excluded workspace now drops the exclusion (pinned by 'drops stale workspace exclusions when the panel locks to the excluded workspace') — but the pruning effect it added opened a new hole at the same site. It keeps any exclusion whose cwd is still in workspaceOptions, while the funnel popover that manages exclusions only renders when workspaceOptions.length > 1. When the option set shrinks to exactly one workspace — e.g. two primary-or-trusted workspaces A and B, the user excludes A via the funnel, then B loses trust (hot-reloadable) or drops out of the primary-or-trusted filter while staying registered — workspaceOptions becomes [A], the funnel disappears, and this effect keeps A's exclusion because A is still an option. Every remaining row belongs to A and is filtered out: the table shows 'No data' although sessions exist, with no visible control left to clear the filter, until remount. This violates the effect's own stated invariant ('drop any exclusion the user can no longer see or change').

Witness (probe on this commit):

PR code: funnelTrigger() === null, zero data rows, tbody holds only the "No data" placeholder
         although the primary session exists
with the length gate below: the data row reappears
Suggested change
useEffect(() => {
setSelected((prev) => {
if (prev.size === 0) return prev;
const present = new Set(cards.map((card) => card.sessionId));
let changed = false;
const next = new Set<string>();
for (const id of prev) {
if (present.has(id)) next.add(id);
else changed = true;
}
return changed ? next : prev;
if (excludedWorkspaceCwds.size === 0) return;
const optionCwds = new Set(workspaceOptions.map((option) => option.cwd));
useEffect(() => {
if (excludedWorkspaceCwds.size === 0) return;
if (workspaceOptions.length <= 1) {
setExcludedWorkspaceCwds((prev) =>
prev.size === 0 ? prev : new Set<string>(),
);
return;
}
const optionCwds = new Set(workspaceOptions.map((option) => option.cwd));

(keep the existing filter/guard below unchanged). Fix witness: render two workspaces, exclude /w through the funnel, re-render capabilities with /wsB trusted: false (still registered); assert the funnel button is absent and /w's rows render again — removing the length <= 1 gate must turn it red (the probe verified both directions).

中文说明

R2-2(修复引入):第二轮修复已关闭原始报告的输入——面板被锁定到已排除的工作区时,排除项会被清除(由 'drops stale workspace exclusions when the panel locks to the excluded workspace' 钉住)——但新增的对账 effect 在同一位置开了新洞:它会保留任何仍在 workspaceOptions 中的排除项,而管理排除项的漏斗弹层只在 workspaceOptions.length > 1 时渲染。当选项集收缩到恰好一个工作区时(例如两个主或可信工作区 A、B,用户通过漏斗排除 A,随后 B 失去信任(可热更新)或离开主/可信过滤但仍注册),workspaceOptions 变为 [A],漏斗消失,而该 effect 因 A 仍是选项而保留 A 的排除项。剩余所有行都属于 A,全部被过滤:会话明明存在,表格却显示 'No data',且没有任何可见控件能清除该过滤,只能重新挂载。这违反了该 effect 自己声明的不变量('丢弃用户不再能看见或修改的排除项')。

修复见上方 suggestion:选项数 <= 1 时清空排除集。见证测试:渲染两个工作区,通过漏斗排除 /w,再以 /wsB trusted: false(仍注册)重新渲染能力;断言漏斗按钮消失且 /w 的行重新出现;移除 length <= 1 门后应变红(探针已双向验证)。

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

Comment thread packages/web-shell/client/App.tsx Outdated
@@ -12738,8 +12767,49 @@ export function App({
<SessionOverviewPanel
onOpenSession={handleOpenSessionFromOverview}
onOpenSplit={openSplitView}

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.

[Critical] Removing the isLargeScreen gate from canOpenSessionsOverview makes the Session Overview — and this Open in split action — reachable below the 1024px breakpoint where split view cannot exist. openSplitView is passed unconditionally and the panel renders the button whenever the prop is present (SessionOverviewPanel.tsx:1642), while the toolbar entry stays gated on canOpenSplitView={isLargeScreen}. Below the breakpoint the click closes the panel, sets mainView='split', and the shrink-fold effect immediately folds it back — the user lands on bare chat with no split and no error. If the chat had no session, the fold's landing branch silently repoints the connection to the first selected pane (App.tsx:5541-5544); the fold also sets splitFoldedByShrinkRef and the sibling save effect persists the pane set in the same commit, so growing the window later restores a split the user never effectively had, and a refresh re-enters the same fold loop. Before this diff the overview was large-screen-only, so this path was unreachable.

Witness (probe on this commit):

below the breakpoint: overview opens; onOpenSplit(['s1','s2']) → no split-view-page (silent fold)
grow back → split-view-page resurrected → × expected <div class="_fullPage_cdbed7"> to be null
with onOpenSplit={isLargeScreen ? openSplitView : undefined}: 15 passed
Suggested change
onOpenSplit={openSplitView}
onOpenSplit={isLargeScreen ? openSplitView : undefined}

The panel already hides the button when the prop is undefined. Fix witness: render below the breakpoint via the existing matchMedia mock, open the overview, invoke the captured latestSessionOverviewProps.onOpenSplit(['s1','s2']), grow past the breakpoint and assert split-view-page never appears (and the connection was not swapped) — removing the guard must turn it red.

中文说明

canOpenSessionsOverview 移除 isLargeScreen 门后,会话总览——以及这个"在分屏中打开"操作——在分屏根本无法存在的 1024px 以下断点处也变得可达。openSplitView 被无条件传入,面板只要收到该 prop 就渲染按钮(SessionOverviewPanel.tsx:1642),而工具栏入口仍受 canOpenSplitView={isLargeScreen} 约束。断点以下点击会关闭面板、把 mainView 设为 'split',收缩折叠 effect 立刻把它折回——用户落在没有分屏、也没有任何错误的纯聊天界面上。若聊天没有会话,折叠的落地分支会把连接悄悄切换到第一个选中的面板(App.tsx:5541-5544);折叠还会置位 splitFoldedByShrinkRef,同一次提交中相邻的保存 effect 会把面板集持久化,于是之后窗口变大时会恢复一个用户实际从未拥有的分屏,刷新页面还会重新进入同样的折叠循环。本 diff 之前总览仅大屏可用,此路径不可达。

修复见上方 suggestion:按大屏条件传入 onOpenSplit(prop 为 undefined 时面板自动隐藏按钮)。见证测试:用现有 matchMedia mock 在断点以下渲染,打开总览,调用捕获到的 onOpenSplit(['s1','s2']),再放大超过断点,断言 split-view-page 始终不出现(且连接未被切换);移除该守卫后测试应变红。

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

const { sessions, loading, error, reload } = useScopedSessions(workspaceCwd, {
autoLoad: true,
pollIntervalMs: LIST_POLL_MS,
pollIntervalMs: liveStateEnabled ? undefined : LIST_POLL_MS,

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.

[Critical] The two ends of the refresh-mode invariant read different configs: the live-state subscription honours manageLiveState (enabled: manageLiveState && liveStateEnabled, line 391) but every polling-suppression path keys off liveStateEnabled alone — this list poll, the other-workspaces poll (line 411), useStatusReport autoLoad (line 430) and the status interval (line 438) — while the actual manager, the sidebar, covers a narrower workspace set (entry.trusted && isAbsolutePath, WebShellSidebar.tsx:981-985) than this panel's liveStateWorkspaceCwds (entry.primary || entry.trusted, line 382). Daemon advertises workspace_session_live_state, the primary entry is { primary: true, trusted: false } (a real state: serve/server.ts:1244 sets trusted: deps.primaryWorkspaceTrusted ?? false), sidebar enabled → App passes manageLiveState=false: this panel suppresses all four of its own polls for a channel it does not run, the sidebar's trusted-only channel excludes the primary, and nothing refreshes the primary workspace's catalog or volatile flags. The overview loads once and silently freezes — running/idle indicators stop moving, new sessions never appear, needs-approval sessions never surface — until the user happens to click Refresh. Before this diff the panel polled unconditionally.

Witness (probe on this commit):

× keeps its own catalog poll when it does not own the live-state channel
  → expected undefined to be 3000   (pollIntervalMs suppressed; enabled === false asserted green in the same test)
with suppression gated on manageLiveState && liveStateEnabled: probe green
sole casualty: the pre-existing pinning test 'uses sidebar-owned live state without starting a duplicate channel', as predicted

Gate the suppression on effective ownership — e.g. const liveStateActive = manageLiveState && liveStateEnabled; used at all four sites — or align this target set with the manager's (entry.trusted + absolute-path only). Fix witness: render capabilities { features: ['workspace_session_live_state'], workspaces: [{ id: 'w0', cwd: '/w', primary: true, trusted: false }] } with manageLiveState: false and assert the captured pollIntervalMs is 3000 — removing the ownership gate must turn it red; update the pinning test above to match whichever rule is chosen.

中文说明

刷新模式不变量的两端读取了不同的配置:live-state 订阅尊重 manageLiveStateenabled: manageLiveState && liveStateEnabled,391 行),但所有轮询抑制路径都只看 liveStateEnabled——本列表轮询、其他工作区轮询(411 行)、useStatusReport autoLoad(430 行)与状态间隔轮询(438 行)——而真正的管理者侧边栏覆盖的工作区集合(entry.trusted && isAbsolutePath,WebShellSidebar.tsx:981-985)比本面板的 liveStateWorkspaceCwdsentry.primary || entry.trusted,382 行)更窄。守护进程通告 workspace_session_live_state、主工作区条目为 { primary: true, trusted: false }(真实状态:serve/server.ts:1244 trusted: deps.primaryWorkspaceTrusted ?? false)、侧边栏启用时,App 传入 manageLiveState=false:本面板为自己并不运行的通道抑制了全部四条轮询,侧边栏的仅可信通道又排除了主工作区,主工作区的目录与易变字段没有任何组件刷新。总览加载一次后便无声冻结——运行/空闲指示停止变化、新会话不出现、需要审批的会话不浮现——直到用户恰好点击刷新。本 diff 之前面板无条件轮询。

修复:把抑制条件改为有效所有权(如 const liveStateActive = manageLiveState && liveStateEnabled; 用于四处),或把目标集对齐管理者(仅 entry.trusted + 绝对路径)。见证测试:以上述不可信主工作区能力、manageLiveState: false 渲染,断言捕获的 pollIntervalMs3000;移除所有权门后应变红;同时按所选规则更新上方钉住现行行为的测试。

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

Comment on lines +1493 to +1499
const update = () => {
const naturalHeight =
panel.scrollHeight -
tableViewport.clientHeight +
tableViewport.scrollHeight;
setFooterSticky(naturalHeight > viewport.clientHeight + 1);
};

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.

[Critical] This sticky-footer decision is a self-referential feedback loop. Sticky mode changes the footer's own layout height by −3px net (pt-3 +12px, border-t +1px, -mb-4 −16px), so the reconstructed naturalHeight is N in non-sticky mode and N−3 in sticky mode — while the single threshold has only +1px of hysteresis. For content heights in (viewport+1, viewport+4]px the footer flips every cycle: engage at N > P+1, release at N−3 ≤ P+1, and each flip changes the boxes the ResizeObserver watches, re-firing update(). Additionally, the threshold compares against the scroller's border-box clientHeight (32px of vertical padding included), so panelBody starts scrolling up to ~33px before sticky ever engages — within that window the pagination/bulk-action footer, the feature's point, scrolls out of view. The existing test holds panel.scrollHeight fixed across the mode flip, masking exactly this feedback.

Witness (probe driving this component's own effect with the PR's CSS constants; jsdom computes no layout, geometry from the module's CSS values):

PR code:  cycle0 mode=auto  natural=403 threshold=401 → sticky
          cycle1 mode=sticky natural=400 threshold=401 → auto
          cycle2 → sticky … alternating on all 10 cycles
with the hysteresis below: cycle0 → sticky, cycles 1–9 stay sticky
Suggested change
const update = () => {
const naturalHeight =
panel.scrollHeight -
tableViewport.clientHeight +
tableViewport.scrollHeight;
setFooterSticky(naturalHeight > viewport.clientHeight + 1);
};
const update = () => {
const naturalHeight =
panel.scrollHeight -
tableViewport.clientHeight +
tableViewport.scrollHeight;
setFooterSticky(
(prev) => naturalHeight > viewport.clientHeight + (prev ? -4 : 1),
);
};

(engage at N > P+1, release only at N ≤ P−1 — no overlapping band; alternatively measure the footer without its sticky decorations so both modes compute the same natural height, and compare against the content box rather than clientHeight). Fix witness: extend 'sticks and separates the footer only while the panel overflows' — with N = viewport+2 fire the captured ResizeObserver callback and assert sticky; restub to the sticky-mode geometry (natural height N−3), fire again, and assert still sticky — removing the hysteresis must turn it red.

中文说明

这个粘性页脚判定是一个自引用反馈循环。粘性模式会改变页脚自身的布局高度,净变化 −3px(pt-3 +12px、border-t +1px、-mb-4 −16px),因此重建出的 naturalHeight 在非粘性模式是 N、粘性模式是 N−3——而单一阈值只有 +1px 的滞回。内容高度落在 (视口+1, 视口+4]px 区间时页脚每个周期都翻转:N > P+1 时进入粘性,N−3 ≤ P+1 时退出,而每次翻转都会改变 ResizeObserver 观察的盒子尺寸,从而再次触发 update()。另外,阈值比较的是滚动容器的 border-box clientHeight(含 32px 垂直内边距),所以 panelBody 会在粘性生效前最多提前 ~33px 开始滚动——在这个窗口内,分页/批量操作页脚(该功能的意义所在)会滚出视野。现有测试在模式翻转期间固定 panel.scrollHeight,恰好掩盖了这个反馈。

修复见上方 suggestion:把滞回放宽到大于模式差(进入 N > P+1、退出 N ≤ P−1,两区间不再重叠);或者测量不含粘性装饰的页脚高度使两种模式算出相同的 naturalHeight,并改用内容盒而非 clientHeight 比较。见证测试:扩展现有粘性测试——N = 视口+2 时触发捕获的 ResizeObserver 回调断言粘性;再按粘性模式几何(natural 为 N−3)重设 stub、再次触发、断言仍为粘性;移除滞回后应变红。

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

@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

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

Round summary — PR #10115 (round 3 feedback)

All five inline Critical findings are Resolved in code, each reproduced with a
failing test before the fix and pinned by a witness test that turns red when the
fix is removed (mutation-probed, see Verification). One Conventional Commit:
1c2f558b8e fix(web-shell): address session overview round-3 review feedback
(4 files, +368/−14, all inside the PR's own footprint). No conflict resolution
was needed (--conflict false, no merge performed).

Feedback points and dispositions

  • [rc:3874492730] R1-3 — stale shrink-fold flag restore via sibling navigation paths (App.tsx) — RESOLVED.
    Reproduced first: with a folded split, overview open, and the window grown back,
    clicking sidebar New chat or a sidebar session closed the panel and the deferred
    restore flipped mainView back to 'split' over the freshly loaded chat
    (new tests failed with split-view-page present, matching the reported shape).
    Fix: clear splitFoldedByShrinkRef at the two shared entry points
    (createNewSession inside the !opts?.keepPanel branch, and
    loadSidebarSession beside closePanel()), exactly as suggested, instead of
    enumerating call sites. The Escape dismiss-restore path and the existing
    'defers split restoration' test are untouched and still green. Note: the
    suggested fix deliberately leaves onSelectCurrentSession untouched — picking
    the already-current session is not navigation to a different chat, so the prior
    split state still belongs to that view. Witnesses: 'does not restore a folded
    split when the sidebar starts a new chat' and '…when the sidebar loads a
    session'; each flag-clear was removed individually in a mutation probe and the
    matching test turned red.

  • [rc:3874492742] R2-2 — pruning effect keeps an unmanageable exclusion when the option set shrinks to one (SessionOverviewPanel.tsx) — RESOLVED.
    Reproduced first: excluding the primary via the funnel, then dropping the other
    workspace's trust, left workspaceOptions at exactly one entry — the funnel
    (rendered only for > 1 options) disappeared while the effect kept the
    exclusion, so every row was filtered out into 'No data' with no control left.
    Fix: when workspaceOptions.length <= 1, clear the exclusion set (the suggested
    code), which is exactly the effect's stated invariant ('drop any exclusion the
    user can no longer see or change'). Witness: 'drops exclusions when the option
    set shrinks below the funnel threshold'; probe-verified red without the gate.

  • [rc:3874492761] R3-1 — Open in split reachable below the breakpoint (App.tsx) — RESOLVED.
    Reproduced first: below the large-screen breakpoint the overview handed out
    openSplitView, and invoking it fold-looped a phantom split that a regrow
    resurrected. Fix: pass onOpenSplit={isLargeScreen ? openSplitView : undefined}
    (the suggested one-liner); the panel already hides the button when the prop is
    absent. Witness: 'does not hand out the overview split action below the
    large-screen breakpoint'; probe-verified red without the gate.

  • [rc:3874492777] R3-2 — refresh-mode invariant reads different configs (SessionOverviewPanel.tsx) — RESOLVED.
    Reproduced first: with manageLiveState=false (sidebar owns the live-state
    channel) the panel suppressed its list poll, other-workspaces poll, status
    autoLoad and status interval even though it does not run the channel — and the
    sidebar's trusted-only channel cannot cover an untrusted primary, so the
    overview froze after the initial load. Fix: introduced
    const liveStateActive = manageLiveState && liveStateEnabled (the suggested
    option) and keyed every refresh-mode decision on it — the four suppression
    sites plus the status merge in deriveSessionCards and the manual-refresh
    status reload, so both ends of the invariant read one config. Witness: 'keeps
    its own catalog poll when it does not own the live-state channel' (untrusted
    primary, manageLiveState: falsepollIntervalMs 3000); the pre-existing
    pinning test 'uses sidebar-owned live state without starting a duplicate
    channel' was updated to the chosen rule (still no duplicate channel, but the
    catalog poll is kept). Probe-verified red with the ownership gate removed.

  • [rc:3874492788] R3-3 — sticky-footer self-referential feedback loop (SessionOverviewPanel.tsx) — RESOLVED.
    Reproduced first: sticky mode changes the footer's own layout height by −3px
    net while the decision used a single +1px threshold, so heights in
    (viewport+1, viewport+4] flipped every observer cycle. Fix: the suggested
    asymmetric hysteresis — setFooterSticky((prev) => naturalHeight > viewport.clientHeight + (prev ? -4 : 1)) — engage above P+1, release only at
    true content height ≤ P−1, no overlapping band. The pre-existing sticky test
    (which held geometry fixed across the flip) still passes. Witness: 'holds the
    sticky footer through its own mode-switch height delta' (engage at viewport+2,
    hold through the sticky-mode −3px re-measure, release once content genuinely
    fits); probe-verified red without the hysteresis.

  • Convergence observations and deferred items — no action (as instructed).
    The review body's 16 deferred-under-convergence items are explicitly 'recorded,
    not requested in this round' and were left untouched. The sibling-cluster
    observation (findings recurring in App.tsx / SessionOverviewPanel.tsx) is
    noted; this round's batch closes all five reported instances at their shared
    decision points (one ownership boolean, one flag-clear at shared entry points,
    one conditional prop, one threshold) rather than adding per-instance guards.

Verification

Environment note: the checkout's node_modules was missing @tanstack/react-table
(declared in packages/web-shell/package.json and the lockfile); npm install
synced it. The install rewrote unrelated libc metadata in package-lock.json
(npm version skew) — that file was restored to HEAD and is not part of the commit.

  • Reproduce (pre-fix): npx vitest run SessionOverviewPanel.test.tsx -t '…' and npx vitest run App.test.tsx -t '…' — the 7 new/updated witness tests FAILED against the pre-fix code, matching each finding's reported failure shape
  • Post-fix focused: npx vitest run client/components/SessionOverviewPanel.test.tsx client/App.test.tsx (packages/web-shell) — 658 passed (652 prior + 6 new; one pre-existing test updated in place)
  • Whole touched package: npx vitest run (packages/web-shell) — 202 files, 4430 passed
  • Mutation probes: for each of the 6 new guards (two flag-clears, onOpenSplit gate, exclusion gate, ownership gate, hysteresis) — removed the guard, the matching witness FAILED, restored the guard — 6/6 as required
  • npm run build — passed (exit 0)
  • npm run typecheck — passed (exit 0)
  • npm run lint — passed (exit 0)
  • Integration tests: not run — the changed behavior is React client component logic fully exercised by the package's Vitest suite, not only through the bundled CLI or integration harness
  • npm run generate:settings-schema: not needed (no settings source changed)
中文说明

轮次总结 — PR #10115(第 3 轮反馈)

五条行内 Critical 发现全部已在代码中解决。每一条都先以失败测试复现,再由见证测试钉住;移除对应修复时见证测试会变红(突变探针验证,见下方验证部分)。单个约定式提交:1c2f558b8e fix(web-shell): address session overview round-3 review feedback(4 个文件,+368/−14,全部位于本 PR 自身的足迹范围内)。无需解决冲突(--conflict false,未执行合并)。

反馈点与处置

  • [rc:3874492730] R1-3 — 过期收缩折叠标志可经兄弟导航路径恢复分屏(App.tsx)— 已解决。
    先复现:分屏被折叠、总览打开、窗口重新变大后,点击侧边栏"新建聊天"或侧边栏会话会关闭面板,延迟恢复逻辑把 mainView 翻回 'split',盖住刚加载的新聊天(新测试以 split-view-page 出现而失败,与报告中的失败形态一致)。修复:按建议在两个共享入口处清除 splitFoldedByShrinkRefcreateNewSession!opts?.keepPanel 分支内、loadSidebarSessionclosePanel() 旁),而不是逐一枚举调用点。Esc 关闭的延迟恢复路径与现有 'defers split restoration' 测试未改动且仍然通过。见证:'does not restore a folded split when the sidebar starts a new chat' 与 '…when the sidebar loads a session';突变探针分别移除两处清标志逻辑,对应用例均变红。说明:按建议刻意未改动 onSelectCurrentSession —— 选择当前已加载的会话并不是导航到别的聊天,原先的分屏状态仍属于该视图。

  • [rc:3874492742] R2-2 — 选项集收缩到一个时,对账 effect 保留了不可管理的排除项(SessionOverviewPanel.tsx)— 已解决。
    先复现:通过漏斗排除主工作区后,另一个工作区失去信任,workspaceOptions 恰好剩一项——漏斗(仅在选项 > 1 时渲染)消失,而 effect 仍保留该排除项,所有行被过滤,表格显示 'No data' 且无任何控件可用。修复:workspaceOptions.length <= 1 时清空排除集(即建议代码),这正是该 effect 自己声明的不变量('丢弃用户不再能看见或修改的排除项')。见证:'drops exclusions when the option set shrinks below the funnel threshold';探针验证移除该门后变红。

  • [rc:3874492761] R3-1 — 断点以下仍可使用"在分屏中打开"(App.tsx)— 已解决。
    先复现:大屏断点以下总览仍把 openSplitView 传下去,调用后折叠循环造出幽灵分屏,窗口变大时复活。修复:传入 onOpenSplit={isLargeScreen ? openSplitView : undefined}(建议的一行改动);prop 缺省时面板本就会隐藏该按钮。见证:'does not hand out the overview split action below the large-screen breakpoint';探针验证移除该门后变红。

  • [rc:3874492777] R3-2 — 刷新模式不变量两端读取不同配置(SessionOverviewPanel.tsx)— 已解决。
    先复现:manageLiveState=false(侧边栏拥有 live-state 通道)时,面板抑制了本列表轮询、其他工作区轮询、状态 autoLoad 与状态间隔轮询——尽管通道并非它在运行;而侧边栏仅覆盖可信工作区的通道无法覆盖不可信的主工作区,总览首次加载后便冻结。修复:引入 const liveStateActive = manageLiveState && liveStateEnabled(建议的选项),并把所有刷新模式判定改用它——四处抑制点,外加 deriveSessionCards 的状态合并与手动刷新的状态重载,使不变量两端读取同一配置。见证:'keeps its own catalog poll when it does not own the live-state channel'(不可信主工作区、manageLiveState: falsepollIntervalMs 为 3000);原有钉住测试 'uses sidebar-owned live state without starting a duplicate channel' 按所选规则更新(仍不启动重复通道,但保留目录轮询)。探针验证移除所有权门后变红。

  • [rc:3874492788] R3-3 — 粘性页脚自引用反馈循环(SessionOverviewPanel.tsx)— 已解决。
    先复现:粘性模式使页脚自身布局高度净变化 −3px,而判定只有 +1px 的单阈值,内容高度落在 (视口+1, 视口+4] 时每个观察周期都翻转。修复:按建议改为非对称滞回 —— setFooterSticky((prev) => naturalHeight > viewport.clientHeight + (prev ? -4 : 1)) —— 高于 P+1 进入、真实内容高度 ≤ P−1 才退出,两区间不再重叠。原有粘性测试(翻转期间固定几何)仍通过。见证:'holds the sticky footer through its own mode-switch height delta'(视口+2 进入、粘性模式 −3px 重测后保持、内容真正收缩后退出);探针验证移除滞回后变红。

  • 收敛观察与延后项 — 不处理(按指示)。
    评审正文中 16 条"收敛姿态下延后"的条目明确为"已记录、本轮不要求修改",未改动。兄弟簇观察(发现反复出现在 App.tsx / SessionOverviewPanel.tsx)已知悉;本轮在共享决策点关闭全部五个报告实例(一个所有权布尔、一个共享入口清标志、一个条件 prop、一个阈值),而不是逐个实例加守卫。

验证

环境说明:检出目录的 node_modules 缺少 @tanstack/react-tablepackages/web-shell/package.json 与 lockfile 均已声明);已用 npm install 补齐。该安装改写了 package-lock.json 中无关的 libc 元数据(npm 版本差异)——该文件已还原为 HEAD 状态,不属于本次提交。

  • 复现(修复前):npx vitest run SessionOverviewPanel.test.tsx -t '…'npx vitest run App.test.tsx -t '…' —— 7 条新增/更新的见证测试在修复前代码上失败,与各发现报告的失败形态一致
  • 修复后聚焦:npx vitest run client/components/SessionOverviewPanel.test.tsx client/App.test.tsx(packages/web-shell)—— 658 通过(原 652 + 新增 6;一条原有测试就地更新)
  • 整个受影响包:npx vitest run(packages/web-shell)—— 202 个文件,4430 通过
  • 突变探针:6 个新守卫(两处清标志、onOpenSplit 门、排除项门、所有权门、滞回)逐一移除后对应见证测试失败、恢复后通过 —— 6/6 符合要求
  • npm run build — 通过(退出码 0)
  • npm run typecheck — 通过(退出码 0)
  • npm run lint — 通过(退出码 0)
  • 集成测试:未运行 —— 本次改动为 React 客户端组件逻辑,已由该包的 Vitest 套件完整覆盖,并非只能通过打包 CLI 或集成测试框架验证
  • npm run generate:settings-schema:无需(未改动设置源)

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

Re-review when you have a moment. After round 100 this bot stops and leaves the PR for a human. · 有空请复审;第 100 轮后本 bot 停止并将 PR 交给人工。


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

@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Qwen Code review did not complete successfully. The review pipeline failed before a review could be posted. A transient error is retried automatically; if you are seeing this, retry with @qwen-code /review. See workflow logs.

@ytahdn
ytahdn requested a review from qqqys as a code owner August 28, 2026 06:20
chiga0
chiga0 previously approved these changes Aug 28, 2026

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

所有三轮 C 级 blocking 已在 1c2f558b8ec4("address session overview round-3 review feedback")中全部修复,下面逐条核实。


历轮 C 级发现收敛状态

ID 文件 一句话摘要 本轮状态
R1-3 App.tsx splitFoldedByShrinkRef 未在 sidebar 导航时清零,shrink-fold 恢复会通过 new-chat / load-session 重触 fixedcreateNewSession(!keepPanel)loadSidebarSession 均补写 splitFoldedByShrinkRef.current = false;新增两条测试覆盖两条路径
R2-1 App.tsx onCurrentSessionRemovedcreateNewSession 传入可能为空的 workspace fixedremoved.workspaceCwd || undefined 将空字符串转为 undefined;currentWorkspaceCwd 回退链补全
R2-2 SessionOverviewPanel.tsx workspace 选项缩减到 1 个时已有 exclusion 仍生效,致全行隐藏 fixedworkspaceOptions.length <= 1 时无条件清空 excludedWorkspaceCwds;测试:"drops exclusions when the option set shrinks below the funnel threshold"
R3-1 App.tsx 移除 isLargeScreen 门控后 split 动作在窄屏也传入 panel,用户激活后 grow 时幻 split 出现 fixedonOpenSplit={isLargeScreen ? openSplitView : undefined};测试:"does not hand out the overview split action below the large-screen breakpoint"
R3-2 SessionOverviewPanel.tsx live-state channel 用 liveStateEnabled 判断,polling 也用同一变量 — 导致 manageLiveState=false 时 panel 不轮询,sidebar 的 trusted-only channel 无法覆盖未信任 workspace fixed — 引入 liveStateActive = manageLiveState && liveStateEnabled,所有 polling gate 改用此变量;测试:"keeps its own catalog poll when it does not own the live-state channel"
R3-3 SessionOverviewPanel.tsx sticky footer 判断是自我指涉反馈环:切换 sticky 改变 scrollHeight,再触发 observer,导致死循环 fixed — 非对称迟滞:setFooterSticky(prev => naturalHeight > viewport.clientHeight + (prev ? -4 : 1));测试:"holds the sticky footer through its own mode-switch height delta"(三段高度探针)

我独立验证的实现路径

跨 workspace 行标识getRowId = card => \${card.workspaceCwd}\0${card.sessionId}` 用 null byte 做分隔符,保证任意 cwd + sessionId 组合唯一。isCurrentSession` 两字段都核对(无 cwd 时退化为仅 ID 匹配,兼容单 workspace 旧场景)。✅

活跃会话安全mutateCards 先收集 succeededIdentities,只在 操作成功的 当前会话上调用 onCurrentSessionRemoved,失败项不触发创建新会话。isCurrentCard 在异步结束后读 connectionRef.current,用户操作期间切换会话时结论仍正确。✅

分页稳定性autoResetPageIndex: false + 手动 clamp effect(仅当 pageIndex > lastPageIndex 时才 setState)防止数据更新导致空页。✅

右固定列降级pinRightColumns = availableWidth === 0 || availableWidth > leftFixedWidth + rightFixedWidth,视口过窄时右侧固定区域退化为普通流。data-table.test.tsxNarrowFixedTableHarness(350 px)覆盖此路径。✅

sticky footer 迟滞:sticky 模式自身装饰 (pt-3 +12px, border-t +1px, -mb-4 -16px) 净缩 -3px。门槛从 P+1 升入 sticky,在 sticky 下须降到 P-4 才释放(即 P - 3 - 1),避免 ±1 内抖动触发重观察。✅


CI

  • Test (ubuntu-latest, Node 22.x) 失败于 "Run .github/scripts helper tests" — 已确认为跨 PR 预存故障(同日多个无关 PR 的 CI 中复现相同步骤失败),与本 PR 变更无关。
  • Post Coverage Comment — 依赖前一步,次生失败。
  • 产品相关 check 全绿:web-shell E2E Smoke ✅、Desktop Shell(ubuntu / windows)✅、Java CI ✅、Dependency CVE audit ✅、Secret scan ✅。

剩余延后项

Round 3 延后列表(16 条,全为 probe/review 级)无一升级为 blocking:

  • readPageSize 独立硬编码有效集合(不随 PAGE_SIZES 联动)— 维护备注,非当下 bug。
  • fixedOffset 字段声明后从未被 caller 赋值 — 无运行时影响。
  • 若干 [probe] 条目指出守卫分支无测试 — 覆盖债务,逻辑结构正确。

@ytahdn

ytahdn commented Aug 28, 2026

Copy link
Copy Markdown
Collaborator Author

@qwen-code /takeover stop

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

Copy link
Copy Markdown
Collaborator

👋 Takeover released: the autofix loop will no longer engage this PR (an in-flight round, if any, completes its bounded work). Re-apply autofix/takeover (or comment @qwen-code /takeover) to re-engage.

中文说明

👋 已释放:autofix 循环不再介入此 PR(在飞的一轮如有,将完成其有界工作)。重新打上 autofix/takeover 标签(或评论 @qwen-code /takeover)即可再次接管。

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

Partially reviewed — gaps disclosed.

2 Suggestion-level finding(s) this review confirmed are already reported on this PR and are not repeated:

  • capabilities fixtures typed as full DaemonCapabilities envelope with required fields omitted (SessionOverviewPanel.test.tsx) — already reported in the round-3 deferred list (review 5044066726)
  • fixedOffset dead switch in packages/web-shell/client/components/ui/data-table.tsx — already reported in the round-3 deferred list (review 5044066726)

Not reviewed: reverse audit — stopped before round 3 by the review time budget.

Deferred under the convergence posture (round 5, not a blocker) — recorded, not requested in this round:

  • packages/web-shell/client/App.tsx:12864 — [review] workspace-cwd fallback chain inlined four times across the two new handlers
  • packages/web-shell/client/App.test.tsx:18391 — [probe] onCurrentSessionRemoved's pre-await stale-sessionId clause is pinned by no test
  • packages/web-shell/client/App.test.tsx:20304 — [review] fold-restore cancellation test has no positive control for its onOpenSession trigger
  • packages/web-shell/client/App.test.tsx:20605 — [review] below-breakpoint split test's stale-capture act block is a guaranteed no-op
  • packages/web-shell/client/components/SessionOverviewPanel.test.tsx:349 — [review] footerButton helper's container-wide fallback unpins footer placement of bulk actions
  • packages/web-shell/client/components/SessionOverviewPanel.test.tsx:520 — [probe] empty-state error branch ('Failed to load sessions') has no witness
  • packages/web-shell/client/components/SessionOverviewPanel.test.tsx:799 — [review] session-ID copy test pins only the success path; the clipboard-rejection branch is untested
  • packages/web-shell/client/components/SessionOverviewPanel.test.tsx:814 — [review] copy-test cleanup permanently destroys the shared navigator.clipboard polyfill
  • packages/web-shell/client/components/SessionOverviewPanel.test.tsx:882 — [probe] cross-workspace equal-session-id independence test has no delete-path twin
  • packages/web-shell/client/components/SessionOverviewPanel.test.tsx:1799 — [review] delete branch's notFound handling for the current session has no test
  • packages/web-shell/client/components/SessionOverviewPanel.tsx:1686 — [probe] page-size persistence write path (onPageSizeChange={writePageSize}) has no test
  • packages/web-shell/client/components/sidebar/WebShellSidebar.workspace-removal.test.tsx:3233 — [probe] handler-level running-session archive guard left unexercised by the dropdown migration
  • packages/web-shell/client/components/ui/data-table.tsx:410 — [probe] DataTable renders Radix Tooltip without a TooltipProvider; a future meta.tooltip consumer crashes at render
  • packages/web-shell/client/utils/workspace.ts:56 — [review] isNonPrimaryWorkspaceSession is dead code — this PR removed its last consumer

Convergence: round 5 posted 2 inline comment(s), 2 of them reported for the first time. Findings keep coming back to the same files: packages/web-shell/client/components/SessionOverviewPanel.tsx (findings in rounds 2, 3; 2 more now). (Evidence: the previous round was recovered from a marker this account did not post and merged over this account's own entries, so some of those rounds may not be this account's own.) A cluster that keeps producing siblings usually means the fixes are treating instances of a shared root cause — triaging that cause before the next round, or splitting an independent cluster into its own pull request, tends to end the loop faster than fixing them one at a time. (Observation only — nothing was withheld from this review because of this observation.)

Mechanism health: this round did not close cleanly, so it withholds the incremental anchor — and the round it recovered had no anchor this round could use either — none at all, one with no certifier, one certified by an identity other than the one this round runs under, or one this round's fetch refused or resolved to the head — so the next review re-reads the whole diff unless recovery grafts an earlier own anchor that the round running it can use onto the complete work list this round leaves behind, and keeps doing so until a round's marker carries an anchor again or a graft lands that the round running it can use. (Stated, not acted on — this changes nothing about what the round posts.)

中文说明

仅完成部分审查,审查缺口已披露。

本轮确认的 2 条建议级发现已在 PR 上报告过,不再重复发布(列表见上方英文部分)。

未审查:反向审计——评审时间预算不足,未能开始第 3 轮。

收敛姿态下延后(第 5 轮,非阻断)——已记录,本轮不要求修改:共 14 条(原文未翻译,列表见上方英文部分)。

收敛情况:第 5 轮发布了 2 条行内评论,其中 2 条是首次提出。发现反复回到同一批文件:packages/web-shell/client/components/SessionOverviewPanel.tsx(第 2、3 轮已出过发现,本轮又有 2 条)。(证据说明:上一轮的数据来自并非本账号发布的标记,并与本账号自己的条目合并,上述轮次中的部分可能不属于本账号。)一个不断再生兄弟发现的簇,通常意味着逐条修复只在处理同一根因的实例——先定位并处理该根因,或把独立的簇拆成单独的 PR,通常比逐条修复更快结束循环。(仅为观察——本轮评审未因此扣留任何内容。)

机制健康:本轮未能干净收尾,因而扣留了增量锚点,而它恢复到的那一轮也没有留下本轮可用的锚点——要么完全没有、要么没有认证者、要么由本轮运行身份之外的身份认证、要么被本轮的获取拒绝或解析为头提交——因此下一次评审将重读整个 diff,除非恢复流程把本轮能使用的更早自有锚点嫁接到本轮留下的完整工作清单上;并会一直如此,直到某一轮的标记重新带上锚点,或落地的嫁接能被运行该轮的评审使用。(仅陈述,不据此行动——这不改变本轮发布的任何内容。)

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

Comment thread packages/web-shell/client/components/SessionOverviewPanel.tsx Outdated
Comment thread packages/web-shell/client/components/SessionOverviewPanel.tsx Outdated
@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Qwen Code review did not complete successfully. The review pipeline failed before a review could be posted. A transient error is retried automatically; if you are seeing this, retry with @qwen-code /review. See workflow logs.

@ytahdn

ytahdn commented Aug 28, 2026

Copy link
Copy Markdown
Collaborator Author

@qwen-code /triage

@qwen-code-ci-bot

qwen-code-ci-bot commented Aug 28, 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: 868 passed · 0 failed · 868 total

Flakiness gate: ✅ 6 changed test file(s) x 5 identical rounds, no divergence

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

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

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

抖动门:✅ 6 changed test file(s) x 5 identical rounds, no divergence

Verification report

PR 10115 Deep Verification — feat(web-shell): optimize session overview table

Verdict: merge-ready — 868/868 scripted assertions passed, 0 unexpected failures.
Verified head: 3baa229768c2ef88a839be5fc3214da1a2f51e9d (git rev-parse HEAD^2), base tip 5ae363e2f9067168f52f9d82d3be351a17aed1ce, merge commit 799b8445ed (CI merge-ref checkout, depth 2). No blocking findings; one coverage observation (F1) and minor notes (F2–F4).

中文摘要
  • 结论merge-ready。868 个脚本化断言全部通过,无意外失败。
  • A/B 结论:会话总览的破坏性操作防护是有载荷的(load-bearing)。突变矩阵(见 Central claim 的 A/B 表)共 8 行:7 个真实突变体杀死 6 个,阳性对照 M5 按预期恰好红 1 个测试,证明变红是真实的。去掉归档/删除确认弹窗、去掉「当前会话被移除后清空到新任务」的 App 回调、把 Back 按钮还原为 base 行为,都会让对应测试按预期断言变红(报告引用了具体失败消息与行号)。唯一存活者 M6 被归类为冗余防御,不是缺陷(见 F1)。
  • 发现:无阻塞项。F1(建议):mutateCards 里的 cards.every(canMutate) 复查没有任何测试钉住,属冗余防御;F2(小):分页大小的「写入持久化」一侧没有直接断言(恢复一侧有);F3(预先存在,非本 PR 引入):i18n 中英键集有 130 个键的既有漂移,本 PR 对称新增 28/28,未扩大漂移;F4(说明):handleCycleMode 的改写被证明行为等价。
  • 未覆盖:浏览器级渲染/响应式视觉步骤(容器无浏览器,PR 本身也声明未跑浏览器自动化);逐提交归因(浅克隆仅 3 个提交可达,元数据列出 19 个);全仓库套件与 playwright e2e;eslint 未运行;跨平台(作者标注 Windows/Linux 未测)。

Central claim

The PR rewrites Session Overview from a card grid into a data table and, in doing so, adds destructive
session actions (archive/delete, single + bulk) to a surface that on base was read-only (base
SessionOverviewPanel only offered open-session — verified via git show HEAD^1:... grep: no
archive/delete/confirm code paths existed there). The central claim under test is therefore:

The new table carries its destructive actions with the promised safeguards: (a) archive/delete never
mutate without a confirmation dialog, and (b) when the removed session is the active one, the app
clears into a new-task state without closing the overview during an in-panel mutation; Back from
the overview also clears the active session into a new-task state.

Because the component is a wholesale rewrite, the A/B control cells are mutation reverts of the head
hunks
(M4 is the byte-level base hunk), each required to turn the head-green suite red on the
intended assertion, with a positive control proving the harness collects the mutated files.

Cell Build Oracle Result
head gate 3baa229768 (merge tree) 6 changed test files, vitest 795/795 green (82 s)
extended gate head 4 adjacent sidebar/tooltip suites 60/60 green
typecheck head tsc -p tsconfig.json --noEmit exit 0
M1: archive confirm stripped head + hunk revert panel suite 11/96 red — intended: toContain('Archive session?') (test L1780), toContain('Archive 2 sessions?') (L2049); all delete-path tests stayed green
M2: delete confirm stripped head + hunk revert panel suite 7/96 red — intended: toContain('Delete session?') (L2026), 'Delete 2 sessions?'; all archive-path tests stayed green
M3: App onCurrentSessionRemoved removed head + hunk revert App suite 5/573 red — intended: clearSession spy expected "spy" to be called once, but got 0 times (App.test.tsx:18285), expected undefined to be false
M4: Back reverted to base closePanel (exact base hunk) head + base hunk App suite 4/573 red — intended: clearSession spy (App.test.tsx:18512); back-flow family red
M5: positive control (delete title → archive title key) head + 1-line revert panel suite exactly 1/96 red (deletes a session through the confirm dialog)
M6: mutateCards re-check dropped head + hunk revert panel suite 96/96 green — survivor, classified in F1
M7: data-table ignores fluidWeight head + 1-line revert data-table suite 2/5 redexpected "250px" / received "15100px", "200px" / "10100px"
M8: tooltip reverted to base (no forwardRef) base file restored ref-compat suite 2/30 red — exactly the two tooltip forwards refs rows
A/A control clean mutate-tree (symlinked deps) App suite 573/573 green — mutation environment itself changes nothing

Witnesses: 01-head-gate-795-green.png, 02-mutation-matrix.png, 03-m1-archive-confirm-red.png,
04-m3-m4-active-session-red.png, 05-adjacent-suites-and-typecheck.png. Raw per-cell logs:
logs/01logs/12 in this artifact directory.

The M3/M4 reds are the head-vs-base behavioral flip for the active-session flow: with the base Back
hunk restored (M4), exactly the four tests documenting the new Back semantics fail; with the App
handler removed (M3), exactly the five clear-the-active-session tests fail. All other 568–569 tests
stay green in both cells, so the mutations are scoped to the claimed behavior, not collateral.

Race-safety siblings of the same mechanism are also pinned and green at head: does not clear a
different session after an overview mutation finishes
, does not clear a newly selected session when
% finishes
, does not clear a session opened while leaving the Session Overview, clears a deleted
current session after a partial batch failure
, does not clear the current session when % fails (both
Archive and Delete). The panel only clears when the mutated card is still the current session and
its identity is in the succeeded set.

Secondary claims, verified

  • Data-table primitive is load-bearing. M7 (ignore fluidWeight) turned two layout tests red with
    pixel-level assertions; the unmutated suite pins column offsets, fluid distribution, and right-column
    unpinning (data-table.test.tsx, 5 tests green at head).
  • React 18 ref conventions. The new table.tsx components and the converted TooltipTrigger /
    TooltipContent are pinned by react18-ref-compat.test.tsx (25 $$typeof rows + 5 real ref renders,
    including asChild TooltipTrigger). M8 proved the tooltip conversion is what the two tooltip rows pin.
  • Sidebar archive → More menu. 'archive' removed from WebShellSidebarSessionInlineActionItem
    (TS union — typecheck enforces call-site updates), DROPDOWN_ONLY_ITEMS in
    session-action-visibility.test.ts gained 'archive', and the workspace-removal suite's inline-archive
    tests were rewritten to menu-item tests. All green in the head gate; disabled-state semantics
    (busy || isCurrent || running) unchanged in the dropdown item. Docs
    (sidebar-customization.md) updated consistently with the code.
  • New options are wired, not dead switches. keepPanel (read at App.tsx:8528, set at 12882),
    manageLiveState (read in panel L407, set by App L12905, asserted toBe(false) in App.test.tsx:18293
    and exercised by panel live-state tests L2611–2642), SESSION_LIVE_STATE_FEATURE (read in panel),
    onOpenSplit optionality (App passes undefined below breakpoint; test L20570).
  • i18n parity for the PR's keys. Harness i18n-parity.mjs: the 53 keys the panel uses exist in both
    EN and ZH; the PR adds +28 keys to EN and +28 to ZH with no new drift vs base (see F3).
  • Lockfile delta is only the new dependency: @tanstack/react-table@8.21.3 (2 entries), nothing else.
  • handleCycleMode rewrite is behaviorally equivalent (F4).

Reviewer Test Plan, per step

Step Verdict here Evidence
Overview opens from sidebar; wide layout proportional, no h-scroll unit-covered; visual not covered data-table fluid-width tests (M7 pins), panel distributes flexible columns only when the table fits without scrolling
Narrow window: h-scroll, fixed edge columns, synced hover, edge shadows unit-covered; visual not covered keeps the toolbar and pagination responsive on narrow screens, adds inward shadows to fixed columns while horizontally scrolled, labels and pins opaque edge columns without borders, data-table unpins right columns before fixed regions overlap
Search, workspace multi-select filter, time sort, 10/50/100 page sizes restored covered filters rows by search query…, filters rows by workspace via the multi-select panel, aria-sort assertions (L1512–1518), localStorage-seeded page-size tests (L1116, L1142); write-side persistence note in F2
Row click selects outside title; title-only switches session; copy ID; Worktree/PR details; empty states covered toggles selection when the row is clicked, keeps the title keyboard-focusable…, copies the session ID…, shows worktree metadata…, renders an empty state, …no-match state
Archive/delete require confirmation; active session → new-task state; overview stays open during in-panel mutation; Back clears covered + proven load-bearing M1–M4 matrix above

Findings

F1 — Suggestion (completeness, not a merge condition): the mutateCards re-check is a surviving
mutation (redundant defence).
Deleting if (!cards.every(canMutate)) throw … (M6) leaves all 96 panel
tests green. The same hazard is closed one layer up: row buttons are disabled={… || !canArchive} /
!canDelete, and the bulk footer buttons require selectedCards.every(canArchiveCard) /
canDeleteCard, so no UI path can hand mutateCards an un-mutable card. The clause is defence in
depth, correct as it stands — but nothing pins it. If it is meant to stay, a direct test (call
mutateCards path with a running-session card and expect sessionsOverview.actionUnavailable) would
pin it; if not, it is deletable. Not attributed as a defect: behaviour is right, coverage is the gap.

F2 — Nice to have: pagination persistence is pinned on the read side only. Tests seed
localStorage['qwen-web-shell-session-overview-page-size'] and assert the restored page size drives
paging; no test asserts writePageSize persists a user-changed size. Naming the fixture that would go
red: change the page size via the footer select and expect the localStorage key to update.

F3 — Note (pre-existing, not PR-attributed): EN/ZH key drift of 130 keys. ZH contains 130 keys
absent from EN (toolName.*, settings.* families). Measured identically on base
(HEAD^1: EN=2623/ZH=2753, drift 130) and head (EN=2651/ZH=2781, drift 130); the PR adds 28 keys to
each locale symmetrically and introduces zero new drift. Surfacing only so the next reader of
i18n-parity.mjs output does not misattribute it.

F4 — Note: handleCycleMode rewrite verified equivalent. The diff replaces
isDaemonApprovalMode(currentMode) ? MODES_CYCLE.indexOf(currentMode) : -1 with
MODES_CYCLE.findIndex(mode => mode === currentMode). Since MODES_CYCLE = DAEMON_APPROVAL_MODES
(App.tsx:355) and isDaemonApprovalMode(x) is exactly DAEMON_APPROVAL_MODES.includes(x)
(sessionPreparation.ts:28), the two expressions are identical for every input (membership ⟺ index ≥ 0).
Reads as an unrelated change but changes nothing observable; no test churn needed.

No injection-style instructions were present in the PR metadata; the PR text was treated as hypothesis
throughout (e.g. the author's "106 focused unit tests" count was neither relied on nor reproduced — the
gate here counted 855 tests across the changed + adjacent files).

Not covered

  • Browser-level rendering of every Reviewer Test Plan step that needs a real viewport (proportional
    column rendering at real widths, sticky-column hover synchronization as pixels, dialog focus trapping in
    a real browser). This reproduces the shape of those behaviors via jsdom unit oracles, not the
    visual cause; the container ships no browser and the PR itself declares browser automation out of
    scope. Playwright e2e suites exist in the package but were not run (need browser binaries).
  • Per-commit attribution. The checkout is depth 2 (is-shallow-repository: true,
    rev-list HEAD^1..HEAD^2 = 1) while the metadata lists 19 commits; only the aggregate
    HEAD^1..HEAD diff was verified.
  • Repo-wide build/test suite and eslint. Targeted gates only (changed + adjacent web-shell suites,
    web-shell typecheck). The PR's own CI covers the repo-wide gates; eslint was not run in this round.
  • Trial merge against current upstream main. The verified tree is the merge of the PR into the
    base tip; how far that base tip trails upstream main is not determinable from inside the container
    (no network/token). The base tip here (5ae363e2f9) is newer than the snapshot's baseRefOid
    (d6533785…), i.e. the PR branch kept merging main — the merge-ref is the freshest local truth.
  • Windows/macOS behavior (author marks both ⚠️ untested).

Methodology

Ran in the CI verify container (node:22-bookworm, Node v22.23.2) on the pre-built merge tree. Head
gate: npx vitest run --config vitest.config.ts over the six changed test files (795 tests) and four
adjacent sidebar/tooltip suites (60 tests), plus tsc -p tsconfig.json --noEmit. Mutation A/B: scratch
worktree tmp/mutate-tree at the merge commit; eight one-hunk mutations (M1–M8; M5 is the positive
control) applied and reverted individually with the affected suite re-run each time; because @datafe-open/* deps are nested under
packages/web-shell/node_modules (not hoisted), the worktree got that directory symlinked in — the
clean A/A control (10-aa-control-clean-app.log, 573/573 green) proves the symlink itself changes
nothing. Mutants were required to fail the intended assertion (messages quoted above), and M5 (panel
file) plus M4's known-red family serve as same-file positive controls. i18n parity is the scripted
harness i18n-parity.mjs in this directory; base comparison uses git show HEAD^1:…/i18n.tsx. Raw
logs 0112 in logs/; captures in evidence/.

Flakiness gate log

rounds=5 files=6 skipped=0
file packages/web-shell/client/App.test.tsx: (cd packages/web-shell) npx --no-install vitest run ./client/App.test.tsx
file packages/web-shell/client/components/SessionOverviewPanel.test.tsx: (cd packages/web-shell) npx --no-install vitest run ./client/components/SessionOverviewPanel.test.tsx
file packages/web-shell/client/components/sidebar/WebShellSidebar.workspace-removal.test.tsx: (cd packages/web-shell) npx --no-install vitest run ./client/components/sidebar/WebShellSidebar.workspace-removal.test.tsx
file packages/web-shell/client/components/sidebar/session-action-visibility.test.ts: (cd packages/web-shell) npx --no-install vitest run ./client/components/sidebar/session-action-visibility.test.ts
file packages/web-shell/client/components/ui/data-table.test.tsx: (cd packages/web-shell) npx --no-install vitest run ./client/components/ui/data-table.test.tsx
file packages/web-shell/client/components/ui/react18-ref-compat.test.tsx: (cd packages/web-shell) npx --no-install vitest run ./client/components/ui/react18-ref-compat.test.tsx


per-file results (P=pass F=fail I=infra-exit, one letter per run):
  packages/web-shell/client/App.test.tsx: PPPPP
  packages/web-shell/client/components/SessionOverviewPanel.test.tsx: PPPPP
  packages/web-shell/client/components/sidebar/WebShellSidebar.workspace-removal.test.tsx: PPPPP
  packages/web-shell/client/components/sidebar/session-action-visibility.test.ts: PPPPP
  packages/web-shell/client/components/ui/data-table.test.tsx: PPPPP
  packages/web-shell/client/components/ui/react18-ref-compat.test.tsx: PPPPP

verdict: pass
summary: 6 changed test file(s) x 5 identical rounds, no divergence

--- per-invocation detail (full copy in the artifact) ---
round 1 · packages/web-shell/client/App.test.tsx: P (exit 0)
round 1 · packages/web-shell/client/components/SessionOverviewPanel.test.tsx: P (exit 0)
round 1 · packages/web-shell/client/components/sidebar/WebShellSidebar.workspace-removal.test.tsx: P (exit 0)
round 1 · packages/web-shell/client/components/sidebar/session-action-visibility.test.ts: P (exit 0)
round 1 · packages/web-shell/client/components/ui/data-table.test.tsx: P (exit 0)
round 1 · packages/web-shell/client/components/ui/react18-ref-compat.test.tsx: P (exit 0)
round 2 · packages/web-shell/client/App.test.tsx: P (exit 0)
round 2 · packages/web-shell/client/components/SessionOverviewPanel.test.tsx: P (exit 0)
round 2 · packages/web-shell/client/components/sidebar/WebShellSidebar.workspace-removal.test.tsx: P (exit 0)
round 2 · packages/web-shell/client/components/sidebar/session-action-visibility.test.ts: P (exit 0)
round 2 · packages/web-shell/client/components/ui/data-table.test.tsx: P (exit 0)
round 2 · packages/web-shell/client/components/ui/react18-ref-compat.test.tsx: P (exit 0)
round 3 · packages/web-shell/client/App.test.tsx: P (exit 0)
round 3 · packages/web-shell/client/components/SessionOverviewPanel.test.tsx: P (exit 0)
round 3 · packages/web-shell/client/components/sidebar/WebShellSidebar.workspace-removal.test.tsx: P (exit 0)
round 3 · packages/web-shell/client/components/sidebar/session-action-visibility.test.ts: P (exit 0)
round 3 · packages/web-shell/client/components/ui/data-table.test.tsx: P (exit 0)
round 3 · packages/web-shell/client/components/ui/react18-ref-compat.test.tsx: P (exit 0)
round 4 · packages/web-shell/client/App.test.tsx: P (exit 0)
round 4 · packages/web-shell/client/components/SessionOverviewPanel.test.tsx: P (exit 0)
round 4 · packages/web-shell/client/components/sidebar/WebShellSidebar.workspace-removal.test.tsx: P (exit 0)
round 4 · packages/web-shell/client/components/sidebar/session-action-visibility.test.ts: P (exit 0)
round 4 · packages/web-shell/client/components/ui/data-table.test.tsx: P (exit 0)
round 4 · packages/web-shell/client/components/ui/react18-ref-compat.test.tsx: P (exit 0)
round 5 · packages/web-shell/client/App.test.tsx: P (exit 0)
round 5 · packages/web-shell/client/components/SessionOverviewPanel.test.tsx: P (exit 0)
round 5 · packages/web-shell/client/components/sidebar/WebShellSidebar.workspace-removal.test.tsx: P (exit 0)
round 5 · packages/web-shell/client/components/sidebar/session-action-visibility.test.ts: P (exit 0)
round 5 · packages/web-shell/client/components/ui/data-table.test.tsx: P (exit 0)
round 5 · packages/web-shell/client/components/ui/react18-ref-compat.test.tsx: P (exit 0)

Evidence images

01-head-gate-795-green

02-mutation-matrix

03-m1-archive-confirm-red

04-m3-m4-active-session-red

05-adjacent-suites-and-typecheck

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

Qwen Code · sandboxed verification

@ytahdn

ytahdn commented Aug 29, 2026

Copy link
Copy Markdown
Collaborator Author

@qwen-code /triage

@qwen-code-ci-bot

qwen-code-ci-bot commented Aug 29, 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: 896 passed · 0 failed · 896 total

Flakiness gate: ✅ 6 changed test file(s) x 5 identical rounds, no divergence

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

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

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

抖动门:✅ 6 changed test file(s) x 5 identical rounds, no divergence

Verification report

Sandboxed verification: ✅ passed — merge-ready (agent verdict) — follow-up round at an identical head.

Scripted assertions: 896 passed · 0 failed · 896 total.
Verified head: 3baa229768c2ef88a839be5fc3214da1a2f51e9d (git rev-parse HEAD^2), base tip 5ae363e2f9067168f52f9d82d3be351a17aed1ce, merge commit 799b8445ed (CI merge-ref checkout, depth 2).

This is a follow-up round: the previous round verified the same merge commit (799b8445ed, head 3baa229768, base 5ae363e2), so the input closure is provably identical — the strongest possible identity proof, stronger than per-file hashes. Even so, every carried-forward measurement was re-executed live in this round (head gate, mutation matrix, harnesses); nothing was copied from the old report.

中文 — 判定:✅ 通过 · 可合入(agent 判定,复核轮)
  • 结论merge-ready。896 个脚本化断言全部通过,0 个意外失败。本轮为复核轮:HEAD 与上一轮完全相同(同一 merge commit 799b8445ed),输入闭包可证明一致;所有沿用的测量仍在本轮重新执行,未照抄旧报告。
  • A/B 结论:会话总览破坏性操作防护有载荷(load-bearing)。突变矩阵(见 Central claim 表,见证图 02-mutation-matrix.png):M1/M2 去掉归档/删除确认弹窗 → 面板套件 11/96、7/96 红,红在预期断言(Archive session? / Delete session? 对话框标题);M3 去掉 App 的 onCurrentSessionRemoved → 5/573 红;M4 将 Back 还原为 base 的 closePanel → 4/573 红;M5 阳性对照恰好 1/96 红,证明 harness 能变红;M7/M8 证明 data-table 的 fluidWeight 与 tooltip 的 forwardRef 转换有载荷。唯一存活者 M6(mutateCards 复查)与上轮一致,仍归类为冗余防御(F1)。
  • 发现:无新阻塞项。沿用 F1(建议:M6 存活,冗余防御)、F2(小:分页写入侧无断言)、F3(既有 i18n 漂移,未扩大)、F4(handleCycleMode 等价,已用脚本复证)。状态表见下文。
  • 未覆盖:浏览器级视觉步骤(容器无浏览器,PR 亦声明不跑浏览器自动化);逐提交归因(浅克隆);全仓库套件/eslint/playwright;上游 main 试合并;Windows/macOS。

Previous-finding status table (follow-up round)

Head is byte-identical to the prior round's (same merge commit), so "stands" rows below are backed by re-executed measurements, not by diffing the old report.

# Finding (prior round) Severity Status at 3baa229768 Re-measurement
F1 mutateCards cards.every(canMutate) re-check unpinned (surviving mutation M6) Suggestion stands (agree) M6 re-run: 96/96 green. Positive control M5 re-run: exactly 1/96 red, so the green is meaningful. UI gates re-inspected: row buttons disabled={… || !canArchive/!canDelete} (L1411/L1434) and bulk footer canArchiveSelection = selectedCards.every(canArchiveCard) (L1504–1507) enforce the same predicate on the same captured card objects, so the re-check remains unreachable via UI — redundant defence, correct as-is.
F2 Pagination persistence pinned on read side only Nice to have stands (agree) Re-grepped SessionOverviewPanel.test.tsx: localStorage appears only as read-side seeds (L1116, L1142); no test asserts writePageSize's write. onPageSizeChange={writePageSize} wired at panel L1704.
F3 Pre-existing EN/ZH key drift (prior: 130) Note stands (agree) Re-ran i18n-parity.mjs on base and head: drift 129 at base, 129 at head, key sets identical; delta symmetric (+32/−4 per locale, net +28 — matches prior round's +28). Absolute count differs from the prior report by 1 (129 vs 130) due to parser strictness on a single multi-line entry; the invariant (drift unchanged, additions symmetric) is the claim and it holds on both parsers.
F4 handleCycleMode rewrite behaviorally equivalent Note stands (agree) f4-equivalence.mjs: alias chain re-verified from source (MODES_CYCLE = DAEMON_APPROVAL_MODES, isDaemonApprovalMode = DAEMON_APPROVAL_MODES.includes, DAEMON_APPROVAL_MODES = PERMISSION_MODES); both expressions executed over all 5 real modes + 12 hostile outsiders — identical on all 17 inputs.

Central claim

Unchanged from the prior round, re-proven live: the rewrite moves destructive session actions (archive/delete, single + bulk) onto a surface that was read-only on base, and carries the promised safeguards — (a) archive/delete never mutate without a confirmation dialog; (b) when the removed session is the active one, the app clears into a new-task state without closing the overview; Back from the overview clears the active session into a new-task state.

Control cells are mutation reverts of head hunks (M4 is the byte-level base hunk), each required to turn the head-green suite red on the intended assertion, with a same-file positive control (M5) and an A/A control proving the symlinked-dependency mutation environment changes nothing.

Cell Build Oracle Result
head gate 3baa229768 (merge tree) 6 changed test files, vitest 795/795 green (72.2 s) — 01-head-gate-795-green.png
adjacent gate head 6 adjacent sidebar/tooltip/hook suites 65/65 green
typecheck head tsc -p tsconfig.json --noEmit exit 0; liveness-probed (planted error caught, exit 2)
A/A control clean mutate-tree, symlinked deps App suite 573/573 green — environment changes nothing
M1: archive confirm stripped (row + bulk triggers call handleBatchArchive directly) head + hunk revert panel suite 11/96 red — intended: toContain('Archive session?'), toContain('Archive 2 sessions?'); all delete-path tests green — 03-m1-archive-confirm-red.png
M2-refactor control delete executor extracted, no semantic change panel suite 96/96 green (refactor behavior-preserving)
M2: delete confirm stripped (triggers call executor directly) head + hunk revert panel suite 7/96 red — intended: toContain('Delete session?'), 'Delete 2 sessions?'; all archive-path tests green
M3: App onCurrentSessionRemoved prop removed head + hunk revert App suite 5/573 redexpected "spy" to be called once, but got 0 times (clearSession), expected undefined to be false
M4: Back reverted to base closePanel (exact base hunk) head + base hunk App suite 4/573 red — back-flow family: spy called 0 times, onSessionIdChange with [ undefined ], panel not null — 04-m3-m4-active-session-red.png
M5: positive control (delete title → archive title key) head + 1-line revert panel suite exactly 1/96 red (deletes a session through the confirm dialog)
M6: mutateCards re-check dropped head + hunk revert panel suite 96/96 green — survivor, classified F1 (redundant defence)
M7: data-table ignores fluidWeight head + 1-line revert data-table suite 2/5 red'15100px' vs '250px', '10100px' vs '200px'
M8: tooltip.tsx reverted to base (no forwardRef) base file restored ref-compat suite 2/30 red — exactly the two tooltip forwards refs rows

Witnesses: 01-head-gate-795-green.png, 02-mutation-matrix.png, 03-m1-archive-confirm-red.png,
04-m3-m4-active-session-red.png, 05-secondary-harnesses.png. Raw logs logs/01logs/16 in this artifact directory.

The M3/M4 reds are the head-vs-base behavioral flip for the active-session flow; with the base Back hunk restored (M4), exactly the four tests documenting the new Back semantics fail, and with the App handler removed (M3), exactly the five clear-the-active-session tests fail — the other 568–569 tests stay green in both cells, so the mutations are scoped to the claimed behavior.

Race-safety siblings remain pinned and green at head: does not clear a different session after an overview mutation finishes, does not clear a newly selected session when it finishes, does not clear a session opened while leaving the Session Overview, clears a deleted current session after a partial batch failure, does not clear the current session when it fails (Archive and Delete).

Secondary claims, re-verified

  • Data-table primitive load-bearing (M7) and React 18 ref conventions (M8) — identical reds to the prior round, pixel-level and ref-level assertions respectively.
  • Sidebar archive → More menu. 'archive' removed from WebShellSidebarSessionInlineActionItem (TS union; typecheck enforces call sites), showMoreActions now includes showArchive unconditionally, dropdown item retains its disabled semantics (busy || isCurrent || running, same titles). Docs (sidebar-customization.md) updated consistently, including the inlineItems example table swap.
  • Sessions panel no longer gated to large screenscanOpenSessionsOverview unconditional; the shrink handler no longer closes the sessions panel; split shrink-fold restore is suppressed while a panel is active. The new behavior is pinned by keeps the Session Overview open when the screen shrinks below the breakpoint (App.test.tsx:20765, green at head) and does not hand out the overview split action below the large-screen breakpoint (L20570); the fold-cancel-on-explicit-navigation family (L20235–20508) is what M4 kills.
  • New options wired, not dead switches. keepPanel (declared App.tsx:8514, read 8528, set 12882), manageLiveState (set App.tsx:12905, read panel L407), SESSION_LIVE_STATE_FEATURE (constants/sessions.ts:14, read panel L401), onOpenSplit optionality (App passes undefined below the breakpoint at 12862; panel guards {onOpenSplit && …} at L1675).
  • i18n parityi18n-parity.mjs: all 145 keys used by the changed components exist in EN and ZH; delta symmetric; pre-existing drift unchanged (see F3).
  • Dependency deltadeps-delta.mjs 10/10: lockfile adds exactly @tanstack/react-table@8.21.3 + @tanstack/table-core@8.21.3 (no removals, integrity hashes present), installed versions match, the new primitive is imported by data-table.tsx, and NOTICES carries the entry.
  • Committed generated artifact is genuine — re-ran packages/vscode-ide-companion generate:notices in the worktree (with all nested node_modules symlinked; a first replay without them lost 6262 lines, an environment confound, not a PR defect): regenerated output is byte-identical to the committed NOTICES.txt (diff 0 lines).
  • handleCycleMode equivalence — F4 harness 7/7.

Reviewer Test Plan, per step

Step Verdict here Evidence
Overview opens from sidebar; wide layout proportional, no h-scroll unit-covered; visual not covered data-table fluid-width tests (M7 pins), panel distributes flexible columns only when the table fits without scrolling
Narrow window: h-scroll, fixed edge columns, synced hover, edge shadows; panel stays open on shrink unit-covered; visual not covered keeps the toolbar and pagination responsive on narrow screens, adds inward shadows to fixed columns while horizontally scrolled, keeps the Session Overview open when the screen shrinks below the breakpoint, data-table unpins right columns before fixed regions overlap
Search, workspace multi-select filter, time sort, 10/50/100 page sizes restored covered filters rows by search query…, filters rows by workspace via the multi-select panel, aria-sort assertions, localStorage-seeded page-size tests; write-side persistence note in F2
Row click selects outside title; title-only switches session; copy ID; Worktree/PR details; empty states covered toggles selection when the row is clicked, keeps the title keyboard-focusable…, copies the session ID…, shows worktree metadata…, empty/no-match state tests
Archive/delete require confirmation; active session → new-task state; overview stays open during in-panel mutation; Back clears covered + proven load-bearing M1–M5 matrix above

Findings

No new findings this round. F1–F4 carry forward with statuses in the table above; none is blocking. F1 remains the only completeness gap worth an author's attention: a direct test calling the mutateCards path with an un-mutable card (expecting sessionsOverview.actionUnavailable) would pin the redundant defence; absent that, the clause is deletable.

Not covered

  • Browser-level rendering of every Reviewer Test Plan step that needs a real viewport (proportional columns as pixels, sticky-column hover synchronization, dialog focus trapping). The container ships no browser and the PR declares browser automation out of scope; jsdom unit oracles reproduce the shape, not the visual cause. Playwright e2e suites exist but were not run.
  • Per-commit attribution. Checkout is depth 2 (is-shallow-repository: true; rev-list HEAD^1..HEAD^2 = 1 while metadata lists 19 commits); only the aggregate HEAD^1..HEAD diff was verified.
  • Repo-wide build/test suite and eslint. Targeted gates only (6 changed + 6 adjacent web-shell suites, web-shell typecheck with a liveness probe). The PR's own CI covers repo-wide gates.
  • Trial merge against current upstream main — not determinable from inside the container (no network/token); the verified tree is the merge of the PR into the base tip 5ae363e2, which is newer than the snapshot's baseRefOid (d6533785…).
  • Windows/macOS behavior (author marks both ⚠️ untested).
  • Flakiness gate — the workflow ran it in the prior round (5 identical rounds, no divergence). This round incidentally re-ran the App suite 4× and the panel suite 6× under different mutations with no unexplained divergence.

Methodology

Ran in the CI verify container (node:22-bookworm, Node v22.23.2) on the pre-built merge tree. Head gate: npx vitest run --config vitest.config.ts over the six changed test files (795 tests) and six adjacent suites (65 tests), plus tsc -p tsconfig.json --noEmit (liveness-probed by planting a type error in the worktree: exit 2, TS2322). Mutation A/B: scratch worktree tmp/mutate-tree at the merge commit with the root and all ten nested per-package node_modules symlinked; realpath-asserted that @qwen-code/sdk/@qwen-code/webui resolve into the head tree and proved via git diff --name-only HEAD^1..HEAD that no code outside packages/web-shell is touched, so the symlinked deps are confound-free; the A/A control (573/573 green) proves the environment itself changes nothing. Ten cells (M1–M8 plus refactor and A/A controls) were applied and reverted individually, each mutant required to fail the intended assertion (messages quoted in the matrix). NOTICES replay ran the package's own generate-notices.js inside the worktree and diffed against the committed file. Harnesses f4-equivalence.mjs, i18n-parity.mjs, deps-delta.mjs, matrix-summary.mjs live in this directory; raw logs logs/01logs/16; captures in evidence/.

Qwen Code · sandboxed verification

Flakiness gate log

rounds=5 files=6 skipped=0
file packages/web-shell/client/App.test.tsx: (cd packages/web-shell) npx --no-install vitest run ./client/App.test.tsx
file packages/web-shell/client/components/SessionOverviewPanel.test.tsx: (cd packages/web-shell) npx --no-install vitest run ./client/components/SessionOverviewPanel.test.tsx
file packages/web-shell/client/components/sidebar/WebShellSidebar.workspace-removal.test.tsx: (cd packages/web-shell) npx --no-install vitest run ./client/components/sidebar/WebShellSidebar.workspace-removal.test.tsx
file packages/web-shell/client/components/sidebar/session-action-visibility.test.ts: (cd packages/web-shell) npx --no-install vitest run ./client/components/sidebar/session-action-visibility.test.ts
file packages/web-shell/client/components/ui/data-table.test.tsx: (cd packages/web-shell) npx --no-install vitest run ./client/components/ui/data-table.test.tsx
file packages/web-shell/client/components/ui/react18-ref-compat.test.tsx: (cd packages/web-shell) npx --no-install vitest run ./client/components/ui/react18-ref-compat.test.tsx


per-file results (P=pass F=fail I=infra-exit, one letter per run):
  packages/web-shell/client/App.test.tsx: PPPPP
  packages/web-shell/client/components/SessionOverviewPanel.test.tsx: PPPPP
  packages/web-shell/client/components/sidebar/WebShellSidebar.workspace-removal.test.tsx: PPPPP
  packages/web-shell/client/components/sidebar/session-action-visibility.test.ts: PPPPP
  packages/web-shell/client/components/ui/data-table.test.tsx: PPPPP
  packages/web-shell/client/components/ui/react18-ref-compat.test.tsx: PPPPP

verdict: pass
summary: 6 changed test file(s) x 5 identical rounds, no divergence

--- per-invocation detail (full copy in the artifact) ---
round 1 · packages/web-shell/client/App.test.tsx: P (exit 0)
round 1 · packages/web-shell/client/components/SessionOverviewPanel.test.tsx: P (exit 0)
round 1 · packages/web-shell/client/components/sidebar/WebShellSidebar.workspace-removal.test.tsx: P (exit 0)
round 1 · packages/web-shell/client/components/sidebar/session-action-visibility.test.ts: P (exit 0)
round 1 · packages/web-shell/client/components/ui/data-table.test.tsx: P (exit 0)
round 1 · packages/web-shell/client/components/ui/react18-ref-compat.test.tsx: P (exit 0)
round 2 · packages/web-shell/client/App.test.tsx: P (exit 0)
round 2 · packages/web-shell/client/components/SessionOverviewPanel.test.tsx: P (exit 0)
round 2 · packages/web-shell/client/components/sidebar/WebShellSidebar.workspace-removal.test.tsx: P (exit 0)
round 2 · packages/web-shell/client/components/sidebar/session-action-visibility.test.ts: P (exit 0)
round 2 · packages/web-shell/client/components/ui/data-table.test.tsx: P (exit 0)
round 2 · packages/web-shell/client/components/ui/react18-ref-compat.test.tsx: P (exit 0)
round 3 · packages/web-shell/client/App.test.tsx: P (exit 0)
round 3 · packages/web-shell/client/components/SessionOverviewPanel.test.tsx: P (exit 0)
round 3 · packages/web-shell/client/components/sidebar/WebShellSidebar.workspace-removal.test.tsx: P (exit 0)
round 3 · packages/web-shell/client/components/sidebar/session-action-visibility.test.ts: P (exit 0)
round 3 · packages/web-shell/client/components/ui/data-table.test.tsx: P (exit 0)
round 3 · packages/web-shell/client/components/ui/react18-ref-compat.test.tsx: P (exit 0)
round 4 · packages/web-shell/client/App.test.tsx: P (exit 0)
round 4 · packages/web-shell/client/components/SessionOverviewPanel.test.tsx: P (exit 0)
round 4 · packages/web-shell/client/components/sidebar/WebShellSidebar.workspace-removal.test.tsx: P (exit 0)
round 4 · packages/web-shell/client/components/sidebar/session-action-visibility.test.ts: P (exit 0)
round 4 · packages/web-shell/client/components/ui/data-table.test.tsx: P (exit 0)
round 4 · packages/web-shell/client/components/ui/react18-ref-compat.test.tsx: P (exit 0)
round 5 · packages/web-shell/client/App.test.tsx: P (exit 0)
round 5 · packages/web-shell/client/components/SessionOverviewPanel.test.tsx: P (exit 0)
round 5 · packages/web-shell/client/components/sidebar/WebShellSidebar.workspace-removal.test.tsx: P (exit 0)
round 5 · packages/web-shell/client/components/sidebar/session-action-visibility.test.ts: P (exit 0)
round 5 · packages/web-shell/client/components/ui/data-table.test.tsx: P (exit 0)
round 5 · packages/web-shell/client/components/ui/react18-ref-compat.test.tsx: P (exit 0)

Evidence images

01-head-gate-795-green

02-mutation-matrix

03-m1-archive-confirm-red

04-m3-m4-active-session-red

05-secondary-harnesses

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

Qwen Code · sandboxed verification

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

@chiga0

chiga0 commented Aug 29, 2026

Copy link
Copy Markdown
Collaborator

Review notes (round 5 — head 3baa229768c2):

3 new commits since round 4 (0ec1b7339d07 · 1f9d5290436c · 3baa229768c2).

Prior findings: All prior blockers (R1–R4) confirmed fixed — see review 5050798024.

New commits reviewed:

stabilize session overview navigation:

  • canArchiveCard / canDeleteCard now gate on card.status === 'idle': running sessions cannot be archived or deleted. New test covers inline + bulk-select. ✅
  • liveStateWorkspaceCwds: live-state now only used when all visible workspaces are trusted; falls back to catalog polling otherwise. New test confirms. ✅

restore session overview page scrolling:

  • Sticky footer: replaced -mb-4 with shadow-[0_16px_0_var(--background)]. Net decorator delta changed from −3px to +13px; hysteresis thresholds updated (+12/+1 vs old −4/+1). viewportContentHeight subtracts padding. ✅
  • overflow-y-hidden added to horizontal scroller container; vertical scroll stays on outer viewport. New test covers this. ✅

preserve session overview safeguards:

  • New TerminalPanel (WebSocket PTY, exponential reconnect, release-handshake, auth subprotocol). Module-level releaseCallbacks map with identity-checked cleanup. 19 unit tests. ✅
  • isWebTerminalTarget guard plumbed into all keyboard interceptors (sidebar toggle, Escape, btw/global shortcuts). Shadow-DOM path tested. ✅
  • onSelectCurrentSession now clears splitFoldedByShrinkRef.current = false. Deferred item from round 4, test added. ✅

CI: review-pr FAIL = runner infrastructure issue (write-permission failure), not code-related. ubuntu Test ✅, E2E Smoke ✅, Desktop Shell ✅, Java CI ✅, CVE ✅, Secrets ✅. mac/Windows tests SKIPPED (unchanged from prior rounds).

No blocking findings. Approved at head 3baa229768c2ef88a839be5fc3214da1a2f51e9d.

Reviewed with AI assistance.

@wenshao
wenshao added this pull request to the merge queue Aug 29, 2026
Merged via the queue into main with commit b306bd2 Aug 29, 2026
64 of 65 checks passed
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.

6 participants