Skip to content

feat: add Agent Team experimental feature for parallel sub-agent coordination#4844

Merged
tanzhenxin merged 39 commits into
mainfrom
feat/agent-team-v2
Jun 10, 2026
Merged

feat: add Agent Team experimental feature for parallel sub-agent coordination#4844
tanzhenxin merged 39 commits into
mainfrom
feat/agent-team-v2

Conversation

@tanzhenxin

@tanzhenxin tanzhenxin commented Jun 8, 2026

Copy link
Copy Markdown
Collaborator

What this PR does

Adds an experimental Agent Team mode. When enabled, the model can create a named team and spawn several sub-agents ("teammates") that work in parallel, message each other and the leader, and share a task list — and the leader collects their results into a consolidated answer. It is off by default and enabled via the experimental.agentTeam setting or QWEN_CODE_ENABLE_AGENT_TEAM=1. With the flag on, the model gains team coordination tools (create/delete a team, send messages to teammates, and create/update/list shared tasks), and the Agent tool gains a name parameter that spawns a long-lived named teammate instead of a one-shot sub-agent. Teammate work and messages surface in both headless and interactive (TUI) modes.

Why it's needed

This re-ports the Agent Team feature onto current main. The original branch (#2886) was opened in April and fell roughly 360 commits behind after main independently rewrote the agent runtime it was built on, so it could no longer be merged cleanly — a mechanical merge produced code that did not build. This is a fresh implementation on top of the current runtime, split into small reviewable commits (foundation → message routing → teammate spawning → rendering → turn-loop integration → headless and interactive drivers). It supersedes #2886.

Reviewer Test Plan

How to verify

Enable the flag (QWEN_CODE_ENABLE_AGENT_TEAM=1 or experimental.agentTeam: true) and give the model a task that benefits from several agents working together — for example: "Review this code for bugs with three reviewers in parallel (one on error handling, one on races, one on edge cases) and give me a consolidated report," or "Coordinate a team to build a small bookmark app." Expected: the model creates a team, spawns named teammates that run concurrently, the teammates report back to the leader as they finish, and the leader produces a single consolidated summary before the team is cleaned up. With the flag off (the default), none of the team tools are registered and behavior is unchanged.

Evidence (Before & After)

See the E2E summary in the comment below. Before: the feature did not exist on main. After: the full team flow (create → spawn teammates → concurrent work → report back → consolidate → cleanup) runs end-to-end against a live model.

demo

Tested on

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

macOS: built, unit + integration suites, and live headless E2E. Windows/Linux: covered by CI.

Environment

Built bundle run headless against a live model (glm-5.1); unit and integration tests via vitest.

Risk & Scope

  • Main risk or tradeoff: large surface area, but the entire feature is behind the experimental flag and inert by default — no change to default behavior.
  • Not validated / out of scope: interactive TUI rendering is exercised but not polished; in E2E the generated demo app's server boot was confirmed by code inspection rather than runtime (local dependency install was flaky in the test environment).
  • Breaking changes / migration notes: none.

Linked Issues

Supersedes #2886.

中文说明

这个 PR 做了什么

新增一个实验性的 Agent Team(智能体团队)模式。启用后,模型可以创建一个具名团队,并派生多个子智能体("队友")并行工作、互相以及与 leader 之间收发消息、共享任务列表,最后由 leader 汇总各队友的结果给出统一的答复。该功能默认关闭,可通过 experimental.agentTeam 设置或 QWEN_CODE_ENABLE_AGENT_TEAM=1 环境变量启用。开启后,模型会获得团队协作工具(创建/删除团队、向队友发送消息、创建/更新/列出共享任务),并且 Agent 工具新增一个 name 参数,用于派生一个长期存在的具名队友,而不是一次性的子智能体。队友的工作与消息在无界面(headless)和交互式(TUI)两种模式下都会呈现。

为什么需要它

本 PR 是将 Agent Team 功能重新移植到当前 main 分支。原分支(#2886)于四月开立,此后 main 独立重写了它所依赖的 agent 运行时,使其落后约 360 个提交,已无法干净合并——机械式合并会产生无法构建的代码。本 PR 是在当前运行时之上的全新实现,并拆分为多个便于审阅的小提交(基础设施 → 消息路由 → 队友派生 → 渲染 → 回合循环集成 → 无界面与交互式驱动)。它取代 #2886

审阅者测试计划

如何验证

启用开关(QWEN_CODE_ENABLE_AGENT_TEAM=1experimental.agentTeam: true),给模型一个适合多个智能体协作的任务——例如:"让三位审阅者并行审查这段代码的 bug(一人看错误处理、一人看竞态、一人看边界情况),并给我一份汇总报告",或"协调一个团队构建一个小型书签应用"。预期:模型会创建团队,派生并发运行的具名队友,队友完成后向 leader 汇报,leader 在团队清理前给出一份统一的汇总。关闭开关(默认)时,团队工具不会被注册,行为保持不变。

证据(前后对比)

见下方评论中的 E2E 测试摘要。之前:该功能在 main 上不存在。之后:完整的团队流程(创建 → 派生队友 → 并发工作 → 汇报 → 汇总 → 清理)可针对真实模型端到端运行。

测试平台

macOS:已构建,并通过单元 + 集成测试与真实模型的无界面 E2E。Windows/Linux:由 CI 覆盖。

风险与范围

  • 主要风险/取舍:改动面较大,但整个功能都在实验性开关之后,默认关闭——不改变默认行为。
  • 未验证/超出范围:交互式 TUI 渲染已被触达但未做打磨;E2E 中生成的演示应用服务端启动是通过代码审阅确认的,而非运行时(测试环境本地依赖安装不稳定)。
  • 破坏性变更/迁移说明:无。

关联 Issue

取代 #2886

First stage of re-porting the Agent Team feature (originally PR #2886) onto
current main. The branch had diverged 362 commits behind a parallel rewrite
of the agent runtime, so the feature is being re-applied stage by stage
rather than merged.

This stage lands the self-contained agents/team/ subsystem (TeamManager,
mailbox, identity, tasks, leader permission bridge, test-utils) plus the
team_create/team_delete and task_create/task_update/task_list tools, with
the additive plumbing they need:

- Config: TeamManager/TeamContext accessors, cleanupTeamRuntime, and
  isAgentTeamEnabled (settings or QWEN_CODE_ENABLE_AGENT_TEAM=1).
- Tool registry: team/task tools registered lazily, gated on the flag.
- Runtime hooks: completeOnIdle for one-shot teammates; args on the
  agent approval event; teammate-aware tool exclusion sets.
- Backend types: TeamAgentHandle, optional getAgent, completeOnIdle.
- New experimental.agentTeam setting.

Everything is gated behind the experimental flag and inert by default.
Build is green; team unit tests and all touched-file regressions pass.
Stage 1 of the Agent Team re-port. Extends the send_message tool so it can
route to a teammate (or "*" for broadcast) via TeamManager in addition to
its existing background-task path, and supports the shutdown_request control
message (leader-only). Recipient selection is a oneOf over `to`/`task_id`.

Layered on top of main's classifier integration: send_message keeps its
'ask' default permission and forwards the routing fields + message to the
AUTO classifier, since the message is an instruction the recipient executes.

Re-adds the team-lifecycle E2E test, which now passes end to end
(create -> tasks -> messages -> list -> update -> delete).
Stage 3 of the Agent Team re-port. Adds the `name` parameter to the Agent
tool: when a team is active and a name is given, the call routes through
TeamManager.spawnTeammate instead of launching a one-shot subagent. Without
a team the call is rejected up front rather than silently falling back. The
tool description advertises team coordination only when the experimental
flag is on. Ported onto main's rewritten Agent tool.
Stage 5 (partial) of the Agent Team re-port. Teaches the ToolMessage
result renderer about the TeamResultDisplay and TaskListResultDisplay
shapes so the team/task tools' output is shown via their returnDisplay
text instead of a stringified object, and adds a JSON.stringify safeguard
for any other non-string display object.

The remaining CLI wiring (nonInteractiveCli + useGeminiStream team
drivers, permissionController.handleTeammateApproval) is coupled to the
turn-loop Teammate handling and will land together with Stage 4.
Stage 4 of the Agent Team re-port. Adds SendMessageType.Teammate and
includes it in isTopLevelInteraction so that a teammate message delivered
to the leader resets the loop detector and opens an interaction span, the
same as a user/cron/notification turn.

Per the agreed minimal integration, teammate turns deliberately do NOT run
the UserQuery/Cron block — they don't bump commit attribution, aren't
recorded as user messages, and don't trigger auto-memory prefetch. That
keeps the edit to main's restructured turn loop to a single condition.
Stage 5 of the Agent Team re-port. Wires the non-interactive/headless run
loop to the active team: it subscribes to TeamManager changes, drains
teammate messages into the leader's conversation as SendMessageType.Teammate
turns, waits for teammate activity when the leader has no pending tool calls,
and routes teammate tool-approval requests through the session's permission
channel (SDK in stream-json mode; YOLO/cancel fallback otherwise).

Adds PermissionController.handleTeammateApproval and exposes it on the
ControlService permission facade. Ported onto main's restructured run loop
(which added its own cron/notification drain mechanism).
Final Stage 5 piece of the Agent Team re-port. Wires the interactive (TUI)
useGeminiStream hook to the active team: it subscribes to TeamManager,
queues teammate messages, and drains them into the conversation as
SendMessageType.Teammate turns when idle, guarded against racing the
notification drain. Treats teammate turns like user/cron for image-format
checks and new-prompt stats. Ported onto main's rewritten hook.
@tanzhenxin

Copy link
Copy Markdown
Collaborator Author

E2E verification

Run headless against a live model (glm-5.1) with the feature flag on, plus the unit suite. The team flow runs end-to-end: flag-gated tool registration → create a team → spawn named teammates via the Agent tool → teammates run concurrently and report back → leader consolidates → team cleanup. Clean exits, no hangs.

Scenario What it checks Result
Unit Team subsystem ✅ 178 tests pass
Tool registration Team tools appear only when the flag is on ✅ all 5 tools registered with flag on
3-agent code review A team reviews code in parallel and consolidates findings ✅ team + 3 teammates spawned, all reported, consolidated report
4-agent app build A team builds a small app (design → backend → frontend → tests) ✅ team + 4 teammates spawned, all reported, all files produced, structured summary

With the flag off (default), the team tools are not registered and behavior is unchanged.

@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Thanks for the PR, @tanzhenxin! This is a substantial feature — let's walk through the gate.

Template looks good ✓ — all required sections present, bilingual, test plan with evidence.

On direction: this is squarely on the roadmap. Claude Code already ships Agent Teams (research preview since ~2.1.33, with ongoing fixes through the latest releases — teammate model inheritance, permission propagation, memory leaks, tmux messaging). This repo has a roadmap/multi-agent label. Re-porting the feature onto current main after the agent runtime rewrite is the right call, and the original #2886 was clearly unmergeable at 360 commits behind. No direction concerns.

On approach: 10K additions / 60 files is large, but the decomposition into 7 layered commits (foundation → message routing → teammate spawning → rendering → turn-loop integration → headless/interactive drivers) makes it reviewable. The entire feature is behind experimental.agentTeam / QWEN_CODE_ENABLE_AGENT_TEAM=1 and inert by default — zero risk to existing behavior. Having oversized-ok as an available label signals the project is comfortable with PRs of this scope when justified.

One thing worth thinking about (not a blocker): TeamManager.ts at 1,316 lines and tasks.ts at 740 lines are large files. If they grow further, splitting the manager into lifecycle/messaging/state submodules would help maintainability. But for the initial landing, the current structure is coherent.

Moving on to code review. 🔍

中文说明

感谢贡献,@tanzhenxin!这是一个重要的功能——让我们过一下门禁。

模板完整 ✓ — 所有必要章节齐全,双语,测试计划带证据。

方向:完全符合路线图。Claude Code 已经发布了 Agent Teams(从 ~2.1.33 开始的研究预览,一直到最新版本都有持续修复——队友模型继承、权限传播、内存泄漏、tmux 消息)。本仓库有 roadmap/multi-agent 标签。在 agent 运行时重写后将功能重新移植到当前 main 是正确的做法,原 #2886 落后 360 个提交显然已无法合并。方向没有问题。

方案:10K 行新增 / 60 个文件规模较大,但拆分为 7 个层次化的提交(基础设施 → 消息路由 → 队友派生 → 渲染 → 回合循环集成 → 无界面/交互式驱动)使其可审阅。整个功能在 experimental.agentTeam / QWEN_CODE_ENABLE_AGENT_TEAM=1 之后,默认关闭——对现有行为零风险。oversized-ok 标签的存在说明项目对合理的大 PR 是接受的。

一个值得考虑的点(不是阻塞项):TeamManager.ts 1,316 行、tasks.ts 740 行都是大文件。如果后续继续增长,建议将管理器拆分为生命周期/消息/状态子模块。但对于初始落地,当前结构是合理的。

进入代码审查 🔍

Qwen Code · qwen3.7-max

@wenshao

wenshao commented Jun 8, 2026

Copy link
Copy Markdown
Collaborator

@qwen-code /review

The Agent Team mailbox and task files import proper-lockfile, but the
dependency was never declared in package.json, so a clean `npm ci` (as CI
runs) failed to resolve the module — cascading into implicit-any and
possibly-undefined errors in the same files. It built locally only because
the working tree's node_modules already had the package from an earlier
install.

Adds proper-lockfile to packages/core dependencies and @types/proper-lockfile
to root devDependencies (matching the original feature branch), and
regenerates the lockfile. Build and typecheck are clean.
@github-actions

github-actions Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Summary

Package Lines Statements Functions Branches
CLI 77.15% 77.15% 80.51% 79.78%
Core 81.63% 81.63% 83.65% 83.75%
CLI Package - Full Text Report
-------------------|---------|----------|---------|---------|-------------------
File               | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-------------------|---------|----------|---------|---------|-------------------
All files          |   77.15 |    79.78 |   80.51 |   77.15 |                   
 src               |   70.11 |    67.08 |   73.33 |   70.11 |                   
  gemini.tsx       |   61.89 |    64.28 |   71.42 |   61.89 | ...1192-1195,1207 
  ...ractiveCli.ts |   69.62 |    63.35 |   66.66 |   69.62 | ...1545-1547,1582 
  ...liCommands.ts |   84.54 |    77.14 |     100 |   84.54 | ...26-335,361,475 
  ...ActiveAuth.ts |     100 |     87.5 |     100 |     100 | 66-80             
 ...cp-integration |    70.7 |    64.93 |   89.47 |    70.7 |                   
  acpAgent.ts      |   70.65 |    64.99 |   89.86 |   70.65 | ...4994,5008-5016 
  authMethods.ts   |      92 |       60 |     100 |      92 | 33-34             
  errorCodes.ts    |       0 |        0 |       0 |       0 | 1-22              
  ...DirContext.ts |     100 |      100 |     100 |     100 |                   
 ...ration/service |   68.65 |    83.33 |   66.66 |   68.65 |                   
  filesystem.ts    |   68.65 |    83.33 |   66.66 |   68.65 | ...32,77-94,97-98 
 ...ration/session |   79.43 |    74.07 |   88.04 |   79.43 |                   
  ...ryReplayer.ts |   67.34 |     75.6 |   81.81 |   67.34 | ...54-269,282-283 
  Session.ts       |   79.48 |    73.41 |   90.62 |   79.48 | ...3345,3371-3375 
  ...entTracker.ts |   90.96 |    84.84 |      90 |   90.96 | ...35,199,251-260 
  index.ts         |       0 |        0 |       0 |       0 | 1-40              
  ...ssionUtils.ts |   84.21 |    78.57 |     100 |   84.21 | ...37-153,209-211 
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 ...ssion/emitters |   96.12 |    90.98 |    92.3 |   96.12 |                   
  BaseEmitter.ts   |   76.92 |    66.66 |      80 |   76.92 | 23-24,39-40,55-56 
  ...ageEmitter.ts |     100 |     90.9 |     100 |     100 | 119,121           
  PlanEmitter.ts   |     100 |      100 |     100 |     100 |                   
  ...allEmitter.ts |   98.06 |     92.3 |     100 |   98.06 | 227-228,327,335   
  index.ts         |       0 |        0 |       0 |       0 | 1-10              
 ...ession/rewrite |    91.3 |    88.09 |   94.44 |    91.3 |                   
  LlmRewriter.ts   |      81 |       84 |     100 |      81 | ...,88-89,155-159 
  ...Middleware.ts |   96.74 |    86.84 |     100 |   96.74 | 135,143-145       
  TurnBuffer.ts    |     100 |      100 |     100 |     100 |                   
  config.ts        |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 src/commands      |   45.67 |    85.71 |   43.47 |   45.67 |                   
  auth.ts          |     100 |    83.33 |     100 |     100 | 11,14             
  channel.ts       |   56.66 |      100 |       0 |   56.66 | 15-19,27-34       
  extensions.tsx   |   96.55 |      100 |      50 |   96.55 | 37                
  hooks.tsx        |   66.66 |      100 |       0 |   66.66 | 20-24             
  mcp.ts           |   94.73 |      100 |      50 |   94.73 | 28                
  review.ts        |   51.85 |      100 |       0 |   51.85 | 24-35,38          
  serve.ts         |    8.02 |      100 |       0 |    8.02 | ...56-152,154-266 
 ...mmands/channel |    39.2 |    79.45 |      50 |    39.2 |                   
  ...l-registry.ts |    8.33 |      100 |       0 |    8.33 | 6-22,25-43        
  config-utils.ts  |      92 |      100 |   66.66 |      92 | 21-26             
  configure.ts     |    14.7 |      100 |       0 |    14.7 | 18-21,23-84       
  pairing.ts       |   26.31 |      100 |       0 |   26.31 | ...30,40-50,52-65 
  pidfile.ts       |   96.34 |    86.95 |     100 |   96.34 | 49,59,91          
  start.ts         |   30.98 |       52 |   69.23 |   30.98 | ...72-475,484-486 
  status.ts        |   17.85 |      100 |       0 |   17.85 | 15-26,32-76       
  stop.ts          |      20 |      100 |       0 |      20 | 14-48             
 ...nds/extensions |    85.1 |    88.77 |   81.81 |    85.1 |                   
  consent.ts       |   72.68 |       90 |   42.85 |   72.68 | ...86-142,157-163 
  disable.ts       |     100 |      100 |     100 |     100 |                   
  enable.ts        |     100 |      100 |     100 |     100 |                   
  install.ts       |    75.6 |    66.66 |   66.66 |    75.6 | ...39-142,145-153 
  link.ts          |     100 |      100 |     100 |     100 |                   
  list.ts          |     100 |      100 |     100 |     100 |                   
  new.ts           |     100 |      100 |     100 |     100 |                   
  settings.ts      |   99.15 |      100 |   83.33 |   99.15 | 151               
  uninstall.ts     |    37.5 |      100 |   33.33 |    37.5 | 23-45,57-64,67-70 
  update.ts        |   96.32 |      100 |     100 |   96.32 | 101-105           
  utils.ts         |   67.77 |    38.88 |     100 |   67.77 | ...,94-98,100-104 
 ...les/mcp-server |       0 |        0 |       0 |       0 |                   
  example.ts       |       0 |        0 |       0 |       0 | 1-60              
 src/commands/mcp  |   92.29 |    86.08 |   88.88 |   92.29 |                   
  add.ts           |     100 |    98.03 |     100 |     100 | 293               
  list.ts          |   91.22 |    80.76 |      80 |   91.22 | ...19-121,146-147 
  reconnect.ts     |   76.72 |    71.42 |   85.71 |   76.72 | 35-48,153-175     
  remove.ts        |     100 |       80 |     100 |     100 | 21-25             
 ...ommands/review |   11.57 |      100 |       0 |   11.57 |                   
  cleanup.ts       |   17.94 |      100 |       0 |   17.94 | ...01-106,108-109 
  deterministic.ts |   13.75 |      100 |       0 |   13.75 | ...22-738,740-741 
  fetch-pr.ts      |   11.36 |      100 |       0 |   11.36 | ...80-201,203-204 
  load-rules.ts    |   11.32 |      100 |       0 |   11.32 | ...41-153,155-156 
  pr-context.ts    |    6.22 |      100 |       0 |    6.22 | ...97-312,314-315 
  presubmit.ts     |    9.35 |      100 |       0 |    9.35 | ...62-287,289-290 
 ...nds/review/lib |      30 |      100 |       0 |      30 |                   
  gh.ts            |   22.58 |      100 |       0 |   22.58 | ...49,53-54,62-69 
  git.ts           |   22.72 |      100 |       0 |   22.72 | 15-18,29-39,43-44 
  paths.ts         |   52.94 |      100 |       0 |   52.94 | ...26,37-38,42-43 
 src/config        |   92.89 |    85.41 |   89.79 |   92.89 |                   
  auth.ts          |   86.74 |    80.88 |     100 |   86.74 | ...40-241,257-258 
  config.ts        |   86.67 |    84.38 |   82.14 |   86.67 | ...2010,2012-2020 
  keyBindings.ts   |   96.87 |       50 |     100 |   96.87 | 201-204           
  ...ngsAdapter.ts |     100 |    94.11 |     100 |     100 | 64                
  ...idersScope.ts |      92 |       90 |     100 |      92 | 11-12             
  sandboxConfig.ts |   61.64 |    71.87 |   66.66 |   61.64 | ...54-68,73,77-89 
  settings.ts      |   87.02 |    88.33 |   89.74 |   87.02 | ...1327,1342-1345 
  ...ingsSchema.ts |     100 |      100 |     100 |     100 |                   
  ...tedFolders.ts |   96.22 |       94 |     100 |   96.22 | ...95-197,212-213 
 ...nfig/migration |   94.89 |    78.94 |   83.33 |   94.89 |                   
  index.ts         |   94.87 |    88.88 |     100 |   94.87 | 91-92             
  scheduler.ts     |   96.55 |    77.77 |     100 |   96.55 | 19-20             
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 ...ation/versions |   94.74 |       96 |     100 |   94.74 |                   
  ...-v2-shared.ts |     100 |      100 |     100 |     100 |                   
  v1-to-v2.ts      |   81.75 |    90.19 |     100 |   81.75 | ...28-229,231-247 
  v2-to-v3.ts      |     100 |      100 |     100 |     100 |                   
  v3-to-v4.ts      |     100 |      100 |     100 |     100 |                   
 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    |   63.09 |    64.51 |   55.55 |   63.09 |                   
  ...tputBridge.ts |   62.94 |    65.51 |   56.25 |   62.94 | ...22-323,331-334 
  ...utContext.tsx |     100 |      100 |     100 |     100 |                   
  index.ts         |       0 |        0 |       0 |       0 | 1-8               
 src/export        |       0 |        0 |       0 |       0 |                   
  index.ts         |       0 |        0 |       0 |       0 | 1-7               
 src/generated     |     100 |      100 |     100 |     100 |                   
  git-commit.ts    |     100 |      100 |     100 |     100 |                   
 src/i18n          |   82.51 |    75.94 |   65.71 |   82.51 |                   
  index.ts         |   63.68 |    69.56 |   53.84 |   63.68 | ...70-271,281-286 
  languages.ts     |   96.92 |    86.66 |     100 |   96.92 | 134-135,167,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 |   72.57 |    71.12 |   74.07 |   72.57 |                   
  session.ts       |   76.64 |     69.4 |   85.71 |   76.64 | ...23-824,833-843 
  types.ts         |    42.5 |      100 |   33.33 |    42.5 | ...90-591,594-595 
 ...active/control |   76.29 |    88.23 |      80 |   76.29 |                   
  ...rolContext.ts |    6.89 |        0 |       0 |    6.89 | 50-86             
  ...Dispatcher.ts |   91.66 |    91.83 |   88.88 |   91.66 | ...54-372,388,391 
  ...rolService.ts |     7.4 |        0 |       0 |     7.4 | 46-185            
 ...ol/controllers |    25.4 |    35.71 |   35.48 |    25.4 |                   
  ...Controller.ts |   36.97 |       80 |      80 |   36.97 | ...15-117,127-210 
  ...Controller.ts |       0 |        0 |       0 |       0 | 1-56              
  ...Controller.ts |   28.33 |    34.48 |      40 |   28.33 | ...64-573,588-593 
  ...Controller.ts |   14.06 |      100 |       0 |   14.06 | ...82-117,130-133 
  ...Controller.ts |   21.97 |    28.57 |   27.27 |   21.97 | ...39-451,460-489 
 .../control/types |       0 |        0 |       0 |       0 |                   
  serviceAPIs.ts   |       0 |        0 |       0 |       0 | 1                 
 ...Interactive/io |   98.01 |    93.77 |   95.23 |   98.01 |                   
  ...putAdapter.ts |   97.89 |    92.82 |   98.07 |   97.89 | ...1303,1398-1399 
  ...putAdapter.ts |      96 |     90.9 |   85.71 |      96 | 51-52             
  ...nputReader.ts |     100 |    94.73 |     100 |     100 | 67                
  ...putAdapter.ts |   98.38 |      100 |   90.47 |   98.38 | 83-84,124-125     
  index.ts         |     100 |      100 |     100 |     100 |                   
 src/patches       |       0 |        0 |       0 |       0 |                   
  is-in-ci.ts      |       0 |        0 |       0 |       0 | 1-17              
 src/remoteInput   |   86.98 |       75 |   85.71 |   86.98 |                   
  ...utContext.tsx |     100 |      100 |     100 |     100 |                   
  ...putWatcher.ts |   88.12 |    76.08 |   91.66 |   88.12 | ...21-222,233-236 
  index.ts         |       0 |        0 |       0 |       0 | 1-8               
 src/serve         |   79.48 |    78.88 |   92.97 |   79.48 |                   
  auth.ts          |   88.49 |    88.63 |     100 |   88.49 | ...49-150,153-155 
  capabilities.ts  |     100 |     90.9 |     100 |     100 | 264               
  ...usProvider.ts |   67.01 |    51.42 |     100 |   67.01 | ...40-245,278-286 
  debugMode.ts     |     100 |      100 |     100 |     100 |                   
  demo.ts          |     100 |      100 |     100 |     100 |                   
  envSnapshot.ts   |    92.3 |       84 |     100 |    92.3 | 108-111,170-177   
  eventBus.ts      |     100 |      100 |     100 |     100 |                   
  httpAcpBridge.ts |   80.09 |    79.06 |   96.51 |   80.09 | ...4283,4314-4355 
  ...oryChannel.ts |     100 |      100 |     100 |     100 |                   
  index.ts         |       0 |        0 |       0 |       0 | 1-106             
  loopbackBinds.ts |     100 |      100 |     100 |     100 |                   
  runQwenServe.ts  |   73.98 |    87.83 |   55.55 |   73.98 | ...94-710,735-737 
  server.ts        |   86.18 |    82.94 |   90.62 |   86.18 | ...2478,2543-2552 
  status.ts        |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
  ...paceAgents.ts |   64.87 |    70.45 |    90.9 |   64.87 | ...1306,1316-1326 
  ...paceMemory.ts |   87.13 |    78.46 |     100 |   87.13 | ...54-361,421-428 
 src/serve/auth    |   86.54 |    78.75 |   93.75 |   86.54 |                   
  deviceFlow.ts    |   96.33 |    79.51 |    97.5 |   96.33 | ...1526,1630,1700 
  ...owProvider.ts |   45.23 |    74.07 |      75 |   45.23 | ...90-359,375,379 
 src/serve/fs      |   84.85 |    79.75 |     100 |   84.85 |                   
  audit.ts         |     100 |    96.15 |     100 |     100 | 201               
  errors.ts        |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  paths.ts         |   77.82 |    77.08 |     100 |   77.82 | ...64,493-497,510 
  policy.ts        |   90.32 |    89.18 |     100 |   90.32 | 142-150           
  ...FileSystem.ts |   83.55 |    76.22 |     100 |   83.55 | ...1859,1886-1887 
 src/serve/routes  |   89.41 |       70 |     100 |   89.41 |                   
  ...ceFileRead.ts |   94.41 |    76.92 |     100 |   94.41 | ...28-329,390-392 
  ...eFileWrite.ts |    82.1 |    60.52 |     100 |    82.1 | ...42-244,247-249 
 src/services      |   91.86 |     90.8 |   97.56 |   91.86 |                   
  ...mandLoader.ts |     100 |    93.75 |     100 |     100 | 93                
  ...killLoader.ts |     100 |     93.1 |     100 |     100 | 48,67             
  ...andService.ts |    98.7 |      100 |     100 |    98.7 | 107               
  ...mandLoader.ts |   86.83 |    83.87 |     100 |   86.83 | ...30-335,340-345 
  ...omptLoader.ts |   75.84 |    80.64 |   83.33 |   75.84 | ...10-211,277-278 
  ...mandLoader.ts |     100 |    96.96 |     100 |     100 | 66                
  ...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.21 |    96.66 |     100 |   98.21 | 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 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...ght/generators |    88.3 |    85.49 |   92.59 |    88.3 |                   
  DataProcessor.ts |   88.22 |    85.48 |      95 |   88.22 | ...1341,1345-1352 
  ...tGenerator.ts |   98.21 |    85.71 |     100 |   98.21 | 46                
  ...teRenderer.ts |   45.45 |      100 |       0 |   45.45 | 13-51             
 .../insight/types |       0 |       50 |      50 |       0 |                   
  ...sightTypes.ts |       0 |        0 |       0 |       0 |                   
  ...sightTypes.ts |       0 |        0 |       0 |       0 | 1                 
 ...mpt-processors |   97.27 |    94.04 |     100 |   97.27 |                   
  ...tProcessor.ts |     100 |      100 |     100 |     100 |                   
  ...eProcessor.ts |   94.52 |    84.21 |     100 |   94.52 | 46-47,93-94       
  ...tionParser.ts |     100 |      100 |     100 |     100 |                   
  ...lProcessor.ts |   97.41 |    95.65 |     100 |   97.41 | 95-98             
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/services/tips |   97.35 |    84.84 |     100 |   97.35 |                   
  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       |   66.82 |    78.94 |   66.66 |   66.82 |                   
  ...reeStartup.ts |   66.82 |    78.94 |   66.66 |   66.82 | ...08-312,363-426 
 src/test-utils    |   93.71 |    83.33 |      80 |   93.71 |                   
  ...omMatchers.ts |   69.69 |       50 |      50 |   69.69 | 32-35,37-39,45-47 
  ...andContext.ts |     100 |      100 |     100 |     100 |                   
  render.tsx       |     100 |      100 |     100 |     100 |                   
 src/ui            |   65.14 |       73 |   59.67 |   65.14 |                   
  App.tsx          |   33.33 |       75 |   33.33 |   33.33 | 32-86             
  AppContainer.tsx |   64.12 |    64.81 |      50 |   64.12 | ...3238,3242-3246 
  ...tionNudge.tsx |    9.58 |      100 |       0 |    9.58 | 24-94             
  ...ackDialog.tsx |   29.23 |      100 |       0 |   29.23 | 25-75             
  ...tionNudge.tsx |    7.69 |      100 |       0 |    7.69 | 25-103            
  colors.ts        |      60 |      100 |   35.29 |      60 | ...52,54-55,60-61 
  constants.ts     |     100 |      100 |     100 |     100 |                   
  keyMatchers.ts   |   95.91 |    97.14 |     100 |   95.91 | 25-26             
  ...tic-colors.ts |     100 |      100 |     100 |     100 |                   
  ...inePresets.ts |   98.28 |    89.87 |     100 |   98.28 | ...34,261,420-422 
  textConstants.ts |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/ui/auth       |   59.16 |    65.94 |   51.11 |   59.16 |                   
  AuthDialog.tsx   |   62.87 |     42.1 |   18.18 |   62.87 | ...03,310-332,336 
  ...nProgress.tsx |       0 |        0 |       0 |       0 | 1-64              
  ...etupSteps.tsx |   60.03 |    70.37 |      56 |   60.03 | ...87,791,800,803 
  useAuth.ts       |   94.55 |    73.52 |     100 |   94.55 | ...19-220,239-245 
  ...rSetupFlow.ts |   43.52 |    33.33 |      50 |   43.52 | ...72-393,410-453 
 src/ui/commands   |   76.49 |    81.96 |   85.05 |   76.49 |                   
  aboutCommand.ts  |     100 |      100 |     100 |     100 |                   
  agentsCommand.ts |   83.78 |      100 |      60 |   83.78 | 30-32,42-44       
  ...odeCommand.ts |   89.47 |    81.25 |     100 |   89.47 | 92-93,95-100      
  arenaCommand.ts  |   62.81 |    58.73 |   65.21 |   62.81 | ...91-596,681-689 
  authCommand.ts   |     100 |      100 |     100 |     100 |                   
  branchCommand.ts |     100 |      100 |     100 |     100 |                   
  btwCommand.ts    |    96.1 |    74.07 |     100 |    96.1 | 149-154           
  bugCommand.ts    |   81.13 |    71.42 |     100 |   81.13 | 60-69             
  clearCommand.ts  |   79.64 |       68 |     100 |   79.64 | ...24-125,133-142 
  ...essCommand.ts |   67.95 |    55.88 |      75 |   67.95 | ...86-187,201-204 
  ...extCommand.ts |   65.06 |    67.24 |   84.61 |   65.06 | ...39-574,585-586 
  copyCommand.ts   |   98.48 |    95.78 |     100 |   98.48 | ...80,280,321,327 
  deleteCommand.ts |     100 |      100 |     100 |     100 |                   
  diffCommand.ts   |     100 |     87.5 |     100 |     100 | ...61,224-225,238 
  ...ryCommand.tsx |   75.55 |    79.03 |   88.88 |   75.55 | ...72-277,331-339 
  docsCommand.ts   |     100 |    88.88 |     100 |     100 | 25                
  doctorCommand.ts |   61.27 |    87.06 |    87.5 |   61.27 | ...71-372,445-665 
  dreamCommand.ts  |      75 |    66.66 |   66.66 |      75 | 22-27,44-47       
  editorCommand.ts |     100 |      100 |     100 |     100 |                   
  exportCommand.ts |   98.25 |    91.02 |     100 |   98.25 | ...81,198-199,364 
  ...onsCommand.ts |   49.33 |     90.9 |   63.63 |   49.33 | ...06-110,163-215 
  forgetCommand.ts |   26.82 |      100 |      50 |   26.82 | 18-51             
  forkCommand.ts   |     100 |    94.44 |     100 |     100 | 92,151            
  goalCommand.ts   |   91.41 |    84.44 |      90 |   91.41 | ...86-189,201-204 
  helpCommand.ts   |     100 |      100 |     100 |     100 |                   
  hooksCommand.ts  |   81.13 |    65.71 |   85.71 |   81.13 | ...,86-93,131-132 
  ideCommand.ts    |   60.75 |    64.28 |   41.17 |   60.75 | ...05-306,310-324 
  initCommand.ts   |   84.33 |    72.72 |     100 |   84.33 | 68,82-87,89-94    
  ...ghtCommand.ts |   74.56 |    68.42 |     100 |   74.56 | ...31-245,250-273 
  ...ageCommand.ts |   92.17 |    82.69 |     100 |   92.17 | ...43,164,173-183 
  lspCommand.ts    |     100 |    86.95 |     100 |     100 | 31,101-102        
  mcpCommand.ts    |     100 |      100 |     100 |     100 |                   
  memoryCommand.ts |     100 |      100 |     100 |     100 |                   
  modelCommand.ts  |   75.09 |    78.18 |      75 |   75.09 | ...20-225,262-267 
  ...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             
  ...berCommand.ts |   29.26 |      100 |      50 |   29.26 | 26-66             
  renameCommand.ts |   85.71 |    86.04 |     100 |   85.71 | ...02-209,216-221 
  ...oreCommand.ts |   90.47 |    84.61 |     100 |   90.47 | ...32-137,167-168 
  resumeCommand.ts |     100 |      100 |     100 |     100 |                   
  rewindCommand.ts |      80 |      100 |      50 |      80 | 19-21             
  ...ngsCommand.ts |     100 |      100 |     100 |     100 |                   
  ...hubCommand.ts |   81.43 |    65.21 |      80 |   81.43 | ...70-173,176-179 
  skillsCommand.ts |   84.12 |    76.92 |     100 |   84.12 | 36-44,68          
  statsCommand.ts  |   91.48 |    89.47 |     100 |   91.48 | 40-43,134-141     
  ...ineCommand.ts |     100 |      100 |     100 |     100 |                   
  ...aryCommand.ts |    6.46 |      100 |      50 |    6.46 | 31-329            
  tasksCommand.ts  |   77.22 |    72.13 |     100 |   77.22 | ...46-150,172-177 
  ...tupCommand.ts |     100 |      100 |     100 |     100 |                   
  themeCommand.ts  |     100 |      100 |     100 |     100 |                   
  toolsCommand.ts  |     100 |      100 |     100 |     100 |                   
  trustCommand.ts  |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
  vimCommand.ts    |   54.54 |      100 |      50 |   54.54 | 19-29             
 src/ui/components |   62.14 |    77.13 |   60.34 |   62.14 |                   
  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 |   16.27 |      100 |       0 |   16.27 | 19-58             
  ...TextInput.tsx |   77.01 |       76 |     100 |   77.01 | ...20,234-236,263 
  Composer.tsx     |    81.6 |     64.7 |     100 |    81.6 | ...90,108,160,173 
  ...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 
  ...ification.tsx |   28.57 |      100 |       0 |   28.57 | 16-36             
  ...gProfiler.tsx |       0 |        0 |       0 |       0 | 1-36              
  ...ogManager.tsx |   11.95 |      100 |       0 |   11.95 | 68-537            
  DiffDialog.tsx   |    2.47 |      100 |       0 |    2.47 | 68-732            
  ...ngsDialog.tsx |    8.44 |      100 |       0 |    8.44 | 37-195            
  ExitWarning.tsx  |     100 |      100 |     100 |     100 |                   
  ...hProgress.tsx |    87.8 |    33.33 |     100 |    87.8 | 28-31,56          
  ...ustDialog.tsx |     100 |      100 |     100 |     100 |                   
  Footer.tsx       |   77.12 |    52.27 |     100 |   77.12 | ...43,167,188-193 
  ...ngSpinner.tsx |   68.42 |       80 |      50 |   68.42 | 35-52,73,80-81    
  GoalPill.tsx     |   76.19 |    81.81 |     100 |   76.19 | 24-30,46-50       
  Header.tsx       |   98.62 |    94.28 |     100 |   98.62 | 162,164           
  Help.tsx         |   98.32 |       90 |     100 |   98.32 | ...24,381,447-448 
  ...emDisplay.tsx |   61.41 |    34.61 |     100 |   61.41 | ...51,354,357-363 
  ...ngeDialog.tsx |     100 |      100 |     100 |     100 |                   
  InputPrompt.tsx  |    81.2 |    79.38 |   83.33 |    81.2 | ...1627,1642,1692 
  ...Shortcuts.tsx |   20.87 |      100 |       0 |   20.87 | ...6,49-51,67-125 
  ...Indicator.tsx |     100 |    91.42 |     100 |     100 | 65,74             
  ...firmation.tsx |   91.42 |      100 |      50 |   91.42 | 26-31             
  MainContent.tsx  |   86.93 |    87.17 |   66.66 |   86.93 | ...26,284,343-347 
  MemoryDialog.tsx |   61.87 |    76.05 |    62.5 |   61.87 | ...72,391,428-430 
  ...geDisplay.tsx |       0 |        0 |       0 |       0 | 1-41              
  ModelDialog.tsx  |   85.19 |    69.17 |     100 |   85.19 | ...80-596,653-657 
  ...tsDisplay.tsx |     100 |    97.22 |     100 |     100 | 270               
  ...fications.tsx |   18.18 |      100 |       0 |   18.18 | 15-58             
  ...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           
  ...dSelector.tsx |   87.11 |     73.8 |     100 |   87.11 | ...48,354-370,406 
  ...ionPicker.tsx |   83.66 |    72.13 |     100 |   83.66 | ...96,402,444-466 
  ...onPreview.tsx |   92.42 |    84.37 |     100 |   92.42 | ...,70-71,143-145 
  ...ryDisplay.tsx |     100 |      100 |     100 |     100 |                   
  ...putPrompt.tsx |   72.56 |       80 |      40 |   72.56 | ...06-109,114-117 
  ...tedDialog.tsx |     100 |      100 |     100 |     100 |                   
  ...ngsDialog.tsx |   66.31 |    71.16 |      75 |   66.31 | ...16-824,830-831 
  ...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             
  ...ionPicker.tsx |   17.59 |      100 |       0 |   17.59 | 55-172            
  ...tivityTab.tsx |    3.94 |      100 |       0 |    3.94 | 27-275            
  StatsDialog.tsx  |    8.85 |      100 |       0 |    8.85 | ...5,49-84,92-238 
  StatsDisplay.tsx |     100 |      100 |     100 |     100 |                   
  ...ciencyTab.tsx |    3.28 |      100 |       0 |    3.28 | 25-258            
  ...atmapView.tsx |    8.98 |      100 |       0 |    8.98 | 20-107            
  ...essionTab.tsx |    5.46 |      100 |       0 |    5.46 | 24-215            
  ...ineDialog.tsx |    93.5 |    85.18 |     100 |    93.5 | ...05,267,287-289 
  ...yTodoList.tsx |   96.33 |    88.23 |     100 |   96.33 | 137-140           
  ...nsDisplay.tsx |   87.25 |       64 |     100 |   87.25 | ...57-159,166-168 
  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 |    81.81 |     100 |     100 | 71-86             
  ...ification.tsx |   36.36 |      100 |       0 |   36.36 | 15-22             
  ...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 |   91.42 |    64.28 |     100 |   91.42 | 15,21,24          
  ...s-helpers.tsx |      25 |      100 |       0 |      25 | ...3,86-89,94-102 
 ...nts/agent-view |   38.55 |    70.83 |   36.36 |   38.55 |                   
  ...atContent.tsx |    8.79 |      100 |       0 |    8.79 | 53-265,271-273    
  ...tChatView.tsx |   21.05 |      100 |       0 |   21.05 | 21-39             
  ...tComposer.tsx |   10.84 |      100 |       0 |   10.84 | 59-308            
  AgentFooter.tsx  |   17.07 |      100 |       0 |   17.07 | 28-66             
  AgentHeader.tsx  |   15.38 |      100 |       0 |   15.38 | 27-64             
  AgentTabBar.tsx  |    87.8 |    27.27 |     100 |    87.8 | ...,85,95-103,121 
  ...oryAdapter.ts |     100 |    91.83 |     100 |     100 | 103,109-110,138   
  index.ts         |       0 |        0 |       0 |       0 | 1-12              
 ...mponents/arena |   45.59 |    70.53 |   60.86 |   45.59 |                   
  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.92 |      100 |       0 |    9.92 | 27-164            
  ...tusDialog.tsx |    5.63 |      100 |       0 |    5.63 | 33-75,80-288      
  ...topDialog.tsx |    6.17 |      100 |       0 |    6.17 | 33-213            
 ...ackground-view |   79.76 |    82.24 |   91.17 |   79.76 |                   
  ...sksDialog.tsx |   76.68 |       80 |   85.71 |   76.68 | ...1139,1215-1217 
  ...TasksPill.tsx |   63.75 |    86.95 |     100 |   63.75 | 44,86-106,114-122 
  ...gentPanel.tsx |    97.4 |    86.31 |     100 |    97.4 | 123,434-438       
 ...nts/extensions |   45.28 |    33.33 |      60 |   45.28 |                   
  ...gerDialog.tsx |   44.31 |    34.14 |      75 |   44.31 | ...71-480,483-488 
  index.ts         |       0 |        0 |       0 |       0 | 1-9               
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...tensions/steps |   54.88 |    94.23 |   66.66 |   54.88 |                   
  ...ctionStep.tsx |   95.12 |    92.85 |   85.71 |   95.12 | 84-86,89          
  ...etailStep.tsx |    6.18 |      100 |       0 |    6.18 | 20-131            
  ...nListStep.tsx |   88.43 |    94.73 |      80 |   88.43 | 52-53,59-72,106   
  ...electStep.tsx |   13.46 |      100 |       0 |   13.46 | 20-70             
  ...nfirmStep.tsx |   19.56 |      100 |       0 |   19.56 | 23-65             
  index.ts         |     100 |      100 |     100 |     100 |                   
 ...mponents/hooks |   86.85 |    81.37 |   91.89 |   86.85 |                   
  ...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 |   20.98 |    86.36 |   83.33 |   20.98 |                   
  ...ealthPill.tsx |   68.42 |    85.71 |     100 |   68.42 | 40-46             
  ...entDialog.tsx |    3.64 |      100 |       0 |    3.64 | 41-717            
  constants.ts     |     100 |      100 |     100 |     100 |                   
  index.ts         |       0 |        0 |       0 |       0 | 1-30              
  types.ts         |     100 |      100 |     100 |     100 |                   
  utils.ts         |   95.83 |    88.88 |     100 |   95.83 | 16,20,109-110     
 ...ents/mcp/steps |   26.74 |    54.54 |   42.85 |   26.74 |                   
  ...icateStep.tsx |    5.88 |      100 |       0 |    5.88 | 40-55,58-296      
  ...electStep.tsx |   10.95 |      100 |       0 |   10.95 | 16-88             
  ...etailStep.tsx |    5.26 |      100 |       0 |    5.26 | 31-247            
  ...rListStep.tsx |   75.18 |    59.37 |     100 |   75.18 | ...53-158,169-173 
  ...etailStep.tsx |   10.41 |      100 |       0 |   10.41 | ...1,67-79,82-139 
  ToolListStep.tsx |   69.02 |       50 |     100 |   69.02 | ...22,125,134-143 
 ...nents/messages |   83.06 |    80.02 |    75.6 |   83.06 |                   
  ...ionDialog.tsx |   80.84 |     77.6 |    62.5 |   80.84 | ...98,516,534-536 
  BtwMessage.tsx   |     100 |      100 |     100 |     100 |                   
  ...upDisplay.tsx |   97.67 |    83.72 |     100 |   97.67 | 119,142,150       
  ...onMessage.tsx |   91.93 |    82.35 |     100 |   91.93 | 57-59,61,63       
  ...nMessages.tsx |   79.06 |      100 |      70 |   79.06 | ...51-264,268-280 
  DiffRenderer.tsx |   93.19 |    86.17 |     100 |   93.19 | ...09,237-238,304 
  ...tsDisplay.tsx |   97.82 |    77.27 |     100 |   97.82 | 87,89             
  ...usMessage.tsx |   76.31 |     42.1 |   66.66 |   76.31 | ...99,101,124,155 
  ...tsDisplay.tsx |    95.1 |    88.05 |     100 |    95.1 | ...29,131,164-169 
  ...ssMessage.tsx |    12.5 |      100 |       0 |    12.5 | 18-59             
  ...edMessage.tsx |   16.66 |      100 |       0 |   16.66 | 22-38             
  ...sMessages.tsx |   55.67 |       40 |   28.57 |   55.67 | ...20-125,133-145 
  ...ryMessage.tsx |   14.28 |      100 |       0 |   14.28 | 23-62             
  ...onMessage.tsx |   81.98 |     72.6 |   33.33 |   81.98 | ...65-467,474-476 
  ...upMessage.tsx |   82.63 |    92.85 |     100 |   82.63 | ...85-412,434-449 
  ToolMessage.tsx  |    87.8 |    73.28 |    92.3 |    87.8 | ...59-764,791-793 
 ...ponents/shared |    84.3 |    80.39 |    95.5 |    84.3 |                   
  ...ctionList.tsx |   99.14 |       96 |     100 |   99.14 | 99                
  ...tonSelect.tsx |     100 |      100 |     100 |     100 |                   
  EnumSelector.tsx |     100 |    96.42 |     100 |     100 | 58                
  MaxSizedBox.tsx  |   83.01 |    86.25 |   88.88 |   83.01 | ...12-513,618-619 
  MultiSelect.tsx  |   93.58 |       75 |     100 |   93.58 | ...43,199-201,211 
  ...tonSelect.tsx |     100 |      100 |     100 |     100 |                   
  ...eSelector.tsx |     100 |       60 |     100 |     100 | 40-45             
  ...lableList.tsx |   76.25 |    81.81 |     100 |   76.25 | 44-58,65-68       
  StaticRender.tsx |   72.72 |      100 |     100 |   72.72 | 31-33             
  TextInput.tsx    |    80.8 |    66.07 |      80 |    80.8 | ...36-240,252-258 
  ...apsedTime.tsx |     100 |      100 |     100 |     100 |                   
  ...Indicator.tsx |     100 |      100 |     100 |     100 |                   
  ...lizedList.tsx |   84.26 |    80.88 |      90 |   84.26 | ...68-696,743-765 
  text-buffer.ts   |   85.67 |    80.84 |   97.91 |   85.67 | ...2616,2714-2715 
  ...er-actions.ts |   73.93 |    67.22 |     100 |   73.93 | ...32-733,934-936 
 ...ponents/skills |    3.64 |      100 |       0 |    3.64 |                   
  ...gerDialog.tsx |    3.64 |      100 |       0 |    3.64 | ...90-148,151-691 
 ...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.51 |    59.52 |   27.27 |   21.51 |                   
  ...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.42 |    59.52 |     100 |   35.42 | ...20-432,437-439 
  ...iewerStep.tsx |   13.72 |      100 |       0 |   13.72 | 18-73             
  ...gerDialog.tsx |    6.74 |      100 |       0 |    6.74 | 35-341            
 ...mponents/views |   70.21 |    67.32 |    64.7 |   70.21 |                   
  ContextUsage.tsx |   70.88 |    63.88 |      80 |   70.88 | ...20-426,463-557 
  DoctorReport.tsx |     9.8 |      100 |       0 |     9.8 | 25-54,57-131      
  ...sionsList.tsx |   87.69 |    73.68 |     100 |   87.69 | 65-72             
  McpStatus.tsx    |   89.53 |    60.52 |     100 |   89.53 | ...72,175-177,262 
  SkillsList.tsx   |   27.27 |      100 |       0 |   27.27 | 18-35             
  ToolsList.tsx    |     100 |      100 |     100 |     100 |                   
 src/ui/contexts   |   77.81 |    78.32 |   81.03 |   77.81 |                   
  ...ewContext.tsx |   65.07 |    88.88 |      50 |   65.07 | ...23-226,232-242 
  AppContext.tsx   |      80 |       50 |     100 |      80 | 19-20             
  ...ewContext.tsx |    93.3 |    64.28 |      50 |    93.3 | ...35-236,263-267 
  ...deContext.tsx |     100 |      100 |     100 |     100 |                   
  ...igContext.tsx |   81.81 |       50 |     100 |   81.81 | 15-16             
  ...ssContext.tsx |   82.35 |    82.84 |     100 |   82.35 | ...1159,1165-1167 
  ...owContext.tsx |   91.07 |    81.81 |     100 |   91.07 | 47-48,60-62       
  ...deContext.tsx |     100 |      100 |      50 |     100 |                   
  ...onContext.tsx |   43.28 |     62.5 |    62.5 |   43.28 | ...56-259,263-266 
  ...gsContext.tsx |   83.33 |       50 |     100 |   83.33 | 17-18             
  ...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             
  ...nsContext.tsx |   88.23 |       50 |     100 |   88.23 | 132-133           
  ...teContext.tsx |   86.66 |       50 |     100 |   86.66 | 198-199           
  ...deContext.tsx |      80 |     87.5 |      75 |      80 | ...11-112,118-120 
 src/ui/daemon     |   90.76 |    73.73 |   95.45 |   90.76 |                   
  ...TuiAdapter.ts |   90.76 |    73.73 |   95.45 |   90.76 | ...53,771-772,858 
 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      |   81.59 |    80.85 |   86.23 |   81.59 |                   
  ...dProcessor.ts |   83.12 |    82.56 |     100 |   83.12 | ...88-389,408-435 
  keyToAnsi.ts     |    3.92 |      100 |       0 |    3.92 | 19-77             
  ...dProcessor.ts |    94.8 |    70.58 |     100 |    94.8 | ...76-277,282-283 
  ...dProcessor.ts |   83.94 |    62.56 |      80 |   83.94 | ...1010,1031-1035 
  ...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 |      32 |       60 |     100 |      32 | 42-44,51-90       
  ...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 |   92.81 |    89.09 |     100 |   92.81 | ...86-187,224-227 
  ...ifications.ts |   86.91 |    96.29 |     100 |   86.91 | 116-130           
  ...tIndicator.ts |   83.49 |    70.96 |     100 |   83.49 | ...60,168,170-178 
  ...waySummary.ts |   96.22 |    69.69 |     100 |   96.22 | 125-127,169       
  ...ndTaskView.ts |   94.21 |    76.08 |     100 |   94.21 | 122-126,213,219   
  ...chedScroll.ts |     100 |      100 |     100 |     100 |                   
  ...ketedPaste.ts |    23.8 |      100 |       0 |    23.8 | 19-37             
  ...nchCommand.ts |   94.36 |    74.35 |     100 |   94.36 | ...60,168-169,209 
  ...ompletion.tsx |   96.01 |    83.87 |     100 |   96.01 | ...22-223,225-226 
  ...dMigration.ts |   90.62 |       75 |     100 |   90.62 | 38-40             
  useCompletion.ts |    92.4 |     87.5 |     100 |    92.4 | 68-69,93-94,98-99 
  ...nitMessage.ts |     100 |      100 |     100 |     100 |                   
  ...extualTips.ts |   77.27 |       50 |     100 |   77.27 | ...2,75-79,93-101 
  ...eteCommand.ts |   78.53 |    88.57 |     100 |   78.53 | ...96-104,112-113 
  ...ialogClose.ts |    12.5 |      100 |     100 |    12.5 | 85-181            
  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.45 |     92.3 |     100 |   93.45 | ...83-287,300-306 
  ...agerDialog.ts |   88.88 |      100 |     100 |   88.88 | 21,25             
  ...backDialog.ts |    63.9 |    76.47 |   66.66 |    63.9 | ...66-168,190-191 
  useFocus.ts      |     100 |      100 |     100 |     100 |                   
  ...olderTrust.ts |     100 |      100 |     100 |     100 |                   
  ...ggestions.tsx |   89.15 |     62.5 |      50 |   89.15 | ...22-124,149-150 
  ...miniStream.ts |   79.08 |    76.39 |    92.3 |   79.08 | ...2608,2659-2667 
  ...BranchName.ts |    90.9 |     92.3 |     100 |    90.9 | 19-20,55-58       
  ...oryManager.ts |   96.92 |    96.29 |     100 |   96.92 | 52,139-142,218    
  ...ooksDialog.ts |    87.5 |      100 |     100 |    87.5 | 19,23             
  ...stListener.ts |     100 |      100 |     100 |     100 |                   
  ...nAuthError.ts |   76.19 |       50 |     100 |   76.19 | 39-40,43-45       
  ...putHistory.ts |   92.59 |    85.71 |     100 |   92.59 | 63-64,72,94-96    
  ...storyStore.ts |     100 |    94.11 |     100 |     100 | 69                
  useKeypress.ts   |     100 |      100 |     100 |     100 |                   
  ...rdProtocol.ts |   36.36 |      100 |       0 |   36.36 | 24-31             
  ...unchEditor.ts |    9.67 |      100 |       0 |    9.67 | 11-32,39-90       
  ...gIndicator.ts |     100 |      100 |     100 |     100 |                   
  useLogger.ts     |   21.05 |      100 |       0 |   21.05 | 15-37             
  useMCPHealth.ts  |   63.15 |       75 |      50 |   63.15 | 42-52,64-67       
  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 |      100 |     100 |     100 |                   
  ...delCommand.ts |     100 |       75 |     100 |     100 | 22                
  ...ouseEvents.ts |   87.17 |    88.88 |   66.66 |   87.17 | 81-82,86-88       
  ...raseCycler.ts |   84.74 |    76.47 |     100 |   84.74 | ...49,52-53,69-71 
  ...rredEditor.ts |   58.33 |    22.22 |     100 |   58.33 | 23-27,29-33       
  ...derUpdates.ts |   86.49 |    77.96 |    90.9 |   86.49 | ...26,288-300,348 
  useQwenAuth.ts   |     100 |      100 |     100 |     100 |                   
  ...lScheduler.ts |    84.7 |    93.33 |     100 |    84.7 | ...71-276,372-382 
  ...oryCommand.ts |       0 |        0 |       0 |       0 | 1-7               
  ...umeCommand.ts |   96.96 |    83.33 |     100 |   96.96 | 101-102,131       
  ...ompletion.tsx |   90.59 |    83.33 |     100 |   90.59 | ...01,104,137-140 
  ...ectionList.ts |   97.05 |    96.11 |     100 |   97.05 | ...90-191,245-248 
  ...sionPicker.ts |   92.87 |    90.35 |     100 |   92.87 | ...99-501,503-505 
  ...earchInput.ts |     100 |      100 |     100 |     100 |                   
  ...ngsCommand.ts |   18.75 |      100 |       0 |   18.75 | 10-25             
  ...ellHistory.ts |   91.74 |    79.41 |     100 |   91.74 | ...74,122-123,133 
  ...oryCommand.ts |       0 |        0 |       0 |       0 | 1-73              
  ...agerDialog.ts |   88.23 |      100 |     100 |   88.23 | 20,24             
  ...Completion.ts |   82.73 |    85.41 |   94.73 |   82.73 | ...70-672,680-716 
  ...tateAndRef.ts |     100 |      100 |     100 |     100 |                   
  ...tatsDialog.ts |     100 |      100 |     100 |     100 |                   
  useStatusLine.ts |    96.3 |    92.19 |     100 |    96.3 | ...77-380,466-473 
  ...eateDialog.ts |   88.23 |      100 |     100 |   88.23 | 14,18             
  ...mInProcess.ts |   27.35 |       80 |      25 |   27.35 | ...82-183,186-188 
  ...tification.ts |     100 |     87.5 |     100 |     100 | 50                
  ...alProgress.ts |   53.06 |       50 |   66.66 |   53.06 | ...53,61-68,79-85 
  ...rminalSize.ts |   76.19 |      100 |      50 |   76.19 | 21-25             
  ...emeCommand.ts |   67.01 |    29.41 |     100 |   67.01 | ...10-111,115-116 
  useTimer.ts      |   88.09 |    85.71 |     100 |   88.09 | 44-45,51-53       
  ...lMigration.ts |       0 |        0 |       0 |       0 |                   
  ...rustModify.ts |     100 |      100 |     100 |     100 |                   
  useTurnDiffs.ts  |   95.12 |    78.57 |     100 |   95.12 | 133-134,156-157   
  ...elcomeBack.ts |   87.36 |     90.9 |     100 |   87.36 | ...,94-96,114-115 
  ...reeSession.ts |   93.75 |       70 |     100 |   93.75 | 44-45,87          
  vim.ts           |   74.37 |    67.77 |   69.23 |   74.37 | ...1842-1849,1857 
 src/ui/layouts    |    90.9 |    90.62 |     100 |    90.9 |                   
  ...AppLayout.tsx |   90.72 |       90 |     100 |   90.72 | 57-59,101-106     
  ...AppLayout.tsx |   91.17 |    91.66 |     100 |   91.17 | 70-75             
 src/ui/models     |   80.24 |    79.16 |   71.42 |   80.24 |                   
  ...ableModels.ts |   80.24 |    79.16 |   71.42 |   80.24 | ...,61-71,123-125 
 ...noninteractive |     100 |      100 |   14.28 |     100 |                   
  ...eractiveUi.ts |     100 |      100 |   14.28 |     100 |                   
 src/ui/state      |   94.91 |    81.81 |     100 |   94.91 |                   
  extensions.ts    |   94.91 |    81.81 |     100 |   94.91 | 68-69,88          
 src/ui/themes     |   98.53 |    70.58 |     100 |   98.53 |                   
  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   |     100 |      100 |     100 |     100 |                   
  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 |   87.98 |    82.89 |     100 |   87.98 | ...48-357,362-363 
  theme.ts         |     100 |    38.02 |     100 |     100 | ...34-449,457-461 
  xcode.ts         |     100 |      100 |     100 |     100 |                   
 src/ui/utils      |   83.32 |    82.82 |   92.77 |   83.32 |                   
  ...Colorizer.tsx |   79.53 |    83.78 |     100 |   79.53 | ...51-152,249-275 
  ...nRenderer.tsx |   68.83 |    70.14 |      50 |   68.83 | ...52-254,274-293 
  ...wnDisplay.tsx |   86.01 |    87.66 |     100 |   86.01 | ...87,704,729-754 
  ...idDiagram.tsx |   87.79 |    95.34 |     100 |   87.79 | 156-179           
  ...eRenderer.tsx |   92.08 |    80.45 |      95 |   92.08 | ...76-679,723-728 
  ...odeDisplay.ts |   96.55 |     90.9 |     100 |   96.55 | 34                
  asciiCharts.ts   |   96.77 |    87.62 |     100 |   96.77 | 173-180,281       
  ...dWorkUtils.ts |     100 |      100 |     100 |     100 |                   
  ...boardUtils.ts |   49.89 |    71.79 |    90.9 |   49.89 | ...79,582-591,594 
  commandUtils.ts  |    95.9 |    88.42 |     100 |    95.9 | ...66,168-169,293 
  computeStats.ts  |     100 |      100 |     100 |     100 |                   
  customBanner.ts  |   90.68 |    91.22 |     100 |   90.68 | ...13,324-327,334 
  displayUtils.ts  |   88.37 |    72.22 |     100 |   88.37 | 23,25,29,31,33    
  formatters.ts    |   95.23 |     98.3 |     100 |   95.23 | 117-120           
  gradientUtils.ts |     100 |      100 |     100 |     100 |                   
  highlight.ts     |     100 |      100 |     100 |     100 |                   
  ...oryMapping.ts |     100 |    96.55 |     100 |     100 | 43                
  historyUtils.ts  |   94.11 |       94 |     100 |   94.11 | 94-97             
  isNarrowWidth.ts |     100 |      100 |     100 |     100 |                   
  ...olDetector.ts |    8.23 |      100 |       0 |    8.23 | ...31-132,135-136 
  latexRenderer.ts |   94.95 |     73.8 |     100 |   94.95 | ...76-178,184-187 
  layoutUtils.ts   |     100 |      100 |     100 |     100 |                   
  ...ightLoader.ts |     100 |    89.47 |     100 |     100 | 81,110            
  ...nUtilities.ts |   69.84 |    85.71 |     100 |   69.84 | 75-91,100-101     
  ...ToolGroups.ts |   98.66 |    96.77 |     100 |   98.66 | 48-49             
  ...geRenderer.ts |   86.23 |    69.06 |   95.12 |   86.23 | ...1284,1324-1330 
  ...alRenderer.ts |   86.69 |     71.9 |     100 |   86.69 | ...1476,1513-1519 
  ...lsBySource.ts |     100 |    95.23 |     100 |     100 | 84                
  mouse.ts         |   90.71 |    73.33 |   88.88 |   90.71 | ...40-143,200-201 
  osc8.ts          |   94.73 |    87.75 |     100 |   94.73 | ...49,434,438-439 
  ...mConstants.ts |     100 |      100 |     100 |     100 |                   
  restoreGoal.ts   |   98.98 |    97.05 |     100 |   98.98 | 98                
  ...storyUtils.ts |   62.74 |    71.26 |      90 |   62.74 | ...84,432,437-459 
  ...ickerUtils.ts |     100 |      100 |     100 |     100 |                   
  ...ataService.ts |   93.17 |     80.3 |     100 |   93.17 | ...14,227,254-256 
  ...izedOutput.ts |   94.94 |      100 |   88.88 |   94.94 | 112-117           
  ...wOptimizer.ts |     100 |    96.77 |     100 |     100 | 69                
  terminalSetup.ts |    4.37 |      100 |       0 |    4.37 | 44-393            
  textUtils.ts     |   97.61 |    94.84 |   92.85 |   97.61 | ...50-251,386-387 
  todoSnapshot.ts  |   89.33 |    93.47 |     100 |   89.33 | ...,66-78,180-181 
  updateCheck.ts   |     100 |    80.95 |     100 |     100 | 30-42             
 ...i/utils/export |   56.77 |     40.8 |   79.41 |   56.77 |                   
  collect.ts       |   55.92 |    50.58 |   86.36 |   55.92 | ...25-640,642-647 
  index.ts         |     100 |      100 |     100 |     100 |                   
  normalize.ts     |   57.47 |    20.51 |      80 |   57.47 | ...09-310,324-359 
  types.ts         |       0 |        0 |       0 |       0 | 1                 
  utils.ts         |      40 |      100 |       0 |      40 | 11-13             
 ...ort/formatters |    3.38 |      100 |       0 |    3.38 |                   
  html.ts          |    9.61 |      100 |       0 |    9.61 | ...28,34-76,82-84 
  json.ts          |      50 |      100 |       0 |      50 | 14-15             
  jsonl.ts         |     3.5 |      100 |       0 |     3.5 | 14-76             
  markdown.ts      |    0.94 |      100 |       0 |    0.94 | 13-295            
 src/utils         |   72.24 |    89.13 |   90.43 |   72.24 |                   
  acpModelUtils.ts |     100 |      100 |     100 |     100 |                   
  apiPreconnect.ts |   96.72 |    97.14 |     100 |   96.72 | 165-168           
  checks.ts        |   33.33 |      100 |       0 |   33.33 | 23-28             
  cleanup.ts       |   84.12 |    93.33 |      80 |   84.12 | 75,106-115        
  commands.ts      |     100 |      100 |     100 |     100 |                   
  commentJson.ts   |   90.51 |    91.89 |     100 |   90.51 | 67-76,116         
  ...Calculator.ts |     100 |      100 |     100 |     100 |                   
  cpuProfiler.ts   |   70.38 |    71.83 |   88.88 |   70.38 | ...27,430-431,438 
  deepMerge.ts     |     100 |       90 |     100 |     100 | 41-43,49          
  ...ScopeUtils.ts |   97.56 |    88.88 |     100 |   97.56 | 67                
  doctorChecks.ts  |   70.31 |    74.57 |     100 |   70.31 | ...95-301,325-341 
  ...putCapture.ts |   90.65 |    86.17 |     100 |   90.65 | ...72,370,372-373 
  ...arResolver.ts |   97.14 |    96.42 |     100 |   97.14 | 125-126           
  errors.ts        |   90.85 |    96.36 |    92.3 |   90.85 | 69-70,298-310     
  events.ts        |     100 |      100 |     100 |     100 |                   
  gitUtils.ts      |   91.91 |    84.61 |     100 |   91.91 | 78-81,124-127     
  ...AutoUpdate.ts |    92.2 |    95.23 |   88.88 |    92.2 | 130-141           
  ...tyWarnings.ts |     100 |      100 |     100 |     100 |                   
  ...lationInfo.ts |   89.17 |    92.77 |     100 |   89.17 | ...55,272-273,318 
  languageUtils.ts |   97.89 |    96.42 |     100 |   97.89 | 132-133           
  math.ts          |       0 |        0 |       0 |       0 | 1-15              
  ...iagnostics.ts |   94.57 |    83.01 |   88.88 |   94.57 | ...05,311,315-317 
  ...onfigUtils.ts |     100 |      100 |     100 |     100 |                   
  ...iveHelpers.ts |   96.79 |    93.28 |     100 |   96.79 | ...76-477,575,588 
  osc.ts           |    97.5 |      100 |   88.88 |    97.5 | 195-196           
  package.ts       |   88.88 |       80 |     100 |   88.88 | 33-34             
  processUtils.ts  |     100 |      100 |     100 |     100 |                   
  readStdin.ts     |   79.62 |       90 |      80 |   79.62 | 33-40,52-54       
  relaunch.ts      |   93.22 |    81.25 |     100 |   93.22 | 65-67,80          
  resolvePath.ts   |   66.66 |       25 |     100 |   66.66 | 12-13,16,18-19    
  runBudget.ts     |   99.35 |    96.77 |     100 |   99.35 | 119               
  sandbox.ts       |       0 |        0 |       0 |       0 | 1-1047            
  sessionPaths.ts  |   90.84 |    90.56 |     100 |   90.84 | ...81-182,185-186 
  settingsUtils.ts |   82.51 |    91.72 |   89.74 |   82.51 | ...76-694,701-709 
  spawnWrapper.ts  |     100 |      100 |     100 |     100 |                   
  ...ate-verify.ts |     100 |      100 |     100 |     100 |                   
  ...one-update.ts |   26.82 |    73.77 |   43.47 |   26.82 | ...36-837,840-859 
  ...upProfiler.ts |   98.46 |    94.52 |     100 |   98.46 | 130-131,305       
  ...upWarnings.ts |     100 |      100 |     100 |     100 |                   
  stdioHelpers.ts  |     100 |       60 |     100 |     100 | 23,32             
  systemInfo.ts    |   95.12 |    89.06 |     100 |   95.12 | ...43-244,249-253 
  ...InfoFields.ts |    87.5 |       65 |     100 |    87.5 | ...24-125,146-147 
  ...alSequence.ts |     100 |    95.23 |     100 |     100 | 60,90             
  ...iffPreview.ts |   94.11 |    83.33 |     100 |   94.11 | 13                
  ...entEmitter.ts |     100 |      100 |     100 |     100 |                   
  ...ansionHook.ts |     100 |      100 |     100 |     100 |                   
  ...upWarnings.ts |   91.17 |    82.35 |     100 |   91.17 | 67-68,73-74,77-78 
  version.ts       |     100 |       50 |     100 |     100 | 11                
  ...ingHandler.ts |     100 |      100 |     100 |     100 |                   
  windowTitle.ts   |     100 |      100 |     100 |     100 |                   
  ...WithBackup.ts |    62.1 |       75 |     100 |    62.1 | 93,107,118-157    
 ...s/housekeeping |   90.15 |     89.7 |   94.11 |   90.15 |                   
  cleanup.ts       |   94.33 |       95 |     100 |   94.33 | 60-62             
  ...eractionAt.ts |     100 |      100 |     100 |     100 |                   
  scheduler.ts     |   89.71 |    88.23 |   85.71 |   89.71 | 51-55,66,116-120  
  throttledOnce.ts |   86.66 |    85.18 |     100 |   86.66 | ...99,105,137-138 
-------------------|---------|----------|---------|---------|-------------------
Core Package - Full Text Report
-------------------|---------|----------|---------|---------|-------------------
File               | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-------------------|---------|----------|---------|---------|-------------------
All files          |   81.63 |    83.75 |   83.65 |   81.63 |                   
 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        |   88.08 |    79.77 |   92.13 |   88.08 |                   
  ...transcript.ts |   92.25 |    85.71 |     100 |   92.25 | ...87,306-307,438 
  ...ent-resume.ts |   82.84 |    71.63 |   77.41 |   82.84 | ...1061-1065,1068 
  ...ound-tasks.ts |   95.76 |    87.57 |     100 |   95.76 | ...26-827,898-899 
  index.ts         |     100 |      100 |     100 |     100 |                   
 src/agents/arena  |   76.54 |    66.87 |   78.72 |   76.54 |                   
  ...gentClient.ts |   79.47 |    88.88 |   81.81 |   79.47 | ...68-183,189-204 
  ArenaManager.ts  |   75.37 |    63.37 |   78.26 |   75.37 | ...1860,1866-1867 
  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 |   76.43 |    86.23 |   73.04 |   76.43 |                   
  ITermBackend.ts  |   97.97 |    93.93 |     100 |   97.97 | ...78-180,255,307 
  ...essBackend.ts |   91.98 |     90.9 |   86.66 |   91.98 | ...95,250-270,329 
  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 |   84.28 |    82.05 |   76.86 |   84.28 |                   
  agent-context.ts |     100 |      100 |     100 |     100 |                   
  agent-core.ts    |   77.22 |    72.55 |   63.63 |   77.22 | ...1658,1685-1732 
  agent-events.ts  |     100 |      100 |     100 |     100 |                   
  ...t-headless.ts |   84.48 |    78.04 |   63.63 |   84.48 | ...00-401,404-405 
  ...nteractive.ts |   80.55 |    81.35 |   74.07 |   80.55 | ...79,481,483,486 
  ...statistics.ts |   98.19 |    82.35 |     100 |   98.19 | 127,151,192,225   
  agent-types.ts   |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...chestrator.ts |    95.6 |    85.71 |     100 |    95.6 | 211-214           
  ...ow-prompts.ts |     100 |      100 |     100 |     100 |                   
  ...ow-sandbox.ts |     100 |    98.09 |     100 |     100 | 117,270           
 src/agents/tasks  |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/agents/team   |   78.43 |    80.47 |   85.59 |   78.43 |                   
  TeamManager.ts   |   66.33 |    75.64 |    73.8 |   66.33 | ...1418,1441-1442 
  identity.ts      |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...sionBridge.ts |     100 |      100 |     100 |     100 |                   
  mailbox.ts       |   91.87 |    78.94 |    92.3 |   91.87 | ...99-200,321-327 
  ...ptAddendum.ts |     100 |      100 |     100 |     100 |                   
  tasks.ts         |   85.81 |     78.3 |   95.45 |   85.81 | ...86-889,933-934 
  team-events.ts   |   60.52 |      100 |      50 |   60.52 | ...37-141,148-152 
  teamHelpers.ts   |   91.66 |    94.33 |      95 |   91.66 | ...07-308,344-354 
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...eam/test-utils |   94.39 |    93.38 |   98.21 |   94.39 |                   
  ...on-harness.ts |   96.49 |    77.77 |     100 |   96.49 | 128-129,141-142   
  fake-agent.ts    |   98.49 |    95.08 |     100 |   98.49 | 201-203           
  fake-backend.ts  |   86.46 |    97.61 |   95.83 |   86.46 | 124-146           
 src/config        |   77.55 |    83.16 |   63.44 |   77.55 |                   
  config.ts        |   75.56 |     82.2 |   59.03 |   75.56 | ...4355,4360-4361 
  constants.ts     |     100 |      100 |     100 |     100 |                   
  models.ts        |     100 |      100 |     100 |     100 |                   
  storage.ts       |    94.9 |     90.9 |   90.24 |    94.9 | ...64-365,368-369 
 ...nfirmation-bus |   98.29 |    97.14 |     100 |   98.29 |                   
  message-bus.ts   |   98.14 |    97.05 |     100 |   98.14 | 42-43             
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/core          |   88.54 |    83.69 |   91.34 |   88.54 |                   
  baseLlmClient.ts |   81.25 |    76.47 |   77.77 |   81.25 | ...13,515-525,534 
  client.ts        |    85.8 |    79.95 |      86 |    85.8 | ...2294,2300-2312 
  ...tGenerator.ts |   84.86 |    69.23 |     100 |   84.86 | ...83,385,392-395 
  ...lScheduler.ts |   88.41 |    82.02 |   95.52 |   88.41 | ...3732,3760-3771 
  geminiChat.ts    |    91.1 |    87.92 |    96.1 |    91.1 | ...2950,3017-3018 
  geminiRequest.ts |     100 |      100 |     100 |     100 |                   
  ...htProtocol.ts |    9.09 |      100 |       0 |    9.09 | 34-42,45-49,52-87 
  logger.ts        |   87.41 |    87.02 |     100 |   87.41 | ...64-568,614-628 
  ...tyDefaults.ts |     100 |      100 |     100 |     100 |                   
  ...olExecutor.ts |   92.59 |       75 |      50 |   92.59 | 41-42             
  ...on-helpers.ts |   86.48 |    72.22 |     100 |   86.48 | ...97-198,212-221 
  ...issionFlow.ts |   98.75 |    95.83 |     100 |   98.75 | 93                
  prompts.ts       |   88.88 |    87.87 |   72.72 |   88.88 | ...-907,1110-1111 
  tokenLimits.ts   |     100 |    89.47 |     100 |     100 | 51-52             
  ...okTriggers.ts |   99.43 |    91.34 |     100 |   99.43 | 172,183           
  turn.ts          |   96.46 |    88.88 |     100 |   96.46 | ...32,445-446,494 
 ...ntentGenerator |   94.88 |    82.07 |      94 |   94.88 |                   
  ...tGenerator.ts |   96.29 |    83.18 |   92.85 |   96.29 | ...1,971,999-1001 
  converter.ts     |   94.51 |    80.72 |     100 |   94.51 | ...06-607,617,823 
  index.ts         |       0 |        0 |       0 |       0 | 1-21              
  usage.ts         |     100 |      100 |     100 |     100 |                   
 ...ntentGenerator |   91.53 |    71.64 |   93.33 |   91.53 |                   
  ...tGenerator.ts |      90 |    70.96 |   92.85 |      90 | ...80-286,304-305 
  index.ts         |     100 |       80 |     100 |     100 | 50                
 ...ntentGenerator |      94 |    83.93 |   91.17 |      94 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...tGenerator.ts |   93.87 |    82.37 |   90.62 |   93.87 | ...2,992-993,1021 
  ...tDetection.ts |     100 |      100 |     100 |     100 |                   
 ...ntentGenerator |   86.33 |    84.37 |   93.67 |   86.33 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  converter.ts     |   84.89 |    82.17 |   96.15 |   84.89 | ...1394,1610-1625 
  errorHandler.ts  |     100 |      100 |     100 |     100 |                   
  index.ts         |   54.54 |    68.75 |      50 |   54.54 | ...79,87-91,95-99 
  ...tGenerator.ts |    66.4 |    70.58 |   88.88 |    66.4 | ...51-157,168-169 
  pipeline.ts      |   94.32 |     86.4 |     100 |   94.32 | ...34-535,543,611 
  ...ureContext.ts |     100 |      100 |     100 |     100 |                   
  ...ingOptions.ts |       0 |        0 |       0 |       0 | 1                 
  ...CallParser.ts |   90.66 |    88.57 |     100 |   90.66 | ...15-319,349-350 
  ...kingParser.ts |     100 |    96.87 |     100 |     100 | 42                
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 ...rator/provider |   96.67 |    88.94 |   96.07 |   96.67 |                   
  dashscope.ts     |   97.37 |    91.39 |   93.33 |   97.37 | ...90-291,369-370 
  deepseek.ts      |   94.91 |    89.36 |     100 |   94.91 | ...31-132,145-146 
  default.ts       |   95.79 |    89.65 |   88.88 |   95.79 | 122-123,193-195   
  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 |                   
 src/extension     |   62.36 |    79.54 |   80.31 |   62.36 |                   
  ...-converter.ts |   66.27 |    52.45 |     100 |   66.27 | ...86-787,796-828 
  ...ionManager.ts |    47.1 |    82.06 |    65.9 |    47.1 | ...1405,1415-1434 
  ...onSettings.ts |   93.46 |    93.05 |     100 |   93.46 | ...17-221,228-232 
  ...-converter.ts |   54.88 |    94.44 |      60 |   54.88 | ...35-146,158-192 
  github.ts        |   46.41 |     87.3 |   63.63 |   46.41 | ...68-374,413-466 
  index.ts         |     100 |      100 |     100 |     100 |                   
  marketplace.ts   |   97.31 |    93.75 |     100 |   97.31 | ...65,185-186,275 
  npm.ts           |   59.01 |    71.69 |    87.5 |   59.01 | ...23-425,432-436 
  override.ts      |   94.11 |    88.88 |     100 |   94.11 | 63-64,81-82       
  redaction.ts     |     100 |      100 |     100 |     100 |                   
  settings.ts      |   66.26 |      100 |      50 |   66.26 | 81-108,143-149    
  storage.ts       |     100 |      100 |     100 |     100 |                   
  ...ableSchema.ts |     100 |      100 |     100 |     100 |                   
  variables.ts     |   88.75 |    83.33 |     100 |   88.75 | ...28-231,234-237 
 src/followup      |   55.57 |    84.14 |   81.25 |   55.57 |                   
  followupState.ts |      96 |    89.74 |     100 |      96 | 159-161,218-219   
  index.ts         |     100 |      100 |     100 |     100 |                   
  overlayFs.ts     |   95.06 |       84 |     100 |   95.06 | 78,108,122,133    
  speculation.ts   |   13.02 |      100 |   16.66 |   13.02 | 89-464,524-575    
  ...onToolGate.ts |     100 |    96.42 |     100 |     100 | 94                
  ...nGenerator.ts |    71.6 |    72.13 |   83.33 |    71.6 | ...88-246,316-318 
 src/generated     |       0 |        0 |       0 |       0 |                   
  git-commit.ts    |       0 |        0 |       0 |       0 | 1-10              
 src/goals         |   89.57 |    83.45 |   94.44 |   89.57 |                   
  ...eGoalStore.ts |    85.1 |    95.45 |   84.61 |    85.1 | ...63-166,174-182 
  goalHook.ts      |   97.26 |    91.48 |     100 |   97.26 | 100-105           
  goalJudge.ts     |   84.33 |    74.28 |     100 |   84.33 | ...57-358,366-368 
  index.ts         |     100 |      100 |     100 |     100 |                   
 src/hooks         |   86.68 |     85.3 |   87.83 |   86.68 |                   
  ...okRegistry.ts |   86.48 |    77.08 |     100 |   86.48 | ...41-344,362-369 
  ...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.35 |    90.69 |     100 |   96.35 | ...00-301,382,384 
  ...entHandler.ts |   95.27 |    86.74 |   94.11 |   95.27 | ...63,920-921,931 
  hookPlanner.ts   |   86.29 |    83.33 |   85.71 |   86.29 | ...15-219,226-237 
  hookRegistry.ts  |   90.17 |    83.33 |     100 |   90.17 | ...33,352,356,360 
  hookRunner.ts    |   62.42 |    72.04 |   66.66 |   62.42 | ...64-765,774-775 
  hookSystem.ts    |   86.78 |      100 |   68.88 |   86.78 | ...07-708,714-715 
  ...HookRunner.ts |   75.51 |     61.9 |      80 |   75.51 | ...05-406,424-425 
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...edCallback.ts |     100 |      100 |     100 |     100 |                   
  ...HookRunner.ts |   96.37 |     90.9 |      90 |   96.37 | 342-350,424-425   
  ...SkillHooks.ts |   78.75 |       75 |   66.66 |   78.75 | 62-66,137-152     
  ...oksManager.ts |   96.66 |    91.66 |     100 |   96.66 | ...90,209-210,223 
  ssrfGuard.ts     |   77.22 |    85.36 |     100 |   77.22 | ...57,261-267,273 
  stopHookCap.ts   |     100 |      100 |     100 |     100 |                   
  trustedHooks.ts  |      90 |    52.63 |     100 |      90 | ...53,66-67,97-98 
  types.ts         |   92.83 |       94 |    87.5 |   92.83 | ...87-488,573-577 
  urlValidator.ts  |     100 |      100 |     100 |     100 |                   
 src/ide           |   75.55 |    83.52 |   78.33 |   75.55 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  detect-ide.ts    |     100 |      100 |     100 |     100 |                   
  ide-client.ts    |   66.14 |    81.75 |   66.66 |   66.14 | ...7-968,997-1005 
  ide-installer.ts |   89.06 |    79.31 |     100 |   89.06 | ...36,143-147,160 
  ideContext.ts    |     100 |      100 |     100 |     100 |                   
  process-utils.ts |   84.84 |    71.79 |     100 |   84.84 | ...37,151,193-194 
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/lsp           |   42.41 |    52.21 |   52.14 |   42.41 |                   
  ...nfigLoader.ts |   70.27 |    35.89 |   94.73 |   70.27 | ...20-422,426-432 
  ...ionFactory.ts |   42.69 |    79.16 |      50 |   42.69 | ...62-413,419-436 
  ...Normalizer.ts |   23.09 |    13.72 |   30.43 |   23.09 | ...04-905,909-924 
  ...verManager.ts |   25.31 |    62.06 |   41.66 |   25.31 | ...85-704,710-740 
  ...eLspClient.ts |   32.77 |       80 |   17.64 |   32.77 | ...84-288,294-295 
  ...LspService.ts |   51.85 |    65.98 |   68.57 |   51.85 | ...1339,1399-1409 
  constants.ts     |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/mcp           |   78.75 |    75.45 |   75.92 |   78.75 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  ...h-provider.ts |   86.95 |      100 |   33.33 |   86.95 | ...,93,97,101-102 
  ...h-provider.ts |   73.82 |    53.92 |     100 |   73.82 | ...88-895,902-904 
  ...en-storage.ts |   98.64 |    97.72 |     100 |   98.64 | 88-89             
  oauth-utils.ts   |   70.58 |    85.29 |    90.9 |   70.58 | ...70-290,315-344 
  ...n-provider.ts |   89.83 |       96 |   45.45 |   89.83 | ...43,147,151-152 
 .../token-storage |   79.72 |    87.05 |   86.36 |   79.72 |                   
  ...en-storage.ts |     100 |      100 |     100 |     100 |                   
  ...en-storage.ts |   83.44 |    84.21 |   92.85 |   83.44 | ...68-178,186-187 
  ...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        |   73.19 |    77.21 |   72.39 |   73.19 |                   
  const.ts         |     100 |      100 |     100 |     100 |                   
  dream.ts         |      66 |    73.33 |      50 |      66 | 51,108-149        
  ...entPlanner.ts |   57.84 |    72.72 |   33.33 |   57.84 | ...35,140-147,152 
  entries.ts       |   63.77 |    79.16 |      50 |   63.77 | ...72-180,183-189 
  extract.ts       |   92.72 |    74.19 |     100 |   92.72 | ...32,151-154,211 
  ...entPlanner.ts |   67.59 |     73.8 |      50 |   67.59 | ...31,240-243,415 
  ...ionPlanner.ts |       0 |        0 |       0 |       0 | 1                 
  forget.ts        |      46 |    61.53 |   44.44 |      46 | ...05,212,215-347 
  indexer.ts       |    86.3 |       50 |     100 |    86.3 | ...56,62-63,75-76 
  manager.ts       |    75.5 |    81.04 |    75.6 |    75.5 | ...1292,1305-1307 
  memoryAge.ts     |   90.47 |    77.77 |     100 |   90.47 | 50-51             
  paths.ts         |   79.06 |    95.12 |     100 |   79.06 | 32-33,49-86       
  prompt.ts        |   94.85 |    78.57 |     100 |   94.85 | ...62,165,303-304 
  recall.ts        |   76.73 |    69.38 |   88.88 |   76.73 | ...72-277,301-312 
  ...ceSelector.ts |   91.86 |    77.27 |     100 |   91.86 | ...24,126-127,135 
  scan.ts          |   92.92 |    78.26 |     100 |   92.92 | ...51-52,62,90-91 
  ...entPlanner.ts |   58.33 |    66.66 |   56.25 |   58.33 | ...61-282,358-403 
  status.ts        |   10.52 |      100 |       0 |   10.52 | 41-98             
  store.ts         |   93.33 |    81.25 |     100 |   93.33 | ...,94-95,119-120 
  types.ts         |     100 |      100 |     100 |     100 |                   
  ...ontextFile.ts |   79.38 |    78.33 |   81.81 |   79.38 | ...58-272,286-291 
 src/mocks         |       0 |        0 |       0 |       0 |                   
  msw.ts           |       0 |        0 |       0 |       0 | 1-9               
 src/models        |   89.98 |    87.37 |   88.15 |   89.98 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  ...tor-config.ts |   90.24 |    91.42 |     100 |   90.24 | 142,148,151-160   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...nfigErrors.ts |   74.22 |    47.82 |   84.61 |   74.22 | ...,67-74,106-117 
  ...igResolver.ts |   98.66 |    92.85 |     100 |   98.66 | 162,324,330       
  modelRegistry.ts |     100 |    98.63 |     100 |     100 | 229               
  modelsConfig.ts  |   86.24 |    85.23 |   82.92 |   86.24 | ...1328,1357-1358 
  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   |   82.65 |    91.86 |   68.32 |   82.65 |                   
  autoMode.ts      |   97.83 |    94.21 |     100 |   97.83 | 521-522,543-550   
  ...transcript.ts |      98 |       84 |     100 |      98 | 200-201           
  classifier.ts    |   93.95 |    94.44 |     100 |   93.95 | 158-165,383-387   
  ...erousRules.ts |     100 |    89.36 |     100 |     100 | 110,133,147,175   
  ...alTracking.ts |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...on-manager.ts |   84.86 |    89.03 |      80 |   84.86 | ...1024,1130-1134 
  rule-parser.ts   |   97.37 |    93.82 |     100 |   97.37 | ...-875,1024-1026 
  ...-semantics.ts |   70.28 |    90.69 |   46.21 |   70.28 | ...2214,2277-2280 
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...sifier-prompts |   99.04 |    95.23 |     100 |   99.04 |                   
  system-prompt.ts |   99.04 |    95.23 |     100 |   99.04 | 219               
 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     |   79.44 |    64.39 |   64.28 |   79.44 |                   
  all-providers.ts |      68 |      100 |       0 |      68 | 68-69,73-79,83-89 
  index.ts         |     100 |      100 |     100 |     100 |                   
  install.ts       |   98.87 |    87.27 |     100 |   98.87 | 268-269           
  ...der-config.ts |   69.73 |    47.29 |   68.42 |   69.73 | ...10-411,418-427 
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 ...viders/presets |   97.31 |    86.36 |      50 |   97.31 |                   
  ...oding-plan.ts |   87.34 |      100 |       0 |   87.34 | 82-84,87-89,91-94 
  ...a-standard.ts |     100 |      100 |     100 |     100 |                   
  ...token-plan.ts |     100 |      100 |     100 |     100 |                   
  ...m-provider.ts |   97.01 |    81.25 |      75 |   97.01 | 120-121           
  deepseek.ts      |     100 |      100 |     100 |     100 |                   
  idealab.ts       |     100 |      100 |     100 |     100 |                   
  minimax.ts       |     100 |      100 |     100 |     100 |                   
  modelscope.ts    |     100 |      100 |     100 |     100 |                   
  openrouter.ts    |     100 |      100 |     100 |     100 |                   
  zai.ts           |     100 |      100 |     100 |     100 |                   
 src/qwen          |   84.48 |     77.6 |   95.83 |   84.48 |                   
  ...tGenerator.ts |   98.64 |    98.18 |     100 |   98.64 | 105-106           
  qwenOAuth2.ts    |   80.85 |    70.74 |   90.32 |   80.85 | ...1169-1185,1215 
  ...kenManager.ts |   85.36 |    76.61 |     100 |   85.36 | ...52-757,778-783 
 src/services      |   85.76 |    83.98 |   92.17 |   85.76 |                   
  ...ionTrailer.ts |     100 |      100 |     100 |     100 |                   
  ...llRegistry.ts |   97.35 |    85.34 |     100 |   97.35 | ...94,117,417-418 
  ...ionService.ts |   98.19 |    94.94 |     100 |   98.19 | 496,498-502,605   
  ...ingService.ts |   83.88 |    83.44 |   83.33 |   83.88 | ...1268,1285-1286 
  ...ttribution.ts |   91.73 |    87.71 |      90 |   91.73 | ...80-685,826-827 
  ...utSlimming.ts |     100 |    97.43 |     100 |     100 | 215,268           
  cronScheduler.ts |   97.57 |    92.85 |     100 |   97.57 | 62-63,77,157      
  ...eryService.ts |   80.43 |    95.45 |      75 |   80.43 | ...19-134,140-141 
  ...oryService.ts |   86.18 |    76.76 |   91.17 |   86.18 | ...1150,1191-1194 
  fileReadCache.ts |     100 |      100 |     100 |     100 |                   
  ...temService.ts |   91.27 |    82.69 |    90.9 |   91.27 | ...94,196,294-301 
  ...ratedFiles.ts |      96 |    88.23 |     100 |      96 | 119-120,146-147   
  gitInit.ts       |     100 |      100 |     100 |     100 |                   
  ...reeService.ts |    69.4 |    68.82 |   93.33 |    69.4 | ...2064,2092-2093 
  ...ionService.ts |   98.13 |     97.8 |   95.45 |   98.13 | ...32-333,380-381 
  ...ticsDumper.ts |   98.18 |    95.23 |     100 |   98.18 | 165-166           
  ...ureMonitor.ts |   95.64 |    91.77 |      96 |   95.64 | ...47,648,662-664 
  ...orRegistry.ts |   97.24 |    92.03 |     100 |   97.24 | ...49-450,601-602 
  ...ttachments.ts |   97.24 |    90.39 |     100 |   97.24 | ...08,646,661-662 
  sessionRecap.ts  |   12.65 |      100 |       0 |   12.65 | 44-150            
  ...ionService.ts |   90.47 |     79.2 |   96.87 |   90.47 | ...1324,1328-1329 
  sessionTitle.ts  |   93.87 |    71.15 |     100 |   93.87 | ...33-236,267-268 
  ...ionService.ts |   81.12 |    77.92 |   89.28 |   81.12 | ...1926,1932-1937 
  ...pInhibitor.ts |   97.02 |    90.74 |     100 |   97.02 | ...14-115,289-290 
  ...Estimation.ts |     100 |      100 |     100 |     100 |                   
  ...UseSummary.ts |   94.63 |    88.46 |     100 |   94.63 | ...62-164,214-215 
  ...oryService.ts |    60.2 |    74.07 |   42.85 |    60.2 | ...00-302,307-308 
  ...reeCleanup.ts |   14.56 |      100 |   33.33 |   14.56 | 58-185            
  ...ionService.ts |   84.21 |    79.41 |     100 |   84.21 | ...18-219,235-236 
 ...icrocompaction |   98.05 |    91.86 |     100 |   98.05 |                   
  microcompact.ts  |   98.05 |    91.86 |     100 |   98.05 | ...19,289,293,391 
 src/skills        |   87.96 |    86.16 |   89.83 |   87.96 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...activation.ts |     100 |     93.1 |     100 |     100 | 93,112            
  skill-load.ts    |   94.79 |     87.5 |     100 |   94.79 | ...00,220,232-234 
  skill-manager.ts |   83.35 |    81.42 |   82.35 |   83.35 | ...1196,1203-1207 
  skill-paths.ts   |   89.15 |    86.36 |     100 |   89.15 | ...00-101,106-107 
  symlinkScope.ts  |     100 |      100 |     100 |     100 |                   
  types.ts         |   97.53 |    97.36 |     100 |   97.53 | 248-249           
 src/subagents     |   82.61 |    78.89 |   95.23 |   82.61 |                   
  ...tin-agents.ts |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...nt-manager.ts |   77.15 |    71.36 |    93.1 |   77.15 | ...1176,1198-1199 
  types.ts         |     100 |      100 |     100 |     100 |                   
  validation.ts    |   92.46 |    95.18 |     100 |   92.46 | 51-56,69-74,78-83 
 src/telemetry     |   78.11 |    87.91 |    81.3 |   78.11 |                   
  config.ts        |     100 |      100 |     100 |     100 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  ...attributes.ts |   98.13 |       88 |     100 |   98.13 | 185-187           
  ...-exporters.ts |   46.37 |      100 |   44.44 |   46.37 | ...85,88-89,92-93 
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...t.circular.ts |       0 |        0 |       0 |       0 | 1-111             
  ...-processor.ts |   99.09 |    95.61 |      95 |   99.09 | 141,365-366       
  ...t.circular.ts |       0 |        0 |       0 |       0 | 1-128             
  loggers.ts       |   54.08 |    65.85 |   60.86 |   54.08 | ...1250,1267-1287 
  metrics.ts       |      75 |    81.52 |   75.43 |      75 | ...1018,1021-1032 
  ...attributes.ts |     100 |      100 |     100 |     100 |                   
  sanitize.ts      |      80 |    83.33 |     100 |      80 | 35-36,41-42       
  sdk.ts           |   93.15 |     88.4 |   81.81 |   93.15 | ...76-577,597-601 
  ...on-context.ts |     100 |      100 |     100 |     100 |                   
  ...on-tracing.ts |   88.47 |    87.39 |   96.29 |   88.47 | ...1345,1376-1379 
  ...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.61 |    89.36 |     100 |   98.61 | 53,108            
  types.ts         |   80.89 |     86.4 |   85.33 |   80.89 | ...1215,1218-1247 
  uiTelemetry.ts   |   91.57 |    96.96 |   76.47 |   91.57 | ...98-199,205-213 
 ...ry/qwen-logger |   68.17 |     80.2 |   65.51 |   68.17 |                   
  event-types.ts   |       0 |        0 |       0 |       0 |                   
  qwen-logger.ts   |   68.17 |       80 |   64.91 |   68.17 | ...1077,1115-1116 
 src/test-utils    |   93.16 |    95.91 |   76.47 |   93.16 |                   
  config.ts        |     100 |      100 |     100 |     100 |                   
  ...st-helpers.ts |   94.11 |       90 |     100 |   94.11 | 69-70             
  index.ts         |     100 |      100 |     100 |     100 |                   
  mock-tool.ts     |   91.19 |    97.14 |   72.41 |   91.19 | ...38,202-203,216 
  ...aceContext.ts |     100 |      100 |     100 |     100 |                   
 src/tools         |   79.86 |    82.13 |   86.05 |   79.86 |                   
  ...erQuestion.ts |   88.93 |    76.74 |    90.9 |   88.93 | ...39-340,347-348 
  cron-create.ts   |   88.11 |    88.88 |    62.5 |   88.11 | ...,43-44,165-172 
  cron-delete.ts   |   96.82 |      100 |   83.33 |   96.82 | 26-27             
  cron-list.ts     |   96.66 |      100 |   83.33 |   96.66 | 25-26             
  diffOptions.ts   |     100 |      100 |     100 |     100 |                   
  edit.ts          |   81.02 |    84.07 |      75 |   81.02 | ...15-716,826-876 
  ...r-worktree.ts |   83.14 |    67.56 |    87.5 |   83.14 | ...84-187,278-279 
  exit-worktree.ts |   84.23 |    85.96 |   91.66 |   84.23 | ...92-293,298-312 
  exitPlanMode.ts  |   85.09 |    85.71 |     100 |   85.09 | ...60-163,177-189 
  glob.ts          |   90.63 |    88.33 |   84.61 |   90.63 | ...28,171,302,305 
  grep.ts          |   79.19 |    85.71 |   78.94 |   79.19 | ...20,560,569-576 
  ls.ts            |   96.74 |    90.27 |     100 |   96.74 | 176-181,212,216   
  lsp.ts           |   72.77 |    60.09 |   90.32 |   72.77 | ...1211,1213-1214 
  ...nt-manager.ts |   84.53 |    82.96 |   84.61 |   84.53 | ...2110-2114,2153 
  mcp-client.ts    |   40.26 |    83.94 |   70.27 |   40.26 | ...1626,1630-1633 
  mcp-tool.ts      |   90.98 |    88.88 |   96.42 |   90.98 | ...95-596,646-647 
  memory-config.ts |       0 |        0 |       0 |       0 | 1-47              
  ...iable-tool.ts |     100 |    84.61 |     100 |     100 | 102,109           
  monitor.ts       |   91.65 |    84.05 |   88.46 |   91.65 | ...87,600,796-801 
  notebook-edit.ts |   85.11 |    76.42 |   81.25 |   85.11 | ...54-870,916-917 
  ...nforcement.ts |   82.57 |       90 |     100 |   82.57 | 174-185,234-247   
  read-file.ts     |    95.4 |    90.32 |      90 |    95.4 | ...99,299-302,305 
  ripGrep.ts       |   94.59 |    85.71 |   93.33 |   94.59 | ...60,463,541-542 
  ...-transport.ts |    6.34 |      100 |       0 |    6.34 | 47-145            
  send-message.ts  |   79.48 |    86.95 |    62.5 |   79.48 | ...97-203,286-294 
  shell.ts         |   74.36 |    80.89 |   91.78 |   74.36 | ...4251,4318-4319 
  skill-utils.ts   |     100 |      100 |     100 |     100 |                   
  skill.ts         |   91.02 |    94.28 |      90 |   91.02 | ...44,548,577-599 
  ...eticOutput.ts |   95.12 |      100 |      80 |   95.12 | 87-88             
  task-create.ts   |   93.85 |     92.3 |   81.81 |   93.85 | 41-45,59-60,91    
  task-list.ts     |   73.38 |    77.77 |   83.33 |   73.38 | ...01,104,108-115 
  task-stop.ts     |   93.14 |    96.15 |   85.71 |   93.14 | 39-40,54-64       
  task-update.ts   |    81.5 |       78 |    92.3 |    81.5 | ...74-382,408-414 
  team-create.ts   |   97.22 |    85.71 |   83.33 |   97.22 | 48-49,129-130     
  team-delete.ts   |   86.41 |    83.33 |   83.33 |   86.41 | 36-37,41-47,71-72 
  todoWrite.ts     |   89.27 |    82.05 |   92.85 |   89.27 | ...50-555,577-578 
  tool-error.ts    |     100 |      100 |     100 |     100 |                   
  tool-names.ts    |     100 |      100 |     100 |     100 |                   
  tool-registry.ts |    74.9 |    77.27 |   79.06 |    74.9 | ...46-847,855-856 
  tool-search.ts   |   92.35 |    85.84 |    92.3 |   92.35 | ...08-213,320-329 
  tools.ts         |   92.14 |    90.38 |   89.47 |   92.14 | ...78-479,495-501 
  web-fetch.ts     |   88.84 |       80 |   92.85 |   88.84 | ...12-313,315-316 
  write-file.ts    |   82.65 |    80.45 |   84.61 |   82.65 | ...65-668,696-731 
 src/tools/agent   |    75.3 |    83.09 |   74.68 |    75.3 |                   
  agent.ts         |    75.5 |    83.23 |      75 |    75.5 | ...2933,2960-3023 
  fork-subagent.ts |   70.73 |    77.77 |   71.42 |   70.73 | ...22-123,158-169 
 ...s/computer-use |   85.21 |     87.9 |   76.31 |   85.21 |                   
  bootstrap.ts     |   72.09 |    92.85 |   66.66 |   72.09 | 137-191,302-303   
  client.ts        |      38 |      100 |      50 |      38 | ...48-178,182-191 
  constants.ts     |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  install-state.ts |   94.44 |       75 |     100 |   94.44 | 40-41             
  ...n-detector.ts |     100 |     87.5 |     100 |     100 | 43                
  schemas.ts       |     100 |      100 |     100 |     100 |                   
  tool.ts          |   95.67 |    82.97 |    92.3 |   95.67 | 49-50,159-165     
 ...tools/workflow |   93.03 |    66.66 |    90.9 |   93.03 |                   
  workflow.ts      |   93.03 |    66.66 |    90.9 |   93.03 | ...24-225,237-240 
 src/utils         |   89.89 |    88.06 |   94.41 |   89.89 |                   
  LruCache.ts      |       0 |        0 |       0 |       0 | 1-41              
  ...Controller.ts |     100 |      100 |     100 |     100 |                   
  ...ssageQueue.ts |     100 |      100 |     100 |     100 |                   
  ...cFileWrite.ts |   94.76 |    93.06 |     100 |   94.76 | ...30-531,634-638 
  bareMode.ts      |   27.27 |      100 |       0 |   27.27 | 9-15,18-19        
  browser.ts       |    7.69 |      100 |       0 |    7.69 | 17-56             
  bundlePaths.ts   |     100 |      100 |     100 |     100 |                   
  ...igResolver.ts |     100 |      100 |     100 |     100 |                   
  ...engthError.ts |      90 |    87.71 |     100 |      90 | ...54-155,158-159 
  cronDisplay.ts   |   42.85 |    23.07 |     100 |   42.85 | 26-31,33-45,47-54 
  cronParser.ts    |   89.74 |    85.71 |     100 |   89.74 | ...,63-64,183-186 
  debugLogger.ts   |   96.42 |    94.11 |   88.23 |   96.42 | 185-189           
  editHelper.ts    |   93.63 |    83.52 |     100 |   93.63 | ...28-429,463-464 
  editor.ts        |    97.6 |     95.4 |     100 |    97.6 | ...25-326,328-329 
  ...arResolver.ts |   94.28 |    88.88 |     100 |   94.28 | 28-29,125-126     
  ...entContext.ts |   97.24 |    95.38 |   93.75 |   97.24 | ...28-130,146-147 
  errorParsing.ts  |    97.7 |    97.05 |     100 |    97.7 | 72-73             
  ...rReporting.ts |   88.46 |       90 |     100 |   88.46 | 69-74             
  errors.ts        |   70.54 |    79.59 |      50 |   70.54 | ...15-231,235-241 
  fetch.ts         |   70.18 |    71.42 |   71.42 |   70.18 | ...42,148,161,186 
  fileUtils.ts     |    91.5 |    86.19 |   95.23 |    91.5 | ...1191,1195-1201 
  forkedAgent.ts   |   80.68 |    78.12 |   83.33 |   80.68 | ...39-545,550-556 
  formatters.ts    |   81.81 |       75 |     100 |   81.81 | 15-16             
  ...eUtilities.ts |   89.21 |    86.66 |     100 |   89.21 | 16-17,49-55,65-66 
  ...rStructure.ts |   94.36 |    94.28 |     100 |   94.36 | ...17-120,330-335 
  getPty.ts        |   31.57 |       50 |     100 |   31.57 | 26-38             
  gitDiff.ts       |   92.36 |    79.53 |     100 |   92.36 | ...55-856,928-929 
  ...noreParser.ts |    92.3 |    89.36 |     100 |    92.3 | ...15-116,186-187 
  gitUtils.ts      |   73.64 |    90.32 |   83.33 |   73.64 | ...,78-79,103-154 
  iconvHelper.ts   |     100 |      100 |     100 |     100 |                   
  ...rePatterns.ts |     100 |      100 |     100 |     100 |                   
  ...ionManager.ts |     100 |     90.9 |     100 |     100 | 27                
  ...lPromptIds.ts |     100 |      100 |     100 |     100 |                   
  jsonl-utils.ts   |   88.98 |    90.66 |   91.66 |   88.98 | ...46-349,359-365 
  ...-detection.ts |     100 |      100 |     100 |     100 |                   
  ...iagnostics.ts |    96.4 |     94.2 |     100 |    96.4 | ...66,293-294,376 
  ...yDiscovery.ts |    92.4 |    89.01 |     100 |    92.4 | ...28,331,522-525 
  ...tProcessor.ts |   93.77 |    89.02 |     100 |   93.77 | ...13-319,406-407 
  ...Inspectors.ts |   61.53 |      100 |      50 |   61.53 | 18-23             
  modelId.ts       |   98.96 |    98.21 |     100 |   98.96 | 153               
  ...kerChecker.ts |   90.78 |    91.66 |     100 |   90.78 | 73-79             
  notebook.ts      |   94.57 |    89.83 |   95.83 |   94.57 | ...21,333,385-387 
  openaiLogger.ts  |   90.85 |    87.87 |     100 |   90.85 | ...97-199,222-227 
  partUtils.ts     |     100 |    98.61 |     100 |     100 | 206               
  pathReader.ts    |     100 |      100 |     100 |     100 |                   
  paths.ts         |   93.21 |    91.95 |     100 |   93.21 | ...89-390,392-394 
  pdf.ts           |   93.68 |    87.05 |     100 |   93.68 | ...96-297,321-325 
  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 |   58.57 |       76 |     100 |   58.57 | ...4,88-89,95-100 
  ...noreParser.ts |   85.45 |    85.18 |     100 |   85.45 | ...59,65-66,72-73 
  rateLimit.ts     |   92.55 |    85.92 |     100 |   92.55 | ...70-272,309-310 
  readManyFiles.ts |   87.59 |       84 |     100 |   87.59 | ...09-211,227-238 
  retry.ts         |   91.86 |    87.17 |     100 |   91.86 | ...30,451,458-459 
  retryContext.ts  |     100 |      100 |     100 |     100 |                   
  ripgrepUtils.ts  |   46.79 |    84.37 |   66.66 |   46.79 | ...45-246,258-335 
  ...sDiscovery.ts |   97.42 |    92.85 |     100 |   97.42 | ...04,182-183,202 
  ...iagnostics.ts |   83.08 |     67.5 |   92.59 |   83.08 | ...23,543-544,550 
  ...tchOptions.ts |   82.18 |    85.18 |   95.23 |   82.18 | ...24,549,578-587 
  ...odelPrefix.ts |     100 |      100 |     100 |     100 |                   
  runtimeStatus.ts |    97.5 |    88.57 |     100 |    97.5 | 162-163           
  safeJsonParse.ts |   74.07 |    83.33 |     100 |   74.07 | 40-46             
  ...nStringify.ts |     100 |      100 |     100 |     100 |                   
  ...aConverter.ts |   90.78 |    88.23 |     100 |   90.78 | ...41-42,93,95-96 
  ...aValidator.ts |      95 |    82.75 |     100 |      95 | ...07,216-219,273 
  ...r-launcher.ts |   76.92 |     91.3 |   66.66 |   76.92 | ...34,136,157-195 
  ...orageUtils.ts |   96.89 |    85.84 |     100 |   96.89 | ...51,367,447,466 
  shell-utils.ts   |   84.39 |    90.46 |     100 |   84.39 | ...1583,1590-1594 
  ...lAstParser.ts |   95.57 |    85.79 |     100 |   95.57 | ...1066-1068,1078 
  ...ContextEnv.ts |     100 |      100 |     100 |     100 |                   
  ...nlyChecker.ts |   95.08 |    91.66 |     100 |   95.08 | ...15-316,324-325 
  sideQuery.ts     |   86.17 |    86.53 |     100 |   86.17 | ...55-161,163-169 
  ...pEventSink.ts |     100 |       80 |     100 |     100 | 61                
  ...tGenerator.ts |     100 |      100 |     100 |     100 |                   
  ...ameContext.ts |     100 |      100 |     100 |     100 |                   
  symlink.ts       |   81.48 |       75 |     100 |   81.48 | 54-59             
  ...emEncoding.ts |   96.36 |    91.17 |     100 |   96.36 | 59-60,124-125     
  terminalSafe.ts  |     100 |      100 |     100 |     100 |                   
  ...Serializer.ts |   98.72 |       90 |     100 |   98.72 | 42-43,134,201-203 
  testUtils.ts     |   53.33 |      100 |   33.33 |   53.33 | ...53,59-64,70-72 
  textUtils.ts     |      60 |      100 |   66.66 |      60 | 36-55             
  thoughtUtils.ts  |     100 |    92.85 |     100 |     100 | 71                
  ...-converter.ts |   94.59 |    85.71 |     100 |   94.59 | 35-36             
  tool-utils.ts    |    93.6 |     91.3 |     100 |    93.6 | ...58-159,162-163 
  truncation.ts    |     100 |       92 |     100 |     100 | 52,71             
  windowsPath.ts   |   89.47 |    79.31 |     100 |   89.47 | ...57-58,62,90-91 
  ...aceContext.ts |   93.71 |    89.28 |   93.33 |   93.71 | ...24-225,249-251 
  xml.ts           |    97.8 |     87.5 |     100 |    97.8 | 98-99             
  yaml-parser.ts   |   86.48 |    81.25 |     100 |   86.48 | ...45-248,253-254 
 ...ils/filesearch |   86.35 |    81.76 |   96.42 |   86.35 |                   
  crawlCache.ts    |     100 |      100 |     100 |     100 |                   
  crawler.ts       |   83.07 |    77.74 |   94.82 |   83.07 | ...1468,1502-1503 
  fileSearch.ts    |   93.58 |    87.32 |     100 |   93.58 | ...46-247,249-250 
  ignore.ts        |     100 |      100 |     100 |     100 |                   
  result-cache.ts  |     100 |     92.3 |     100 |     100 | 46                
 ...uest-tokenizer |   56.63 |    74.52 |   74.19 |   56.63 |                   
  ...eTokenizer.ts |   41.86 |    76.47 |   69.23 |   41.86 | ...70-443,453-507 
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...tTokenizer.ts |   68.39 |    69.49 |    90.9 |   68.39 | ...24-325,327-328 
  ...ageFormats.ts |      76 |      100 |   33.33 |      76 | 45-48,55-56       
  textTokenizer.ts |     100 |      100 |     100 |     100 |                   
  types.ts         |       0 |        0 |       0 |       0 | 1                 
-------------------|---------|----------|---------|---------|-------------------

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

promises.push(this.sendMessage(LEADER_NAME, message, fromName));
}

await Promise.all(promises);

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] broadcast uses Promise.all, which means if one sendMessage call fails (e.g. a teammate terminates mid-broadcast and its mailbox is deleted), the entire broadcast rejects — even though other teammates successfully received the message. The leader then sees an error with no indication of partial delivery.

Consider using Promise.allSettled and logging any individual delivery failures:

Suggested change
await Promise.all(promises);
const results = await Promise.allSettled(promises);
for (const r of results) {
if (r.status === 'rejected') {
debug.warn(`broadcast delivery failed: ${r.reason}`);
}
}

— qwen3.7-max via Qwen Code /review

this.agentIdentities.clear();
this.teamEventEmitter.removeAllListeners();

await this.backend.cleanup();

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] cleanup() clears eventBridgeCleanups, pendingMessages, lastActivityAt, agentIdentities, and removes event listeners — but does not clear _shutdownPending. If a TeamManager instance is ever inspected after cleanup (in tests or debug tooling), stale entries in _shutdownPending could cause false positives.

Suggested change
await this.backend.cleanup();
this._shutdownPending.clear();
await this.backend.cleanup();

— qwen3.7-max via Qwen Code /review

/**
* List all tasks for a team, optionally filtered.
*/
export async function listTasks(

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] listTasks() reads every task JSON file from disk on every call. This is invoked from several hot paths: isAgentBusy(), unassignTeammateTasks(), getAgentStatuses(), scanIdleAgentsForTasks() (which fires on every onTasksUpdated event), and the task_list tool itself. With many tasks, a single task update can trigger an amplification loop — the notifyTasksUpdatedscanIdleAgentsForTaskslistTasks chain does O(n) file reads per teammate.

For an experimental feature behind a flag with MAX_TEAMMATES=10, this is acceptable today. For a follow-up, consider maintaining an in-memory task index (Map) updated under the existing file lock, and using it for filtered queries — falling back to disk reads only on cold start.

— qwen3.7-max via Qwen Code /review

// ─── Helpers ────────────────────────────────────────────────

/** Get the next task ID by scanning existing files. */
async function getNextTaskId(dir: string): Promise<string> {

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] getNextTaskId() scans all task filenames on every createTask() call to find the max numeric ID. Combined with the EEXIST retry loop (up to 15 attempts), a burst of concurrent task creates can do up to 15× readdir calls.

For a follow-up, consider storing a monotonically increasing counter in a separate file protected by proper-lockfile, making ID generation O(1).

— qwen3.7-max via Qwen Code /review

*/
private ensureLeaderInboxPolling(): void {
if (this.pollingInterval) return;
this.pollingInterval = setInterval(() => void this.pollLeaderInbox(), 500);

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 leader inbox is polled every 500ms via setInterval regardless of whether any messages are being sent. This keeps the Node.js event loop active and prevents idle-state optimizations during long teammate work periods.

For a follow-up, consider an event-driven approach where sendMessage/writeMessage notify the TeamManager via an in-process event when new messages are available, using polling only as a fallback. Alternatively, increasing the interval to 2–5s in the steady state with an immediate trigger for the hot path would reduce overhead.

— qwen3.7-max via Qwen Code /review

* that inject the structured shutdown message directly without
* going through `requestShutdown`. */
markShutdownRequested(name: string): void {
this._shutdownPending.add(name);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Suggestion] Test coverage for TeamManager internals has notable gaps. The following methods are critical to team session correctness but have no direct tests:

  • cleanup() — full teardown sequence (polling stop, listener unsubscribe, event bridge cleanup) is not verified. team-delete.test.ts mocks it as vi.fn().
  • waitForTeammateActivity — resolves on four conditions (message, terminated, timeout, aborted), none tested. The nonInteractiveCli exit loop depends on this.
  • allRemainingStalled / abortStalledTeammates — 600s stall threshold not tested. Risk of false positives (aborting active agents) or false negatives (infinite hangs).
  • readLeaderInboxOrQuarantine — corrupt-file quarantine at the TeamManager level (the code path the leader actually hits during polling) is untested.

Consider adding focused tests for at least the cleanup and wait-loop paths, as they govern whether a team session can start, run, and exit correctly.

— qwen3.7-max via Qwen Code /review

…imental)

Triaged the unresolved review threads from the superseded PR #2886 against
the re-ported code and applied the valid fixes:

- task_update(status:'deleted') now enforces the same ownership guard as
  updateTask, so a teammate cannot delete another teammate's task.
- Completing a task and adding a blocks edge in the same call no longer
  leaves the dependent permanently blocked by the just-completed task.
- listTasks treats a momentarily-empty (mid-create) task file as a create
  in flight and skips it instead of quarantining and losing the task.
- Fire-and-forget coordination calls (flush, auto-claim, unassign, poll)
  log rejections instead of surfacing as unhandled rejections.
- pollLeaderInbox re-checks the leader callback after the awaited read so a
  detach during the read cannot throw or drop the batch.
- scanIdleAgentsForTasks skips teammates with a pending shutdown.
- broadcast uses allSettled so one terminated recipient does not fail the
  whole broadcast.
- Hybrid tool-response+teammate turns reset the loop detector, preventing a
  false LoopDetected when a polling leader merges teammate messages.
- useGeminiStream drains its teammate queue on a manager swap; the join
  event carries the teammate model for the UI tab label.
- Removed dead consumeUnreadByType and an unreachable ENOENT branch.

Verified: core unit tests (incl. new regressions for the delete guard, the
complete+addBlocks re-block, and the empty-file create race) plus live L3
(3-agent) and L4 (4-agent) E2E, both clean.
Comment thread packages/core/src/agents/team/tasks.ts Outdated
Comment thread packages/core/src/agents/team/TeamManager.ts Outdated
Comment thread packages/core/src/agents/team/TeamManager.ts
Comment thread packages/core/src/agents/team/TeamManager.ts
* with an empty queue is not considered active — it has
* finished its current work and is waiting to be re-engaged.
*/
hasActiveTeammates(): boolean {

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] Race between flushNextMessage and hasActiveTeammates. After flushNextMessage delivers a message to an IDLE teammate via enqueueWithIdentity (line 1244), the agent's status transition from IDLE → RUNNING is asynchronous. In the window between enqueue and status change, hasActiveTeammates() sees: agent status = IDLE, TeamManager queue = empty, and returns false.

If the nonInteractiveCli wait loop checks hasActiveTeammates() in that window, it exits prematurely and the leader may call team_delete while a teammate is about to process a just-delivered message.

Suggested fix: Track recently-enqueued messages in a separate set that hasActiveTeammates also checks:

private readonly recentlyEnqueued = new Set<string>();

// In flushNextMessage, after enqueue:
this.recentlyEnqueued.add(agentId);
// Clear in onStatusChange when agent goes non-IDLE:
this.recentlyEnqueued.delete(agentId);

// In hasActiveTeammates:
if (this.recentlyEnqueued.has(member.agentId)) return true;

— qwen3.7-max via Qwen Code /review

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I think this one is a false alarm — the IDLE→RUNNING transition is synchronous, not async.

enqueueMessage starts runLoop synchronously (agent-interactive.ts:251-256), whose sync prefix calls runOneRound, which sets RUNNING at agent-interactive.ts:154 before its first await (line 166). sendMessage awaits flushNextMessage, and there's no await between queue.shift() and enqueueWithIdentity (TeamManager.ts:1249-1253) — so by the time control returns to the leader, status is already RUNNING, and hasActiveTeammates returns true via the status !== IDLE check. The empty-queue + IDLE window doesn't occur.

Left unchanged — but happy to add the guard if you can point to a path (for the InProcessBackend teammates use) where enqueue doesn't synchronously start the loop.

Comment thread packages/core/src/agents/runtime/agent-types.ts
Comment thread packages/core/src/agents/team/tasks.ts Outdated
Comment thread packages/core/src/tools/task-create.ts
// name on the next `team_create`. Sweep once more after a
// short delay to catch the race.
await deleteTeamDirs(teamName);
await new Promise((r) => setTimeout(r, 250));

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 fixed 250ms delay between the two deleteTeamDirs calls is a fragile mitigation for the recreate-after-delete race. Under high system load, slow disk I/O, or when a teammate has a long-running tool call that takes longer than 250ms to settle after cleanup(), the directory can be recreated after the second deleteTeamDirs, leaving orphan artifacts that wedge the team name on the next team_create.

Consider a retry loop with exponential backoff (e.g., 3 attempts at 100ms, 500ms, 2000ms) or watching the directory briefly for recreation, rather than relying on a single fixed delay:

Suggested change
await new Promise((r) => setTimeout(r, 250));
await deleteTeamDirs(teamName);
for (const delayMs of [100, 500, 2000]) {
await new Promise((r) => setTimeout(r, delayMs));
await deleteTeamDirs(teamName);
}

— Qwen Code via /review

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I'd lean toward leaving the fixed delay as-is for now. The suggested [100, 500, 2000] backoff would add up to ~2.6s of guaranteed latency to every team_delete to catch a race the existing double-sweep already handles in the common case — the cure costs more than the disease here. If we see actual orphan-dir flakiness in practice I'm happy to add bounded retries (and probably watch the dir rather than fixed sleeps). Leaving open in case you disagree.

if (this.leaderMessageCallback === wrappedCallback) {
this.leaderMessageCallback = origCb;
}
origCb?.(msg);

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] When an external setLeaderMessageCallback(newCb) fires during waitForTeammateActivity (e.g., during team teardown or manager swap), the wrapper correctly avoids restoring origCb over newCb. However, the current message is still forwarded to origCb (the pre-wait callback) rather than to newCb. The external caller who installed newCb expecting to receive all subsequent messages silently misses this one.

This is a narrow edge case (team teardown is the most common trigger), but the message loss is silent and could make debugging teammate-final-message delivery confusing. Consider documenting this trade-off, or delivering to whichever callback is currently installed at the time the message arrives.

— Qwen Code via /review

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I don't think newCb actually misses the message here. Delivery reads this.leaderMessageCallback fresh at TeamManager.ts:705-708, with no await between the read and the call. Once an external setLeaderMessageCallback(newCb) runs, wrappedCallback is no longer the installed callback and is unreachable (it's only ever assigned to that field), so the next message goes straight to newCb. The wrappedCallback → origCb forward only fires when no swap happened, where forwarding to origCb is correct.

So I believe there's no lost-message path — but leaving this open in case you're seeing a concrete delivery route I'm missing.

agentId: string,
opts?: { checkAgentBusy?: boolean; ownerName?: string },
): Promise<SwarmTask | undefined> {
if (opts?.checkAgentBusy) {

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] TOCTOU gap in claimTask with checkAgentBusy: the isAgentBusy() check reads all in-progress tasks without holding any lock, then the per-task lock is acquired later. Between the busy check and the lock acquisition, a concurrent event (e.g., updateTask from another teammate assigning work, or scanIdleAgentsForTasks racing with this call) could give this agent a new in-progress task, making it busy after the check passed. The agent ends up owning multiple in-progress tasks despite the guard.

This is a soft constraint (the system doesn't crash), but it undermines the "one task per agent" invariant that auto-claim and the UI rely on. Consider moving the busy check inside the per-task lock, or using a compare-and-swap pattern.

— Qwen Code via /review

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Real but soft — I'd like to defer this one. isAgentBusy scans all in-progress task files, so moving it inside this task's per-task lock wouldn't actually close the gap: a concurrent claim of a different task by the same agent isn't covered by this task's lock. A correct fix needs per-agent serialization/CAS, which feels disproportionate for a best-effort "one task per agent" invariant in an experimental feature — momentary double-ownership self-heals as the agent finishes a task. Happy to file a follow-up issue to track a proper per-agent guard. Leaving open.

…eam tasks

deleteTask checked ownership against a pre-lock read, so a concurrent
claimTask/updateTask could reassign the owner between the check and the
unlink — silently destroying another teammate's task. Acquire the lock
first, then re-read and re-check ownership inside it before unlinking,
mirroring updateTask. Reciprocal edge cleanup now runs after the lock is
released (never holding two per-task locks at once) but before the single
tasks-updated notification, so no listener observes a phantom blocker.

blockTask issued its two updateTask writes via Promise.all; two calls over
the same pair in opposite directions could deadlock on per-task locks.
Serialize the writes to remove the lock-ordering hazard.
- Cap per-agent pending messages (MAX_PENDING_MESSAGES). The queue only
  drains when its recipient goes IDLE, so an unbounded queue let a single
  looping teammate balloon a busy teammate's memory; sendMessage now
  applies backpressure once the cap is reached.
- Wrap auto-claimed task content (subject/description, authored by another
  agent) in a <task_content> envelope with a defensive instruction so it
  is treated as data, not as instructions to obey.
- Surface fire-and-forget coordination failures (flush, auto-claim,
  unassign) to the leader's conversation. They were only logged via a
  namespaced debug logger, i.e. invisible in production, despite mapping
  to silent stuck-teammate / stuck-task symptoms.
A task's subject/description becomes the prompt an idle teammate
auto-claims and executes with full tool access — the same privileged-sink
shape as send_message. Both tools inherited the base default 'allow',
which short-circuits the classifier in AUTO mode. Override
getDefaultPermission to 'ask' so that injection path stays under the
classifier / human-in-the-loop, matching send_message.
The JSDoc cited team teammates as the use-case for completeOnIdle:true,
but teammates set it to false so they settle to IDLE (not COMPLETED) and
stay alive for follow-up messages and auto-claim. Document the actual
semantics and the invariant the leader's wait loop relies on.
Comment thread packages/core/src/agents/team/TeamManager.ts Outdated
Comment thread packages/core/src/agents/team/TeamManager.ts Outdated
Comment thread packages/core/src/agents/team/tasks.ts
- fireAndForget: wrap leaderMessageCallback in try/catch so a throwing
  callback cannot re-introduce the unhandled rejection the wrapper exists
  to prevent (enforces the documented 'must not throw from this catch').
- tryAutoClaimTask: nonce-tag the <task_content> envelope with the
  per-session envelopeNonce (same pattern as formatLeaderEnvelope) so a
  teammate-authored description cannot forge the closing tag and break
  out of the protected zone via a </task_content> payload.
Use Promise.allSettled (was Promise.all) for post-unlink edge cleanup so
a single failing dependent (corrupt JSON, EACCES, lock exhaustion) no
longer skips notifyTasksUpdated for the dependents that were cleaned.
Without this their blockedBy is cleared but scanIdleAgentsForTasks never
re-runs, leaving them stuck idle with no recovery (the task file is
already unlinked, so a retry returns false). Per-failure warnings are
logged.
The hook bridging team TEAMMATE_JOINED events to agent-tab registration
(useTeamInProcess) was authored but never mounted in AgentViewProvider —
only useArenaInProcess was. As a result teammate tabs never registered and
the teammate tab bar never appeared during in-process team runs.

Mount useTeamInProcess alongside useArenaInProcess, and label teammate tabs
by name rather than model (teammates inherit the leader's model, so a model
label collapses to a generic "teammate" and is identical across the team).
Add a regression test asserting the provider mounts the team bridge.
Add a standalone streaming demo of the agent-team feature that captures the
full lifecycle and the teammate tab navigation into a single GIF
(scenarios/agent-team-demo.ts).

Supporting engine fixes:
- capture(): scroll the xterm viewport to the live bottom before
  screenshotting, so a capture taken after an idle period shows the current
  state instead of stale top-of-buffer scrollback.
- scenario-runner: skip scenarios/*.ts files with no default export (driver
  scripts that guard their own entrypoint), so batch runs don't choke.
…lakiness

The concurrent-write test fired 10 writeMessage() calls at one inbox,
each contending for the same proper-lockfile lock with a fixed,
non-randomized backoff. On Windows, slower fs syscalls let the tail
writers exhaust the retry budget before winning the lock, throwing
ELOCKED ("Lock file is already being held") — a flaky failure that
alternated pass/fail across CI runs.

Add a per-inbox in-process Mutex (async-mutex, the pattern already used
in jsonl-utils and writeContextFile) so same-process writers serialize
in memory and only one reaches for the file lock at a time. The
proper-lockfile lock stays inside the mutex to preserve cross-process
safety between agent processes. Also randomize the lock backoff to
de-synchronize genuine cross-process contenders.
A teammate's report was injected into the leader's conversation as a
raw <teammate_message_<nonce>> envelope and rendered verbatim as a user
bubble — a large, scaffolding-heavy block on screen for what is often
the biggest payload in the feature.

Adopt the two-text split the notification queue already uses: the full
nonce-tagged envelope still goes to the leader's model, but the user now
sees a compact "● <name> reported back" line in its place. The verbatim
USER bubble is suppressed for SendMessageType.Teammate exactly as it is
for Cron, and coordination-error notices get the same treatment.

The leader callback now delivers both the model text and a display
string built in TeamManager (where the structured sender/summary live),
so the UI never parses the envelope. Headless is unchanged — it ignores
the extra arg.
…F doesn't cut off

The leader sits idle (no Main-view output) while teammates read their
files, so Phase C captures no frames until a report lands — making
maxPolls the real wall-clock budget. At 80 polls (~112s) a slow second
scout could exhaust it before reporting, ending the GIF mid-run. Bump to
200 polls (~5min) so the capture outlasts the slowest scout plus the
combined summary and delete; the loop still exits early on `deleted` and
idle polls capture no frames, so the GIF doesn't bloat.
@pomelo-nwu

Copy link
Copy Markdown
Collaborator

Direction is sound (mirrors Claude Code's Agent Teams) and the flag isolation is clean. But the core is over-engineered: it's an in-process feature (all teammates share one Node process), yet the leader's inbox goes through lock-guarded files + ~1s polling while teammates use a plain in-memory queue — same operation, two transports. I'd route the leader inbox in-memory too (dropping mailbox.ts's locks/quarantine/polling), and add unit tests for the 1495-line untested TeamManager before this leaves experimental.

中文

方向成立(对标 Claude Code 的 Agent Teams),flag 隔离也干净。但核心过度设计:明明是进程内特性(队友共享一个 Node 进程),leader 收件箱却走文件锁 + 每秒轮询,而队友走内存队列——同一操作两套传输。建议 leader 也改内存(可删掉 mailbox.ts 的锁/quarantine/轮询),并给 1495 行无测试的 TeamManager 补上单测,再出实验阶段。

…nsient I/O

- createTask claims the ID with an empty O_EXCL placeholder and fills
  it via temp-file + rename, so concurrent readers never see partial
  JSON (which the quarantine would have destroyed mid-create)
- listTasks quarantines only on parse failures; transient read errors
  (EMFILE/EIO/EACCES) skip the file for one round instead of renaming
  a healthy task away, and the read fan-out is capped at 16
- updateTask / claimTask / releaseOwnedTask guard the in-lock readFile
  against ENOENT (resetTaskList and the quarantine rename run without
  per-task locks), mirroring deleteTask
- cover releaseOwnedTask's three defensive branches with tests
… abort on idle agents

- a message enqueued from inside the synchronous IDLE STATUS_CHANGE
  emit (TeamManager's flush) landed after the run loop's final empty
  check while `processing` was still true — enqueueMessage would not
  restart the loop and the message stranded in a dead queue; the loop
  now re-checks the queue after `processing` flips false
- abort() on an idle/initializing agent only set the signal: no loop
  was running to observe it, so the agent never reached a terminal
  status and allTeammatesTerminated()-style gates never fired; abort
  now settles CANCELLED directly when no loop is in flight
- regression tests drive the real AgentInteractive (stub model, real
  loop) through send-during-idle-emit and abort-while-idle
…active

FakeAgent modeled a friendlier runtime than the one that ships:
enqueueMessage processed inline (no queue, no processing flag,
resurrecting terminal agents via unconditional RUNNING), which is
exactly what masked the flush-into-dead-queue bug. It now queues
while a round is in flight, drains before settling IDLE, drops
messages after abort()/shutdown() like the real drained queue, and
never resurrects a terminal agent.
… peer messages

- spawnTeammate now checks the agent's status after spawnAgent
  resolves: start() reports chat-creation failure via FAILED without
  throwing, so the leader was told the teammate joined while sends
  were accepted into a queue that could never flush; a failed spawn
  now rolls back and surfaces the reason (with a terminal-status
  replay in setupEventBridge for the attach race)
- shutdown_rejected now clears _shutdownPending: a teammate that
  declined once stayed excluded from auto-claim and kill-armed on any
  later "shutdown_approved" mention
- peer-to-peer deliveries get a fresh-nonce envelope like leader
  deliveries, closing inline leader impersonation between teammates
  (deliberately not the leader-trust nonce, which must never reach
  teammate context)
The teammate ALS identity propagates into anything a teammate spawns,
so prepareTools() keeps choosing the teammate exclusion set for nested
agents — without WORKFLOW in it, a teammate-launched workflow re-arms
the O(k^n) recursive fan-out the subagent exclusion set prevents.
…dency cycles

- task_create / task_update now project their content (subject,
  description, status, owner, edges) to the AUTO classifier — the base
  '' sentinel projected to an empty object, so the classifier ruled on
  task_create({}) and the 'ask' override was blind; the interactive
  confirmation now shows the description (truncated), since that text
  is what a claiming teammate executes
- task_update rejects self-edges and dependency cycles instead of
  silently persisting a graph that auto-claim can never unblock
- regression tests pin the 'ask' default and a non-empty classifier
  projection for both tools
…name

Nothing deletes team dirs on normal exit (only an explicit team_delete
does), so every Ctrl+C, completed headless run, or crash permanently
wedged the team name behind createTeamFile's wx-exclusive create, with
manual rm -rf as the default recovery. team_create now records the
owner identity (leadSessionId + leadPid) and, on EEXIST, reclaims the
team when the recorded lead process is gone (or is this process);
only a live concurrent owner keeps the name refused.
…ll/@/slash preprocessing

Teammate envelopes are model-authored text already rendered as a
notification line by the teammate drain, but they still flowed through
the user-input preprocessing: with shell mode active a teammate report
was EXECUTED as a shell command, and a leading / or an @path was
reinterpreted against the leader's session. They now early-return like
Notification.
… in chat history

Teammate envelopes are machine-driven re-entries like Cron and
Notification: user-authored UserPromptSubmit hooks must not fire on
(or block) internal coordination traffic. They also never reached any
chat-recording path — record them like notifications so a resumed
session restores the same compact info line the live UI rendered.
…d rejections

The stream-json listener voided handleTeammateApproval's promise while
the handler's own error path re-issues a respond() that can reject
(teammate terminated mid-request) — an unhandledRejection that can take
down an SDK session. The call site now catches like its headless
siblings, and the controller's catch-path respond(Cancel) is wrapped so
the method never rejects out of its own error path.
@tanzhenxin

Copy link
Copy Markdown
Collaborator Author

Round 5 addressed — commits b5d6018..f3d32a9, per-thread replies cite the specific fix.

All 8 blockers are fixed. Of the robustness items, everything is fixed except leader-inbox compaction (one item — the unassign resurrect — was already addressed by 74cc344 before your pass landed). The compaction thread is deliberately deferred: it collides with @pomelo-nwu's proposal to route the leader inbox in-memory, and I'd rather not rework the cursor scheme twice — both go into one follow-up issue on the leader-inbox transport.

On the "for the record" list: agreed on all counts, and they go into the same follow-up issue — headless waitForTeammateActivity timeout sit-out + stream-json drain consumption, roster corpse slots / rolled-back member persistence, tasks.ts mutex+backoff parity with mailbox.ts, sanitizeName reserved device names + length cap, the Agent tool advertising name with the flag off, task_list/team_result TUI rendering, the FakeBackend initialTask/waitForCompletion fidelity gap, and the remaining test gaps (the fixed-sleep claim-race test included). The duplicated already-merged main commits will be cleaned up with a rebase before merge so the final diff is honest.

Verification: core 426 tests (team / runtime / tools / client suites) + cli 106 (useGeminiStream, permissionController) green; tsc --noEmit clean on both packages. New regression tests drive the real AgentInteractive through send-while-busy → idle flush and abort-while-idle, and the real TeamManager through spawn-failure, per the fake-fidelity suggestion.

@tanzhenxin

Copy link
Copy Markdown
Collaborator Author

Thanks @pomelo-nwu — the two-transport observation is a fair hit: with every teammate in-process, lock-guarded files + ~1s polling for the leader inbox is more machinery than the job needs. The file transport does buy crash-inspectable artifacts and is what an out-of-process backend would need (the Backend interface anticipates one), but if in-process stays the only backend, routing the leader inbox in-memory and deleting mailbox.ts's locks/quarantine/polling is the right end state.

I'm not swapping the transport at round 5 of this PR, though — it would invalidate the just-stabilized offset/compaction behavior wenshao also flagged. Consolidating both (your in-memory proposal + the leader-inbox compaction finding) into a follow-up issue on the leader-inbox transport, to land while the feature is still behind the experimental flag.

On TeamManager tests: the coordination harness (real TeamManager + FakeBackend) covers routing, priority, claiming, shutdown protocol, broadcast, and — new this round — spawn failure; this round also added integration tests against the real agent runtime where the fakes had been flattering it. Agreed it should grow further before leaving experimental — that's in the follow-up too.

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

No high-confidence issues found. LGTM! ✅

The Agent Team feature is well-structured with comprehensive test coverage (261 team-specific tests passing) and thorough defensive programming. Five low-confidence findings involving timing-dependent races in auto-claim and notification ordering were identified but not confirmed with sufficient certainty to warrant blocking — they are suitable for follow-up review.

— qwen3.7-max via Qwen Code /review

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

No high-confidence issues found. The Agent Team feature is well-engineered with extensive defensive coding: nonce envelopes for anti-spoofing, proper permission defaults ('ask' for privileged sinks), path traversal prevention (sanitizeName, assertValidTaskId), concurrency controls (mutex + file locks, inbox serialization, rollback on spawn failures), resource management (message queue backpressure, metadata size limits), and thorough error handling (corrupt file quarantine, fire-and-forget with error logging). All CI checks pass. LGTM. -- claude-sonnet-4-20250514 via Qwen Code /review

@wenshao

wenshao commented Jun 10, 2026

Copy link
Copy Markdown
Collaborator

Independent maintainer verification — Linux, real build + live E2E

Ran an independent verification pass of this PR on Linux (the author tested macOS; Windows/Linux were CI-only), covering build, the touched unit suites, deterministic flag gating, and four live end-to-end scenarios (headless + interactive TUI via tmux, in both yolo and default approval modes) against a live model.

Environment: Debian Linux (kernel 6.12.63, x86_64) · Node v22.22.2 · npm 10.9.7 · tmux 3.5a · head 96410d17 (contains current main @ ce53283a) · live model glm-5.1 (anthropic-protocol provider) · bundle built with npm ci && npm run bundle (v0.17.1)

Summary

# Scenario Result
1 Build (npm ci + npm run bundle)
2 Unit tests — core team suites (18 files) ✅ 571/571
3 Unit tests — touched CLI suites (4 files) ✅ 174 pass, 1 skip
4 Flag gating, deterministic (stream-json init.tools) ✅ OFF: 32 tools, no team tools · ON: 37 (+5, exactly the team set)
5 Headless E2E, yolo + stream-json, 3 parallel reviewers ✅ full lifecycle, 83.8 s, 8 turns
6 Interactive TUI (tmux), yolo, 2 parallel reviewers ✅ full lifecycle incl. tab navigation
7 Interactive TUI (tmux), default approval mode ✅ works end-to-end, ⚠️ 2 findings below
8 Headless, default approval mode ✅ graceful degradation (spawn rejected with -y guidance, team cleaned up)

No orphan processes or tmux panes left behind after any scenario (teammates are in-process); a follow-up prompt in the same session after team deletion behaves normally.

5. Headless E2E (yolo, -o stream-json)

Seeded a queue.js with 6 known bugs across three categories (swallowed errors / fire-and-forget async write / check-then-act race with an await between check and set / off-by-one i <= length / NaN on empty array / shift()-undefined passed to handler), then asked for a 3-reviewer parallel team review.

Observed tool sequence (from the stream):

read_file → team_create("queue-review") → agent(name="error-handler-reviewer")
→ agent(name="race-condition-reviewer") → agent(name="edge-case-reviewer")
→ [leader idles, tracks todos] → teammate reports arrive incrementally
→ consolidated report → team_delete → result(success)
  • Each agent call returned Teammate "…" is now running concurrently — all three live at once, and the leader's interim text confirms incremental delivery (“received error-handler-reviewer and race-condition-reviewer, still waiting on edge-case-reviewer”).
  • The consolidated report found all seeded bugs with correct line numbers, plus a legitimate extra (no catch around the handler call losing shifted jobs).
  • result: success, is_error: false, 83.8 s, 8 turns, exit 0.

6. Interactive TUI (tmux 120×40, yolo)

Same seeded file, 2 reviewers (races, edges). Full lifecycle rendered correctly:

│ ✓  TeamCreate Create team "review-crew"                                   │
│ ✓  Agent Review for race conditions                                       │
│    Teammate "races" is now running concurrently. …                        │
│ ✓  Agent Review for edge cases                                            │
│    Teammate "edges" is now running concurrently. …                        │
✦ Both reviewers are running. Waiting for their reports.
  Main  │  edges  ●  races  ●  ↓ tabs          ← tab bar appears
  • Tab navigation ( focus, ←/→ switch, release) works; a teammate's tab shows its own live tool stream (read_file, task_list, send_message → "Message sent to 'leader'") and its findings, with a "Send a message to this agent" input.
  • Main view shows ● edges reported back / ● races reported back as reports land; leader waited for both, produced a consolidated 7-bug table (3 race, 3 edge, 1 both — all seeded bugs covered, line numbers correct), then TeamDelete; the tab bar disappears after cleanup.

7. Interactive TUI, default approval mode (leaderPermissionBridge surface)

Task: one teammate (scribe) must write_file a hello.txt and report back.

What works:

  • Leader's own gated calls (task_create, agent spawn) prompt normally.
  • The teammate's gated calls (task_update, write_file with the standard diff preview, send_message) do surface confirmation dialogs and block until decided; after approving, the file landed with exactly the requested content, the report reached the leader, and the leader verified + deleted the team. Nothing executed before approval.

Two findings, both specific to this mode (yolo/headless paths unaffected):

Finding A — teammate pending approvals are invisible from the Main view. The confirmation dialogs render only inside the teammate's own tab; Main shows no pending-approval indicator (the tab-bar means "running", indistinguishable from "blocked waiting for the user"). A user sitting on Main sees the team stall with no cue that input is needed — in my run the leader model meanwhile burned turns polling with sleep/task_list because nothing told either of us a dialog was waiting. Given leaderPermissionBridge.ts documents the intent of routing teammate approvals "alongside the leader's own pending approvals" with a worker badge, this looks like the known-unpolished part of the TUI; suggest at minimum a distinct tab-bar state (e.g. ?/ instead of ) or a Main-view notice line. Fine as a follow-up.

Finding B — teammate identity is lost on the approval-resume path; messages get mis-attributed to "leader". After approving the teammate's send_message, the Main view announced ● leader reported back (should be scribe), and the mis-attribution also reached the model-facing envelope — the leader literally narrated: “The teammate "scribe" (appearing as "leader" in the message routing) has reported …”. In the yolo session the same path attributed correctly (● edges reported back). Likely mechanism: send-message.ts resolves the sender at execute time via the AsyncLocalStorage identity (const sender = getAgentName() ?? LEADER_NAME, identity.ts); when execution resumes from the approval callback rather than inside the teammate's ALS scope, getAgentName() returns undefined and the fallback silently claims the message came from the leader. Since the from= attribute also feeds the anti-spoofing envelope (formatLeaderEnvelope), and the same ALS lookup backs the isTeammate() guard that keeps send_message(type=shutdown_request) leader-only (a teammate whose context is lost on the approval-resume path would look like the leader to that check), I'd treat this as worth fixing before (or right after) merge — e.g. capture the identity when the tool call is built instead of when it executes, or wrap the post-approval resume in runWithTeammateIdentity. Repro: default approval mode, any teammate send_message that requires confirmation.

8. Headless, default approval mode

The leader's own agent spawn is rejected by the existing non-interactive approval rule with clear guidance (Tool "agent" requires user approval but cannot execute in non-interactive mode. … use the -y flag); the leader then reported honestly and deleted the team. No hang, no crash, clean exit.

Verdict

The feature does what the PR claims, end-to-end, on Linux against a live model: gating is airtight and default behavior is unchanged (verified at the tool-registry level, not just by prompt behavior), the full lifecycle works in headless and interactive modes, teammate tabs/live streams render well, and cleanup is reliable. Finding B is the only thing I'd want addressed (small, well-localized); Finding A is acceptable follow-up polish for an experimental flag. From this verification's perspective: ✅ merge-ready once B has an owner (fix in this PR or a fast-follow issue).

中文摘要

在 Linux 上对本 PR 做了独立验证(作者测试了 macOS):构建、相关单元测试(core 571 + cli 174 全部通过)、确定性的开关门控验证(关闭时 32 个工具且无任何团队工具,开启时恰好 +5)、以及 4 个真实模型 E2E 场景(headless / tmux 交互式 TUI × yolo / 默认审批模式,模型 glm-5.1)。

完整生命周期(建团队 → 并行派生具名队友 → 增量汇报 → 汇总 → 清理)在 headless 和交互式下均正常;TUI 的 tab 栏、队友独立视图、● xxx reported back 通知、清理后 tab 消失均符合预期;植入的全部 bug 都被找到且行号正确;测试后无孤儿进程。

两个发现(仅默认审批模式受影响):A:队友的审批对话框只在其自己的 tab 内渲染,Main 视图无任何待审批提示,用户容易毫无察觉地等在主视图;建议后续给 tab 加状态标记。B:审批恢复路径会丢失队友身份——批准 send_message 后消息被错标为来自 "leader"(UI 通知行与发给模型的 envelope 均错标,leader 模型明显被干扰);疑似 send-message.ts 在执行时通过 AsyncLocalStorage 取发送者并以 ?? LEADER_NAME 兜底,而审批回调恢复执行时已不在队友的 ALS 上下文内。同一个 ALS 查询还支撑着 shutdown_request 的 leader-only 防护(isTeammate()),身份丢失时队友会被该检查误认为 leader。建议在合并前修复或立即开 issue 跟进(改动应当很小:在构建工具调用时捕获身份,或恢复执行时包回 runWithTeammateIdentity)。

结论:功能符合 PR 描述,默认行为零变化已在工具注册层面验证;B 有归属后即可合并。✅

@tanzhenxin tanzhenxin merged commit afd6313 into main Jun 10, 2026
28 checks passed
@tanzhenxin

Copy link
Copy Markdown
Collaborator Author

Thanks for the independent Linux verification pass, @wenshao — especially the live default-approval-mode run that surfaced both findings.

Finding B (teammate identity lost on the approval-resume path) is fixed in #4979, taking the fast-follow route you suggested. The fix is essentially your second option — the teammate identity is captured while the loop frame is still live and restored across the post-approval resume boundary, generalized to the shared resume path so it covers the message tool, the task tools, and the leader-only shutdown_request guard in one place. That PR's E2E reproduces the exact symptom you saw (● leader reported back) and confirms the fix (● scribe reported back); your comment is cross-referenced there as the source.

Finding A (teammate pending approvals invisible from the Main view) we're treating as the follow-up polish you suggested. Two tiers: a cheap interim cue (a distinct tab-bar state for awaiting-approval and/or a Main-view notice line) in the near-term follow-up, and the proper fix — activating leaderPermissionBridge so teammate approvals surface in the leader's own view with the worker badge — in the Phase-2 leader-approval work. It'll be tracked in the consolidated follow-up issue for this feature alongside the other deferred items.

中文说明

感谢 @wenshao 的独立 Linux 验证——尤其是默认审批模式下的真实运行,发现了这两个问题。

Finding B(审批恢复路径丢失队友身份)已在 #4979 修复,采用了你建议的紧随其后的方式。修复本质上就是你给的第二个方案——在循环帧仍存活时捕获队友身份,并在审批后恢复的边界上重建,并推广到共用的恢复路径,从而一处覆盖消息工具、任务工具以及 shutdown_request 的"仅 leader"防护。该 PR 的 E2E 复现了你看到的确切症状(● leader reported back)并确认修复(● scribe reported back);你的评论已作为来源在那里交叉引用。

Finding A(Main 视图看不到队友的待审批)按你建议作为后续打磨处理。分两层:近期后续里先加一个轻量提示(给待审批一个不同的 tab 栏状态,和/或 Main 视图的提示行),而真正的修复——激活 leaderPermissionBridge,让队友审批带 worker 徽章出现在 leader 自己的视图中——放到 Phase-2 的 leader 审批工作中。它会和该特性其余延后项一起在合并后的统一后续 issue 中跟踪。

LaZzyMan added a commit that referenced this pull request Jun 11, 2026
… SECURITY comment

R1 review by @wenshao (4 [Suggestion] threads + 1 review-body comment). The
fifth thread, [Critical] nested deadlock on a thunk-level limiter, was already
caught and fixed in commit 0401ac88f by the dispatch-layer refactor — that
commit was authored before the review posted, so the thread is on the
pre-fix code; verified resolved by independent round-1 self-review fan-out
that converged on the same finding from a different angle, and by a real-LLM
E2E scenario (parallel-in-pipeline at concurrency=1 against qwen3-max).

settleToNullArray observability + abort docs (T2 / T3 wenshao):
- settled.map now logs the discarded rejection reason at debug level when a
  thunk rejects. Operators investigating a workflow that returned unexpected
  nulls can now disambiguate the four indistinguishable null paths (dispatch
  failure, 1000-cap, pipeline stage exception, non-JSON-serializable result)
  via the WORKFLOW debug logger; the contract to the script stays opaque.
- Docstring now explicitly explains the abort-responsiveness path: the
  apparent Promise.allSettled "wait for all to complete" is in practice "wait
  for all to reach an abort-aware rejection" because the dispatch signal is
  threaded all the way down to subagent.execute, and the limiter's separate
  abort listener drains the not-yet-started queue instantly.

env-override hard ceilings (T4 wenshao):
- HARD_MAX_AGENTS_PER_RUN_CEILING = 10000 caps QWEN_CODE_MAX_WORKFLOW_AGENTS.
- HARD_MAX_CONCURRENCY_CEILING = 64 caps QWEN_CODE_MAX_WORKFLOW_CONCURRENCY.
- Both clamp with a debug warning rather than silently dropping the override.
- Two RED-verified tests cover the over-ceiling clamp path (and a just-under
  value preserved).
- Not a security issue (env is operator-controlled), but stops a fat-finger
  =999999999 from silently uncapping the run.

reviveInRealm SECURITY comment (T5 wenshao):
- Added a SECURITY block warning future maintainers that the revival function
  MUST stay inside the vm init runInContext block. JSON / Array / Object here
  are vm-realm globals; extracting this textually-identical helper into a
  host-side utility would resolve those names against the host realm and
  silently reopen the T1/T8/T14 escape that the revival is designed to
  prevent. The textual identity to a host-side util is exactly the trap.

Declined this round (review-body 4 pipeline test-coverage sub-claims):
- pipeline abort, parallel+pipeline shared-limiter, pipeline 1000-cap,
  pipeline E2E. After the dispatch-layer refactor in 0401ac88f, parallel and
  pipeline mechanically share the SAME countedDispatch.limiter.run path — the
  parallel-side abort / cap / concurrency tests cover the mechanism. Explicit
  per-shape sibling tests would not catch a regression that the parallel
  versions don't already catch.

145/145 workflow-suite tests pass; tsc + eslint clean. The 2 config tests
fail locally only because the rebase pulled in #4844 (Agent Team)'s new
proper-lockfile dependency which the symlinked node_modules doesn't have —
CI resolves on fresh install.
wenshao pushed a commit that referenced this pull request Jun 12, 2026
Deferred hardening from the #4844 review, all behind the experimental
flag:

- Recognize a teammate's shutdown approval by a structured signal at
  send time instead of a free-text regex over its reply, so a reply that
  merely mentions the token in prose no longer aborts a pending teammate.
- Replace the per-session envelope nonce (which the leader model could
  echo and leak to a teammate) with a stable tag plus structural
  escaping of the delimiter in untrusted bodies — nothing left to leak.
- Bound the leader inbox: consumed messages are marked read so the
  retention compaction fires, replacing the never-compacting index
  cursor. No persisted-format change.
- Evict per-inbox in-process locks on team teardown.

Refs #4844
LaZzyMan added a commit that referenced this pull request Jun 12, 2026
…4721) (#4947)

* feat(core): add createConcurrencyLimiter sliding-window util

A p-limit-style concurrency limiter that keeps at most `limit` thunks in
flight and starts a queued thunk the instant a slot frees — so one instance
can be SHARED across several fan-out calls and still hold the total in-flight
count under a single cap. The existing in-repo concurrency control
(memoryDiscovery.ts) is fixed-size sequential batching, not a sliding window,
so this is a new primitive rather than a refactor.

API:
- run(thunk): schedule one thunk through the shared window; rejections
  propagate raw.
- settleAll(thunks): batch convenience that resolves to a position-aligned
  Array<T|null> where a rejected thunk becomes null (errors-as-data) and the
  ONLY rejection is an abort of the limiter's signal — so an aborted run
  surfaces as a rejection rather than a silent array of nulls.

Guards a non-positive-integer limit (mirrors background-tasks.ts), preserves
input order, short-circuits empty input, and (with an AbortSignal) refuses to
start new queued work once aborted. 13 unit tests cover the window cap,
errors-as-data, order, sharing across calls, and the abort paths.

* feat(core): Workflow P2 — parallel() + pipeline() + 1000-agent cap

Implements the P2 phase of the dynamic-workflow port (#4721): concurrent
fan-out primitives on top of P1's sequential agent().

parallel(thunks)
- Runs thunks through a per-run shared sliding window (createConcurrencyLimiter,
  cap = max(1, min(16, cpus-2)) — the max() guards 1–2 core machines).
- Resolves to a position-aligned array; a thunk that throws becomes null at its
  index (errors-as-data). parallel() itself only rejects on abort, so an aborted
  run surfaces a rejection rather than a silent array of nulls.
- Rejects on a non-function element (eager promise instead of a thunk).

pipeline(items, ...stages)
- Parallel-of-chains: one thunk per item, all sharing the SAME window, so it is
  staggered (item A can be in stage 3 while item B is in stage 1) with no
  inter-stage barrier. Stage callbacks receive (prev, item, idx); the first
  stage's prev is the item itself. A stage that throws OR returns null drops
  that item to null and skips its remaining stages.

1000-agent-per-run cap
- The orchestrator wraps this.dispatch with a counter, so EVERY agent() call —
  sequential, parallel, or pipeline — funnels through one chokepoint. A fan-out
  cannot bypass the cap; the 1001st call throws.

SECURITY — vm-realm result revival (closes an uncovered escape)
- vmAsync's resolve path is verbatim: it does NOT re-wrap resolved values. The
  host parallel/pipeline impl resolves with a HOST-realm array, so handing it to
  the script would reopen the T1/T8/T14 escape
  (out.constructor.constructor('return process')() reaches host process via the
  host Array.prototype chain). The vm wrapper now revives the array in-realm with
  JSON.parse(JSON.stringify(...)) — the same mechanism that makes `args` safe —
  before the script sees it. The pre-P2 escape test only probed the *Promise*
  (already vm-realm), not the resolved array; new tests probe the resolved array
  (outer + nested) and were verified to FAIL against a verbatim wrapper.

Real impls are injected by the orchestrator; the sandbox keeps its throwing
P1-unsupported stubs as the default when parallel/pipeline are not injected, so
an un-wired sandbox still gives a clear error. Tool description updated to
document the P2 surface. Full workflow suite + new orchestrator/sandbox/tool
tests green; tsc + eslint clean on all touched files.

* fix(core): Workflow P2 self-review — per-element revival + honest tool description

Adversarial self-review (6-dimension finder fan-out) surfaced two genuine
defects plus three test gaps.

EAD-1 [major] — reviveInRealm did JSON.parse(JSON.stringify(WHOLE array)), so a
single slot whose VALUE is non-serializable (a thunk that returns a BigInt or a
circular object) threw on the entire array and REJECTED the whole
parallel()/pipeline(), destroying every sibling result. That defeats
errors-as-data for return values. Revive PER-ELEMENT instead: a bad slot becomes
null at its index, siblings survive, and the outer array is still built in-realm
so the host-process escape stays closed. Regression test:
parallel([() => 'a', () => 1n, () => 'c', () => circular]) => ['a', null, 'c', null].

API-1 [major] — the WorkflowTool top-level description (passed to super()) still
read "No parallel, no pipeline" while the param-schema description and the runtime
both now support them. Updated to describe the P2 surface (parallel/pipeline,
≤16 in flight, ≤1000 total). Also refreshed the now-stale "scheduled for P2"
messages on the un-injected fallback stubs to an accurate "unavailable: sandbox
created without an implementation" wording.

Test gaps closed:
- TST-1: pipeline() now has a concurrency test proving it shares the SAME per-run
  window as parallel (peak in-flight === cap), so a pipeline impl that bypassed
  the shared limiter would fail.
- TST-2: pipeline() staggering is now tested — item 0 reaches stage 2 long before
  item 1's slow stage 1 finishes, proving there is no inter-stage barrier (a
  stage-by-stage barrier impl would fail the <50ms threshold).
- TST-3: mid-flight abort through the orchestrator is now tested (the prior test
  only used a pre-aborted controller), proving parallel() rejects after
  dispatches start rather than resolving with a silent array of nulls.

150 workflow-suite tests green; tsc + eslint clean on touched files.

* feat(core): make Workflow P2 caps env-overridable

Mirror the established QWEN_CODE_MAX_BACKGROUND_AGENTS / P1
QWEN_CODE_MAX_WORKFLOW_SECONDS precedent so operators can tune the P2 caps
without a code change:

- QWEN_CODE_MAX_WORKFLOW_AGENTS  — override the per-run 1000-agent cap.
- QWEN_CODE_MAX_WORKFLOW_CONCURRENCY — override the cpu-derived
  min(16, cpus-2) in-flight window with an explicit integer.

Both use the house resolver shape (resolveMaxConcurrentBackgroundAgents):
a non-integer / <1 value is rejected with a debug warning and the default
is used. The agent cap default is renamed DEFAULT_MAX_AGENTS_PER_RUN and the
cap message is now built from the resolved value. Resolvers take an injectable
env arg for pure unit testing.

Adds resolver unit tests (default / valid / invalid) plus an integration test
proving QWEN_CODE_MAX_WORKFLOW_AGENTS=3 makes a 4-thunk parallel() yield
exactly 3 results + 1 null at run time. 154 workflow-suite tests green.

* fix(core): throttle Workflow P2 concurrency at the dispatch layer, not the thunk layer

P2 self-review (independent adversarial fan-out) caught a real deadlock the
mock-tested suite missed: the concurrency window was applied at the thunk
level (parallel()/pipeline() scheduled their thunks through the shared
limiter). A nested fan-out — e.g. `pipeline([items], item => parallel([...]))`,
the canonical /deep-research shape — would have every outer slot held by an
outer thunk awaiting an inner settleAll() whose thunks can never acquire a
slot. pump() only re-runs from an in-flight thunk's finally, so the queue
never drains: unrecoverable silent hang until the 30-min wall clock. On 1-3
core machines (limit = 1) a SINGLE nested call deadlocks; abort cannot break
it because pump() is never re-invoked.

Fix: the window throttles AGENT DISPATCHES, not orchestration thunks. The
limiter now wraps `this.dispatch` inside countedDispatch, so only leaf agent()
calls acquire a slot; parallel()/pipeline() compose promises freely via a
plain Promise.allSettled + position-aligned null-map (settleToNullArray) and
cannot deadlock when nested. This is also the correct "N agents in flight per
run" semantics (the cap is about concurrent model calls, not orchestration
depth) and makes abort prompt (dispatch slots free normally).

The limiter's unused settleAll() is removed — its errors-as-data null-mapping
+ abort-reject moved into settleToNullArray in the orchestrator, where the
batch semantics belong. The tool description's "≤16" is softened to "16 by
default" now that QWEN_CODE_MAX_WORKFLOW_CONCURRENCY can raise it.

Adds two RED-verified regression tests (nested parallel-in-pipeline and
parallel-of-parallel, forced to concurrency=1) that deadlocked before the fix
and now resolve in ms. 150 workflow-suite tests green; tsc + eslint clean.

* fix(core): Workflow P2 round-2 self-review — prompt queue abort + AbortError consistency + doc accuracy

Round-2 adversarial review of the post-F1 code (fresh finders + skeptics) found
no new critical/major behaviour bugs (architectural convergence after the
dispatch-layer concurrency fix), but surfaced two real correctness items plus
a doc-accuracy cleanup pass.

createConcurrencyLimiter — prompt queue abort
- The limiter previously rejected queued jobs only lazily, inside pump(),
  which re-runs from an in-flight thunk's .finally. So if an in-flight thunk
  never settled (a buggy/hung future dispatcher), queued jobs would hang
  forever even after abort. Production today never hits this because
  subagent.execute always settles, but the limiter shouldn't lean on an
  unenforced invariant. Now an `{once: true}` 'abort' listener drains the
  queue the moment the signal fires. Adds a RED-confirmed regression test
  (limit=1, in-flight = `new Promise(()=>{})`, abort → queued must reject
  within 200ms).

settleToNullArray — abort error type consistency
- Was throwing `new Error('Workflow run aborted.')`, which `isAbortError()`
  (utils/errors.ts) does NOT recognise — an aborted parallel/pipeline would
  surface as a generic run failure. Now throws
  `new DOMException('Workflow run aborted.', 'AbortError')` to match the
  limiter, so the whole P2 abort path classifies uniformly.

Doc accuracy pass (review caught 5 stale strings)
- Tool descriptions accurately state the default cap is `min(16, cpus-2)`
  (not a flat "16"), document both env-overrides
  (QWEN_CODE_MAX_WORKFLOW_CONCURRENCY, QWEN_CODE_MAX_WORKFLOW_AGENTS), and
  note that a thunk resolving to a non-JSON-serializable value also becomes
  null at its index.
- makeParallelImpl docstring updated: parallel() rejects on invalid input OR
  abort (not "only on abort" — that was contradicted by the array/function
  validation right above).
- WorkflowTool fileoverview no longer claims "P1 sequential only".
- Orchestrator.run() comment updated to describe the actual P2 signal flow
  (per-run limiter derived from abortOnTimeout, not P1's
  "sandbox-level signal intentionally not exposed").
- Wall-clock rationale loses its stale "P1 sequential" framing.

151 workflow-suite tests pass (was 150 + 1 new lazy-abort regression);
tsc + eslint clean.

* docs(core): Workflow P2 round-3 self-review — wall-clock honesty + cpu-floor + symmetric pipeline docs

Round-3 adversarial review found one confirmed factual error in the round-2
doc rewrite plus three real consistency gaps. No new behaviour bugs; the
architecture has converged after the round-1 dispatch-layer fix and the
round-2 prompt-queue-abort + AbortError consistency.

(1) wall-clock docstring: the round-2 rewrite claimed "even a long pipeline
with the 1000-agent cap is bounded well under" 30 min. Arithmetically false:
1000 agents × 10-min subagent cap ÷ default 16-concurrency ≈ 10.5 hours,
20× the wall clock. Rewritten honestly: the wall clock is a 0-token-hang
backstop, NOT a precise cost cap; for cost control point operators at the
env-overridable per-run cap (QWEN_CODE_MAX_WORKFLOW_AGENTS) and concurrency
window (QWEN_CODE_MAX_WORKFLOW_CONCURRENCY).

(2) tool descriptions now show the actual default formula
`max(1, min(16, cpus-2))`, including the outer max(1, ...) floor — without
it, the displayed default would be -1 on a 1-CPU container even though the
runtime clamps to 1.

(3) tool descriptions now document the non-JSON-serializable→null rule for
pipeline() as well as parallel() — they share the same reviveInRealm code
path (per-element JSON round-trip), so the asymmetric docs were inaccurate.

(4) settleToNullArray's AbortError comment is corrected: the round-2 commit
overclaimed "uniform classification via isAbortError() at the WorkflowTool
boundary". In reality the DOMException name is preserved at the HOST callsite
inside the orchestrator, but vmAsync re-throws the script-visible rejection
as a fresh `new Error(msg)` and the outer catch wraps it as
WorkflowExecutionError — so isAbortError() at the tool boundary returns false
either way. The DOMException is still useful as host-internal consistency,
but the script-observability claim was wrong.

Declined this round (intentional, documented):
- F4/P2-R3-F2 wall-clock is plain Error, not AbortError — wall-clock IS a
  timeout, not an abort; semantically correct as-is. A unified abort surface
  is P3+ work.
- R2-MIN-1 limiter listener leak — only triggers if signal outlives the
  limiter and never aborts; production caller is per-run and always aborts.
- F6 new symbols not re-exported from index.ts — same internal-API decision
  as createConcurrencyLimiter.
- Various test-vacuity nits — tests already cover real failure modes.

151 workflow-suite tests pass; tsc + eslint clean.

* fix(core): Workflow P2 PR review R1 — observability + hard ceilings + SECURITY comment

R1 review by @wenshao (4 [Suggestion] threads + 1 review-body comment). The
fifth thread, [Critical] nested deadlock on a thunk-level limiter, was already
caught and fixed in commit 0401ac88f by the dispatch-layer refactor — that
commit was authored before the review posted, so the thread is on the
pre-fix code; verified resolved by independent round-1 self-review fan-out
that converged on the same finding from a different angle, and by a real-LLM
E2E scenario (parallel-in-pipeline at concurrency=1 against qwen3-max).

settleToNullArray observability + abort docs (T2 / T3 wenshao):
- settled.map now logs the discarded rejection reason at debug level when a
  thunk rejects. Operators investigating a workflow that returned unexpected
  nulls can now disambiguate the four indistinguishable null paths (dispatch
  failure, 1000-cap, pipeline stage exception, non-JSON-serializable result)
  via the WORKFLOW debug logger; the contract to the script stays opaque.
- Docstring now explicitly explains the abort-responsiveness path: the
  apparent Promise.allSettled "wait for all to complete" is in practice "wait
  for all to reach an abort-aware rejection" because the dispatch signal is
  threaded all the way down to subagent.execute, and the limiter's separate
  abort listener drains the not-yet-started queue instantly.

env-override hard ceilings (T4 wenshao):
- HARD_MAX_AGENTS_PER_RUN_CEILING = 10000 caps QWEN_CODE_MAX_WORKFLOW_AGENTS.
- HARD_MAX_CONCURRENCY_CEILING = 64 caps QWEN_CODE_MAX_WORKFLOW_CONCURRENCY.
- Both clamp with a debug warning rather than silently dropping the override.
- Two RED-verified tests cover the over-ceiling clamp path (and a just-under
  value preserved).
- Not a security issue (env is operator-controlled), but stops a fat-finger
  =999999999 from silently uncapping the run.

reviveInRealm SECURITY comment (T5 wenshao):
- Added a SECURITY block warning future maintainers that the revival function
  MUST stay inside the vm init runInContext block. JSON / Array / Object here
  are vm-realm globals; extracting this textually-identical helper into a
  host-side utility would resolve those names against the host realm and
  silently reopen the T1/T8/T14 escape that the revival is designed to
  prevent. The textual identity to a host-side util is exactly the trap.

Declined this round (review-body 4 pipeline test-coverage sub-claims):
- pipeline abort, parallel+pipeline shared-limiter, pipeline 1000-cap,
  pipeline E2E. After the dispatch-layer refactor in 0401ac88f, parallel and
  pipeline mechanically share the SAME countedDispatch.limiter.run path — the
  parallel-side abort / cap / concurrency tests cover the mechanism. Explicit
  per-shape sibling tests would not catch a regression that the parallel
  versions don't already catch.

145/145 workflow-suite tests pass; tsc + eslint clean. The 2 config tests
fail locally only because the rebase pulled in #4844 (Agent Team)'s new
proper-lockfile dependency which the symlinked node_modules doesn't have —
CI resolves on fresh install.

* fix(core): Workflow P2 PR review R2 — staggering test + revival logging + pipeline E2E

R2 review by @DragonnZhang (re-review after R1 push) and @qwen-code-ci-bot
(post-fix review). Three real items addressed; one style/wording inconsistency
in the bot's review body declined per the round-weighted bar.

T6 [Bug] staggering test deterministically fails on macOS-14 CI (DragonnZhang)
- The test asserted item 0 reaches stage 2 within 50ms while item 1's stage 1
  takes 120ms. That timing assumption holds only at concurrency ≥ 2. On
  GitHub's macos-14 runners (3 CPU cores) cpu-derived concurrency = 1, FIFO
  forces all stage-1 dispatches to settle before any stage-2 starts, and the
  ~122ms s2-of-0 timestamp blows the threshold. The test passed on my workstation
  but blocks the macos-latest CI matrix — root cause of the failing
  `Test (macos-latest, Node 22.x)` check that downgraded the prior APPROVE.
- Replaced with a deterministic gate-based assertion that does NOT depend on
  wall-clock thresholds: force QWEN_CODE_MAX_WORKFLOW_CONCURRENCY=2, have
  item 1's stage 1 block on a Promise gate that only item 0's stage 2 can
  release. A staggered impl completes (item 0 advances while item 1 is held);
  a barrier impl deadlocks (item 0's stage 2 can't start until item 1's stage
  1 finishes, which can't finish until item 0 reaches stage 2). Vitest timeout
  catches the barrier-deadlock case; the assertion `item0ReachedStage2 ===
  true` is timing-free.

T7 [Suggestion] reviveInRealm catch silently sets null with no log (qwen-code-ci-bot)
- The R1 fix added debugLogger.warn for rejected thunks in settleToNullArray,
  but a thunk that *resolves* to a non-JSON-serializable value (BigInt /
  circular object) takes a different path through reviveInRealm's catch in
  the vm init script. Operators with debug logging on still couldn't
  distinguish "rejected" from "resolved-but-unserializable" — symmetric
  observability was missing. The R1 audit should have caught the sibling and
  didn't.
- Added a host-side `logRevivalFailure(idx, reason)` hook to the bridge
  (debugLogger.warn host-side) and call it from reviveInRealm's catch with
  the coerced-to-string error message. The bridge contract is preserved:
  only primitive strings/numbers cross back; reviveInRealm itself stays
  inside the vm runInContext block per the SECURITY comment.

T8 [Suggestion] no pipeline() end-to-end test through WorkflowTool (qwen-code-ci-bot)
- This is the SAME finding wenshao raised in his R1 review-body, which I
  declined on a "parallel/pipeline share mechanism — symmetric tests
  redundant" basis. The bot's R2 raise provides specific mechanism evidence
  that breaks that argument: pipeline's vm wrapper uses
  `callPipeline.apply(null, arguments)` and `[items].concat(stages)` to
  spread the variadic stage list, a code path structurally distinct from
  parallel's single-argument call. A regression in the vm-to-host stage
  forwarding would not be caught by the parallel E2E. My R1 decline was
  based on incomplete grep — apologies, accepting now.
- Added a pipeline E2E test mirroring the parallel E2E shape: full stack
  drive through WorkflowTool → orchestrator → sandbox revival, asserting
  the chained stage results `[11, 21]`.

Declined this round (review-body):
- qwen-code-ci-bot's workflow() stub wording inconsistency ("not supported
  in P1" vs the new "is unavailable: ..." on parallel/pipeline). R2 style/
  nit per the round-weighted bar; no behavioural impact.

146/146 workflow-suite tests pass; tsc + eslint clean.

* chore(core): Workflow P2 — dedupe WORKFLOW debugLogger + simplify revival error coercion

Post-R2 /simplify pass. Two findings that are pure cleanup of code added in
the R2 commit, with no scope drift:

(1) The R2 fix added `createDebugLogger('WORKFLOW')` to workflow-sandbox.ts,
duplicating the identical call in workflow-orchestrator.ts:21. Export the
sandbox-side instance and import it in orchestrator — single source of
truth, one fewer logger object retained for process lifetime. Direction is
natural (orchestrator already imports from sandbox; the reverse would be
circular).

(2) The reviveInRealm catch coercion `String((e && e.message != null) ?
e.message : e)` collapses to `String(e?.message ?? e)`. The truthy/null
distinction the original drew (treating empty-string message different from
the toString fallback) was not meaningful for a debug log line. Same
behaviour for any realistic error; less noise to read.

Deferred per the same self-review discipline that the R2 commit message
documented:
- `withEnv` helper to dedupe the 6-line env-var save/restore boilerplate
  (now 3 sites in workflow-orchestrator.test.ts): real ~10 LOC win but
  touches 2 pre-existing tests, out of R2 scope.
- Rename `bridge.logRevivalFailure` to a generic `bridge.warn(category,
  msg)` for future vmAsync silent-reject logging: speculative; per the
  altitude analysis, "zero rename cost when the second consumer arrives"
  means deferring loses nothing.

146/146 workflow-suite tests pass; tsc + eslint clean.
@tanzhenxin tanzhenxin deleted the feat/agent-team-v2 branch June 13, 2026 13:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants