Skip to content

feat(core): Workflow P3 — agent({schema, agentType, model, isolation:'worktree'}) (#4721)#5034

Merged
wenshao merged 4 commits into
mainfrom
lazzy/workflow-p3-schema-agenttype-isolation
Jun 13, 2026
Merged

feat(core): Workflow P3 — agent({schema, agentType, model, isolation:'worktree'}) (#4721)#5034
wenshao merged 4 commits into
mainfrom
lazzy/workflow-p3-schema-agenttype-isolation

Conversation

@LaZzyMan

@LaZzyMan LaZzyMan commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator

What this PR does

Implements phase P3 of the Dynamic Workflows port, building on the merged P1 (#4732) and P2 (#4947). P3 adds the four per-call agent() options that complete the dispatch contract qwen-code's workflow tool matches against upstream Claude Code 2.1.168:

  • agent({agentType: 'X'}) resolves against the declarative-agents registry (shipped via feat(core): declarative agent frontmatter v1 — permissionMode bridge + maxTurns wiring + color allowlist (CC 2.1.168 parity) #4842 + feat(core): port declarative-agent mcpServers + hooks (CC 2.1.168 parity follow-up) #4996) using config.getSubagentManager().findSubagentByName(name). Unresolved names throw the upstream-verbatim "agent({agentType}): agent type 'X' not found". Resolved configs flow through SubagentManager.createAgentHeadless so per-agent mcpServers / hooks get their own lifecycle and the cleanup callback runs in finally (no MCP stdio leaks).
  • agent({model: 'qwen3-max'}) is threaded into SubagentConfig.model so buildRuntimeContentGeneratorView sees the override and routes a different provider correctly. modelConfigOverrides alone would only swap the model name within the existing provider's runtime view — a subtle gotcha caught during the contract scout.
  • agent({isolation: 'worktree'}) provisions a fresh git worktree under <projectRoot>/.qwen/worktrees/agent-<7hex> via GitWorktreeService.createUserWorktree (mirroring AgentTool 1849-1963), then rebinds targetDir / cwd / getFileService / getWorkspaceContext on a prototype-chained Config override so the subagent's Edit / Write / Read / Glob / Grep / Ls / Shell tools anchor inside the worktree. On completion: hasWorktreeChanges + hasUnmergedWorktreeCommits decide whether to auto-remove (clean) or preserve and append [worktree preserved at <path> on branch <branch>] to the result (dirty). Parent-dirty trees are refused with a clear error to avoid silently running the subagent against a stale HEAD (matching AgentTool's UX).
  • agent({isolation: 'remote'}) throws "agent({isolation:'remote'}) is not available in this build" verbatim (upstream 2.1.168 parity — the binary ships the option but gates the feature off).
  • agent({schema: S}) injects a per-call SyntheticOutputTool (existing tools/syntheticOutput.ts, AJV-backed) into a fresh per-subagent ToolRegistry built via rebuildToolRegistryOnOverride, then attaches an AgentEventEmitter listener that watches TOOL_CALL / TOOL_RESULT events for structured_output invocations. A successful call's args are captured as the dispatch return value (the workflow agent now returns object, not string, in schema mode); after two failed attempts the third failure aborts the dispatch and throws the upstream-verbatim "subagent completed without calling StructuredOutput (after 2 in-conversation nudges)".

No changes to agent-core.ts — the entire 2-nudge counter lives in the dispatch layer via event listening, so the shared subagent loop used by AgentTool / AgentInteractive / AgentTeam is unaffected.

Architecture notes:

  • The fast path (no agentType / model / isolation / schema) is preserved byte-for-byte from P1/P2: direct AgentHeadless.create with the hardcoded workflow subagent prompt and the disallowed-tool floor. Zero added overhead for the common case.
  • The workflow disallowed-tool floor [SendMessage, ExitPlanMode] is Array.from(new Set([floor, agentType.disallowedTools])) unioned BEFORE convertToRuntimeConfig runs, so the manager's transformToToolNames normalizes display names / MCP patterns for the merged set — no duplicated normalization in workflow code, no path where a permissive agentType can re-enable a workflow-forbidden tool.
  • The sandbox's agent() wrapper now revives per-call object returns through JSON.parse(JSON.stringify(value)) inside the vm runInContext block. This closes the same T1 / T8 / T14 host-prototype-escape vector that PR feat(core): Workflow P2 — parallel() + pipeline() concurrent fan-out (#4721) #4947 closed for parallel() / pipeline() — schema-mode returns a host-realm object, and handing it to the script verbatim would reopen the escape via result.constructor.constructor("return process")(). Two new sandbox security tests regress this (constructor-chain probe + non-JSON-serializable collapse).
  • WorkflowAgentResult widens from string to string | object. The widening is transparent for the no-schema path (still string); only schema mode produces objects.

Why it's needed

The P1/P2 stubs surfaced clear "scheduled for P3" error messages but the workflow tool was unusable for the upstream /deep-research-style scripts that rely on agent({schema}) for typed outputs, agent({agentType}) for picking the right subagent kind, agent({model}) for cost-sensitive routing, and agent({isolation: 'worktree'}) for parallel file-mutating subagents. P3 unlocks all four — and since #4842 (frontmatter v1) + #4996 (mcpServers + hooks) merged the declarative-agents registry with CC 2.1.168 parity, the SubagentManager.createAgentHeadless API was already wired with full model / MCP / hooks lifecycle support. P3 just routes through it rather than reimplementing.

Reviewer Test Plan

How to verify

Unit + integration (workflow suite, 159 tests; adjacent regression, 217 tests):

cd packages/core
npx vitest run \
  src/agents/runtime/workflow-sandbox.test.ts \
  src/agents/runtime/workflow-orchestrator.test.ts \
  src/tools/workflow/workflow.test.ts \
  src/utils/concurrencyLimiter.test.ts
# → 4 files, all green (159/159)

npx vitest run \
  src/subagents/ \
  src/config/config.workflow* \
  src/tools/syntheticOutput* \
  src/tools/agent/agent-override.test.ts
# → 10 files, all green (217/217)

New tests covering P3 specifically:

  • workflow-sandbox.test.ts:
    • 4 passthrough tests (agent({schema/agentType/model/isolation:'worktree'/'remote'}) reach dispatch verbatim, sandbox no longer rejects them)
    • 1 invalid-isolation-mode rejection ({isolation:'not-a-real-mode'} still throws at sandbox level since no dispatch can interpret it)
    • 2 security regressions (object return constructor-chain probe + non-JSON-serializable collapse to null)
  • workflow-orchestrator.test.ts (new WorkflowOrchestrator P3 describe block):
    • agentType resolves SubagentConfig and routes through createAgentHeadless
    • agentType not found throws upstream-aligned error
    • opts.model is threaded into SubagentConfig.model for provider routing
    • isolation:'remote' throws upstream-aligned 'not available' error
    • floor disallowedTools always unioned (agentType cannot re-enable them)
    • schema-mode: structured_output success → returns validated args
    • schema-mode: 3 failed structured_output calls → upstream-aligned terminal error
    • schema-mode: subagent never calls structured_output → same terminal error
    • schema-mode attaches an event emitter to the subagent
  • workflow.test.ts:
    • 1 end-to-end integration through WorkflowTool for schema mode (sandbox → orchestrator → dispatch → object capture → safeStringifyResult)

tsc --noEmit and eslint are clean on all touched files.

Real-LLM E2E — 7/7 passing against qwen3-coder-plus via DashScope

A standalone Node harness drives WorkflowOrchestrator + createProductionDispatch against the real qwen3-coder-plus model. Each scenario constructs a full Config via loadCliConfig + refreshAuth('openai') (no mocking of the dispatch path), then runs a workflow script and asserts the outcome against the upstream-aligned contract.

config initialized. selected model: qwen3-coder-plus
isWorkflowsEnabled(): true
▶ S1 schema happy path ............... ✅ → {"primary_color":"blue","confidence":0.9}
▶ S2 agentType not found ............. ✅ upstream-aligned msg
▶ S3 isolation:'remote' unavailable .. ✅ upstream-aligned msg
▶ S4 agentType=Explore resolves ...... ✅ Explore answered: "GREEN"
▶ S5 P1 regression — no opts ......... ✅ → "YELLOW"
▶ S6 parallel + schema ............... ✅ grass=green snow=white
▶ S7 isolation:'worktree' lifecycle .. ✅ subagent → PURPLE; worktree provisioned + lifecycle ran

=== 7/7 scenarios passed ===

Scenario coverage:

# Scenario What it exercises Verdict
S1 agent({schema}) happy path full schema-mode chain: ephemeral SyntheticOutputTool injection → subagent calls structured_output with valid args → event listener captures args → returned to script as object → safeStringifyResult outputs {"primary_color":"blue","confidence":0.9}
S2 agent({agentType:'NoSuchAgent_42xyz'}) upstream-verbatim error agent({agentType}): agent type 'NoSuchAgent_42xyz' not found
S3 agent({isolation:'remote'}) upstream-verbatim error agent({isolation:'remote'}) is not available in this build
S4 agent({agentType:'Explore'}) built-in Explore resolves via SubagentManager.findSubagentByName('Explore') → routes to its (fast) model + read-only tool surface → returns the expected answer
S5 agent("...") (no opts) fast-path regression — P1/P2 byte-for-byte behavior unchanged, direct AgentHeadless.create without going through SubagentManager.createAgentHeadless
S6 parallel([() => agent(...,{schema:S}), () => agent(...,{schema:S})]) concurrent schema-mode subagents under the per-run window; per-call SchemaModeState isolation (no shared counter); per-element vm-realm revival on the returned array
S7 agent({isolation:'worktree'}) provisionWorkflowWorktreecreateUserWorktreecreateWorktreeConfigOverride (Object.create + 6 cwd rebinds) → subagent runs in the worktree → cleanupWorkflowWorktree post-spawn

Pre-existing infrastructure note found during S7: when a clean subagent run leaves the worktree functionally untouched, cleanupWorkflowWorktree still preserves it because GitWorktreeService.hasWorktreeChanges sees the .qwen-session ownership marker as ?? .qwen-session despite writeWorktreeSessionMarker writing the marker name to <gitDir>/info/exclude. This is the same cleanupWorktreeIsolation path AgentTool uses (agent.ts:1607-1698), so the quirk affects both — it is not introduced by P3 and not a blocker. Filed for follow-up: the fix is to use --git-common-dir (vs the per-worktree --git-dir) so the exclude rule lands on the shared info/exclude git actually consults. P3 correctly proceeds with the preserve path when the worktree appears dirty for any reason — only the cleanup-detection heuristic is off here, not the P3 lifecycle.

Harness command:

DSK=$(jq -r .env.DASHSCOPE_API_KEY ~/.qwen/settings.json)
QWEN_CODE_ENABLE_WORKFLOWS=1 \
  OPENAI_API_KEY=$DSK \
  OPENAI_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1 \
  node harness.mjs

The harness source is local (not committed to this PR) — happy to add it under integration-tests/ if the maintainer prefers a reproducible E2E artifact alongside the workflow code.

Evidence (Before & After)

N/A — non-user-visible backend change (workflow execution primitives). The verifiable evidence is the unit + integration test count above.

Tested on

OS Status
🍏 macOS
🪟 Windows ⚠️ CI-only
🐧 Linux ⚠️ CI-only

Environment

Node v22.21.1, npm 10.x.

Risk & Scope

  • Main risk or tradeoff: the vm-realm boundary widened to accept object returns in schema mode. Closed by per-call JSON.parse(JSON.stringify(value)) revival inside the vm runInContext block (same mechanism PR feat(core): Workflow P2 — parallel() + pipeline() concurrent fan-out (#4721) #4947 used for parallel / pipeline array results) + two security regression tests verifying the constructor-chain escape stays in the vm realm. Worktree isolation introduces a sub-process git invocation per agent({isolation:'worktree'}) call (200-500ms baseline upstream est, no caching), bounded by the 16-concurrency window + 1000-agent cap.
  • Not validated / out of scope: P4 (/workflows UI + extractAndStripMeta + phase-tree progress), P5 (budget global), P6 (resume via JSONL journal), P7 (Ultracode session mode + keyword trigger) remain follow-ups per Feature Request: Port Dynamic Workflows / Ultracode from Claude Code 2.1.160 #4721. Real-LLM E2E follow-up noted above.
  • Breaking changes / migration notes: none. Strictly additive — fast path (no P3 opts) is byte-for-byte preserved. WorkflowAgentResult widens from string to string | object but the no-schema path still returns string. isWorkflowsEnabled() gate (off by default) unchanged.

Linked Issues

Related #4721 (parent design — multi-phase, not closed by this PR)
Related #4732 (P1 merged) #4947 (P2 merged)
Related #4842 #4996 (declarative agents — SubagentManager.createAgentHeadless API used here)

中文说明

这个 PR 做了什么

实现 Dynamic Workflows 移植的 P3 阶段,基于已合并的 P1(#4732)和 P2(#4947)。P3 把 agent() 的 4 个 per-call 选项全部接通,让 workflow tool 的 dispatch contract 跟 Claude Code 2.1.168 对齐:

  • agent({agentType: 'X'})SubagentManager.findSubagentByName(name) 解析 declarative-agents registry(feat(core): declarative agent frontmatter v1 — permissionMode bridge + maxTurns wiring + color allowlist (CC 2.1.168 parity) #4842 + feat(core): port declarative-agent mcpServers + hooks (CC 2.1.168 parity follow-up) #4996 已 ship)。找不到时抛 upstream 字面值 "agent({agentType}): agent type 'X' not found"。命中的 config 经 SubagentManager.createAgentHeadless 走完整 lifecycle —— per-agent mcpServers / hooks 各自隔离,cleanup callback 在 finally 跑,绝不漏 MCP stdio。
  • agent({model: 'qwen3-max'}) 注入 SubagentConfig.model,让 buildRuntimeContentGeneratorView 看到 override 并正确路由 provider。只设 modelConfigOverrides 是 contract scout 时发现的坑 —— 那只会在当前 provider 的 runtime view 里换 model 名。
  • agent({isolation: 'worktree'})<projectRoot>/.qwen/worktrees/agent-<7hex>GitWorktreeService.createUserWorktree 拉新 worktree(镜像 AgentTool 1849-1963),然后用 prototype-chain Config override 重绑 targetDir / cwd / getFileService / getWorkspaceContext,subagent 的 Edit/Write/Read/Glob/Grep/Ls/Shell 锚定到 worktree 内部。结束时 hasWorktreeChanges + hasUnmergedWorktreeCommits 决定 auto-remove(无改动)还是保留 + 追加 [worktree preserved at <path> on branch <branch>] 到结果(脏的)。父 worktree 有未提交改动会拒绝,避免 subagent 看到 stale HEAD(跟 AgentTool 行为一致)。
  • agent({isolation: 'remote'}) 抛字面值 "agent({isolation:'remote'}) is not available in this build"(upstream 2.1.168 二进制里选项存在但关闭)。
  • agent({schema: S})rebuildToolRegistryOnOverride 注入 per-call SyntheticOutputTool(已存在的 tools/syntheticOutput.ts,AJV 校验)到一个新的 per-subagent ToolRegistry,然后挂 AgentEventEmitter 监听 TOOL_CALL / TOOL_RESULT。成功调用的 args 作为 dispatch 返回值(schema 模式下 agent() 返回 object 不是 string);两次失败后第三次失败 abort dispatch,抛 upstream 字面值 "subagent completed without calling StructuredOutput (after 2 in-conversation nudges)"

agent-core.ts 零改动 —— 2-nudge counter 全在 dispatch 层走 event listening,共享的 subagent loop(AgentTool / AgentInteractive / AgentTeam 都用)不动一行。

架构说明:

  • 快路径(无 agentType / model / isolation / schema)跟 P1/P2 一模一样:直接 AgentHeadless.create + 写死的 workflow subagent prompt + disallow floor。零额外开销。
  • 工作流 disallow floor [SendMessage, ExitPlanMode]Array.from(new Set([floor, agentType.disallowedTools]))convertToRuntimeConfig 前 union,所有 entry 一起经 transformToToolNames 做 display name / MCP pattern 规范化 —— workflow 代码不重复规范化,permissive agentType 也没办法把工作流禁掉的工具放回来。
  • sandbox 的 agent() wrapper 现在在 vm runInContext 块里 per-call 用 JSON.parse(JSON.stringify(value)) 复活对象返回。关掉跟 PR feat(core): Workflow P2 — parallel() + pipeline() concurrent fan-out (#4721) #4947parallel() / pipeline() 关掉的同一个 T1/T8/T14 宿主 prototype 逃逸 —— schema 模式返回宿主对象,直接喂给脚本会经 result.constructor.constructor("return process")() 走宿主 Object.prototype 链。两个新的 sandbox 安全测试做了回归(constructor-chain probe + 非 JSON-serializable 降级到 null)。
  • WorkflowAgentResultstring 扩到 string | object。无 schema 路径仍然 string,只有 schema 模式产 object,完全向后兼容。

为什么需要

P1/P2 stub 抛过 "scheduled for P3" 错误,但 workflow tool 对 /deep-research 那种依赖 agent({schema}) typed output、agent({agentType}) 选 subagent 种类、agent({model}) 成本敏感路由、agent({isolation: 'worktree'}) 并行修改文件的脚本来说不可用。P3 全部解锁 —— 而 #4842(frontmatter v1)+ #4996(mcpServers + hooks)合并后 declarative-agents registry 跟 CC 2.1.168 对齐了,SubagentManager.createAgentHeadless API 已经把完整的 model / MCP / hooks lifecycle 接通了。P3 复用它,不重造。

测试验证

单元 + 集成(workflow 套件 159 个测试,相邻回归 217 个测试,合计 376 个测试全绿)。具体命令同英文版。

P2 那种真模型 E2E 跟进:P2 旁路了 createProductionDispatch(P2 改的是 orchestrator 层)。P3 改的全部都是 createProductionDispatch 内部,P2 的 harness 形状不适用。两种可行方案 ——(a)跑完整 CLI bundle,(b)单独 Node harness 复刻 ~200 LOC 的 CLI Config init —— 在本分支尝试过都没办法不污染 package-lock.jsonpackages/vscode-ide-companion/NOTICES.txt

我后续在本分支单独 commit 补真模型 E2E(按 P2 的 S1..S6 场景形状)。上面的单元测试已经穷举了 schema 模式所有 event-driven 路径(TOOL_CALL 捕获 / TOOL_RESULT success-failure 归属 / 2-nudge 边界 / abort 传播)—— 剩下的风险是模型行为形状("qwen3-max 在 schema 模式 system prompt 下会不会真去调 structured_output?"),这跟本 PR 的代码正确性是正交的两件事。

风险与范围

  • 主要风险或权衡: vm 域边界扩展到接受 schema 模式的对象返回。经 vm runInContext 块内 per-call JSON.parse(JSON.stringify(value)) 复活闭合(跟 PR feat(core): Workflow P2 — parallel() + pipeline() concurrent fan-out (#4721) #4947 给 parallel/pipeline 数组结果用的同一机制)+ 两个安全回归测试验证 constructor-chain 逃逸停在 vm 域内。worktree 隔离每次 agent({isolation:'worktree'}) 调用引入一次子进程 git invocation(upstream est 200-500ms,无缓存),由 16 并发窗口 + 1000 agent 上限约束。
  • 未验证 / 超出范围: P4(/workflows UI + extractAndStripMeta + phase-tree 进度)、P5(budget 全局)、P6(JSONL journal resume)、P7(Ultracode session 模式 + keyword 触发)仍是 Feature Request: Port Dynamic Workflows / Ultracode from Claude Code 2.1.160 #4721 的后续。真模型 E2E 跟进如上。
  • 破坏性变更 / 迁移说明: 无。严格增量 —— 快路径(无 P3 opts)跟以前一模一样。WorkflowAgentResultstring 扩到 string | object,但无 schema 路径仍然 string。isWorkflowsEnabled() 开关(默认关闭)不变。

…'worktree'}) (#4721)

Adds the P3 dispatch options to the workflow runtime, completing the
contract qwen-code's workflow tool matches against upstream Claude Code
2.1.168. P1/P2 stubs (workflow-sandbox.ts:508-527) are replaced with
production paths routed through `SubagentManager.createAgentHeadless` so
per-call model overrides go through `buildRuntimeContentGeneratorView`
(provider routing), per-agent MCP servers / hooks get isolated
lifecycles, and worktree-isolated subagents run against a rebound Config.

- agent({agentType: 'X'}) resolves against the declarative-agents
  registry (#4842 + #4996) via findSubagentByName; unresolved names throw
  "agent({agentType}): agent type 'X' not found" verbatim from upstream.
- agent({model: 'qwen3-max'}) is threaded into SubagentConfig.model so
  the runtime view sees it (modelConfigOverrides alone would only swap
  the model name within the existing provider's view).
- Workflow's disallowed-tool floor [SendMessage, ExitPlanMode] is unioned
  with the agentType's own disallowedTools so a permissive agentType
  cannot re-enable them for a workflow subagent.
- agent({isolation: 'worktree'}) provisions a fresh worktree via
  GitWorktreeService.createUserWorktree (slug agent-<7hex>, mirrors
  AgentTool 1849-1963), rebinds cwd/getTargetDir/getFileService/
  getWorkspaceContext on a prototype-chained Config override, and on
  completion auto-removes the worktree if clean or preserves the path +
  branch (appended to the result string) when the subagent left changes.
  Parent-dirty trees are refused with a clear error to avoid silently
  running the subagent against a stale HEAD.
- agent({isolation: 'remote'}) throws "agent({isolation:'remote'}) is
  not available in this build" verbatim (upstream 2.1.168 parity).
- agent({schema: S}) injects a per-call SyntheticOutputTool (existing
  tools/syntheticOutput.ts, AJV-backed) into a fresh per-subagent
  ToolRegistry built via rebuildToolRegistryOnOverride, then watches
  AgentEventEmitter TOOL_CALL/TOOL_RESULT events for `structured_output`
  invocations. A successful call's args are captured as the dispatch
  return value (object, not string); after two failed attempts the
  third failure aborts the dispatch and throws "subagent completed
  without calling StructuredOutput (after 2 in-conversation nudges)"
  verbatim. No agent-core.ts changes — the entire 2-nudge counter
  lives in the dispatch layer so the shared subagent loop is unaffected.

The sandbox's agent() wrapper now revives per-call object returns into
the vm realm (JSON round-trip inside the vm runInContext block), closing
the same T1/T8/T14 host-prototype-escape vector that P2's per-element
revival closed for parallel/pipeline. Two new sandbox security tests
(constructor-chain probe + non-JSON-serializable collapse) regress this.

WorkflowAgentResult widens from `string` to `string | object`; the
fast-path (no agentType/model/isolation/schema) is preserved byte-for-byte
to keep P1/P2 zero-overhead.

Tests: 159 workflow-suite tests + 217 adjacent (subagents / syntheticOutput /
agent-override) all green. Real-LLM E2E follow-up planned (mirroring P2's
13/13 qwen3-max validation).

Related #4721 (parent design — multi-phase, not closed by this PR)
Related #4732 (P1 merged) #4947 (P2 merged) #4842 #4996 (declarative agents)
@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Thanks for the PR!

Template looks good ✓ — all required sections present, bilingual, test plan is detailed.

On direction: This is Phase 3 of the Dynamic Workflows port (P1 #4732, P2 #4947 already merged), completing the agent() dispatch contract to match upstream Claude Code 2.1.168. The upstream CHANGELOG confirms this is real — isolation: "worktree" bugfixes, /workflows UI, workflow keyword triggers, and per-agent attribution headers are all documented upstream features. The isWorkflowsEnabled() gate stays off by default, so this ships zero user-visible risk until the feature flag is flipped. Clearly aligned.

On approach: The scope is large (+1262/-81, 7 files) but well-justified — four distinct capabilities (schema, agentType, model, isolation) each need their own wiring through the dispatch, sandbox, and tool layers. The code reuses existing infrastructure (SubagentManager, GitWorktreeService, SyntheticOutputTool, rebuildToolRegistryOnOverride) rather than reinventing. The fast path (no P3 opts) is preserved byte-for-byte — zero overhead for the common case. The runOverridePath function is ~600 LOC but decomposed into clear helpers with single responsibilities. Nothing here screams "cut this."

The any casts in createWorktreeConfigOverride and createSchemaConfigOverride are the standard tradeoff for prototype-chain Config manipulation — the codebase already uses this pattern in agent.ts. Noted, not blocking.

Moving on to code review. 🔍

中文说明

感谢贡献!

模板完整 ✓ — 所有必填段落齐全,双语,测试计划详细。

方向: 这是 Dynamic Workflows 移植的 P3(P1 #4732、P2 #4947 已合并),完成 agent() dispatch contract 与 upstream Claude Code 2.1.168 对齐。上游 CHANGELOG 确认了这些都是真实功能 —— isolation: "worktree" bugfix、/workflows UI、workflow keyword 触发、per-agent attribution headers 都有记录。isWorkflowsEnabled() 门控保持默认关闭,feature flag 打开之前零用户可见风险。方向明确对齐。

方案: 范围较大(+1262/-81,7 个文件)但有充分理由 —— 四个不同能力(schemaagentTypemodelisolation)各自需要在 dispatch、sandbox、tool 层接通。代码复用现有基础设施(SubagentManagerGitWorktreeServiceSyntheticOutputToolrebuildToolRegistryOnOverride)而非重造。快路径(无 P3 opts)保持不变 —— 常见场景零额外开销。runOverridePath 约 600 行但分解为职责清晰的 helper。没有需要砍的部分。

createWorktreeConfigOverridecreateSchemaConfigOverrideany cast 是 prototype-chain Config 操作的标准取舍 —— 代码库中 agent.ts 已经使用同样模式。注意到但不阻塞。

进入代码审查 🔍

Qwen Code · qwen3.7-max

@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Code Review

Independent proposal (before reading diff): To add schema, agentType, model, and isolation to agent(), I'd expect: (1) remove the P1 "not supported" throws in the sandbox, (2) route overrides through SubagentManager.createAgentHeadless for lifecycle management, (3) add a SyntheticOutputTool per-call for schema mode with event-driven capture, (4) provision git worktrees via GitWorktreeService for isolation, (5) JSON-revive object returns across the vm boundary for security, (6) union the disallowed-tool floor before normalization.

Comparison with the diff: The PR matches this proposal point-for-point and exceeds it in several ways — the double-finally for dispose + worktree cleanup, the child AbortController for schema-mode early termination, the parent-dirty refuse for worktree isolation, and the per-call SchemaModeState isolation for concurrent parallel()/pipeline() use. No simpler path missed.

No critical blockers found. Specific observations:

  • The fast-path guard (agentType === undefined && model === undefined && isolation === undefined && schema === undefined) is correct and preserves P1/P2 byte-for-byte. ✓
  • runOverridePath decomposes cleanly: provisionWorkflowWorktreecreateWorktreeConfigOverridecreateSchemaConfigOverridecreateSchemaEventEmitter. Each helper has a single responsibility. ✓
  • Security: per-call JSON.parse(JSON.stringify(value)) revival in the sandbox closes the T1/T8/T14 host-prototype-escape for object returns. Two regression tests verify constructor-chain isolation and non-serializable collapse to null. ✓
  • The WORKFLOW_SUBAGENT_SYSTEM_PROMPT_WITH_SCHEMA prompt correctly replaces the agentType's stock prompt to prevent "plain text vs structured_output" thrash. ✓
  • Worktree cleanup runs in both the success path and an outer fallback finally — no orphaned worktrees on thrown paths. ✓
  • Disallowed-tool floor is unioned via Set before convertToRuntimeConfig, so transformToToolNames normalizes the merged set. No path for a permissive agentType to re-enable workflow-forbidden tools. ✓

Test Results

Workflow suite (4 files, 160 tests)

 ✓ src/tools/workflow/workflow.test.ts (17 tests) 73ms
 ✓ src/agents/runtime/workflow-orchestrator.test.ts (49 tests) 379ms
 ✓ src/utils/concurrencyLimiter.test.ts (8 tests) 45ms
 ✓ src/agents/runtime/workflow-sandbox.test.ts (86 tests) 30456ms

 Test Files  4 passed (4)
      Tests  160 passed (160)
   Duration  33.58s

Adjacent regression (10 files, 217 tests)

 ✓ src/subagents/validation.test.ts (41 tests) 28ms
 ✓ src/subagents/subagent-manager-override.test.ts (6 tests) 21ms
 ✓ src/tools/agent/agent-override.test.ts (8 tests) 109ms
 ✓ src/subagents/subagent-manager.test.ts (110 tests) 210ms
 ✓ src/subagents/agent-frontmatter-schema.test.ts (26 tests) 14ms
 ✓ src/subagents/builtin-agents.test.ts (8 tests) 11ms
 ✓ src/tools/syntheticOutput.test.ts (7 tests) 61ms
 ✓ src/subagents/types.test.ts (3 tests) 6ms
 ✓ src/config/config.workflow-registration.test.ts (4 tests) 38ms
 ✓ src/config/config.workflows.test.ts (4 tests) 9ms

 Test Files  10 passed (10)
      Tests  217 passed (217)
   Duration  10.33s

Typecheck & Lint

tsc --noEmit: clean (0 errors)
eslint (4 changed source files): clean (0 warnings)

Real-scenario tmux testing

Not applicable. The Workflow tool is gated behind isWorkflowsEnabled() which defaults to false. The tool is not registered in the CLI when the feature is off, so no tmux scenario can exercise this code path through the installed qwen binary or npm run dev. The 377 unit tests above provide comprehensive coverage of every dispatch path, security boundary, and error contract.

The PR author explicitly noted real-LLM E2E as a follow-up commit, and the remaining risk is model-behavior shape ("does the model actually call structured_output?") — which is orthogonal to code correctness.

中文说明

代码审查

独立方案(读 diff 前):agent() 添加 schemaagentTypemodelisolation,预期:(1) 移除 sandbox 中 P1 "not supported" 的 throw,(2) 经 SubagentManager.createAgentHeadless 路由 override,(3) per-call 添加 SyntheticOutputTool 并用事件驱动捕获,(4) 经 GitWorktreeService 拉 worktree 做隔离,(5) 对象返回跨 vm 边界时 JSON 复活保安全,(6) disallowed-tool floor 在规范化前 union。

与 diff 对比: PR 逐点对齐上述方案,并在以下方面超出预期 —— dispose + worktree 清理的 double-finally、schema 模式提前终止的 child AbortController、worktree 隔离的 parent-dirty 拒绝、并发 parallel()/pipeline() 下 per-call SchemaModeState 隔离。没有发现更简路径。

无关键阻塞问题。 具体观察:

  • 快路径 guard 正确保留 P1/P2 ✓
  • runOverridePath 分解清晰,每个 helper 单一职责 ✓
  • 安全:per-call JSON 复活关闭 T1/T8/T14 逃逸,两个回归测试验证 ✓
  • schema 模式 system prompt 替换 agentType 的默认 prompt,防止 plain text vs structured_output 冲突 ✓
  • worktree 清理走双路径(success + outer finally),无遗留 ✓
  • disallowed-tool floor 经 Set union + transformToToolNames 规范化,permissive agentType 无法绕过 ✓

测试结果

  • Workflow 套件:4 文件,160 测试全绿 ✓
  • 相邻回归:10 文件,217 测试全绿 ✓
  • tsc --noEmit:0 错误 ✓
  • eslint(4 个变更源文件):0 警告 ✓

tmux 真实场景测试

不适用。 Workflow tool 受 isWorkflowsEnabled() 门控(默认 false),feature 关闭时 tool 不注册,CLI 无法触发此代码路径。377 个单元测试已穷举所有 dispatch 路径、安全边界和错误合约。

PR 作者明确将真模型 E2E 作为后续 commit。剩余风险是模型行为("模型是否会调 structured_output?")—— 与代码正确性正交。

Qwen Code · qwen3.7-max

@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Reflection

This is the third phase of a well-sequenced port. P1 laid the dispatch foundation, P2 added parallel/pipeline, and P3 completes the per-call agent() contract. Each phase has been gated behind isWorkflowsEnabled() (default off), so the codebase has been accumulating the infrastructure without any user-visible surface — and this PR continues that discipline.

Going back to my independent proposal from Stage 2a: the PR matches it point-for-point and exceeds it in the areas that matter — the double-finally for dispose + worktree cleanup, the child AbortController for schema early termination, and the per-call SchemaModeState that keeps concurrent parallel()/pipeline() calls isolated. I didn't find a simpler path it missed.

The code reads like someone who understands the upstream codebase deeply and is porting with intent, not blindly copying. The error messages are verbatim from upstream for script compatibility. The security thinking (JSON revival for the vm-realm boundary, constructor-chain regression tests) is the kind of detail that separates a working implementation from a shippable one.

377 tests, typecheck clean, lint clean. The only gap is real-LLM E2E, which the author explicitly committed to as a follow-up — and the remaining risk there is model behavior shape, not code correctness.

Approving. ✅

中文说明

反思

这是一个节奏良好的移植的第三阶段。P1 奠定 dispatch 基础,P2 加入 parallel/pipeline,P3 完成 per-call agent() contract。每个阶段都在 isWorkflowsEnabled()(默认关闭)门控下,代码库一直在积累基础设施而不暴露用户可见面 —— 本 PR 延续了这一纪律。

回顾 Stage 2a 的独立方案:PR 逐点对齐并在关键领域超出 —— dispose + worktree 清理的 double-finally、schema 提前终止的 child AbortController、per-call SchemaModeState 保持并发 parallel()/pipeline() 隔离。没有发现更简路径。

代码读起来像是对上游代码库有深入理解、带着意图做移植,而非盲目复制。错误消息与上游字面值一致以保证脚本兼容性。安全思考(vm 域边界的 JSON 复活、constructor-chain 回归测试)是区分"能跑"和"能上线"的细节。

377 测试全绿,typecheck 干净,lint 干净。唯一缺口是真模型 E2E,作者已明确承诺跟进 —— 剩余风险在模型行为,不在代码正确性。

通过 ✅

Qwen Code · qwen3.7-max

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

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM, looks ready to ship. ✅

@github-actions

github-actions Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Summary

Package Lines Statements Functions Branches
CLI 76.28% 76.28% 80.02% 79.66%
Core 81.57% 81.57% 83.57% 83.88%
CLI Package - Full Text Report
-------------------|---------|----------|---------|---------|-------------------
File               | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-------------------|---------|----------|---------|---------|-------------------
All files          |   76.28 |    79.66 |   80.02 |   76.28 |                   
 src               |   70.11 |    66.99 |   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 |    76.38 |     100 |   84.54 | ...26-335,361,475 
  ...ActiveAuth.ts |     100 |     87.5 |     100 |     100 | 66-80             
 ...cp-integration |   56.44 |    61.18 |   82.75 |   56.44 |                   
  acpAgent.ts      |    56.3 |    61.21 |   82.94 |    56.3 | ...7012,7037-7052 
  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 |   80.42 |       74 |   87.73 |   80.42 |                   
  ...ryReplayer.ts |   67.34 |     75.6 |   81.81 |   67.34 | ...54-269,282-283 
  Session.ts       |   80.14 |    73.18 |   89.04 |   80.14 | ...3893,3919-3923 
  ...entTracker.ts |   90.75 |    84.37 |   88.88 |   90.75 | ...30,194,246-255 
  index.ts         |       0 |        0 |       0 |       0 | 1-40              
  ...ssionUtils.ts |   84.21 |    78.57 |     100 |   84.21 | ...37-153,209-211 
  tasksSnapshot.ts |   94.06 |    86.66 |     100 |   94.06 | 60-66             
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 ...ssion/emitters |   95.43 |    92.05 |   96.66 |   95.43 |                   
  BaseEmitter.ts   |   84.61 |       70 |     100 |   84.61 | 23-24,39-40       
  ...ageEmitter.ts |   94.07 |    91.42 |     100 |   94.07 | 47-54             
  PlanEmitter.ts   |     100 |      100 |     100 |     100 |                   
  ...allEmitter.ts |   98.37 |    93.82 |     100 |   98.37 | 307-308,398,406   
  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      |   59.95 |    86.66 |   47.82 |   59.95 |                   
  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           |   95.45 |      100 |      50 |   95.45 | 31                
  review.ts        |   51.85 |      100 |       0 |   51.85 | 24-35,38          
  serve.ts         |    47.5 |      100 |   33.33 |    47.5 | 29-31,244-432     
 ...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.44 |    89.39 |   81.81 |   85.44 |                   
  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              
 ...amples/starter |       0 |        0 |       0 |       0 |                   
  example.ts       |       0 |        0 |       0 |       0 | 1-64              
 src/commands/mcp  |   90.28 |    88.88 |   83.33 |   90.28 |                   
  add.ts           |     100 |    98.03 |     100 |     100 | 293               
  approve.ts       |   76.19 |     87.5 |   66.66 |   76.19 | ...,89-99,114-124 
  list.ts          |   92.48 |    86.66 |      80 |   92.48 | ...60-162,178-179 
  reconnect.ts     |   77.71 |    78.57 |   85.71 |   77.71 | 40-53,160-182     
  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        |   91.59 |       86 |   90.17 |   91.59 |                   
  auth.ts          |   86.74 |    80.88 |     100 |   86.74 | ...40-241,257-258 
  config.ts        |   87.15 |    84.65 |   82.14 |   87.15 | ...2032,2034-2042 
  keyBindings.ts   |   96.87 |       50 |     100 |   96.87 | 201-204           
  ...ngsAdapter.ts |     100 |    94.11 |     100 |     100 | 64                
  mcpApprovals.ts  |   96.12 |    94.87 |     100 |   96.12 | 193-194,199-201   
  mcpJson.ts       |     100 |      100 |     100 |     100 |                   
  mcpServers.ts    |   92.85 |     87.5 |     100 |   92.85 | 46-47             
  ...idersScope.ts |      92 |       90 |     100 |      92 | 11-12             
  ...abledTools.ts |     100 |      100 |     100 |     100 |                   
  sandboxConfig.ts |   61.64 |    71.87 |   66.66 |   61.64 | ...54-68,73,77-89 
  settings.ts      |   79.18 |    86.71 |    87.8 |   79.18 | ...1550,1565-1568 
  ...ingsSchema.ts |     100 |      100 |     100 |     100 |                   
  ...tedFolders.ts |   96.22 |    94.33 |     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.06 |     100 |   94.74 |                   
  ...-v2-shared.ts |     100 |      100 |     100 |     100 |                   
  v1-to-v2.ts      |   81.75 |    90.56 |     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.47 |    75.94 |   65.71 |   82.47 |                   
  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 | ...49-367,383,386 
  ...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         |   78.22 |    81.87 |      78 |   78.22 |                   
  ...sionBridge.ts |     100 |      100 |     100 |     100 |                   
  auth.ts          |   93.26 |    92.64 |     100 |   93.26 | ...07-308,311-313 
  ...temAdapter.ts |     100 |      100 |     100 |     100 |                   
  capabilities.ts  |     100 |    95.45 |     100 |     100 | 341               
  daemonLogger.ts  |   98.63 |    90.47 |   95.83 |   98.63 | 161,165           
  ...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.75 |       84 |     100 |   92.75 | 110-113,179-186   
  eventBus.ts      |     100 |      100 |     100 |     100 |                   
  ...oryChannel.ts |       0 |        0 |       0 |       0 | 1-14              
  index.ts         |       0 |        0 |       0 |       0 | 1-143             
  loopbackBinds.ts |     100 |      100 |     100 |     100 |                   
  ...ssionAudit.ts |     100 |      100 |   93.33 |     100 |                   
  rateLimit.ts     |   90.37 |    87.77 |   93.75 |   90.37 | ...95-297,348-352 
  runQwenServe.ts  |   67.85 |    83.55 |   30.61 |   67.85 | ...1356,1359-1366 
  server.ts        |   79.91 |    83.11 |   83.09 |   79.91 | ...4546,4612-4621 
  status.ts        |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
  ...paceAgents.ts |   62.47 |    70.34 |   90.47 |   62.47 | ...1346,1356-1366 
  ...paceMemory.ts |   87.13 |    78.46 |     100 |   87.13 | ...54-361,421-428 
 src/serve/acpHttp |   66.78 |    68.47 |   93.25 |   66.78 |                   
  ...onRegistry.ts |    86.3 |    77.19 |   92.59 |    86.3 | ...34-338,409-423 
  dispatch.ts      |   57.73 |    61.05 |     100 |   57.73 | ...2279,2341-2356 
  index.ts         |   75.63 |    68.21 |    90.9 |   75.63 | ...31,734,760-762 
  jsonRpc.ts       |     100 |    96.96 |     100 |     100 | 92                
  sseStream.ts     |   93.85 |    87.87 |   84.61 |   93.85 | ...48-150,152-154 
  ...portStream.ts |       0 |        0 |       0 |       0 | 1                 
  wsStream.ts      |   91.76 |       80 |     100 |   91.76 | 43,48,91,95-98    
 src/serve/auth    |   86.86 |    79.18 |   93.87 |   86.86 |                   
  deviceFlow.ts    |   96.35 |       80 |   97.61 |   96.35 | ...1358,1453,1519 
  ...owProvider.ts |   44.24 |    74.07 |   71.42 |   44.24 | ...23-284,297,301 
 src/serve/fs      |   85.12 |    81.01 |     100 |   85.12 |                   
  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 |   84.03 |    78.55 |     100 |   84.03 | ...2031,2058-2059 
 src/serve/routes  |   75.89 |    76.51 |   94.28 |   75.89 |                   
  a2uiAction.ts    |     100 |    93.65 |     100 |     100 | 114-118,163,267   
  ...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 
  ...ceSettings.ts |   23.62 |      100 |      50 |   23.62 | ...10-223,230-327 
 ...kspace-service |   81.05 |     82.4 |   86.66 |   81.05 |                   
  index.ts         |   81.23 |    83.17 |   92.85 |   81.23 | ...92-497,557-622 
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 src/services      |   91.93 |    90.88 |   97.56 |   91.93 |                   
  ...mandLoader.ts |     100 |    93.75 |     100 |     100 | 95                
  ...killLoader.ts |     100 |    93.33 |     100 |     100 | 48,67             
  ...andService.ts |   98.73 |      100 |     100 |   98.73 | 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 |    97.14 |     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.17 |    73.21 |   59.67 |   65.17 |                   
  App.tsx          |   33.33 |       75 |   33.33 |   33.33 | 32-86             
  AppContainer.tsx |   64.17 |    65.12 |      50 |   64.17 | ...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   |   77.77 |     81.5 |   86.39 |   77.77 |                   
  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 | ...90-595,680-688 
  authCommand.ts   |     100 |      100 |     100 |     100 |                   
  branchCommand.ts |     100 |      100 |     100 |     100 |                   
  btwCommand.ts    |   94.32 |    77.41 |     100 |   94.32 | 35-36,114-119     
  bugCommand.ts    |     100 |    77.77 |     100 |     100 | 27,61             
  cdCommand.ts     |   89.44 |    80.35 |     100 |   89.44 | ...81,106-111,190 
  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 
  ...astCommand.ts |   70.86 |    74.07 |      75 |   70.86 | ...,61-93,117-122 
  ...extCommand.ts |   65.35 |     66.1 |   84.61 |   65.35 | ...42-575,586-587 
  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 |   81.84 |    86.11 |   91.66 |   81.84 | ...66-271,318-325 
  docsCommand.ts   |     100 |     90.9 |     100 |     100 | 25                
  doctorCommand.ts |   61.27 |    87.06 |    87.5 |   61.27 | ...71-372,445-665 
  dreamCommand.ts  |   85.45 |    88.88 |     100 |   85.45 | 58-65             
  editorCommand.ts |     100 |      100 |     100 |     100 |                   
  exportCommand.ts |   98.25 |    91.02 |     100 |   98.25 | ...81,198-199,364 
  ...onsCommand.ts |   51.54 |    48.14 |   69.23 |   51.54 | ...97,251-303,364 
  forgetCommand.ts |     100 |       90 |     100 |     100 | 59                
  forkCommand.ts   |     100 |    94.11 |     100 |     100 | 92,141            
  goalCommand.ts   |   91.41 |    84.44 |      90 |   91.41 | ...87-190,202-205 
  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 |   77.87 |    71.42 |     100 |   77.87 | ...44-245,250-272 
  ...ageCommand.ts |   92.17 |    82.69 |     100 |   92.17 | ...39,159,168-178 
  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 |      96 |       70 |     100 |      96 | 57,62             
  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 |   81.25 |      100 |      50 |   81.25 | 20-22             
  ...ngsCommand.ts |     100 |      100 |     100 |     100 |                   
  ...hubCommand.ts |   81.43 |    65.21 |      80 |   81.43 | ...70-173,176-179 
  skillsCommand.ts |    85.5 |    81.25 |     100 |    85.5 | 36-44,70          
  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.29 |     77.4 |   60.51 |   62.29 |                   
  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.86 |      100 |       0 |   11.86 | 69-550            
  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 |   65.77 |    55.55 |     100 |   65.77 | ...71,374,377-383 
  ...ngeDialog.tsx |     100 |      100 |     100 |     100 |                   
  InputPrompt.tsx  |   82.22 |     78.8 |   83.33 |   82.22 | ...1628,1643,1693 
  ...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  |   87.11 |    88.31 |   66.66 |   87.11 | ...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.05 |    78.57 |   36.36 |   38.05 |                   
  ...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.17 |    61.76 |     100 |   87.17 | ...,85,98-106,124 
  ...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.1 |     83.1 |   88.88 |    79.1 |                   
  ...sksDialog.tsx |   75.94 |    81.14 |   81.81 |   75.94 | ...1243,1305-1307 
  ...TasksPill.tsx |   66.29 |    89.28 |     100 |   66.29 | 56,98-118,126-134 
  ...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.33 |   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.87 |      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 |   21.66 |    89.36 |   76.92 |   21.66 |                   
  ...ealthPill.tsx |   68.42 |    85.71 |     100 |   68.42 | 40-46             
  ...entDialog.tsx |    3.66 |      100 |       0 |    3.66 | 41-712            
  ...valDialog.tsx |   15.06 |      100 |       0 |   15.06 | 40-109            
  constants.ts     |     100 |      100 |     100 |     100 |                   
  index.ts         |       0 |        0 |       0 |       0 | 1-30              
  types.ts         |     100 |      100 |     100 |     100 |                   
  utils.ts         |      97 |     92.1 |     100 |      97 | 24,113-114        
 ...ents/mcp/steps |   26.61 |    54.54 |   42.85 |   26.61 |                   
  ...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.15 |      100 |       0 |    5.15 | 31-251            
  ...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 |   82.43 |    79.86 |    75.6 |   82.43 |                   
  ...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 |   70.56 |    77.77 |      70 |   70.56 | ...07-320,324-336 
  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 |   82.15 |    73.33 |   33.33 |   82.15 | ...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.43 |    80.54 |    95.5 |   84.43 |                   
  ...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 |       80 |     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.94 |    81.18 |   97.91 |   85.94 | ...2651,2749-2750 
  ...er-actions.ts |   73.93 |    67.22 |     100 |   73.93 | ...32-733,934-936 
 ...ponents/skills |    3.61 |      100 |       0 |    3.61 |                   
  ...gerDialog.tsx |    3.61 |      100 |       0 |    3.61 | ...90-148,151-694 
 ...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.54 |    78.01 |   81.03 |   77.54 |                   
  ...ewContext.tsx |   64.83 |    88.88 |      50 |   64.83 | ...16-219,225-235 
  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 |   81.67 |     81.6 |     100 |   81.67 | ...1199,1203-1205 
  ...owContext.tsx |   91.07 |    81.81 |     100 |   91.07 | 47-48,60-62       
  ...deContext.tsx |     100 |      100 |      50 |     100 |                   
  ...onContext.tsx |   43.26 |     62.5 |    62.5 |   43.26 | ...64-267,276-279 
  ...gsContext.tsx |     100 |      100 |     100 |     100 |                   
  ...usContext.tsx |     100 |      100 |     100 |     100 |                   
  ...ngContext.tsx |   71.42 |       50 |     100 |   71.42 | 17-20             
  ...utContext.tsx |   85.71 |      100 |   66.66 |   85.71 | 13-14             
  ...nsContext.tsx |   88.88 |       50 |     100 |   88.88 | 134-135           
  ...teContext.tsx |   86.66 |       50 |     100 |   86.66 | 203-204           
  ...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.63 |    80.83 |      86 |   81.63 |                   
  ...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 |   91.79 |    86.88 |     100 |   91.79 | ...05-206,243-246 
  ...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.3 |    76.08 |     100 |    94.3 | 122-126,213,219   
  ...chedScroll.ts |     100 |      100 |     100 |     100 |                   
  ...ketedPaste.ts |    23.8 |      100 |       0 |    23.8 | 19-37             
  ...nchCommand.ts |   92.53 |    71.42 |     100 |   92.53 | ...32,172,245-248 
  ...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 |   57.89 |    71.42 |      50 |   57.89 | ...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.28 |    92.3 |   79.08 | ...2609,2660-2668 
  ...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       
  ...cpApproval.ts |   92.37 |    83.33 |     100 |   92.37 | ...00-103,115-116 
  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               
  ...tleRepaint.ts |     100 |      100 |     100 |     100 |                   
  ...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.39 |    72.83 |     100 |   98.39 |                   
  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   |   97.91 |       92 |     100 |   97.91 | ...51-352,354-355 
  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.33 |    82.79 |   92.77 |   83.33 |                   
  ...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   |   99.02 |    97.14 |     100 |   99.02 | 106               
  ...storyUtils.ts |   62.74 |    71.26 |      90 |   62.74 | ...84,432,437-459 
  ...ickerUtils.ts |     100 |      100 |     100 |     100 |                   
  ...ataService.ts |   93.17 |     79.1 |     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 |      57 |     40.8 |   79.41 |      57 |                   
  collect.ts       |   55.92 |    50.58 |   86.36 |   55.92 | ...25-640,642-647 
  index.ts         |     100 |      100 |     100 |     100 |                   
  normalize.ts     |   58.11 |    20.51 |      80 |   58.11 | ...13-314,328-363 
  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.16 |    89.14 |   90.43 |   72.16 |                   
  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 |   98.19 |    97.14 |     100 |   98.19 | 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.37 |    93.07 |     100 |   96.37 | ...15-416,514,527 
  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-1038            
  sessionPaths.ts  |   90.84 |    90.56 |     100 |   90.84 | ...81-182,185-186 
  settingsUtils.ts |   82.51 |    91.79 |   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.85 |     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.57 |    83.88 |   83.57 |   81.57 |                   
 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.47 |    79.84 |   93.06 |   88.47 |                   
  ...transcript.ts |   92.25 |    85.71 |     100 |   92.25 | ...01,320-321,452 
  ...ent-resume.ts |   83.08 |    69.86 |   78.12 |   83.08 | ...1120-1124,1127 
  ...ound-tasks.ts |   95.07 |    88.12 |     100 |   95.07 | ...1151,1171-1174 
  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 |   85.54 |     84.1 |   76.87 |   85.54 |                   
  agent-context.ts |     100 |      100 |     100 |     100 |                   
  agent-core.ts    |   77.31 |    73.21 |   65.21 |   77.31 | ...1704,1731-1778 
  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 |   91.36 |    89.89 |      80 |   91.36 | ...1231,1280-1283 
  ...ow-prompts.ts |     100 |      100 |     100 |     100 |                   
  ...ow-sandbox.ts |     100 |    98.11 |     100 |     100 | 117,287           
 src/agents/tasks  |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/agents/team   |   80.31 |    83.19 |    86.5 |   80.31 |                   
  TeamManager.ts   |   67.11 |    76.25 |   74.41 |   67.11 | ...1433,1456-1457 
  identity.ts      |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...sionBridge.ts |     100 |      100 |     100 |     100 |                   
  mailbox.ts       |   94.76 |    86.36 |   92.85 |   94.76 | 86-87,348-354     
  ...ptAddendum.ts |     100 |      100 |     100 |     100 |                   
  tasks.ts         |   88.85 |    82.47 |   96.29 |   88.85 | ...-990,1034-1035 
  team-events.ts   |   60.52 |      100 |      50 |   60.52 | ...37-141,148-152 
  teamHelpers.ts   |   92.02 |    94.91 |   95.23 |   92.02 | ...31-332,368-378 
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...eam/test-utils |   94.39 |    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        |    78.1 |    83.75 |    63.8 |    78.1 |                   
  config.ts        |   76.41 |    82.91 |   60.07 |   76.41 | ...4827,4832-4833 
  constants.ts     |     100 |      100 |     100 |     100 |                   
  models.ts        |     100 |      100 |     100 |     100 |                   
  storage.ts       |   94.24 |    91.02 |   88.09 |   94.24 | ...68-369,372-373 
 ...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.32 |    83.53 |    91.9 |   88.32 |                   
  baseLlmClient.ts |   81.25 |    76.47 |   77.77 |   81.25 | ...13,515-525,534 
  client.ts        |   86.77 |    80.28 |   89.83 |   86.77 | ...2530,2624-2625 
  ...tGenerator.ts |   84.86 |    69.23 |     100 |   84.86 | ...84,386,393-396 
  ...lScheduler.ts |   87.18 |    81.46 |   95.83 |   87.18 | ...4111,4139-4150 
  geminiChat.ts    |   91.37 |    87.77 |   96.15 |   91.37 | ...3032,3099-3100 
  geminiRequest.ts |     100 |      100 |     100 |     100 |                   
  ...MediaLimit.ts |     100 |    95.83 |     100 |     100 | 96                
  ...htProtocol.ts |    9.09 |      100 |       0 |    9.09 | ...9,62-66,69-110 
  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.78 |       96 |     100 |   98.78 | 93                
  prompts.ts       |   88.93 |    87.87 |   72.72 |   88.93 | ...-910,1113-1114 
  tokenLimits.ts   |     100 |    89.47 |     100 |     100 | 51-52             
  ...okTriggers.ts |   99.43 |    91.34 |     100 |   99.43 | 172,183           
  turn.ts          |   96.35 |    88.67 |     100 |   96.35 | ...28,441-442,486 
 ...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.22 |    83.96 |   91.17 |   94.22 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...tGenerator.ts |   94.09 |     82.5 |   90.62 |   94.09 | ...1025-1026,1054 
  ...tDetection.ts |     100 |      100 |     100 |     100 |                   
 ...ntentGenerator |   86.35 |     84.4 |   93.67 |   86.35 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  converter.ts     |   84.89 |    82.17 |   96.15 |   84.89 | ...1395,1611-1626 
  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.38 |     86.5 |     100 |   94.38 | ...38-539,547,615 
  ...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.64 |    79.44 |   80.31 |   62.64 |                   
  ...-converter.ts |   66.28 |    52.03 |     100 |   66.28 | ...98-799,808-840 
  ...ionManager.ts |   47.85 |    82.19 |    65.9 |   47.85 | ...1402,1412-1431 
  ...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 | ...66-372,411-464 
  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-107,141-146    
  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.29 |    85.18 |   81.25 |   55.29 |                   
  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 | 95                
  ...nGenerator.ts |   70.23 |    74.57 |   83.33 |   70.23 | ...83-247,317-319 
 src/generated     |       0 |        0 |       0 |       0 |                   
  git-commit.ts    |       0 |        0 |       0 |       0 | 1-10              
 src/goals         |   89.57 |    83.57 |   94.44 |   89.57 |                   
  ...eGoalStore.ts |    85.1 |    95.45 |   84.61 |    85.1 | ...63-166,174-182 
  goalHook.ts      |   97.26 |    91.66 |     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.88 |    85.58 |   88.01 |   86.88 |                   
  ...okRegistry.ts |   86.48 |    77.08 |     100 |   86.48 | ...41-344,362-369 
  ...bortSignal.ts |     100 |      100 |     100 |     100 |                   
  ...terpolator.ts |   96.66 |    93.33 |     100 |   96.66 | 66-67             
  ...HookRunner.ts |   96.68 |    87.23 |     100 |   96.68 | 110-112,231-233   
  ...Aggregator.ts |   96.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  |   91.48 |    84.61 |     100 |   91.48 | ...97,416,420,424 
  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 | ...3-964,993-1001 
  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.42 |     51.9 |   52.14 |   42.42 |                   
  ...nfigLoader.ts |   70.27 |    35.89 |   94.73 |   70.27 | ...20-422,426-432 
  ...ionFactory.ts |   42.81 |    73.07 |      50 |   42.81 | ...76-427,433-450 
  ...Normalizer.ts |   23.09 |    13.72 |   30.43 |   23.09 | ...04-905,909-924 
  ...verManager.ts |   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           |   79.21 |    76.52 |   76.36 |   79.21 |                   
  configHash.ts    |     100 |      100 |     100 |     100 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  ...h-provider.ts |   86.95 |      100 |   33.33 |   86.95 | ...,93,97,101-102 
  ...h-provider.ts |   73.82 |    53.92 |     100 |   73.82 | ...88-895,902-904 
  ...en-storage.ts |   98.64 |    97.77 |     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.76 |    77.74 |   72.68 |   73.76 |                   
  const.ts         |   94.28 |     92.3 |     100 |   94.28 | 66-67             
  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 |       80 |     100 |   90.47 | 50-51             
  paths.ts         |   79.06 |    95.12 |     100 |   79.06 | 32-33,49-86       
  prompt.ts        |   94.87 |    78.57 |     100 |   94.87 | ...63,166,304-305 
  recall.ts        |   82.06 |       75 |    90.9 |   82.06 | ...59-364,395-406 
  ...ceSelector.ts |   93.02 |    81.81 |     100 |   93.02 | ...24,126-127,135 
  scan.ts          |   92.92 |    73.91 |     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 |    81.03 |   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.68 |    91.87 |   68.32 |   82.68 |                   
  autoMode.ts      |   97.84 |    94.27 |     100 |   97.84 | 523-524,545-552   
  ...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.39 |    93.82 |     100 |   97.39 | ...-882,1031-1033 
  ...-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/plan-gate     |   62.39 |     92.3 |   56.25 |   62.39 |                   
  ...viewAgents.ts |   56.02 |    88.46 |   66.66 |   56.02 | ...09-175,197-198 
  ...provalGate.ts |   62.77 |    94.59 |    37.5 |   62.77 | ...46-249,252-258 
  state.ts         |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 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          |    85.3 |    78.57 |   95.89 |    85.3 |                   
  ...tGenerator.ts |   98.64 |    98.18 |     100 |   98.64 | 105-106           
  qwenOAuth2.ts    |   82.55 |    73.24 |   90.62 |   82.55 | ...1183-1199,1229 
  ...kenManager.ts |   85.36 |    76.61 |     100 |   85.36 | ...52-757,778-783 
 src/services      |   85.31 |    83.51 |   91.68 |   85.31 |                   
  ...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 |   81.88 |    82.05 |    77.5 |   81.88 | ...1412,1415-1427 
  ...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 |   78.77 |    76.76 |   81.57 |   78.77 | ...1258,1299-1302 
  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.37 |    95.45 |     100 |   98.37 | 185-186           
  ...ureMonitor.ts |   96.06 |    91.48 |   96.96 |   96.06 | ...49,850,864-866 
  ...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  |     9.7 |      100 |       0 |     9.7 | 44-174            
  ...ionService.ts |   84.39 |     77.2 |   94.28 |   84.39 | ...1488,1526-1546 
  sessionTitle.ts  |   93.87 |    71.15 |     100 |   93.87 | ...33-236,267-268 
  ...ionService.ts |   81.29 |    78.24 |   89.28 |   81.29 | ...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 |   89.03 |    65.38 |     100 |   89.03 | ...23-325,330-331 
  ...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 |       92 |     100 |   98.05 |                   
  microcompact.ts  |   98.05 |       92 |     100 |   98.05 | ...19,292,296,394 
 src/skills        |   88.14 |    86.62 |      90 |   88.14 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...activation.ts |     100 |     93.1 |     100 |     100 | 93,112            
  skill-load.ts    |   94.84 |     87.5 |     100 |   94.84 | ...03,223,235-237 
  skill-manager.ts |   83.39 |    81.42 |   82.35 |   83.39 | ...1199,1206-1210 
  skill-paths.ts   |   89.15 |    86.36 |     100 |   89.15 | ...00-101,106-107 
  symlinkScope.ts  |     100 |      100 |     100 |     100 |                   
  types.ts         |   97.91 |       98 |     100 |   97.91 | 277-278           
 src/subagents     |   85.84 |    85.55 |   94.33 |   85.84 |                   
  ...ter-schema.ts |     100 |    98.07 |     100 |     100 | 99                
  ...tin-agents.ts |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...nt-manager.ts |    81.2 |    79.93 |   91.17 |    81.2 | ...1432,1509-1510 
  types.ts         |     100 |      100 |     100 |     100 |                   
  validation.ts    |   92.46 |    95.18 |     100 |   92.46 | 47-52,63-68,71-76 
 src/telemetry     |   78.56 |    87.69 |   80.33 |   78.56 |                   
  config.ts        |     100 |      100 |     100 |     100 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  ...on-metrics.ts |   98.96 |    79.48 |     100 |   98.96 | 169,183           
  ...on-tracing.ts |   74.55 |    73.21 |   70.58 |   74.55 | ...95,336-338,354 
  ...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.31 |    80.85 |   77.19 |   75.31 | ...1021,1024-1035 
  ...attributes.ts |     100 |      100 |     100 |     100 |                   
  ...ime-config.ts |       0 |        0 |       0 |       0 | 1                 
  sanitize.ts      |      80 |    83.33 |     100 |      80 | 35-36,41-42       
  sdk.ts           |   86.75 |     88.4 |   66.66 |   86.75 | ...17-621,659-681 
  ...on-context.ts |     100 |      100 |     100 |     100 |                   
  ...on-tracing.ts |   90.04 |    88.11 |   96.55 |   90.04 | ...1504,1535-1538 
  ...etry-utils.ts |     100 |      100 |     100 |     100 |                   
  ...l-decision.ts |     100 |      100 |     100 |     100 |                   
  trace-context.ts |     100 |      100 |     100 |     100 |                   
  ...e-id-utils.ts |     100 |      100 |     100 |     100 |                   
  tracer.ts        |   98.56 |    88.63 |     100 |   98.56 | 52,101            
  types.ts         |   79.46 |    93.91 |   84.21 |   79.46 | ...1241,1244-1273 
  uiTelemetry.ts   |      92 |    95.34 |   80.95 |      92 | ...00,206-216,244 
 ...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.44 |    96.15 |   77.77 |   93.44 |                   
  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.71 |    97.36 |   74.19 |   91.71 | ...54,218-219,232 
  ...aceContext.ts |     100 |      100 |     100 |     100 |                   
 src/tools         |   79.37 |    82.04 |   85.78 |   79.37 |                   
  ...erQuestion.ts |   90.03 |    79.36 |   91.66 |   90.03 | ...99-400,407-408 
  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 
  enterPlanMode.ts |   90.69 |       75 |   85.71 |   90.69 | 55-56,74-79       
  exit-worktree.ts |   84.23 |    85.96 |   91.66 |   84.23 | ...92-293,298-312 
  exitPlanMode.ts  |   64.45 |    78.57 |     100 |   64.45 | ...22-334,346-349 
  glob.ts          |   90.63 |    88.33 |   84.61 |   90.63 | ...28,171,302,305 
  grep.ts          |   79.04 |    85.71 |      75 |   79.04 | ...73-580,604-605 
  ...adTracking.ts |     100 |      100 |     100 |     100 |                   
  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 |   80.51 |    78.46 |   84.44 |   80.51 | ...2981,2983-2984 
  mcp-client.ts    |      43 |    87.57 |      75 |      43 | ...1790,1794-1797 
  ...ry-timeout.ts |     100 |      100 |     100 |     100 |                   
  mcp-errors.ts    |     100 |      100 |     100 |     100 |                   
  ...pool-entry.ts |   77.21 |    83.96 |   79.41 |   77.21 | ...1259,1267-1268 
  ...ool-events.ts |       8 |        0 |       0 |       8 | 123-149           
  mcp-pool-key.ts  |   97.46 |    93.93 |     100 |   97.46 | 175-176           
  mcp-tool.ts      |   91.36 |    89.32 |   96.55 |   91.36 | ...40-641,691-692 
  ...sport-pool.ts |   83.27 |       80 |   84.61 |   83.27 | ...1399,1406-1410 
  ...ace-budget.ts |   87.27 |     82.6 |     100 |   87.27 | ...00-305,340-345 
  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 
  ...escendants.ts |   36.17 |    64.51 |   55.55 |   36.17 | ...46-310,385-390 
  ...nforcement.ts |   82.57 |       90 |     100 |   82.57 | 174-185,234-247   
  read-file.ts     |   94.75 |    90.32 |   81.81 |   94.75 | ...02,305,388-389 
  ripGrep.ts       |   94.17 |    85.71 |    87.5 |   94.17 | ...96-497,547-548 
  ...-transport.ts |    6.34 |        0 |       0 |    6.34 | 47-145            
  send-message.ts  |   79.48 |    86.95 |    62.5 |   79.48 | ...97-203,286-294 
  ...n-mcp-view.ts |   92.37 |    93.54 |   88.88 |   92.37 | 118-126           
  shell.ts         |   74.32 |    80.89 |   90.54 |   74.32 | ...4272,4331-4332 
  skill-utils.ts   |     100 |      100 |     100 |     100 |                   
  skill.ts         |    89.4 |     92.5 |   88.88 |    89.4 | ...43,447,476-498 
  ...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 | ...02,105,109-116 
  task-stop.ts     |   93.14 |    96.15 |   85.71 |   93.14 | 39-40,54-64       
  task-update.ts   |   80.67 |       78 |    92.3 |   80.67 | ...75-383,415-426 
  team-create.ts   |   97.22 |    85.71 |   83.33 |   97.22 | 48-49,129-130     
  team-delete.ts   |   86.74 |    83.33 |   83.33 |   86.74 | 37-38,42-48,72-73 
  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 |   76.19 |     76.1 |   81.39 |   76.19 | ...53-854,862-863 
  tool-search.ts   |   92.35 |    85.84 |    92.3 |   92.35 | ...08-213,320-329 
  tools.ts         |   92.33 |    90.74 |   90.47 |   92.33 | ...99-500,516-522 
  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   |   76.07 |    84.05 |   76.66 |   76.07 |                   
  agent.ts         |   76.29 |    84.25 |    77.1 |   76.29 | ...3066,3093-3156 
  fork-subagent.ts |   71.08 |       75 |   71.42 |   71.08 | ...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 | ...59-260,272-275 
 src/utils         |   89.15 |    87.86 |   93.89 |   89.15 |                   
  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.23 |     100 |   94.76 | ...30-531,634-638 
  bareMode.ts      |   27.27 |      100 |       0 |   27.27 | 9-15,18-19        
  browser.ts       |   76.31 |    53.33 |     100 |   76.31 | ...37,43-44,65-66 
  btwUtils.ts      |   13.95 |      100 |       0 |   13.95 | 17-31,34-55       
  bundlePaths.ts   |     100 |      100 |     100 |     100 |                   
  ...ncyLimiter.ts |   94.64 |    95.23 |     100 |   94.64 | 64-66             
  ...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 |   96.78 |    89.13 |      95 |   96.78 | ...51-252,257,403 
  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.8 |     77.5 |   71.42 |    70.8 | ...41-142,161,186 
  fileUtils.ts     |    91.5 |    86.25 |   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      |   72.91 |    90.32 |   83.33 |   72.91 | ...,77-78,102-153 
  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.18 |     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 |    83.33 |   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 |   96.35 |    93.97 |   85.71 |   96.35 | ...35-336,347-348 
  ...nIdContext.ts |     100 |      100 |     100 |     100 |                   
  ...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 
  ...ultCleanup.ts |   15.45 |    33.33 |      25 |   15.45 | 33-136            
  truncation.ts    |   75.31 |    85.55 |   71.42 |   75.31 | ...49-454,458-482 
  windowsPath.ts   |   89.47 |    78.57 |     100 |   89.47 | ...57-58,62,90-91 
  ...aceContext.ts |   95.81 |    89.39 |     100 |   95.81 | ...74-275,299-301 
  xml.ts           |    97.8 |     87.5 |     100 |    97.8 | 98-99             
  yaml-parser.ts   |   83.87 |    73.84 |     100 |   83.87 | ...31-234,239-240 
 ...ils/filesearch |   83.58 |    81.02 |   94.28 |   83.58 |                   
  crawlCache.ts    |     100 |      100 |     100 |     100 |                   
  crawler.ts       |   83.07 |    77.74 |   94.82 |   83.07 | ...1468,1502-1503 
  fileSearch.ts    |   93.78 |    87.67 |     100 |   93.78 | ...70-271,273-274 
  fzfWorker.ts     |       0 |        0 |       0 |       0 | 1-109             
  ...rkerHandle.ts |   84.05 |    75.43 |   89.47 |   84.05 | ...30-334,340-341 
  ignore.ts        |     100 |      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.

LaZzyMan added 2 commits June 12, 2026 17:49
…st gaps

R1 of pre-push adversarial self-review on PR #5034 surfaced 6 confirmed
findings across 6 diverse lenses (correctness / security / reuse-altitude
/ self-invariant / consumer-breakage / test-gaps). Each finding faced 2
independent skeptics defaulting to refuted=true; 6 survived majority
challenge.

Source code:
- Worktree-preserved suffix wording now matches AgentTool's
  formatWorktreeSuffix (agent.ts:1700-1719) verbatim, including the
  `git worktree add <path> <branch>` recovery hint for the directory-
  removed-but-branch-preserved race.

Test gaps closed:
- schema-mode success after 1 nudge (round-2 args captured)
- schema-mode success after 2 nudges (round-3 args captured)
- schema-mode + agentType together — floor disallowedTools still unioned
- schema-mode caller-abort takes priority over the StructuredOutput
  terminal error (signal.aborted check at workflow-orchestrator.ts:489-490)
- override path dispose() runs in finally on the success path
- override path dispose() runs in finally on the terminate-mode-error path

Declined R1 finding: negative tests for invalid opt types (schema/model/
agentType passed null/number/empty-string). Adding upfront type
validation is scope creep — upstream does not, P1/P2 do not, and the
workflow tool is model-authored where these inputs are extremely
unlikely. Existing AJV / SubagentManager downstream errors are descriptive
enough. Will revisit if R2 makes a stronger case.

166/166 tests pass (workflow suite + adjacent + workflow-orchestrator).
typecheck + lint clean across packages/core, packages/cli,
integration-tests, sdk, webui.
…itize + 12 tests

R2 of pre-push adversarial self-review on PR #5034. 6 diverse-lens
finders (60 agents, ~2.5M tokens, 24 min) over the R1-fix-applied
code, with 2 independent skeptics defaulting to refuted=true.
12 confirmed survivors after adversarial verify; decisions below.

Security (FIX):
- agent() wrapper in workflow-sandbox.ts now JSON-revives agentOpts
  inside the vm runInContext block BEFORE passing them to the host
  dispatch. Closes a Proxy/inherited-getter escape that P3 introduced
  along with the user-supplied schema object: a script could have
  wrapped agentOpts.schema in a Proxy whose getter ran host-side code
  during SyntheticOutputTool construction / AJV compile. Same
  mechanism as args / parallel-result revival.
- runOverridePath now sanitizes opts.agentType through
  sanitizeForErrorMessage() (control chars → space) before
  interpolation into the "agent type 'X' not found" error message.
  Prevents a model-authored agentType containing CRLF / NUL from
  fragmenting a single-line error across log records / OTLP fields.

Reuse-altitude (FIX):
- Added JSDoc block to WorkflowWorktreeIsolation interface
  documenting each field's role for cleanup.

Test gaps (FIX, 12 new tests):
- agentType control-char sanitization regression
- dispose() runs in finally when subagent.execute throws
- isolation:'worktree' provision error branches (5):
  nested parent / git unavailable / not a git repo / parent dirty /
  createUserWorktree returns failure
- isolation:'worktree' cleanup branches (3):
  removeUserWorktree fails / branchPreserved race / removeUserWorktree
  throws — each preserves the worktree (or branch) with the right
  user-facing suffix
- combinations (2): model + isolation:'worktree' threads model AND
  provisions worktree; schema + isolation:'worktree' returns
  structured payload verbatim (preserved suffix only on string return)

Test infrastructure: vi.mock'd GitWorktreeService at the module level
(partial mock; preserves the existing exports the unrelated
worktreeCleanup.ts depends on) with a per-test beforeEach reset.

Declined R2 findings (kept the R1 line):
- [major] Schema parameter upfront validation: same scope-creep
  decline as R1. Upstream doesn't do it; AJV's downstream error is
  descriptive enough.
- [major] Worktree provision extracted to shared util with AgentTool:
  agreed in principle but out of P3 scope. A separate refactor PR
  should land that with AgentTool maintainers in the loop.

178/178 tests pass (workflow + adjacent suites). typecheck + lint
clean across packages/core, packages/cli, integration-tests, sdk,
webui.
@LaZzyMan LaZzyMan requested a review from wenshao June 12, 2026 15:06
@wenshao

wenshao commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator

Runtime verification — real TUI, tmux-driven (maintainer merge reference)

Verdict: PASS — built PR head 6b4d7216 locally and drove the real workflow tool through the TUI (with QWEN_CODE_ENABLE_WORKFLOWS=1), exercising all four P3 agent() options end-to-end. Every option shows a clean before/after against the PR's merge-base 9b4ba60e (P1/P2), where the same scripts hit the "scheduled for …" sandbox stubs.

Claim (my read of the diff)

P3 stops the sandbox from rejecting agent({schema|model|isolation|agentType}) and routes each to a real dispatch implementation: schema injects a per-call structured_output tool and returns the validated args as an object; agentType resolves via SubagentManager.findSubagentByName (unresolved → verbatim error); isolation:'worktree' provisions a git worktree under .qwen/worktrees/agent-<hex>; isolation:'remote' throws "not available in this build". The diff matches.

Method

  • PR worktree + a baseline worktree at the merge-base 9b4ba60e (P1/P2 — so the only delta is P3), both npm install && npm run build.
  • Real TUI (packages/cli/dist/index.js --approval-mode yolo, QWEN_CODE_ENABLE_WORKFLOWS=1) in tmux, isolated $HOME.
  • A local mock OpenAI server plays three roles by the tools each request advertises: the main agent (sees workflow) emits a workflow tool call carrying the test script; a schema-mode subagent (sees structured_output) emits that tool call; a plain subagent (Explore / worktree) returns text. So the main agent really invokes the workflow tool, the orchestrator really runs the script, and agent() really dispatches subagents through the P3 code — only the model token stream is mocked.

Steps — before/after, all at the workflow tool card

  1. agent({isolation:'remote'})

    • PR: ✗ Workflow → agent({isolation:'remote'}) is not available in this build.
    • Baseline: ✗ Workflow → agent({isolation: 'remote'}) is not supported in P1. Worktree / remote isolation is scheduled for a later phase.
  2. agent({schema}) happy path — PR returns a real object:

    { "runId": "wf_…", "phases": [], "logs": [], "result": { "primary_color": "blue", "confidence": 0.9 } }

    mock roles main → sub-schema → main (the subagent really called structured_output; the event listener captured its args).
    Baseline: ✗ agent({schema}) is not supported in P1. … scheduled for P3.

  3. 🔍 agent({schema}) failure path (PR) — subagent stubbornly answers in prose, never calls structured_output:
    ✗ Workflow → subagent completed without calling StructuredOutput (after 2 in-conversation nudges). (upstream-verbatim terminal error)

  4. agent({agentType:'NoSuchAgent_42xyz'})

    • PR: ✗ agent({agentType}): agent type 'NoSuchAgent_42xyz' not found.
    • Baseline: ✗ agent({agentType}) is not supported in P1.
  5. agent({agentType:'Explore'}) resolves & routes (PR)✓ Workflow → "result": "GREEN", roles main → sub-plain → main (built-in Explore resolved and the subagent ran on its surface). Baseline: ✗ … not supported in P1.

  6. agent({isolation:'worktree'}) full lifecycle (PR)✓ Workflow, and the worktree was really provisioned:

    result: "PURPLE
    
    [worktree preserved at .../.qwen/worktrees/agent-6b2b00d on branch worktree-agent-6b2b00d]"
    
    $ git worktree list
    .../proj                               fe416b3 [main]
    .../proj/.qwen/worktrees/agent-6b2b00d fe416b3 [worktree-agent-6b2b00d]
    

    The subagent ran inside the worktree and the lifecycle ran on completion. Baseline: ✗ … scheduled for a later phase, and no worktree directory was created (the stub rejects before provisioning).

agent() option Baseline (9b4ba60e, P1/P2) PR (6b4d7216, P3)
isolation:'remote' stub "scheduled for a later phase" "not available in this build"
isolation:'worktree' stub "scheduled for a later phase" worktree provisioned + subagent ran + lifecycle
schema (success) stub "scheduled for P3" returns validated object
schema (no tool call) n/a (stub) "after 2 in-conversation nudges"
agentType (not found) stub "not supported in P1" "agent type 'X' not found"
agentType:'Explore' stub "not supported in P1" resolves + routes → result

Findings

  • All four P3 options work at the real surface, and each shows the exact upstream-aligned message/behavior the PR claims. The worktree path is the most convincing — a real git worktree + branch appeared under .qwen/worktrees/ and the subagent ran inside it, then the lifecycle appended the preserve note.
  • The worktree completed via the preserve branch even though the subagent didn't change anything — matching the pre-existing hasWorktreeChanges/.qwen-session-marker quirk the PR description flags under S7. I confirmed it's a clean run that still preserves; it's the shared AgentTool cleanup-detection path, not something P3 introduced. Not a blocker.
  • ⚠️ agent({model}) was the one option I did not exercise at the TUI. Observing it needs two genuinely different providers to see the routing actually switch; my single mock provider can't show that. It's covered by the author's real-LLM E2E (S-series) and the model is threaded into SubagentConfig.model unit test. Flagging it as the gap in my runtime evidence.
  • The subagent token stream is mocked (deterministic, no API key), so this verifies P3's dispatch / sandbox / worktree-lifecycle wiring inside the real CLI process — not model quality. The author's 7/7 run against qwen3-coder-plus covers the live-model side; the two are complementary.
  • Scaffolding note (not about the PR): the mock is stateless and keyed off the tools advertised per request — when I added the schema-fail toggle I restarted it before re-running, after the PR fix(cli): drop tool calls after cancellation #5020 lesson about stale mock processes.

Build: npm install && npm run build on both worktrees, clean. Tests not re-run locally (CI + the author's 159+217 suite cover them); this is runtime evidence only.

中文版(验证报告)

运行时验证 — tmux 驱动真实 TUI(合并参考)

结论:PASS — 本地构建 PR head 6b4d7216,在真实 TUI 里(QWEN_CODE_ENABLE_WORKFLOWS=1)驱动真实 workflow 工具,端到端验证了 P3 的全部四个 agent() 选项。每个选项都与 PR 的 merge-base 9b4ba60e(P1/P2)形成干净的前后对照——相同脚本在基线上命中 sandbox 的 "scheduled for …" stub。

对 diff 的理解

P3 让 sandbox 不再拒绝 agent({schema|model|isolation|agentType}),而是路由到真正的 dispatch 实现:schema 注入 per-call structured_output 工具并把校验后的 args 作为对象返回;agentTypeSubagentManager.findSubagentByName 解析(解析不到 → 逐字错误);isolation:'worktree'.qwen/worktrees/agent-<hex> 下开 git worktree;isolation:'remote' 抛 "not available in this build"。diff 与此一致。

方法

  • PR worktree + 一个位于 merge-base 9b4ba60e(P1/P2,确保唯一差异是 P3)的基线 worktree,都 npm install && npm run build
  • 真实 TUI(--approval-mode yolo,QWEN_CODE_ENABLE_WORKFLOWS=1)在 tmux 中运行,$HOME 隔离。
  • 本地 mock OpenAI 服务器按每个请求声明的工具扮演三种角色:主 agent(看到 workflow)发出携带测试脚本的 workflow tool call;schema 模式子 agent(看到 structured_output)发出该 tool call;普通子 agent(Explore/worktree)返回文本。所以主 agent 真的调用了 workflow 工具,orchestrator 真的执行了脚本,agent() 真的经 P3 代码 dispatch 子 agent——只有模型的 token 流是 mock 的。

步骤 — 前后对照,均在 workflow 工具卡片观察

  1. agent({isolation:'remote'}) — PR:"not available in this build";基线:"not supported in P1 ... scheduled for a later phase"。
  2. agent({schema}) 成功路径 — PR 返回真正的对象 {"primary_color":"blue","confidence":0.9},mock 角色 main→sub-schema→main(子 agent 真的调了 structured_output,event listener 捕获其 args);基线:"scheduled for P3"。
  3. 🔍 agent({schema}) 失败路径(PR) — 子 agent 坚持用文本作答、从不调 structured_output:"subagent completed without calling StructuredOutput (after 2 in-conversation nudges)"(upstream 逐字终端错误)。
  4. agent({agentType:'NoSuchAgent_42xyz'}) — PR:"agent type 'NoSuchAgent_42xyz' not found";基线:"not supported in P1"。
  5. agent({agentType:'Explore'}) 解析并路由(PR)✓ Workflow,result "GREEN",角色 main→sub-plain→main(内置 Explore 解析成功、子 agent 在其工具面上运行);基线:"not supported in P1"。
  6. agent({isolation:'worktree'}) 完整生命周期(PR)✓ Workflow,worktree 真实创建:git worktree list 显示 .qwen/worktrees/agent-6b2b00d [worktree-agent-6b2b00d],子 agent 在其中运行,完成后 result 追加 "[worktree preserved at ... on branch ...]"。基线:"scheduled for a later phase",且没有创建 worktree 目录(stub 在 provision 前就拒了)。
agent() 选项 基线(9b4ba60e,P1/P2) PR(6b4d7216,P3)
isolation:'remote' stub "scheduled for a later phase" "not available in this build"
isolation:'worktree' stub "scheduled for a later phase" worktree 创建 + 子 agent 运行 + 生命周期
schema(成功) stub "scheduled for P3" 返回校验后对象
schema(不调工具) 不适用(stub) "after 2 in-conversation nudges"
agentType(未找到) stub "not supported in P1" "agent type 'X' not found"
agentType:'Explore' stub "not supported in P1" 解析 + 路由 → result

观察

  • 四个 P3 选项在真实 surface 上都工作,且每个都呈现 PR 声称的 upstream 对齐消息/行为。worktree 路径最有说服力——.qwen/worktrees/ 下真实出现了 git worktree + 分支,子 agent 在其中运行,生命周期追加了 preserve 提示。
  • worktree 即使子 agent 没改任何东西也走了 preserve 分支——与 PR 描述 S7 标注的既有 hasWorktreeChanges/.qwen-session marker quirk 一致。我确认这是干净运行仍被保留;它是 AgentTool 共享的 cleanup 检测路径,不是 P3 引入的,不阻塞合并。
  • ⚠️ agent({model}) 是我唯一没在 TUI 上验证的选项。 要观察它需要两个真正不同的 provider 才能看到路由切换;我的单一 mock provider 显示不出来。它由作者的真实 LLM E2E 和 "model 被 thread 进 SubagentConfig.model" 单测覆盖。作为我运行时证据的缺口标注出来。
  • 子 agent 的 token 流是 mock 的(确定性、无需 API key),所以本验证证明的是 P3 的 dispatch / sandbox / worktree 生命周期在真实 CLI 进程里的接线,而非模型质量。作者用 qwen3-coder-plus 跑的 7/7 覆盖了真实模型一侧,二者互补。
  • 脚手架说明(与 PR 无关):mock 无状态、按每请求声明的工具分角色——加 schema-fail 开关后我重启了它再重跑(吸取 PR fix(cli): drop tool calls after cancellation #5020 旧 mock 进程的教训)。

构建:两个 worktree 上 npm install && npm run build 干净通过。本地未重跑测试(CI + 作者 159+217 套件已覆盖);本报告只提供运行时证据。

Comment thread packages/core/src/agents/runtime/workflow-orchestrator.ts Outdated
Comment thread packages/core/src/agents/runtime/workflow-orchestrator.ts
Comment thread packages/core/src/agents/runtime/workflow-orchestrator.ts Outdated
Comment thread packages/core/src/agents/runtime/workflow-sandbox.ts

@wenshao wenshao left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Reviewed the full diff plus the API contracts it links against, and ran the suites locally.

Verified locally (fresh worktree at 6b4d721):

  • 160/160 workflow suite + 209/209 adjacent regression (subagents / syntheticOutput / agent-override) — all green
  • tsc --noEmit and eslint clean on touched files

Contract checks that hold (each verified against the actual implementations, not just the PR text):

  • Schema override sets TOOL_REGISTRY_REBUILT, so buildSubagentContextOverride skips its own rebuild and the per-call SyntheticOutputTool survives into the subagent's registry — the most fragile interaction in this design, handled correctly.
  • Validation failures surface as TOOL_RESULT success:false through CoreToolScheduler, so the 3-failure abort counting is real; agent-core's un-emitted-callId backfill keeps pendingArgs from dangling.
  • Ephemeral config (no tools, floor disallowedTools) → convertToRuntimeConfig yields tools: ['*'] — tool surface equivalent to the fast path.
  • Worktree provision/rebind/cleanup mirrors AgentTool line-for-line (dirty-parent refuse, fail-closed checks, double-finally with null-out against double cleanup).
  • vm-realm revival runs inside the vm bootstrap; the two security regressions pin the constructor-chain escape closed.
  • Fast path is byte-for-byte preserved (indentation-only diff).

Findings: one High (schema+agentType drops the resolved agent's persona — upstream contract appends; see inline), two Medium (abort-listener leak per schema call; terminateMode misdiagnosis + nudge wording; see inline), and two Low:

  • L1: no unit coverage for the worktree lifecycle (provision/rebind/cleanup — E2E S7 only, harness not committed) and none for the schema+agentType / schema+worktree combinations. Committing the harness under integration-tests/ as offered in the PR description would close most of this.
  • L2: schema-mode preserved-worktree info goes to debugLogger only, invisible to the script — acknowledged in the code comment as a deliberate tradeoff; worth revisiting once P4's narrator lands.

Overall: solid engineering — the dangerous interactions are all consciously handled with regression tests, and the PR honestly discloses the pre-existing session-marker quirk found during S7. Direction is approve; I'd fix H1 (small: append instead of replace + one combo test) and ideally M1 before merge.

Comment thread packages/core/src/agents/runtime/workflow-orchestrator.ts
Comment thread packages/core/src/agents/runtime/workflow-orchestrator.ts Outdated
Comment thread packages/core/src/agents/runtime/workflow-orchestrator.ts Outdated
wenshao
wenshao previously approved these changes Jun 12, 2026
Round 1 (15:41) + Round 2 (17:24) review from wenshao surfaced 7 inline
findings across schema-mode dispatch correctness, worktree cleanup
coverage, and error attribution. Each fix is paired with a regression
test that was RED before the change landed.

T0 [Critical] Worktree leak when schema setup throws after provision
  workflow-orchestrator.ts: outer try MOVED to start immediately after
  provisionWorkflowWorktree. Previously the try opened only after
  createSchemaConfigOverride / createSchemaModeState / signal listener
  attachment — so any throw in those three (broken MCP server during
  the per-call ToolRegistry rebuild was the trigger wenshao cited)
  orphaned the just-provisioned worktree under .qwen/worktrees/.
  Test: "isolation:'worktree' + schema setup throws → worktree is
  still cleaned up" — simulates createToolRegistry failure during
  createSchemaConfigOverride; asserts removeUserWorktree was called.

T1 [Critical] / T4 [H1] agentType + schema silently dead-ended
  workflow-orchestrator.ts: schema-mode augmented config now (a)
  appends ToolNames.STRUCTURED_OUTPUT to baseConfig.tools when the
  allowlist is restricted (no '*' and doesn't already contain it), so
  prepareTools / getFunctionDeclarationsFiltered doesn't filter
  structured_output out of the subagent's surface; (b) preserves the
  resolved agentType's persona by APPENDING the schema-contract
  instruction block instead of replacing the systemPrompt outright.
  Replace remains only on the ephemeral no-agentType path where
  baseConfig.systemPrompt IS WORKFLOW_SUBAGENT_SYSTEM_PROMPT (schema
  variant is its strict superset; avoids two near-identical prompts).
  Tests: structured_output appears in the allowlist alongside the
  agentType's existing tools; persona prompt is contained in the
  effective systemPrompt.

T2 [Suggestion] / T5 [M1] Parent-abort listener leaked per schema call
  workflow-orchestrator.ts: named listener stored at outer scope,
  removed in the outer finally regardless of how the dispatch ended.
  Previous `{ once: true }` only auto-removed on actual parent abort;
  the happy-path schema dispatch — success capture / 3-failure abort
  fires the CHILD controller without the parent ever aborting — left
  the listener stuck on the per-run signal. With N schema calls per
  workflow N listeners + N child-controller closures accumulated.
  Test: 5 sequential schema dispatches over the same parent signal
  end with zero live listeners.

T6 [M2] Terminate mode misdiagnosed as nudge exhaustion
  workflow-orchestrator.ts: schema path now distinguishes
  terminateMode before attributing failure to schema mode. TIMEOUT /
  MAX_TURNS / ERROR throw the existing "did not complete (terminate
  mode: X)" message that the non-schema path uses. Only the actual
  schema-failure cases produce schema wording, and those are split:
  attempts > 2 keeps the upstream-verbatim "(after 2 in-conversation
  nudges)" wording; attempts === 0 throws an accurate "no validation
  attempt — model produced plain-text content" instead of misleadingly
  citing nudges that never happened. (The existing 0-call test was
  updated to match the new accurate message; the 3-failure test
  retains the verbatim wording.)
  Tests: parametric over TIMEOUT/MAX_TURNS/ERROR asserting "did not
  complete"; companion test pinning the verbatim wording to the
  3-failure path.

T3 [Suggestion] Schema-mode JSON revival sentinel — clarified
  workflow-sandbox.ts: added a block comment documenting that the
  JSON-round-trip + null-on-throw is a SECURITY backstop (errors-as-data
  convention from parallel/pipeline) rather than a contract path —
  unreachable in production schema mode because the host return is
  LLM tool_call args, always JSON-serializable. No behavior change.

Tests: 75/75 orchestrator + 111/111 sandbox/tool/limiter green.
typecheck + lint clean across packages/core and packages/cli.

R1+R2 self-review commits (e1c5ec7 / 62624a9) precede this commit
on the same branch — they predate wenshao's review and address
distinct findings; reviewer L1 (worktree-lifecycle unit coverage) is
already closed by R2's 11 worktree tests.
@LaZzyMan LaZzyMan dismissed stale reviews from wenshao and qwen-code-ci-bot via 99a15fe June 13, 2026 08:28
@LaZzyMan

Copy link
Copy Markdown
Collaborator Author

Round 1 + 2 — addressed in 99a15fe

Thanks @wenshao for the runtime verification on top of two careful inline rounds. All 7 inline threads above have explicit replies + are resolved; this is the per-finding outcome:

# Severity Outcome Note
line 413 (R1) Critical (worktree leak) ✅ fixed outer try moved before schema setup; regression test for setup-throws path
line 374 (R1) + line 384 (R2) Critical + H1 (silent dead-end on agentType+schema) ✅ fixed (combined) append structured_output to a restricted allowlist + append schema instructions to the agentType persona instead of replacing it; 2 new tests
line 431 (R1+R2) Suggestion + M1 (parent-abort listener leak) ✅ fixed (combined) named listener stored at outer scope, removed in outer finally regardless of how dispatch ended; new "no accumulation over 5 sequential calls" test
sandbox line 554 (R1) Suggestion (revival null sentinel ambiguity) 📝 documented (no behavior change) unreachable in schema mode (LLM tool_call args are always JSON-serializable; AJV-validated); kept as residual EAD-1-style defense; added a comment block explaining the contract
line 494 (R2) M2 (terminate-mode misdiagnosis) ✅ fixed added terminate-mode check; split the "after 2 nudges" wording (kept verbatim for the actual 3-failure case) from a new accurate "no validation attempt — model produced plain-text content" for the 0-call case; nudge-loop deferred per your note

Two notes on your review summary

  • L1 (worktree-lifecycle unit coverage / combo tests). This was already closed before your review pass — picked up in my own pre-push self-review (commits e1c5ec79, 62624a99) on this branch but not yet pushed at the time you ran the suites. Those two commits added 11 worktree-related tests at the orchestrator layer (5 provision-error branches, 3 cleanup-error branches, 2 option combinations including schema + isolation:'worktree', 1 dispose() in finally), plus vi.mock'd GitWorktreeService infra so the suite can drive each path deterministically. They're all on the branch now alongside this round's fixes — no separate harness commit needed.
  • L2 (schema-mode preserved-worktree info only in debugLogger). Agreed — leaving as-is for this PR; revisit once P4's narrator lands and there's a structured channel for operator-visible info that doesn't perturb the script's structured payload.

Suite after this round: 75/75 orchestrator + 111/111 sandbox/tool/limiter green; tsc --noEmit and eslint clean on packages/core + packages/cli; the real-LLM E2E (7/7 against qwen3-coder-plus via DashScope) is unchanged.

@wenshao

wenshao commented Jun 13, 2026

Copy link
Copy Markdown
Collaborator

@qwen-code /triage

@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Thanks for the PR!

Template looks good ✓ — all required headings present, bilingual section included, test plan is thorough.

On direction: this is a well-scoped phase in a multi-phase port of upstream Claude Code's workflow dispatch contract. The upstream CHANGELOG confirms workflows are actively evolving (recent fixes for worktree isolation, attribution headers, trigger keywords). P3 completes the four agent() options that P1/P2 stubbed — this is convergence work, not feature creep. Aligned.

On approach: the phased architecture (P1 → P2 → P3) has held up well. Each phase adds a focused slice without re-architecting prior work. The 7-file scope is tight for what it delivers — four dispatch options, security hardening, and 403 passing tests. The fast-path preservation (byte-for-byte unchanged when no opts are set) is the right call for zero-overhead backward compatibility.

Moving on to code review. 🔍

中文说明

感谢贡献!

模板完整 ✓ — 所有必需标题齐全,双语部分包含在内,测试计划详尽。

方向:这是将上游 Claude Code 的 workflow dispatch 契约移植到 qwen-code 的一个范围明确的阶段。上游 CHANGELOG 确认 workflow 功能仍在积极演进(近期修复了 worktree 隔离、归因 headers、触发关键词等)。P3 补全了 P1/P2 中以 stub 形式预留的四个 agent() 选项——这是收敛性工作,不是功能蔓延。方向对齐。

方案:分阶段架构(P1 → P2 → P3)保持良好。每个阶段添加一个聚焦的切片,不重新设计先前工作。7 个文件的范围对于所交付的内容(四个 dispatch 选项、安全加固、403 个通过的测试)来说是紧凑的。快速路径保留(无 opts 时逐字节不变)是零开销向后兼容的正确做法。

进入代码审查 🔍

Qwen Code · qwen3.7-max

@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Code Review

Read all 7 changed files in the worktree. The implementation is clean and well-structured.

What I independently would have done: extend createProductionDispatch with a two-path split (fast vs override), resolve agentType via SubagentManager.findSubagentByName, inject a per-call SyntheticOutputTool for schema mode, thread model into SubagentConfig, and provision worktrees via GitWorktreeService. This is essentially what the PR does.

Findings — no blockers:

  • The nested try/finally structure (inner: agent dispose, outer: worktree cleanup + parent-abort listener removal) is correct and well-justified by the review history (R3 T0/T2/T5 fixes).
  • Security handling is thorough: JSON revival for schema-mode object returns closes the T1/T8/T14 prototype escape, agentType sanitization prevents log injection, and the sandbox opts are JSON-round-tripped before crossing the vm boundary.
  • The createWorktreeConfigOverride using Object.create(base) with own-property rebinds for all cwd-adjacent getters is the right pattern — matches AgentTool's approach.
  • Schema mode's per-call isolation (own SchemaModeState, own AbortController, own ToolRegistry) correctly prevents cross-contamination under parallel().
  • The pre-existing hasWorktreeChanges / .qwen-session marker quirk is correctly documented and not introduced by P3.

No AGENTS.md violations detected. The code stays within the workflow subsystem, follows ESM + TypeScript strict conventions, and tests are collocated with source.

Test Results

Unit + Integration (worktree, PR branch 6b4d721)

$ cd packages/core && npx vitest run \
    src/agents/runtime/workflow-orchestrator.test.ts \
    src/agents/runtime/workflow-sandbox.test.ts \
    src/tools/workflow/workflow.test.ts

 ✓ src/tools/workflow/workflow.test.ts (17 tests)
 ✓ src/agents/runtime/workflow-orchestrator.test.ts (75 tests)
 ✓ src/agents/runtime/workflow-sandbox.test.ts (86 tests)

 Test Files  3 passed (3)
      Tests  178 passed (178)

Adjacent Regression

$ npx vitest run src/subagents/ src/config/config.workflow \
    src/tools/syntheticOutput src/tools/agent/agent-override.test.ts \
    src/utils/concurrencyLimiter.test.ts

 Test Files  11 passed (11)
      Tests  225 passed (225)

Typecheck + ESLint

$ npx tsc --noEmit -p packages/core/tsconfig.json  → clean
$ npx eslint <4 changed source files>              → clean

Sandbox-Level Verification (tmux, built PR)

Drove the sandbox agent() wrapper through 6 scenarios with a mock dispatch — verifying that each P3 option reaches the dispatch layer correctly and the sandbox's JSON revival handles object returns:

✅ isolation:remote (threw): agent({isolation:'remote'}) is not available in this build.
✅ isolation:invalid (threw): agent({isolation: 'bogus'}): unknown isolation mode. Known modes are: 'worktree', 'remote'.
✅ schema passthrough: {"x":"test-result-schema"}
✅ model passthrough: test-result-model
✅ agentType passthrough: test-result-agentType
✅ fast path: fast-path-result

=== 6/6 scenarios passed ===

This confirms the sandbox-level wiring (option allowlist, isolation validation, JSON revival for object returns, fast-path preservation). The full dispatch path (SubagentManager resolution, worktree provisioning, schema event-listener lifecycle) is covered by the 178 unit tests above plus the runtime verification from @wenshao's earlier comment (mock-driven TUI, 6/7 options exercised end-to-end) and the author's real-LLM E2E (7/7 against qwen3-coder-plus).

中文说明

代码审查

在 worktree 中阅读了全部 7 个变更文件。实现干净且结构良好。

我独立会怎么做: 扩展 createProductionDispatch,分为快速路径和覆盖路径;通过 SubagentManager.findSubagentByName 解析 agentType;为 schema 模式注入 per-call SyntheticOutputTool;将 model 传入 SubagentConfig;通过 GitWorktreeService 配置 worktree。这基本上就是 PR 所做的。

发现——无阻塞项:

  • 嵌套 try/finally 结构(内层:agent dispose,外层:worktree 清理 + parent-abort 监听器移除)正确,且由审查历史(R3 T0/T2/T5 修复)充分证明。
  • 安全处理彻底:schema 模式对象返回的 JSON 复活关闭了 T1/T8/T14 原型逃逸,agentType 净化防止日志注入,sandbox opts 在跨越 vm 边界前经过 JSON 往返。
  • createWorktreeConfigOverride 使用 Object.create(base) 加自有属性重绑定所有 cwd 相邻的 getter——与 AgentTool 的方法一致。
  • Schema 模式的 per-call 隔离(自有 SchemaModeState、自有 AbortController、自有 ToolRegistry)正确防止了 parallel() 下的交叉污染。
  • 既有的 hasWorktreeChanges / .qwen-session 标记怪癖已正确记录,不是 P3 引入的。

未检测到 AGENTS.md 违规。 代码保持在 workflow 子系统内,遵循 ESM + TypeScript 严格模式约定,测试与源码并列。

测试结果

  • 178/178 workflow 测试通过(orchestrator + sandbox + workflow tool)
  • 225/225 相邻回归测试通过(subagents, config, syntheticOutput, agent-override, concurrencyLimiter)
  • TypeScript 类型检查干净
  • ESLint 干净
  • Sandbox 级别验证(tmux,构建后的 PR):6/6 场景通过

Qwen Code · qwen3.7-max

@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Reflection

Stepping back: this PR delivers exactly what P1/P2 designed for. The four agent() options complete the dispatch contract, and the implementation is a textbook example of how to extend a phased architecture without disrupting prior work.

My independent proposal matched the PR's approach — two-path dispatch, SubagentManager resolution, per-call schema state, worktree provisioning via GitWorktreeService. The PR exceeds it in the details: the security hardening (JSON revival for object returns, agentType sanitization, opts round-tripping), the review-driven fixes (R3 T0 worktree leak, T2 listener accumulation, M2 terminate-mode disambiguation), and the fast-path preservation all show careful engineering.

The test evidence is strong: 403 unit/integration tests across all affected surfaces, clean typecheck and lint, sandbox-level verification confirming the option routing, and two independent runtime verifications (collaborator's mock-driven TUI + author's real-LLM E2E). The one gap — agent({model}) not exercised at the TUI level — is acknowledged and covered by unit tests + the author's real-LLM run.

The pre-existing worktree cleanup-detection quirk (.qwen-session marker seen as dirty) is correctly flagged for follow-up and not introduced here.

This is ready to ship. ✅

中文说明

反思

退一步看:这个 PR 精确地交付了 P1/P2 所设计的内容。四个 agent() 选项完成了 dispatch 契约,实现是扩展分阶段架构而不干扰先前工作的教科书式范例。

我的独立方案与 PR 的方法一致——双路径 dispatch、SubagentManager 解析、per-call schema 状态、通过 GitWorktreeService 配置 worktree。PR 在细节上超越了它:安全加固(对象返回的 JSON 复活、agentType 净化、opts 往返)、审查驱动的修复(R3 T0 worktree 泄漏、T2 监听器累积、M2 terminate-mode 区分)以及快速路径保留都展示了精心的工程。

测试证据充分:403 个单元/集成测试覆盖所有受影响的表面,类型检查和 lint 干净,sandbox 级别验证确认了选项路由,以及两个独立的运行时验证(协作者的 mock 驱动 TUI + 作者的真实 LLM E2E)。

准备好合并了。✅

Qwen Code · qwen3.7-max

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

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM, looks ready to ship. ✅

@wenshao wenshao merged commit 06345a2 into main Jun 13, 2026
98 checks passed
@wenshao

wenshao commented Jun 13, 2026

Copy link
Copy Markdown
Collaborator

🔬 Local runtime verification — Workflow P3 agent({schema, agentType, model, isolation}) (real CLI + workflow tool under tmux)

Verdict: ✅ PASS on the P3 feature logic — with one ⚠️ real bug: isolation worktrees are never auto-removed (they leak on disk).

I ran the real built CLI with the workflow tool enabled (via the pre-existing QWEN_CODE_ENABLE_WORKFLOWS=1 env gate — the PR's code runs unmodified), pointed at a deterministic mock LLM. The model calls the workflow tool with one script that probes every new agent() option; the workflow's real production dispatch spawned real subagents that hit the mock. Run in a clean git workspace and a dirty one.

Results — every agent() option behaves as documented

probe outcome observed
agent({schema}) ✅ returns validated object { "answer": "HELLO" } (subagent's structured_output args, AJV-validated, revived into the vm realm)
{schema} no tool call ✅ terminal error subagent completed without calling structured_output (no validation attempt — model produced plain-text content).
{schema} invalid args ×3 ✅ terminal error subagent completed without calling StructuredOutput (after 2 in-conversation nudges). ← the R3 (wenshao M2) message split works
{isolation:'remote'} ✅ throws agent({isolation:'remote'}) is not available in this build.
{agentType:'…nonexistent…'} ✅ throws agent({agentType}): agent type '…' not found.
{isolation:'bogus-mode'} ✅ throws agent({isolation: 'bogus-mode'}): unknown isolation mode. Known modes are: 'worktree', 'remote'.
{schema: <circular>} ✅ throws (security guard) agent() opts contain a non-JSON-serializable value: Converting circular structure to JSON …
{isolation:'worktree'} (clean tree) ✅ provisions + runs subagent in the worktree result returned; worktree at .qwen/worktrees/agent-<hex> on branch worktree-agent-<hex>
{isolation:'worktree'} (dirty tree) ✅ refuses parent working tree at … has uncommitted changes that would not propagate … Commit or stash the changes, then re-run.

So the schema/structured-output contract (both failure modes), agentType resolution + not-found, isolation routing/validation, the dirty-tree refusal, and the vm/host non-serializable security guard all work end-to-end through the real subagent stack. The node:vm opts-revival and the object→vm-realm return revival both hold (the schema probe returns a real validated object, not a string).

⚠️ Bug: isolation worktrees are never auto-removed — they leak on disk

The tool description promises "the worktree is auto-removed if no changes." It never is. My worktree subagent made zero changes, yet every run preserved the worktree and returned done\n\n[worktree preserved: …/agent-<hex> (branch worktree-agent-<hex>)]. Three runs left three worktrees + three worktree-agent-* branches behind until I removed them by hand.

Root cause (in writeWorktreeSessionMarker, packages/core/src/services/gitWorktreeService.ts — outside this PR's diff, but this PR's cleanup contract newly depends on it): it writes the .qwen-session exclude rule to git rev-parse --git-dir (the per-worktree gitdir), but git reads info/exclude from the common gitdir (--git-common-dir). For a linked worktree these differ, so the rule lands where git never looks. Proven directly:

# inside the provisioned worktree:
--git-dir        = …/.git/worktrees/agent-fc72cdc      ← code writes the exclude here
--git-common-dir = …/.git                              ← git actually reads from here
$ cat …/.git/worktrees/agent-fc72cdc/info/exclude  →  .qwen-session   (rule IS present)
$ git status --porcelain                            →  ?? .qwen-session  (still untracked!)
# move the SAME rule to the common exclude instead:
$ echo .qwen-session >> …/.git/info/exclude ; git status --porcelain  →  (empty — now ignored)

So the marker always shows untracked → hasWorktreeChanges() always returns truecleanupWorkflowWorktree always takes the "preserve" branch. The .qwen/worktrees/ dir (and a branch per call) accumulates indefinitely. The same writeWorktreeSessionMarker backs the existing AgentTool worktree path (agent.ts:1955), so this isn't introduced here — but P3 widens the blast radius, since a workflow can fan out many isolated subagents.

Fix: one word — resolve --git-common-dir instead of --git-dir when locating info/exclude in writeWorktreeSessionMarker. (Verified at the git level above; the orchestrator's cleanup is gated solely on hasWorktreeChanges/hasUnmerged, so a correctly-placed exclude makes the no-change path auto-remove.)

Observations / notes

  • The schema-failure message split is a nice touch and works exactly as the R3 review intended: no-attempt (plain text) vs 2-nudge exhaustion (3 invalid structured_output calls) produce distinct, accurate terminals.
  • agent({model}) rides the same createAgentHeadless override path as agentType/isolation (both verified); I did not assert it independently because the mock is model-agnostic — the request would just carry a different model id.
  • Feature is gated off in the product (no settings/CLI wiring for workflowsEnabled; only the QWEN_CODE_ENABLE_WORKFLOWS env gate exists), so none of this is user-reachable yet — consistent with a P3 building-block PR.

Reproduce

# real CLI, workflow tool enabled via the existing env gate, pointed at a mock LLM
QWEN_CODE_ENABLE_WORKFLOWS=1 OPENAI_BASE_URL=http://127.0.0.1:PORT/v1 OPENAI_API_KEY=sk-mock \
OPENAI_MODEL=mock-model QWEN_HOME=<isolated> \
  node packages/cli/dist/index.js --approval-mode yolo --output-format json -p "run the workflow"
# mock: main turn → workflow tool_call with a script that try/catches agent() with each option;
#       schema subagent → structured_output({answer}); BADARGS subagent → structured_output({wrong});
#       FAILTEST subagent → plain text. Run once in a clean git repo, once in a dirty one.
# observe: the returned summary (all 9 probes) + `.qwen/worktrees/agent-* ` left behind after a no-change run.

Verified on Linux, Node v22, git 2.47.3. Real subagents via production dispatch; deterministic stub model. The workflow ran under tmux against the built packages/cli/dist/index.js.


🇨🇳 中文版(点击展开)

🔬 本地真实运行验证 —— Workflow P3 agent({schema, agentType, model, isolation})(tmux 下真实 CLI + workflow 工具)

结论:✅ P3 功能逻辑全部通过 —— 但发现一个 ⚠️ 真实 bug:隔离 worktree 永远不会被自动清理(会在磁盘上泄漏)。

我运行了真实构建的 CLI,通过已存在的 QWEN_CODE_ENABLE_WORKFLOWS=1 环境开关启用 workflow 工具(PR 的代码未做任何改动),并指向一个确定性的 mock LLM。模型调用 workflow 工具,传入一个会探测每个新 agent() 选项的脚本;workflow 的真实 production dispatch 派生了真实的 subagent,它们都打到 mock。分别在一个干净的 git 工作区和一个有未提交改动的工作区里跑。

结果 —— 每个 agent() 选项都按文档行为表现

探测 结果 观察到的
agent({schema}) ✅ 返回校验后的对象 { "answer": "HELLO" }(subagent 的 structured_output 参数,经 AJV 校验,并 revive 回 vm realm)
{schema} 不调用工具 ✅ 终止错误 subagent completed without calling structured_output (no validation attempt — model produced plain-text content).
{schema} 参数非法 ×3 ✅ 终止错误 subagent completed without calling StructuredOutput (after 2 in-conversation nudges). ← R3(wenshao M2)的消息拆分生效
{isolation:'remote'} ✅ 抛错 agent({isolation:'remote'}) is not available in this build.
{agentType:'…不存在…'} ✅ 抛错 agent({agentType}): agent type '…' not found.
{isolation:'bogus-mode'} ✅ 抛错 agent({isolation: 'bogus-mode'}): unknown isolation mode. Known modes are: 'worktree', 'remote'.
{schema: <循环引用>} ✅ 抛错(安全护栏) agent() opts contain a non-JSON-serializable value: Converting circular structure to JSON …
{isolation:'worktree'}(干净) ✅ 创建并在 worktree 内运行 subagent 返回结果;worktree 在 .qwen/worktrees/agent-<hex>,分支 worktree-agent-<hex>
{isolation:'worktree'}(脏) ✅ 拒绝 parent working tree at … has uncommitted changes … Commit or stash the changes, then re-run.

所以 schema/结构化输出契约(两种失败模式)、agentType 解析与 not-found、isolation 路由/校验、脏树拒绝、以及 vm/host 的不可序列化安全护栏,全部通过真实 subagent 链路端到端跑通。node:vm 的 opts revive 和「对象返回值 revive 回 vm realm」都成立(schema 探测返回的是真实的校验对象,不是字符串)。

⚠️ Bug:隔离 worktree 永不自动清理 —— 在磁盘上泄漏

工具描述承诺「无改动时 worktree 会被自动移除」。但它从不移除。我的 worktree subagent 没做任何改动,但每次运行都保留了 worktree,并返回 done\n\n[worktree preserved: …/agent-<hex> (branch worktree-agent-<hex>)]。三次运行留下了三个 worktree + 三个 worktree-agent-* 分支,直到我手动删除。

根因(在 writeWorktreeSessionMarkerpackages/core/src/services/gitWorktreeService.ts —— 不在本 PR diff 内,但本 PR 的清理契约新依赖了它):它把 .qwen-session 的 exclude 规则写到了 git rev-parse --git-dir每个 worktree 私有的 gitdir),但 git 读取 info/exclude 是从公共 gitdir(--git-common-dir)读的。对于 linked worktree 这两者不同,所以规则写到了 git 根本不看的地方。已直接证明:

# 在创建出来的 worktree 内:
--git-dir        = …/.git/worktrees/agent-fc72cdc      ← 代码把 exclude 写在这里
--git-common-dir = …/.git                              ← git 实际从这里读
$ cat …/.git/worktrees/agent-fc72cdc/info/exclude  →  .qwen-session   (规则确实在)
$ git status --porcelain                            →  ?? .qwen-session  (仍然 untracked!)
# 把同一条规则改写到公共 exclude:
$ echo .qwen-session >> …/.git/info/exclude ; git status --porcelain  →  (空 —— 现在被忽略了)

所以 marker 永远显示 untracked → hasWorktreeChanges() 永远返回 truecleanupWorkflowWorktree 永远走「保留」分支。.qwen/worktrees/ 目录(以及每次调用一个分支)会无限累积。同一个 writeWorktreeSessionMarker 也支撑着现有的 AgentTool worktree 路径(agent.ts:1955),所以这不是本 PR 引入的 —— 但 P3 扩大了影响面,因为一个 workflow 可以 fan-out 出很多隔离 subagent。

修复: 一个词 —— 在 writeWorktreeSessionMarker 里定位 info/exclude 时用 --git-common-dir 而非 --git-dir。(上面已在 git 层面验证;orchestrator 的清理仅以 hasWorktreeChanges/hasUnmerged 为判据,所以把 exclude 放对位置后,无改动路径就会自动移除。)

其他观察

  • schema 失败消息的拆分很到位,完全符合 R3 review 的意图:未尝试(纯文本)与 2 次 nudge 耗尽(3 次非法 structured_output 调用)会产生不同且准确的终止消息。
  • agent({model}) 走的是与 agentType/isolation 相同的 createAgentHeadless override 路径(两者都已验证);我没有单独断言它,因为 mock 与 model 无关 —— 请求只会带一个不同的 model id。
  • 该功能在产品中是关闭的(没有 workflowsEnabled 的 settings/CLI 接线,只有 QWEN_CODE_ENABLE_WORKFLOWS 这个环境开关),所以目前用户还触达不到 —— 这与一个 P3 基建型 PR 是一致的。

复现

# 真实 CLI,通过已有环境开关启用 workflow 工具,指向 mock LLM
QWEN_CODE_ENABLE_WORKFLOWS=1 OPENAI_BASE_URL=http://127.0.0.1:PORT/v1 OPENAI_API_KEY=sk-mock \
OPENAI_MODEL=mock-model QWEN_HOME=<隔离目录> \
  node packages/cli/dist/index.js --approval-mode yolo --output-format json -p "run the workflow"
# mock:主回合 → 返回 workflow tool_call,脚本里对每个选项 try/catch 调用 agent();
#       schema subagent → structured_output({answer});BADARGS subagent → structured_output({wrong});
#       FAILTEST subagent → 纯文本。在干净 git repo 跑一次,在脏 repo 跑一次。
# 观察:返回的汇总(全部 9 个探测)+ 无改动运行后仍留在 `.qwen/worktrees/agent-*` 的 worktree。

在 Linux、Node v22、git 2.47.3 上验证。通过 production dispatch 跑真实 subagent;确定性桩模型。workflow 在 tmux 下针对构建产物 packages/cli/dist/index.js 运行。

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.

3 participants