Skip to content

refactor(core): collapse three task registries into one TaskRegistry#3982

Closed
tanzhenxin wants to merge 13 commits into
mainfrom
refactor/task-registry-collapse
Closed

refactor(core): collapse three task registries into one TaskRegistry#3982
tanzhenxin wants to merge 13 commits into
mainfrom
refactor/task-registry-collapse

Conversation

@tanzhenxin

Copy link
Copy Markdown
Collaborator

Stacked on #3970. Review and merge that one first.

Summary

  • What changed: The three per-kind registry classes for background subagents, background shells, and monitors are replaced with a single thin generic TaskRegistry plus per-kind modules that hold each kind's lifecycle helpers as free functions and register a small Task implementation with a polymorphic dispatcher. The CLI's background-tasks hook collapses from a four-source merge with dream-signature dedup to a single registry subscription plus a thin dream adapter, and the dialog's cancel switch becomes a single dispatcher call.
  • Why it changed: The three registry classes were mechanical near-duplicates of each other, and the CLI hook + cancel switch had grown into spaghetti to keep them merged. Per the design doc, collapsing to one store narrows the surface every consumer touches and lets per-kind quirks live in their own modules. Aligns the qwen-code architecture with the upstream claw-code reference.
  • Reviewer focus: The dispatcher pattern (register-on-startup in Config to avoid an import cycle with the registry); whether the per-kind module split keeps each kind's helpers cohesive; and whether the CLI hook's new shape-signature filter behaves correctly across agent activity bursts, monitor event count bumps, and dream metadata updates.

Net diff: ~3950 lines deleted, no user-observable behavior change.

Validation

  • Commands run:
    npm run build && npm run bundle
    cd packages/core && npx vitest run    # 7115 passing, 3 pre-existing skips
    cd ../cli && npx vitest run           # 5283 passing, 7 pre-existing skips
    npm run typecheck                     # clean across all packages
  • Prompts / inputs used: see the E2E test plan at knowledge/qwen-code/e2e-tests/task-registry-unification-pr2.md — exercises foreground/background subagent persistence, headless holdback, dialog cancel routing for each kind, and mixed dialog ordering.
  • Expected result: structural invariance from the user's POV. Every behavior PR 3970 already exercises must produce the same observable result on this branch, plus dialog cancel routes correctly to each kind's terminator.
  • Observed result: all expected behaviors hold. One positive divergence: the foreground-subagent SIGINT meta-status limitation flagged in PR 3970 (meta stuck at running) self-resolved on this build — the meta now correctly transitions to cancelled.
  • Quickest reviewer verification path: read the design doc (knowledge/qwen-code/design/task-registry-unification-pr2-impl.md) for intent, then walk the new task module surface (registry + dispatcher + four kind modules), then spot-check that the migrated consumers (agent tool, shell tool, monitor tool, send-message, task-stop, background-agent-resume, the CLI hook, dialog context) all look right.
  • Evidence: detailed E2E reproduction summary posted as a separate PR comment.

Scope / Risk

  • Main risk or tradeoff: The agent and monitor kinds now use module-level singletons for their notification and register callbacks instead of per-instance fields on the old registry classes. This intentionally mirrors the claw-code architecture but means a process running multiple Config instances concurrently would have the second instance overwrite the first's callbacks. No qwen-code production use case hits this today; flagging in case future SDK multi-session work needs to revisit.
  • Not covered / not validated: The dream-task cancel path (Group E4 in the test plan) and the dream row in mixed-ordering (Group F dream slot) — scheduleDream() preconditions can't be met in a fresh test workdir. The kill path is structurally identical to the verified kinds and is covered by unit tests.
  • Breaking changes / migration notes: External SDK consumers that imported the three registry classes' public types from @qwen-code/qwen-code-core keep their imports working through one release via re-export shims in the old paths (scheduled for removal one release after this lands). The three Config getters for the old registries were dropped atomically — consumers that hold a Config reference and expected getBackgroundTaskRegistry() etc. need to switch to getTaskRegistry() plus the per-kind helpers.

Testing Matrix

🍏 🪟 🐧
npm run ⚠️ ⚠️
npx ⚠️ ⚠️ ⚠️
Docker ⚠️ ⚠️ ⚠️
Podman ⚠️ N/A N/A
Seatbelt ⚠️ N/A N/A

Testing matrix notes:

  • Validated on Linux (the dev environment). Other platforms unchanged from PR 3970's baseline.

@tanzhenxin

Copy link
Copy Markdown
Collaborator Author

E2E Test Reproduction Report

Test plan: knowledge/qwen-code/e2e-tests/task-registry-unification-pr2.md — Groups A–D (regression checks against PR #3970), E (dialog cancel routing), F (mixed dialog ordering).

Build under test: node dist/cli.js after npm run build && npm run bundle against this branch.

Methodology: Headless tests with --approval-mode yolo --output-format json, plus interactive (tmux) sessions for dialog-driven cases. Each test runs in its own mktemp -d workdir with a per-runtime QWEN_RUNTIME_DIR so transcripts and meta sidecars are uniquely findable. Compared each result against PR #3970's verification log line by line.

Results

Group Test PR #3970 baseline This branch Verdict
A A1 — foreground subagent persists jsonl + meta completed; no <task-notification> jsonl (4 records) + meta completed; 0 <task-notification> hits Pass — same
A A2 — foreground subagent fails not externally reproducible (inherited from A1 + unit tests) same — skipped for same reason Pass — same
A A3 — foreground cancelled mid-run via SIGINT files on disk; meta stuck at running (known limitation) files on disk (1 JSONL record); meta cancelled Positive divergence — PR #3970's known limitation self-resolved
B B1 — background subagent persistence jsonl + meta completed + <task-notification> jsonl (4 records) + meta completed + task_notification event Pass — no regression
C C1 — headless holdback for backgrounded loop stayed alive until terminal notification loop stayed alive until task_notification; process exited after Pass — no regression
C C2 — no holdback for foreground zero <task-notification> for foreground run zero task-notification in stream and runtime files Pass — no regression
D D1 — foreground tool-result delivery parent's follow-up turn cited subagent's result parent emitted exact JSON array from subagent; 0 task-notification hits Pass — no regression
E E1 — background subagent dialog-cancel (new in this PR) cancel notification fired immediately; hint updated; no error toast Pass
E E2 — background shell dialog-cancel (new in this PR) sleep 120 process killed (confirmed via ps); footer pill updated to 1 task done Pass
E E3 — monitor dialog-cancel + live eventCount (new in this PR) eventCount advanced 41→46 in detail view via the new per-entry subscription while list mode did not flicker; cancel from detail mode fired terminal notification Pass — also verifies the new per-selected-entry subscription path
E E4 — dream dialog-cancel (new in this PR) deferred — scheduleDream() preconditions can't be met in a fresh single-session workdir Deferred
F F1 — mixed dialog ordering (new in this PR) 5 rows in startTime order (3 user-launched: agent → shell → monitor; 2 subagent-spawned interleaved at correct chronological positions); no kind-clustering Pass

Notes

  • A3 positive divergence: PR refactor(core): TaskBase envelope + foreground subagent persistence #3970's verification log flagged "meta status stuck at running on SIGINT" as a known limitation — the foreground finally block didn't flush before the process exited under hard signal. This branch's run produced status: cancelled correctly. The change is unrelated to the registry collapse itself; it's likely a side-effect of the consumer migration touching the agent path's settle ordering.
  • E3 extra coverage: The dialog's per-selected-entry subscription was extended in this PR to cover monitors (previously only agents). The test ran a noisy monitor (~5 events/sec) in detail mode and confirmed both that eventCount updated live in the detail view AND that the list-mode rendering did not flicker — proving the new shape-signature filter in the hook correctly suppresses redundant snapshot rebuilds for in-place mutations.
  • E4 / F1 dream slot deferred: Same precondition issue both times — scheduleDream() requires meeting min-hours-between-dreams, min-sessions, and a session-scan throttle that a fresh mktemp -d workdir can't satisfy in a single run. Will need a dedicated test environment with pre-seeded memory state to cover. The dream kill path is structurally identical to the verified kinds (delegates to MemoryManager.cancelTask) and is covered by unit tests.

Test environment

  • Date: 2026-05-09
  • Binary: node dist/cli.js (rebuilt + rebundled at 03:30 PT)
  • Model: deepseek-v4-pro via Dashscope
  • Linux (kernel 6.8.0-1051-azure)

@tanzhenxin tanzhenxin force-pushed the refactor/task-registry-collapse branch from 752a0a4 to 2764df1 Compare May 17, 2026 14:35
@tanzhenxin tanzhenxin changed the base branch from refactor/task-base-foreground-persistence to main May 17, 2026 14:40
});
});
mockMonitorRegistry.abortAll.mockImplementation(() => {
mockMonitorAbortAll.mockImplementation(() => {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Critical] Incomplete test migration — 6 test cases further down in this file (lines 2547, 2663, 2787, 3207, 3334, 3447) still reference the old getBackgroundTaskRegistry API and the removed mockMonitorRegistry variable. The beforeEach block was correctly migrated to use getTaskRegistry + hoisted mocks, but these deeper test cases were missed.

This causes 7 TypeScript compilation errors (TS2339/TS2552) and prevents the entire test suite from running.

Affected test groups: structured-output shutdown tests, monitor-event drain tests, and holdback-gate tests.

Fix: Migrate the remaining 6 test cases to use getTaskRegistry() and the hoisted mock surface. Replace mockMonitorRegistry.setNotificationCallback (line 3207) with mockSetMonitorNotificationCallback (already hoisted).

— qwen3.7-max via Qwen Code /review

.mockImplementationOnce(() => undefined);

const registry = mockConfig.getBackgroundShellRegistry();
const registry = mockConfig.getTaskRegistry();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Critical] Incomplete test migration — 13 assertions further down in this file (lines 3696, 4062, 4105, 4113, 4126, 4204, 4277, 4371, 4383, 4466, 4559, 4565, 4778) still call the old per-kind registry methods cancel, complete, and fail on TaskRegistry. These methods no longer exist — the new API uses per-kind free functions (shellRequestCancel, shellComplete, shellFail, etc.).

This causes 13 TypeScript compilation errors (TS2339) and 18 runtime test failures in the "foreground-to-background promote" suites.

Fix: Update these assertions to mock and assert against the per-kind free functions instead of the removed registry methods.

— qwen3.7-max via Qwen Code /review

'a-just-finished',
'a-quick-and-old',
]);
expect(result.current.entries.map(entryId)).toEqual(['s1', 'a1', 'm1']);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Critical] Test expectation does not match the new sort order. With startTime values a1=100, s1=50, m1=200 and the new buildMerged descending-startTime bucket sort for running entries, m1 (200) sorts first, not last. The actual result is ['m1', 'a1', 's1'].

The same issue appears at line 178: expects ['m1', 'a1'] but the new sort produces ['a1', 'm1'] (a1.startTime=100 > m1.startTime=50).

Fix: Update expectations to match the descending-startTime sort:

Suggested change
expect(result.current.entries.map(entryId)).toEqual(['s1', 'a1', 'm1']);
expect(result.current.entries.map(entryId)).toEqual(['m1', 'a1', 's1']);

And at line 178:

expect(result.current.entries.map(entryId)).toEqual(['a1', 'm1']);

— qwen3.7-max via Qwen Code /review

memoryManager.listTasksByType('dream', projectRoot),
);

const unsubscribeRegistry = registry.subscribe(() => {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Suggestion] The registry.subscribe callback calls buildMerged() (which includes listDreamTasks + sort) on every fireChange, including activity bursts (agentAppendActivity) and monitor event emissions. The old code's setStatusChangeCallback explicitly excluded activity updates, and MonitorRegistry.emitEvent fired no callback at all.

While registrySnapshotShape correctly suppresses React re-renders, the CPU cost of listDreamTasks (reads MemoryManager, filters, sorts) + building the full merged array + computing the shape signature is paid on every event — even when the shape hasn't changed. Under sustained monitor output or rapid agent tool calls, this becomes a hot path doing no useful work.

Fix: Use the entry argument for a fast-path check before calling buildMerged():

const unsubscribeRegistry = registry.subscribe((entry) => {
  if (entry) {
    const prev = statusCache.get(entryId(entry));
    if (prev === entry.status) return;
    statusCache.set(entryId(entry), entry.status);
  }
  const merged = buildMerged();
  // ... shape check as before
});

— qwen3.7-max via Qwen Code /review

Comment thread packages/core/src/tools/monitor.ts Outdated
// Declared up-front (before `abortHandler`) so that the synchronous abort
// path — either `entryAc.signal.aborted` already true at registration
// time, or `registry.register()` throwing — can flush via
// time, or `monitorRegister(registry, )` throwing — can flush via

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Suggestion] Malformed function call in comment: monitorRegister(registry, ) has a dangling comma with a missing second argument. This was introduced during the rename from registry.register(registration) to monitorRegister(registry, registration).

Suggested change
// time, or `monitorRegister(registry, )` throwing — can flush via
// time, or `monitorRegister(registry, registration)` throwing — can flush via

— qwen3.7-max via Qwen Code /review

Comment thread packages/core/src/config/config.ts Outdated
// `Task` implementation is wired up. Idempotent — re-importing this
// module (or constructing additional Config instances) does not
// re-register.
registerTaskKind(AgentTaskKind);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Suggestion] Four registerTaskKind(...) side-effect calls are placed between two groups of import declarations. While ESM hoists all imports before executing module-level code (so this is functionally correct), it is visually surprising — imports continue at line 90 after this executable block. Most style guides and linters expect all imports to precede executable statements.

Fix: Move the registerTaskKind(...) block below the last import declaration in this file, so imports are contiguous.

— qwen3.7-max via Qwen Code /review

Comment thread packages/core/src/tasks/dispatcher.ts Outdated
* registry`, which ESM tolerates but JS hoisting around `const`
* exports does not.
*
* Init order: `Config.initialize()` calls `registerAllTaskKinds()`

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Suggestion] The comment says "Config.initialize() calls registerAllTaskKinds()" but in reality registration happens as a module-load side effect at config.ts:86-89 (top-level registerTaskKind(...) calls). There is no registerAllTaskKinds() function and no Config.initialize() method.

This creates a test infrastructure trap: _resetTaskKindsForTest() clears the dispatcher table, but there is no exported function to re-register all kinds. A test author who calls it in afterEach will break all subsequent tests that use registry.kill() or cancelSelected(), with an error message pointing to a nonexistent method.

Fix: Update the comment to say "module-load side effects in config.ts" and either export a registerAllTaskKinds() function for test recovery or remove _resetTaskKindsForTest() if it's not meant to be used.

— qwen3.7-max via Qwen Code /review

cb: MonitorNotificationCallback | undefined,
): void {
notificationCallback = cb;
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Suggestion] agentNotificationCallbacks and agentLifecycleCallbacks are module-level Maps that are not cleared by monitorAbortAll — only by monitorReset. Since Config.close() calls monitorAbortAll(this.taskRegistry, { notify: false }) but not monitorReset, these Maps survive session teardown.

In tests with multiple Config instances or a daemon process with session recycling, stale callbacks could route notifications to dead owner agents.

Fix: Have monitorAbortAll also clear these Maps (when called with { notify: false }), or have Config.close() call monitorReset after monitorAbortAll.

— qwen3.7-max via Qwen Code /review

tanzhenxin added a commit that referenced this pull request Jun 1, 2026
…ask module

Folds PR #4324's per-instance BackgroundTaskRegistry cap into the
collapsed tasks/agent-task.ts module as kind-local module state.
The new architecture's per-kind module is the natural home for an
agent-only behavior — the generic TaskRegistry no longer needs
to carry it.

What moves into tasks/agent-task.ts:

  - MAX_CONCURRENT_BACKGROUND_AGENTS and the env-var resolver
  - agentAssertCanStartBackground(registry) free function
  - The race-guard inside agentRegister() (skips re-registers of
    already-running entries so resume can recover)
  - setAgentBackgroundCapForTest() for test override (mirrors the
    existing setAgentNotificationCallback pattern)

What moves out of agent.ts:

  - The early preflight calls agentAssertCanStartBackground instead
    of registry.assertCanStartBackgroundAgent().
  - The post-register error path is unchanged structurally — it still
    aborts the bgAbortController, fires SubagentStop, cleans up the
    worktree, and returns the cap message to the model.

Resume path (background-agent-resume.ts) now wraps agentRegister
in the same try/catch #4324 added, but routes to the new free
function.

Also addresses wenshao's review on #3982:

  1. config.ts — moves the four registerTaskKind(...) calls below
     all imports, instead of dangling between two import groups.
  2. dispatcher.ts — comment updated to describe actual init order
     (module-load side effect in config.ts), removes the
     fictional registerAllTaskKinds() / Config.initialize()
     references.
  3. monitor.ts — fixes a stale comment that still referred to
     monitorRegister(registry, ) (dangling comma).
  4. monitor-task.ts — monitorAbortAll now clears the module-level
     owner-routed callbacks so a daemon process recycling sessions
     doesn't leak handlers to dead owner agents.
  5. useBackgroundTaskView.ts — moves the registry shape probe to
     getAll() BEFORE buildMerged() so activity bursts and
     monitor event bumps don't pay the listDreamTasks cost.

Tests added:

  - tasks/agent-task.test.ts — covers env resolution, cap
    enforcement (running-only, foreground exclusion, paused
    exclusion, resume race exception), and module-level cap reset.

Tests fixed (rebase fallout):

  - nonInteractiveCli.test.ts — six structured-output assertions
    migrated from mockBackgroundTaskRegistry.abortAll to the
    module-level mockAgentAbortAll mock.
  - shell.test.ts — 13 assertions migrated from
    registry.{cancel,complete,fail} to
    shellTaskModule.shell{Cancel,Complete,Fail} (called with
    (registry, ...)).
  - useBackgroundTaskView.test.ts — sort assertions updated to the
    new descending-startTime active-bucket order.
  - agent.test.ts — adds the getStopHookBlockingCap mock that
    was lost in the auto-merge with PR #4208.
  - clearCommand.test.ts — drops the SessionStart assertion that
    was lost in the auto-merge with PR #4115.
  - background-agent-resume.test.ts — monitorRegistry is now a
    set of vi.spyOn against the new module-level free functions.
  - InlineParallelAgentsDisplay.test.tsx — makeRegistryConfig
    exposes getTaskRegistry (matching the renamed Config method).
@tanzhenxin tanzhenxin force-pushed the refactor/task-registry-collapse branch from 2764df1 to 942ea3f Compare June 1, 2026 07:02
@tanzhenxin

Copy link
Copy Markdown
Collaborator Author

@wenshao Thanks for the thorough review. Rebased onto current main (138 commits ahead) and addressed every comment. Highlights:

Critical (3) — all resolved

  1. nonInteractiveCli.test.ts stale registry refs — migrated the six lingering (mockConfig.getBackgroundTaskRegistry as Mock) blocks to mockAgentAbortAll / mockSetMonitorNotificationCallback (the module-level hoisted mocks already in vi.mock).
  2. shell.test.ts cancel/complete/fail on TaskRegistry — 13 assertions migrated from expect(registry.X) to expect(shellTaskModule.shellX).toHaveBeenCalledWith(registry, ...); the test already spied on the free functions via vi.spyOn(shellTaskModule, ...), so only the assertion targets changed.
  3. useBackgroundTaskView.test.ts sort expectations — updated to the new descending-startTime active-bucket order. Added a comment explaining the sort (m1/a1/s1 for startTimes 200/100/50).

Suggestions (5) — all addressed

  1. config.ts import ordering — moved the four registerTaskKind(...) side-effect calls below the last import declaration. Added a comment explaining the placement.
  2. dispatcher.ts comment about init — replaced the fictional Config.initialize() / registerAllTaskKinds() mention with an accurate description ("module-load side effect in config.ts") and a pointer to _resetTaskKindsForTest for test infra.
  3. monitor.ts malformed comment — fixed monitorRegister(registry, )monitorRegister(registry, registration).
  4. monitor-task.ts callback cleanup on monitorAbortAllmonitorAbortAll now clears agentNotificationCallbacks and agentLifecycleCallbacks so a daemon process recycling sessions doesn't leak handlers to dead owner agents. Distinct from monitorReset (full teardown) — abortAll runs on cancel paths that keep the registry alive but tear down owners.
  5. useBackgroundTaskView.ts perfregistrySnapshotShape now reads registry.getAll() directly (without dreams) and runs BEFORE buildMerged(). Activity bursts and monitor event bumps now early-return without paying the listDreamTasks + sort cost. Tests still pass.

Bonus: integrated PR #4324 (background-agent concurrency cap)

#4324 merged after this PR was opened and added MAX_CONCURRENT_BACKGROUND_AGENTS on the old BackgroundTaskRegistry class. The cap is inherently agent-specific (only isBackgrounded agents matter), so the collapsed architecture is actually a better home for it:

  • MAX_CONCURRENT_BACKGROUND_AGENTS + env-var resolver moved to tasks/agent-task.ts as module state.
  • New agentAssertCanStartBackground(registry) free function replaces BackgroundTaskRegistry.assertCanStartBackgroundAgent(). Uses the generic registry.getByKind('agent') to count.
  • The race-guard inside agentRegister() (skips the cap check when re-registering an already-running entry, so resume can recover).
  • setAgentBackgroundCapForTest() for test override (mirrors the existing setAgentNotificationCallback pattern).
  • New file packages/core/src/tasks/agent-task.test.ts — 15 cases covering env resolution, running-only counting, foreground exclusion, paused exclusion, and resume-race exception.

E2E smoke report (rebuilt bundle)

# Test Result Evidence
1 QWEN_CODE_MAX_BACKGROUND_AGENTS=1 + launch 2 bg agents ✅ Pass 1st succeeds (task_started), 2nd rejected with Cannot start background agent: maximum concurrent background agents (1) reached. Stop an existing agent first. 1st completes normally with task_notification(completed).
2 Cap=1 + foreground subagent ✅ Pass Returns 4, no cap error — getByKind('agent').filter(isBackgrounded) correctly excludes foreground.
3 Default cap + single bg agent ✅ Pass task_started + task_notification(completed) + meta sidecar on disk with "status": "completed" + JSONL transcript.
4a task_stop on bg shell (dispatcher kill) ✅ Pass Shell bg_xxx cancelled; underlying pid no longer in ps.
4b task_stop on bg agent (dispatcher kill) ✅ Pass Cancelled: slowmath + task_notification(cancelled).

All four runs produced clean stderr (no unexpected warnings or stack traces).

Verification

  • npm run typecheck — clean across all packages
  • npm run build && npm run bundle — clean
  • packages/core vitest: 9623 passed (3 pre-existing failures on main: skill-manager, gitDiff, gitWorktreeService.symlinks)
  • packages/cli vitest: 6972 passed (3 pre-existing failures on main: useAtCompletion)
  • New cap tests: 15 passed

Ready for re-review.

@tanzhenxin tanzhenxin marked this pull request as ready for review June 1, 2026 07:05
@github-actions

github-actions Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Summary

Package Lines Statements Functions Branches
CLI 77.4% 77.4% 80.61% 80.06%
Core 81.36% 81.36% 82.96% 83.6%
CLI Package - Full Text Report
-------------------|---------|----------|---------|---------|-------------------
File               | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-------------------|---------|----------|---------|---------|-------------------
All files          |    77.4 |    80.06 |   80.61 |    77.4 |                   
 src               |   74.36 |    68.46 |   76.74 |   74.36 |                   
  gemini.tsx       |   63.03 |    64.28 |   71.42 |   63.03 | ...1167-1170,1182 
  ...ractiveCli.ts |   78.51 |    66.66 |      75 |   78.51 | ...1303-1304,1339 
  ...liCommands.ts |   84.59 |    77.14 |     100 |   84.59 | ...26-335,361,476 
  ...ActiveAuth.ts |     100 |     87.5 |     100 |     100 | 66-80             
 ...cp-integration |   65.53 |    65.98 |   85.48 |   65.53 |                   
  acpAgent.ts      |   65.27 |     66.2 |    86.2 |   65.27 | ...2097,2111-2119 
  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 |   78.76 |     72.9 |   87.77 |   78.76 |                   
  ...ryReplayer.ts |   67.34 |     75.6 |   81.81 |   67.34 | ...54-269,282-283 
  Session.ts       |   78.67 |    71.98 |   90.32 |   78.67 | ...3161,3167-3170 
  ...entTracker.ts |   90.85 |    84.84 |      90 |   90.85 | ...35,199,251-260 
  index.ts         |       0 |        0 |       0 |       0 | 1-40              
  ...ssionUtils.ts |   84.21 |    78.57 |     100 |   84.21 | ...37-153,209-211 
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 ...ssion/emitters |   96.01 |    90.83 |    92.3 |   96.01 |                   
  BaseEmitter.ts   |   76.92 |    66.66 |      80 |   76.92 | 23-24,39-40,55-56 
  ...ageEmitter.ts |     100 |       90 |     100 |     100 | 109,111           
  PlanEmitter.ts   |     100 |      100 |     100 |     100 |                   
  ...allEmitter.ts |   98.06 |     92.3 |     100 |   98.06 | 227-228,327,335   
  index.ts         |       0 |        0 |       0 |       0 | 1-10              
 ...ession/rewrite |    91.3 |    88.09 |   94.44 |    91.3 |                   
  LlmRewriter.ts   |      81 |       84 |     100 |      81 | ...,88-89,155-159 
  ...Middleware.ts |   96.74 |    86.84 |     100 |   96.74 | 135,143-145       
  TurnBuffer.ts    |     100 |      100 |     100 |     100 |                   
  config.ts        |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 src/commands      |   45.67 |    85.71 |   43.47 |   45.67 |                   
  auth.ts          |     100 |    83.33 |     100 |     100 | 11,14             
  channel.ts       |   56.66 |      100 |       0 |   56.66 | 15-19,27-34       
  extensions.tsx   |   96.55 |      100 |      50 |   96.55 | 37                
  hooks.tsx        |   66.66 |      100 |       0 |   66.66 | 20-24             
  mcp.ts           |   94.73 |      100 |      50 |   94.73 | 28                
  review.ts        |   51.85 |      100 |       0 |   51.85 | 24-35,38          
  serve.ts         |    8.02 |      100 |       0 |    8.02 | ...56-152,154-266 
 ...mmands/channel |    39.2 |    79.45 |      50 |    39.2 |                   
  ...l-registry.ts |    8.33 |      100 |       0 |    8.33 | 6-22,25-43        
  config-utils.ts  |      92 |      100 |   66.66 |      92 | 21-26             
  configure.ts     |    14.7 |      100 |       0 |    14.7 | 18-21,23-84       
  pairing.ts       |   26.31 |      100 |       0 |   26.31 | ...30,40-50,52-65 
  pidfile.ts       |   96.34 |    86.95 |     100 |   96.34 | 49,59,91          
  start.ts         |   30.98 |       52 |   69.23 |   30.98 | ...72-475,484-486 
  status.ts        |   17.85 |      100 |       0 |   17.85 | 15-26,32-76       
  stop.ts          |      20 |      100 |       0 |      20 | 14-48             
 ...nds/extensions |   84.89 |    88.52 |   81.81 |   84.89 |                   
  consent.ts       |   71.65 |    89.28 |   42.85 |   71.65 | ...85-141,156-162 
  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         |   65.06 |    31.25 |     100 |   65.06 | ...85,87-91,93-97 
 ...les/mcp-server |       0 |        0 |       0 |       0 |                   
  example.ts       |       0 |        0 |       0 |       0 | 1-60              
 src/commands/mcp  |   92.29 |    86.08 |   88.88 |   92.29 |                   
  add.ts           |     100 |    98.03 |     100 |     100 | 293               
  list.ts          |   91.22 |    80.76 |      80 |   91.22 | ...19-121,146-147 
  reconnect.ts     |   76.72 |    71.42 |   85.71 |   76.72 | 35-48,153-175     
  remove.ts        |     100 |       80 |     100 |     100 | 21-25             
 ...ommands/review |   11.57 |      100 |       0 |   11.57 |                   
  cleanup.ts       |   17.94 |      100 |       0 |   17.94 | ...01-106,108-109 
  deterministic.ts |   13.75 |      100 |       0 |   13.75 | ...22-738,740-741 
  fetch-pr.ts      |   11.36 |      100 |       0 |   11.36 | ...80-201,203-204 
  load-rules.ts    |   11.32 |      100 |       0 |   11.32 | ...41-153,155-156 
  pr-context.ts    |    6.22 |      100 |       0 |    6.22 | ...97-312,314-315 
  presubmit.ts     |    9.35 |      100 |       0 |    9.35 | ...62-287,289-290 
 ...nds/review/lib |      30 |      100 |       0 |      30 |                   
  gh.ts            |   22.58 |      100 |       0 |   22.58 | ...49,53-54,62-69 
  git.ts           |   22.72 |      100 |       0 |   22.72 | 15-18,29-39,43-44 
  paths.ts         |   52.94 |      100 |       0 |   52.94 | ...26,37-38,42-43 
 src/config        |   92.91 |    85.15 |   89.79 |   92.91 |                   
  auth.ts          |   86.74 |    80.88 |     100 |   86.74 | ...40-241,257-258 
  config.ts        |   86.75 |    83.96 |   82.14 |   86.75 | ...2018,2020-2028 
  keyBindings.ts   |   96.87 |       50 |     100 |   96.87 | 201-204           
  ...ngsAdapter.ts |     100 |    94.11 |     100 |     100 | 64                
  ...idersScope.ts |      92 |       90 |     100 |      92 | 11-12             
  sandboxConfig.ts |   61.64 |    71.87 |   66.66 |   61.64 | ...54-68,73,77-89 
  settings.ts      |   86.98 |    88.23 |   89.74 |   86.98 | ...1322,1337-1340 
  ...ingsSchema.ts |     100 |      100 |     100 |     100 |                   
  ...tedFolders.ts |   96.22 |       94 |     100 |   96.22 | ...95-197,212-213 
 ...nfig/migration |   94.89 |    78.94 |   83.33 |   94.89 |                   
  index.ts         |   94.87 |    88.88 |     100 |   94.87 | 91-92             
  scheduler.ts     |   96.55 |    77.77 |     100 |   96.55 | 19-20             
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 ...ation/versions |   94.74 |       96 |     100 |   94.74 |                   
  ...-v2-shared.ts |     100 |      100 |     100 |     100 |                   
  v1-to-v2.ts      |   81.75 |    90.19 |     100 |   81.75 | ...28-229,231-247 
  v2-to-v3.ts      |     100 |      100 |     100 |     100 |                   
  v3-to-v4.ts      |     100 |      100 |     100 |     100 |                   
 src/core          |     100 |      100 |     100 |     100 |                   
  auth.ts          |     100 |      100 |     100 |     100 |                   
  initializer.ts   |     100 |      100 |     100 |     100 |                   
  theme.ts         |     100 |      100 |     100 |     100 |                   
 src/dualOutput    |   63.09 |    64.51 |   55.55 |   63.09 |                   
  ...tputBridge.ts |   62.94 |    65.51 |   56.25 |   62.94 | ...22-323,331-334 
  ...utContext.tsx |     100 |      100 |     100 |     100 |                   
  index.ts         |       0 |        0 |       0 |       0 | 1-8               
 src/export        |       0 |        0 |       0 |       0 |                   
  index.ts         |       0 |        0 |       0 |       0 | 1-7               
 src/generated     |     100 |      100 |     100 |     100 |                   
  git-commit.ts    |     100 |      100 |     100 |     100 |                   
 src/i18n          |   82.02 |    75.94 |   65.71 |   82.02 |                   
  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.49 |    71.12 |   74.07 |   72.49 |                   
  session.ts       |   76.57 |     69.4 |   85.71 |   76.57 | ...29-830,839-849 
  types.ts         |    42.5 |      100 |   33.33 |    42.5 | ...90-591,594-595 
 ...active/control |   76.79 |    88.23 |      80 |   76.79 |                   
  ...rolContext.ts |    6.89 |        0 |       0 |    6.89 | 50-86             
  ...Dispatcher.ts |   91.66 |    91.83 |   88.88 |   91.66 | ...54-372,388,391 
  ...rolService.ts |       8 |        0 |       0 |       8 | 46-179            
 ...ol/controllers |   27.25 |    35.71 |   36.66 |   27.25 |                   
  ...Controller.ts |   36.97 |       80 |      80 |   36.97 | ...15-117,127-210 
  ...Controller.ts |       0 |        0 |       0 |       0 | 1-56              
  ...Controller.ts |    33.7 |    34.48 |   44.44 |    33.7 | ...57-466,481-486 
  ...Controller.ts |   14.06 |      100 |       0 |   14.06 | ...82-117,130-133 
  ...Controller.ts |   21.97 |    28.57 |   27.27 |   21.97 | ...39-451,460-489 
 .../control/types |       0 |        0 |       0 |       0 |                   
  serviceAPIs.ts   |       0 |        0 |       0 |       0 | 1                 
 ...Interactive/io |   98.01 |    93.77 |   95.23 |   98.01 |                   
  ...putAdapter.ts |   97.89 |    92.82 |   98.07 |   97.89 | ...1303,1398-1399 
  ...putAdapter.ts |      96 |     90.9 |   85.71 |      96 | 51-52             
  ...nputReader.ts |     100 |    94.73 |     100 |     100 | 67                
  ...putAdapter.ts |   98.38 |      100 |   90.47 |   98.38 | 83-84,124-125     
  index.ts         |     100 |      100 |     100 |     100 |                   
 src/patches       |       0 |        0 |       0 |       0 |                   
  is-in-ci.ts      |       0 |        0 |       0 |       0 | 1-17              
 src/remoteInput   |   86.98 |       75 |   85.71 |   86.98 |                   
  ...utContext.tsx |     100 |      100 |     100 |     100 |                   
  ...putWatcher.ts |   88.12 |    76.08 |   91.66 |   88.12 | ...21-222,233-236 
  index.ts         |       0 |        0 |       0 |       0 | 1-8               
 src/serve         |   79.44 |    78.92 |   92.93 |   79.44 |                   
  auth.ts          |   88.49 |    88.63 |     100 |   88.49 | ...49-150,153-155 
  capabilities.ts  |     100 |     90.9 |     100 |     100 | 264               
  ...usProvider.ts |   67.01 |    51.42 |     100 |   67.01 | ...40-245,278-286 
  debugMode.ts     |     100 |      100 |     100 |     100 |                   
  demo.ts          |     100 |      100 |     100 |     100 |                   
  envSnapshot.ts   |    92.3 |       84 |     100 |    92.3 | 108-111,170-177   
  eventBus.ts      |     100 |      100 |     100 |     100 |                   
  httpAcpBridge.ts |   79.99 |    79.16 |   96.47 |   79.99 | ...4270,4301-4342 
  ...oryChannel.ts |     100 |      100 |     100 |     100 |                   
  index.ts         |       0 |        0 |       0 |       0 | 1-106             
  loopbackBinds.ts |     100 |      100 |     100 |     100 |                   
  runQwenServe.ts  |   73.98 |    87.83 |   55.55 |   73.98 | ...94-710,735-737 
  server.ts        |   86.18 |    82.94 |   90.62 |   86.18 | ...2478,2543-2552 
  status.ts        |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
  ...paceAgents.ts |   64.87 |    70.45 |    90.9 |   64.87 | ...1306,1316-1326 
  ...paceMemory.ts |   87.13 |    78.46 |     100 |   87.13 | ...54-361,421-428 
 src/serve/auth    |   86.54 |    78.75 |   93.75 |   86.54 |                   
  deviceFlow.ts    |   96.33 |    79.51 |    97.5 |   96.33 | ...1526,1630,1700 
  ...owProvider.ts |   45.23 |    74.07 |      75 |   45.23 | ...90-359,375,379 
 src/serve/fs      |   84.85 |    79.75 |     100 |   84.85 |                   
  audit.ts         |     100 |    96.15 |     100 |     100 | 201               
  errors.ts        |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  paths.ts         |   77.82 |    77.08 |     100 |   77.82 | ...64,493-497,510 
  policy.ts        |   90.32 |    89.18 |     100 |   90.32 | 142-150           
  ...FileSystem.ts |   83.55 |    76.22 |     100 |   83.55 | ...1859,1886-1887 
 src/serve/routes  |   89.41 |       70 |     100 |   89.41 |                   
  ...ceFileRead.ts |   94.41 |    76.92 |     100 |   94.41 | ...28-329,390-392 
  ...eFileWrite.ts |    82.1 |    60.52 |     100 |    82.1 | ...42-244,247-249 
 src/services      |   91.73 |    90.78 |   97.56 |   91.73 |                   
  ...mandLoader.ts |     100 |    93.75 |     100 |     100 | 93                
  ...killLoader.ts |     100 |     93.1 |     100 |     100 | 47,66             
  ...andService.ts |    98.7 |      100 |     100 |    98.7 | 107               
  ...mandLoader.ts |   86.83 |    83.87 |     100 |   86.83 | ...30-335,340-345 
  ...omptLoader.ts |   75.84 |    80.64 |   83.33 |   75.84 | ...10-211,277-278 
  ...mandLoader.ts |     100 |    96.87 |     100 |     100 | 65                
  ...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.75 |    83.33 |      80 |   93.75 |                   
  ...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.08 |    72.94 |   59.67 |   65.08 |                   
  App.tsx          |   33.33 |       75 |   33.33 |   33.33 | 32-86             
  AppContainer.tsx |   64.03 |     64.7 |      50 |   64.03 | ...3218,3222-3226 
  ...tionNudge.tsx |    9.58 |      100 |       0 |    9.58 | 24-94             
  ...ackDialog.tsx |   29.23 |      100 |       0 |   29.23 | 25-75             
  ...tionNudge.tsx |    7.69 |      100 |       0 |    7.69 | 25-103            
  colors.ts        |      60 |      100 |   35.29 |      60 | ...52,54-55,60-61 
  constants.ts     |     100 |      100 |     100 |     100 |                   
  keyMatchers.ts   |   95.91 |    97.14 |     100 |   95.91 | 25-26             
  ...tic-colors.ts |     100 |      100 |     100 |     100 |                   
  ...inePresets.ts |   98.28 |    89.87 |     100 |   98.28 | ...34,261,420-422 
  textConstants.ts |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/ui/auth       |   59.16 |    65.94 |   51.11 |   59.16 |                   
  AuthDialog.tsx   |   62.87 |     42.1 |   18.18 |   62.87 | ...03,310-332,336 
  ...nProgress.tsx |       0 |        0 |       0 |       0 | 1-64              
  ...etupSteps.tsx |   60.03 |    70.37 |      56 |   60.03 | ...87,791,800,803 
  useAuth.ts       |   94.55 |    73.52 |     100 |   94.55 | ...19-220,239-245 
  ...rSetupFlow.ts |   43.52 |    33.33 |      50 |   43.52 | ...72-393,410-453 
 src/ui/commands   |   76.55 |    82.09 |   85.05 |   76.55 |                   
  aboutCommand.ts  |     100 |      100 |     100 |     100 |                   
  agentsCommand.ts |   83.78 |      100 |      60 |   83.78 | 30-32,42-44       
  ...odeCommand.ts |   89.47 |    81.25 |     100 |   89.47 | 92-93,95-100      
  arenaCommand.ts  |   62.81 |    58.73 |   65.21 |   62.81 | ...91-596,681-689 
  authCommand.ts   |     100 |      100 |     100 |     100 |                   
  branchCommand.ts |     100 |      100 |     100 |     100 |                   
  btwCommand.ts    |    96.1 |    74.07 |     100 |    96.1 | 149-154           
  bugCommand.ts    |   81.13 |    71.42 |     100 |   81.13 | 60-69             
  clearCommand.ts  |    92.1 |    72.22 |     100 |    92.1 | 46-47,76-77,95-96 
  ...essCommand.ts |   67.95 |    55.88 |      75 |   67.95 | ...86-187,201-204 
  ...extCommand.ts |   65.06 |    67.24 |   84.61 |   65.06 | ...39-574,585-586 
  copyCommand.ts   |   98.48 |    95.78 |     100 |   98.48 | ...80,280,321,327 
  deleteCommand.ts |     100 |      100 |     100 |     100 |                   
  diffCommand.ts   |     100 |     87.5 |     100 |     100 | ...61,224-225,238 
  ...ryCommand.tsx |   77.02 |    79.03 |   88.88 |   77.02 | ...65-270,324-332 
  docsCommand.ts   |     100 |    88.88 |     100 |     100 | 25                
  doctorCommand.ts |   60.93 |    87.06 |    87.5 |   60.93 | ...66-367,440-660 
  dreamCommand.ts  |      75 |    66.66 |   66.66 |      75 | 22-27,44-47       
  editorCommand.ts |     100 |      100 |     100 |     100 |                   
  exportCommand.ts |   98.25 |    91.02 |     100 |   98.25 | ...81,198-199,364 
  ...onsCommand.ts |   49.33 |     90.9 |   63.63 |   49.33 | ...06-110,163-215 
  forgetCommand.ts |   26.82 |      100 |      50 |   26.82 | 18-51             
  forkCommand.ts   |     100 |    94.44 |     100 |     100 | 92,151            
  goalCommand.ts   |   91.41 |    84.44 |      90 |   91.41 | ...86-189,201-204 
  helpCommand.ts   |     100 |      100 |     100 |     100 |                   
  hooksCommand.ts  |   81.13 |    65.71 |   85.71 |   81.13 | ...,86-93,131-132 
  ideCommand.ts    |   60.75 |    64.28 |   41.17 |   60.75 | ...05-306,310-324 
  initCommand.ts   |   84.33 |    72.72 |     100 |   84.33 | 68,82-87,89-94    
  ...ghtCommand.ts |   74.56 |    68.42 |     100 |   74.56 | ...31-245,250-273 
  ...ageCommand.ts |   92.17 |    82.69 |     100 |   92.17 | ...43,164,173-183 
  lspCommand.ts    |     100 |    86.95 |     100 |     100 | 31,101-102        
  mcpCommand.ts    |     100 |      100 |     100 |     100 |                   
  memoryCommand.ts |     100 |      100 |     100 |     100 |                   
  modelCommand.ts  |   75.09 |    78.18 |      75 |   75.09 | ...20-225,262-267 
  ...onsCommand.ts |     100 |      100 |     100 |     100 |                   
  planCommand.ts   |   78.82 |    76.92 |     100 |   78.82 | 30-35,51-56,68-73 
  quitCommand.ts   |     100 |      100 |     100 |     100 |                   
  recapCommand.ts  |   21.81 |      100 |      50 |   21.81 | 24-73             
  ...berCommand.ts |   32.43 |      100 |      50 |   32.43 | 23-57             
  renameCommand.ts |   85.71 |    86.04 |     100 |   85.71 | ...02-209,216-221 
  ...oreCommand.ts |    92.3 |    87.87 |     100 |    92.3 | ...,83-88,129-130 
  resumeCommand.ts |     100 |      100 |     100 |     100 |                   
  rewindCommand.ts |      80 |      100 |      50 |      80 | 19-21             
  ...ngsCommand.ts |     100 |      100 |     100 |     100 |                   
  ...hubCommand.ts |   81.43 |    65.21 |      80 |   81.43 | ...70-173,176-179 
  skillsCommand.ts |   84.12 |    76.92 |     100 |   84.12 | 36-44,68          
  statsCommand.ts  |   88.19 |    84.21 |     100 |   88.19 | ...,58-61,143-146 
  ...ineCommand.ts |     100 |      100 |     100 |     100 |                   
  ...aryCommand.ts |    6.46 |      100 |      50 |    6.46 | 31-329            
  tasksCommand.ts  |   75.91 |    72.13 |     100 |   75.91 | ...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 |   64.07 |    76.76 |    65.4 |   64.07 |                   
  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 |   10.56 |      100 |       0 |   10.56 | 39-173            
  AsciiArt.ts      |     100 |      100 |     100 |     100 |                   
  ...Indicator.tsx |   16.27 |      100 |       0 |   16.27 | 19-58             
  ...TextInput.tsx |    83.8 |    76.92 |     100 |    83.8 | ...38,252-254,356 
  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.83 |      100 |       0 |   11.83 | 66-525            
  DiffDialog.tsx   |    2.47 |      100 |       0 |    2.47 | 68-732            
  ...ngsDialog.tsx |    8.44 |      100 |       0 |    8.44 | 37-195            
  ExitWarning.tsx  |     100 |      100 |     100 |     100 |                   
  ...hProgress.tsx |    87.8 |    33.33 |     100 |    87.8 | 28-31,56          
  ...ustDialog.tsx |     100 |      100 |     100 |     100 |                   
  Footer.tsx       |   77.12 |    52.27 |     100 |   77.12 | ...43,167,188-193 
  ...ngSpinner.tsx |   68.42 |       80 |      50 |   68.42 | 35-52,73,80-81    
  GoalPill.tsx     |   76.19 |    81.81 |     100 |   76.19 | 24-30,46-50       
  Header.tsx       |   98.62 |    94.28 |     100 |   98.62 | 162,164           
  Help.tsx         |   98.32 |       90 |     100 |   98.32 | ...24,381,447-448 
  ...emDisplay.tsx |   61.41 |    34.61 |     100 |   61.41 | ...51,354,357-363 
  ...ngeDialog.tsx |     100 |      100 |     100 |     100 |                   
  InputPrompt.tsx  |   81.31 |    79.69 |   83.33 |   81.31 | ...1627,1651,1702 
  ...Shortcuts.tsx |   20.87 |      100 |       0 |   20.87 | ...6,49-51,67-125 
  ...Indicator.tsx |     100 |    91.42 |     100 |     100 | 65,74             
  ...firmation.tsx |   91.42 |      100 |      50 |   91.42 | 26-31             
  MainContent.tsx  |   86.93 |    87.17 |   66.66 |   86.93 | ...26,284,343-347 
  MemoryDialog.tsx |   61.87 |    76.05 |    62.5 |   61.87 | ...72,391,428-430 
  ...geDisplay.tsx |       0 |        0 |       0 |       0 | 1-41              
  ModelDialog.tsx  |   85.68 |    69.17 |     100 |   85.68 | ...75-591,648-652 
  ...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 |   41.26 |    61.53 |   71.42 |   41.26 | ...74-472,476-520 
  ...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 |    87.8 |      100 |   33.33 |    87.8 | 36-39,44-51       
  ...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            
  StatsDisplay.tsx |     100 |      100 |     100 |     100 |                   
  ...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          
 ...nts/agent-view |   38.45 |    70.83 |   36.36 |   38.45 |                   
  ...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.74 |      100 |       0 |   10.74 | 59-310            
  AgentFooter.tsx  |   17.07 |      100 |       0 |   17.07 | 28-66             
  AgentHeader.tsx  |   15.38 |      100 |       0 |   15.38 | 27-64             
  AgentTabBar.tsx  |    87.8 |    27.27 |     100 |    87.8 | ...,85,95-103,121 
  ...oryAdapter.ts |     100 |    91.83 |     100 |     100 | 103,109-110,138   
  index.ts         |       0 |        0 |       0 |       0 | 1-12              
 ...mponents/arena |   45.59 |    70.53 |   60.86 |   45.59 |                   
  ArenaCards.tsx   |   73.06 |    71.79 |   85.71 |   73.06 | ...83-185,321-326 
  ...ectDialog.tsx |   83.48 |    69.86 |   88.88 |   83.48 | ...88-392,409-410 
  ...artDialog.tsx |    9.92 |      100 |       0 |    9.92 | 27-164            
  ...tusDialog.tsx |    5.63 |      100 |       0 |    5.63 | 33-75,80-288      
  ...topDialog.tsx |    6.17 |      100 |       0 |    6.17 | 33-213            
 ...ackground-view |   79.37 |    82.35 |   93.93 |   79.37 |                   
  ...sksDialog.tsx |   76.18 |    80.18 |      90 |   76.18 | ...1157,1233-1235 
  ...TasksPill.tsx |   63.75 |    86.95 |     100 |   63.75 | 44,86-106,114-122 
  ...gentPanel.tsx |    97.4 |    86.31 |     100 |    97.4 | 124,435-439       
 ...nts/extensions |   45.28 |    33.33 |      60 |   45.28 |                   
  ...gerDialog.tsx |   44.31 |    34.14 |      75 |   44.31 | ...71-480,483-488 
  index.ts         |       0 |        0 |       0 |       0 | 1-9               
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...tensions/steps |   54.88 |    94.23 |   66.66 |   54.88 |                   
  ...ctionStep.tsx |   95.12 |    92.85 |   85.71 |   95.12 | 84-86,89          
  ...etailStep.tsx |    6.18 |      100 |       0 |    6.18 | 20-131            
  ...nListStep.tsx |   88.43 |    94.73 |      80 |   88.43 | 52-53,59-72,106   
  ...electStep.tsx |   13.46 |      100 |       0 |   13.46 | 20-70             
  ...nfirmStep.tsx |   19.56 |      100 |       0 |   19.56 | 23-65             
  index.ts         |     100 |      100 |     100 |     100 |                   
 ...mponents/hooks |   86.78 |     81.3 |   91.89 |   86.78 |                   
  ...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.24 |     100 |   72.29 | ...51,563-568,572 
  constants.ts     |     100 |      100 |     100 |     100 |                   
  index.ts         |       0 |        0 |       0 |       0 | 1-13              
  ...erGrouping.ts |     100 |      100 |     100 |     100 |                   
  sourceLabels.ts  |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...components/mcp |   20.98 |    86.36 |   83.33 |   20.98 |                   
  ...ealthPill.tsx |   68.42 |    85.71 |     100 |   68.42 | 40-46             
  ...entDialog.tsx |    3.64 |      100 |       0 |    3.64 | 41-717            
  constants.ts     |     100 |      100 |     100 |     100 |                   
  index.ts         |       0 |        0 |       0 |       0 | 1-30              
  types.ts         |     100 |      100 |     100 |     100 |                   
  utils.ts         |   95.83 |    88.88 |     100 |   95.83 | 16,20,109-110     
 ...ents/mcp/steps |   26.74 |    54.54 |   42.85 |   26.74 |                   
  ...icateStep.tsx |    5.88 |      100 |       0 |    5.88 | 40-55,58-296      
  ...electStep.tsx |   10.95 |      100 |       0 |   10.95 | 16-88             
  ...etailStep.tsx |    5.26 |      100 |       0 |    5.26 | 31-247            
  ...rListStep.tsx |   75.18 |    59.37 |     100 |   75.18 | ...53-158,169-173 
  ...etailStep.tsx |   10.41 |      100 |       0 |   10.41 | ...1,67-79,82-139 
  ToolListStep.tsx |   69.02 |       50 |     100 |   69.02 | ...22,125,134-143 
 ...nents/messages |   83.24 |    80.64 |    75.6 |   83.24 |                   
  ...ionDialog.tsx |   80.84 |     77.6 |    62.5 |   80.84 | ...98,516,534-536 
  BtwMessage.tsx   |     100 |      100 |     100 |     100 |                   
  ...upDisplay.tsx |   97.67 |    83.72 |     100 |   97.67 | 119,142,150       
  ...onMessage.tsx |   91.93 |    82.35 |     100 |   91.93 | 57-59,61,63       
  ...nMessages.tsx |   79.06 |      100 |      70 |   79.06 | ...51-264,268-280 
  DiffRenderer.tsx |   93.19 |    86.17 |     100 |   93.19 | ...09,237-238,304 
  ...tsDisplay.tsx |   97.82 |    77.27 |     100 |   97.82 | 87,89             
  ...usMessage.tsx |   76.31 |     42.1 |   66.66 |   76.31 | ...99,101,124,155 
  ...tsDisplay.tsx |   95.16 |    88.57 |     100 |   95.16 | ...29,131,164-169 
  ...ssMessage.tsx |    12.5 |      100 |       0 |    12.5 | 18-59             
  ...edMessage.tsx |   16.66 |      100 |       0 |   16.66 | 22-38             
  ...sMessages.tsx |   55.67 |       40 |   28.57 |   55.67 | ...20-125,133-145 
  ...ryMessage.tsx |   14.28 |      100 |       0 |   14.28 | 23-62             
  ...onMessage.tsx |   81.98 |     72.6 |   33.33 |   81.98 | ...65-467,474-476 
  ...upMessage.tsx |   82.63 |    92.85 |     100 |   82.63 | ...85-412,434-449 
  ToolMessage.tsx  |   88.84 |    75.71 |    92.3 |   88.84 | ...44-749,776-778 
 ...ponents/shared |   84.26 |    80.36 |   95.45 |   84.26 |                   
  ...ctionList.tsx |   99.03 |    95.65 |     100 |   99.03 | 85                
  ...tonSelect.tsx |     100 |      100 |     100 |     100 |                   
  EnumSelector.tsx |     100 |    96.42 |     100 |     100 | 58                
  MaxSizedBox.tsx  |   83.01 |    86.25 |   88.88 |   83.01 | ...12-513,618-619 
  MultiSelect.tsx  |   93.58 |       75 |     100 |   93.58 | ...43,199-201,211 
  ...tonSelect.tsx |     100 |      100 |     100 |     100 |                   
  ...eSelector.tsx |     100 |       60 |     100 |     100 | 40-45             
  ...lableList.tsx |   76.25 |    81.81 |     100 |   76.25 | 44-58,65-68       
  StaticRender.tsx |   72.72 |      100 |     100 |   72.72 | 31-33             
  TextInput.tsx    |    80.8 |    66.07 |      80 |    80.8 | ...36-240,252-258 
  ...apsedTime.tsx |     100 |      100 |     100 |     100 |                   
  ...Indicator.tsx |     100 |      100 |     100 |     100 |                   
  ...lizedList.tsx |   84.26 |    80.88 |      90 |   84.26 | ...68-696,743-765 
  text-buffer.ts   |   85.67 |    80.84 |   97.91 |   85.67 | ...2616,2714-2715 
  ...er-actions.ts |   73.93 |    67.22 |     100 |   73.93 | ...32-733,934-936 
 ...ponents/skills |    3.64 |      100 |       0 |    3.64 |                   
  ...gerDialog.tsx |    3.64 |      100 |       0 |    3.64 | ...90-148,151-691 
 ...ents/subagents |   30.87 |        0 |       0 |   30.87 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  index.ts         |       0 |        0 |       0 |       0 | 1-11              
  reducers.tsx     |    12.1 |      100 |       0 |    12.1 | 33-190            
  types.ts         |     100 |      100 |     100 |     100 |                   
  utils.ts         |   10.95 |      100 |       0 |   10.95 | ...1,56-57,60-102 
 ...bagents/create |    9.13 |      100 |       0 |    9.13 |                   
  ...ionWizard.tsx |    7.28 |      100 |       0 |    7.28 | 34-299            
  ...rSelector.tsx |   14.75 |      100 |       0 |   14.75 | 26-85             
  ...onSummary.tsx |    4.26 |      100 |       0 |    4.26 | 27-331            
  ...tionInput.tsx |    8.63 |      100 |       0 |    8.63 | 23-177            
  ...dSelector.tsx |   33.33 |      100 |       0 |   33.33 | 20-21,26-27,36-63 
  ...nSelector.tsx |    37.5 |      100 |       0 |    37.5 | 20-21,26-27,36-58 
  ...EntryStep.tsx |   12.76 |      100 |       0 |   12.76 | 34-78             
  ToolSelector.tsx |    4.16 |      100 |       0 |    4.16 | 31-253            
 ...bagents/manage |   21.51 |    59.52 |   27.27 |   21.51 |                   
  ...ctionStep.tsx |   10.25 |      100 |       0 |   10.25 | 21-103            
  ...eleteStep.tsx |   20.93 |      100 |       0 |   20.93 | 23-62             
  ...tEditStep.tsx |   25.53 |      100 |       0 |   25.53 | ...2,37-38,51-124 
  ...ctionStep.tsx |   35.42 |    59.52 |     100 |   35.42 | ...20-432,437-439 
  ...iewerStep.tsx |   13.72 |      100 |       0 |   13.72 | 18-73             
  ...gerDialog.tsx |    6.74 |      100 |       0 |    6.74 | 35-341            
 ...mponents/views |   70.21 |    67.32 |    64.7 |   70.21 |                   
  ContextUsage.tsx |   70.88 |    63.88 |      80 |   70.88 | ...20-426,463-557 
  DoctorReport.tsx |     9.8 |      100 |       0 |     9.8 | 25-54,57-131      
  ...sionsList.tsx |   87.69 |    73.68 |     100 |   87.69 | 65-72             
  McpStatus.tsx    |   89.53 |    60.52 |     100 |   89.53 | ...72,175-177,262 
  SkillsList.tsx   |   27.27 |      100 |       0 |   27.27 | 18-35             
  ToolsList.tsx    |     100 |      100 |     100 |     100 |                   
 src/ui/contexts   |   77.45 |    78.23 |   81.03 |   77.45 |                   
  ...ewContext.tsx |    64.7 |    85.71 |      50 |    64.7 | ...22-225,231-241 
  AppContext.tsx   |      80 |       50 |     100 |      80 | 19-20             
  ...ewContext.tsx |   90.73 |    63.15 |      50 |   90.73 | ...45-250,253-258 
  ...deContext.tsx |     100 |      100 |     100 |     100 |                   
  ...igContext.tsx |   81.81 |       50 |     100 |   81.81 | 15-16             
  ...ssContext.tsx |   82.35 |    82.84 |     100 |   82.35 | ...1159,1165-1167 
  ...owContext.tsx |   91.07 |    81.81 |     100 |   91.07 | 47-48,60-62       
  ...deContext.tsx |     100 |      100 |      50 |     100 |                   
  ...onContext.tsx |   43.28 |     62.5 |    62.5 |   43.28 | ...56-259,263-266 
  ...gsContext.tsx |   83.33 |       50 |     100 |   83.33 | 17-18             
  ...usContext.tsx |     100 |      100 |     100 |     100 |                   
  ...ngContext.tsx |   71.42 |       50 |     100 |   71.42 | 17-20             
  ...utContext.tsx |   85.71 |      100 |   66.66 |   85.71 | 13-14             
  ...nsContext.tsx |   88.23 |       50 |     100 |   88.23 | 131-132           
  ...teContext.tsx |   86.66 |       50 |     100 |   86.66 | 197-198           
  ...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.76 |    80.67 |   86.49 |   81.76 |                   
  ...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 |   84.05 |    62.76 |      80 |   84.05 | ...1017,1038-1042 
  ...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 |   19.81 |    66.66 |      25 |   19.81 | 57-175            
  ...Completion.ts |   92.81 |    89.09 |     100 |   92.81 | ...86-187,224-227 
  ...ifications.ts |   92.07 |    96.29 |     100 |   92.07 | 116-124           
  ...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 |   93.67 |    76.92 |     100 |   93.67 | 75-79             
  ...chedScroll.ts |     100 |      100 |     100 |     100 |                   
  ...ketedPaste.ts |    23.8 |      100 |       0 |    23.8 | 19-37             
  ...nchCommand.ts |   94.36 |    74.35 |     100 |   94.36 | ...60,168-169,209 
  ...ompletion.tsx |   96.01 |    83.87 |     100 |   96.01 | ...22-223,225-226 
  ...dMigration.ts |   90.62 |       75 |     100 |   90.62 | 38-40             
  useCompletion.ts |    92.4 |     87.5 |     100 |    92.4 | 68-69,93-94,98-99 
  ...nitMessage.ts |     100 |      100 |     100 |     100 |                   
  ...extualTips.ts |   77.27 |       50 |     100 |   77.27 | ...2,75-79,93-101 
  ...eteCommand.ts |   78.53 |    88.57 |     100 |   78.53 | ...96-104,112-113 
  ...ialogClose.ts |   13.33 |      100 |     100 |   13.33 | 82-173            
  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 |   78.42 |    76.16 |   91.66 |   78.42 | ...2570,2595-2600 
  ...BranchName.ts |    90.9 |     92.3 |     100 |    90.9 | 19-20,55-58       
  ...oryManager.ts |   94.04 |    94.11 |     100 |   94.04 | 47,119-122        
  ...ooksDialog.ts |    87.5 |      100 |     100 |    87.5 | 19,23             
  ...stListener.ts |     100 |      100 |     100 |     100 |                   
  ...nAuthError.ts |   76.19 |       50 |     100 |   76.19 | 39-40,43-45       
  ...putHistory.ts |   92.59 |    85.71 |     100 |   92.59 | 63-64,72,94-96    
  ...storyStore.ts |     100 |    94.11 |     100 |     100 | 69                
  useKeypress.ts   |     100 |      100 |     100 |     100 |                   
  ...rdProtocol.ts |   36.36 |      100 |       0 |   36.36 | 24-31             
  ...unchEditor.ts |    9.67 |      100 |       0 |    9.67 | 11-32,39-90       
  ...gIndicator.ts |     100 |      100 |     100 |     100 |                   
  useLogger.ts     |   21.05 |      100 |       0 |   21.05 | 15-37             
  useMCPHealth.ts  |   63.15 |       75 |      50 |   63.15 | 42-52,64-67       
  useMcpDialog.ts  |    87.5 |      100 |     100 |    87.5 | 19,23             
  ...moryDialog.ts |    87.5 |      100 |     100 |    87.5 | 19,23             
  ...oryMonitor.ts |     100 |      100 |     100 |     100 |                   
  ...ssageQueue.ts |     100 |      100 |     100 |     100 |                   
  ...delCommand.ts |     100 |       75 |     100 |     100 | 22                
  ...ouseEvents.ts |   87.17 |    88.88 |   66.66 |   87.17 | 81-82,86-88       
  ...raseCycler.ts |   84.74 |    76.47 |     100 |   84.74 | ...49,52-53,69-71 
  ...rredEditor.ts |   58.33 |    22.22 |     100 |   58.33 | 23-27,29-33       
  ...derUpdates.ts |   86.49 |    77.96 |    90.9 |   86.49 | ...26,288-300,348 
  useQwenAuth.ts   |     100 |      100 |     100 |     100 |                   
  ...lScheduler.ts |    84.7 |    93.33 |     100 |    84.7 | ...71-276,372-382 
  ...oryCommand.ts |       0 |        0 |       0 |       0 | 1-7               
  ...umeCommand.ts |   96.96 |    83.33 |     100 |   96.96 | 101-102,131       
  ...ompletion.tsx |   90.59 |    83.33 |     100 |   90.59 | ...01,104,137-140 
  ...ectionList.ts |   97.05 |    96.07 |     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 |                   
  useStatusLine.ts |    96.3 |    92.19 |     100 |    96.3 | ...77-380,466-473 
  ...eateDialog.ts |   88.23 |      100 |     100 |   88.23 | 14,18             
  ...tification.ts |     100 |    85.71 |     100 |     100 | 47                
  ...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    |   89.72 |     87.5 |     100 |   89.72 |                   
  ...AppLayout.tsx |   89.88 |     87.5 |     100 |   89.88 | 51-53,93-98       
  ...AppLayout.tsx |   89.47 |     87.5 |     100 |   89.47 | 58-63             
 src/ui/models     |   80.24 |    79.16 |   71.42 |   80.24 |                   
  ...ableModels.ts |   80.24 |    79.16 |   71.42 |   80.24 | ...,61-71,123-125 
 ...noninteractive |     100 |      100 |   14.28 |     100 |                   
  ...eractiveUi.ts |     100 |      100 |   14.28 |     100 |                   
 src/ui/state      |   94.91 |    81.81 |     100 |   94.91 |                   
  extensions.ts    |   94.91 |    81.81 |     100 |   94.91 | 68-69,88          
 src/ui/themes     |   98.53 |    70.58 |     100 |   98.53 |                   
  ansi-light.ts    |     100 |      100 |     100 |     100 |                   
  ansi.ts          |     100 |      100 |     100 |     100 |                   
  atom-one-dark.ts |     100 |      100 |     100 |     100 |                   
  ayu-light.ts     |     100 |      100 |     100 |     100 |                   
  ayu.ts           |     100 |      100 |     100 |     100 |                   
  color-utils.ts   |     100 |      100 |     100 |     100 |                   
  default-light.ts |     100 |      100 |     100 |     100 |                   
  default.ts       |     100 |      100 |     100 |     100 |                   
  ...inal-theme.ts |   88.59 |    85.96 |     100 |   88.59 | ...57-261,266-270 
  dracula.ts       |     100 |      100 |     100 |     100 |                   
  github-dark.ts   |     100 |      100 |     100 |     100 |                   
  github-light.ts  |     100 |      100 |     100 |     100 |                   
  googlecode.ts    |     100 |      100 |     100 |     100 |                   
  no-color.ts      |     100 |      100 |     100 |     100 |                   
  qwen-dark.ts     |     100 |      100 |     100 |     100 |                   
  qwen-light.ts    |     100 |      100 |     100 |     100 |                   
  ...tic-tokens.ts |     100 |      100 |     100 |     100 |                   
  ...-of-purple.ts |     100 |      100 |     100 |     100 |                   
  theme-manager.ts |   87.98 |    82.89 |     100 |   87.98 | ...48-357,362-363 
  theme.ts         |     100 |    38.02 |     100 |     100 | ...34-449,457-461 
  xcode.ts         |     100 |      100 |     100 |     100 |                   
 src/ui/utils      |   82.58 |    82.66 |    92.4 |   82.58 |                   
  ...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                
  ...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.27 |     100 |   95.23 | 117-120           
  gradientUtils.ts |     100 |      100 |     100 |     100 |                   
  highlight.ts     |     100 |      100 |     100 |     100 |                   
  ...oryMapping.ts |     100 |    94.59 |     100 |     100 | 40,62             
  historyUtils.ts  |   94.11 |       94 |     100 |   94.11 | 94-97             
  isNarrowWidth.ts |     100 |      100 |     100 |     100 |                   
  ...olDetector.ts |    8.23 |      100 |       0 |    8.23 | ...31-132,135-136 
  latexRenderer.ts |   94.95 |     73.8 |     100 |   94.95 | ...76-178,184-187 
  layoutUtils.ts   |     100 |      100 |     100 |     100 |                   
  ...ightLoader.ts |     100 |    89.47 |     100 |     100 | 81,110            
  ...nUtilities.ts |   69.84 |    85.71 |     100 |   69.84 | 75-91,100-101     
  ...ToolGroups.ts |   98.66 |    96.77 |     100 |   98.66 | 48-49             
  ...geRenderer.ts |   86.23 |    69.06 |   95.12 |   86.23 | ...1284,1324-1330 
  ...alRenderer.ts |   86.69 |     71.9 |     100 |   86.69 | ...1476,1513-1519 
  ...lsBySource.ts |     100 |    95.23 |     100 |     100 | 84                
  mouse.ts         |   90.71 |    73.33 |   88.88 |   90.71 | ...40-143,200-201 
  osc8.ts          |   94.73 |    87.75 |     100 |   94.73 | ...49,434,438-439 
  ...mConstants.ts |     100 |      100 |     100 |     100 |                   
  restoreGoal.ts   |   98.98 |    97.05 |     100 |   98.98 | 98                
  ...storyUtils.ts |   62.74 |    71.26 |      90 |   62.74 | ...84,432,437-459 
  ...ickerUtils.ts |     100 |      100 |     100 |     100 |                   
  ...izedOutput.ts |   94.94 |      100 |   88.88 |   94.94 | 112-117           
  ...wOptimizer.ts |     100 |    96.77 |     100 |     100 | 69                
  terminalSetup.ts |    4.37 |      100 |       0 |    4.37 | 44-393            
  textUtils.ts     |   97.61 |    94.84 |   92.85 |   97.61 | ...50-251,386-387 
  todoSnapshot.ts  |   89.33 |    93.47 |     100 |   89.33 | ...,66-78,180-181 
  updateCheck.ts   |     100 |    80.95 |     100 |     100 | 30-42             
 ...i/utils/export |   56.77 |     40.8 |   79.41 |   56.77 |                   
  collect.ts       |   55.92 |    50.58 |   86.36 |   55.92 | ...25-640,642-647 
  index.ts         |     100 |      100 |     100 |     100 |                   
  normalize.ts     |   57.47 |    20.51 |      80 |   57.47 | ...09-310,324-359 
  types.ts         |       0 |        0 |       0 |       0 | 1                 
  utils.ts         |      40 |      100 |       0 |      40 | 11-13             
 ...ort/formatters |    3.38 |      100 |       0 |    3.38 |                   
  html.ts          |    9.61 |      100 |       0 |    9.61 | ...28,34-76,82-84 
  json.ts          |      50 |      100 |       0 |      50 | 14-15             
  jsonl.ts         |     3.5 |      100 |       0 |     3.5 | 14-76             
  markdown.ts      |    0.94 |      100 |       0 |    0.94 | 13-295            
 src/utils         |   71.87 |    88.84 |   90.34 |   71.87 |                   
  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.98 |       75 |     100 |   70.98 | ...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 |   90.96 |    90.47 |   88.88 |   90.96 | 125-136,144,155   
  ...tyWarnings.ts |     100 |      100 |     100 |     100 |                   
  ...lationInfo.ts |   89.17 |    92.77 |     100 |   89.17 | ...55,272-273,318 
  languageUtils.ts |   97.89 |    96.42 |     100 |   97.89 | 132-133           
  math.ts          |       0 |        0 |       0 |       0 | 1-15              
  ...iagnostics.ts |   94.57 |    83.01 |   88.88 |   94.57 | ...05,311,315-317 
  ...onfigUtils.ts |     100 |      100 |     100 |     100 |                   
  ...iveHelpers.ts |   96.79 |    93.28 |     100 |   96.79 | ...76-477,575,588 
  osc.ts           |    97.5 |      100 |   88.88 |    97.5 | 195-196           
  package.ts       |   88.88 |       80 |     100 |   88.88 | 33-34             
  processUtils.ts  |     100 |      100 |     100 |     100 |                   
  readStdin.ts     |   79.62 |       90 |      80 |   79.62 | 33-40,52-54       
  relaunch.ts      |   93.22 |    81.25 |     100 |   93.22 | 65-67,80          
  resolvePath.ts   |   66.66 |       25 |     100 |   66.66 | 12-13,16,18-19    
  runBudget.ts     |   99.35 |    96.77 |     100 |   99.35 | 119               
  sandbox.ts       |       0 |        0 |       0 |       0 | 1-1047            
  sessionPaths.ts  |   90.84 |    90.56 |     100 |   90.84 | ...81-182,185-186 
  settingsUtils.ts |   82.51 |    91.72 |   89.74 |   82.51 | ...76-694,701-709 
  spawnWrapper.ts  |     100 |      100 |     100 |     100 |                   
  ...ate-verify.ts |     100 |      100 |     100 |     100 |                   
  ...one-update.ts |   26.82 |    73.77 |   43.47 |   26.82 | ...36-837,840-859 
  ...upProfiler.ts |   98.46 |    94.52 |     100 |   98.46 | 130-131,305       
  ...upWarnings.ts |     100 |      100 |     100 |     100 |                   
  stdioHelpers.ts  |     100 |       60 |     100 |     100 | 23,32             
  systemInfo.ts    |   95.12 |    89.06 |     100 |   95.12 | ...43-244,249-253 
  ...InfoFields.ts |    87.5 |       65 |     100 |    87.5 | ...24-125,146-147 
  ...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.36 |     83.6 |   82.96 |   81.36 |                   
 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        |   84.88 |    74.63 |   84.31 |   84.88 |                   
  ...transcript.ts |   92.25 |    85.71 |     100 |   92.25 | ...87,306-307,438 
  ...ent-resume.ts |   82.75 |    71.63 |   77.41 |   82.75 | ...1080-1084,1087 
  ...ound-tasks.ts |       0 |        0 |       0 |       0 | 1-19              
  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.29 |    86.15 |   73.04 |   76.29 |                   
  ITermBackend.ts  |   97.97 |    93.93 |     100 |   97.97 | ...78-180,255,307 
  ...essBackend.ts |   91.25 |    90.62 |   86.66 |   91.25 | ...94,249-269,328 
  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 |   81.82 |    78.04 |   73.27 |   81.82 |                   
  agent-context.ts |     100 |      100 |     100 |     100 |                   
  agent-core.ts    |   76.81 |    72.89 |   63.63 |   76.81 | ...1614,1641-1688 
  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.07 |    80.76 |   74.07 |   80.07 | ...53,455,457,460 
  ...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 |                   
 src/config        |   78.42 |    82.82 |   65.24 |   78.42 |                   
  config.ts        |   76.42 |    81.77 |   60.83 |   76.42 | ...4218,4229-4241 
  constants.ts     |     100 |      100 |     100 |     100 |                   
  models.ts        |     100 |      100 |     100 |     100 |                   
  storage.ts       |   95.01 |    91.02 |   90.47 |   95.01 | ...71-372,375-376 
 ...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.44 |    83.87 |   91.16 |   88.44 |                   
  baseLlmClient.ts |   81.25 |    76.47 |   77.77 |   81.25 | ...13,515-525,534 
  client.ts        |   86.74 |     81.1 |   84.44 |   86.74 | ...2101,2107-2119 
  ...tGenerator.ts |    72.1 |    61.11 |     100 |    72.1 | ...63,365,372-375 
  ...lScheduler.ts |   88.41 |    82.02 |   95.52 |   88.41 | ...3732,3760-3771 
  geminiChat.ts    |   90.93 |    87.95 |   96.05 |   90.93 | ...2914,2981-2982 
  geminiRequest.ts |     100 |      100 |     100 |     100 |                   
  ...htProtocol.ts |    9.09 |      100 |       0 |    9.09 | 34-42,45-49,52-87 
  logger.ts        |   87.41 |    87.02 |     100 |   87.41 | ...64-568,614-628 
  ...tyDefaults.ts |     100 |      100 |     100 |     100 |                   
  ...olExecutor.ts |   92.59 |       75 |      50 |   92.59 | 41-42             
  ...on-helpers.ts |   86.48 |    72.22 |     100 |   86.48 | ...97-198,212-221 
  ...issionFlow.ts |   98.75 |    95.83 |     100 |   98.75 | 93                
  prompts.ts       |   89.28 |    86.25 |      75 |   89.28 | ...-979,1182-1183 
  tokenLimits.ts   |     100 |    89.47 |     100 |     100 | 51-52             
  ...okTriggers.ts |   99.42 |     90.9 |     100 |   99.42 | 172,183           
  turn.ts          |   96.46 |    88.88 |     100 |   96.46 | ...32,445-446,494 
 ...ntentGenerator |   94.88 |    82.07 |      94 |   94.88 |                   
  ...tGenerator.ts |   96.29 |    83.18 |   92.85 |   96.29 | ...1,971,999-1001 
  converter.ts     |   94.51 |    80.72 |     100 |   94.51 | ...06-607,617,823 
  index.ts         |       0 |        0 |       0 |       0 | 1-21              
  usage.ts         |     100 |      100 |     100 |     100 |                   
 ...ntentGenerator |   91.53 |    71.64 |   93.33 |   91.53 |                   
  ...tGenerator.ts |      90 |    70.96 |   92.85 |      90 | ...80-286,304-305 
  index.ts         |     100 |       80 |     100 |     100 | 50                
 ...ntentGenerator |      94 |    83.93 |   91.17 |      94 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...tGenerator.ts |   93.87 |    82.37 |   90.62 |   93.87 | ...2,992-993,1021 
  ...tDetection.ts |     100 |      100 |     100 |     100 |                   
 ...ntentGenerator |   86.12 |    83.98 |   93.58 |   86.12 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  converter.ts     |   84.89 |    82.17 |   96.15 |   84.89 | ...1394,1610-1625 
  errorHandler.ts  |     100 |      100 |     100 |     100 |                   
  index.ts         |   54.54 |    68.75 |      50 |   54.54 | ...79,87-91,95-99 
  ...tGenerator.ts |    66.4 |    70.58 |   88.88 |    66.4 | ...51-157,168-169 
  pipeline.ts      |   93.82 |     84.4 |     100 |   93.82 | ...89-490,498,566 
  ...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.35 |    79.54 |   80.31 |   62.35 |                   
  ...-converter.ts |   66.21 |    52.45 |     100 |   66.21 | ...85-786,795-827 
  ...ionManager.ts |    47.1 |    82.06 |    65.9 |    47.1 | ...1404,1414-1433 
  ...onSettings.ts |   93.46 |    93.05 |     100 |   93.46 | ...17-221,228-232 
  ...-converter.ts |   54.88 |    94.44 |      60 |   54.88 | ...35-146,158-192 
  github.ts        |   46.41 |     87.3 |   63.63 |   46.41 | ...68-374,413-466 
  index.ts         |     100 |      100 |     100 |     100 |                   
  marketplace.ts   |   97.31 |    93.75 |     100 |   97.31 | ...65,185-186,275 
  npm.ts           |   59.01 |    71.69 |    87.5 |   59.01 | ...23-425,432-436 
  override.ts      |   94.11 |    88.88 |     100 |   94.11 | 63-64,81-82       
  redaction.ts     |     100 |      100 |     100 |     100 |                   
  settings.ts      |   66.26 |      100 |      50 |   66.26 | 81-108,143-149    
  storage.ts       |     100 |      100 |     100 |     100 |                   
  ...ableSchema.ts |     100 |      100 |     100 |     100 |                   
  variables.ts     |   88.75 |    83.33 |     100 |   88.75 | ...28-231,234-237 
 src/followup      |   55.57 |    84.14 |   81.25 |   55.57 |                   
  followupState.ts |      96 |    89.74 |     100 |      96 | 159-161,218-219   
  index.ts         |     100 |      100 |     100 |     100 |                   
  overlayFs.ts     |   95.06 |       84 |     100 |   95.06 | 78,108,122,133    
  speculation.ts   |   13.02 |      100 |   16.66 |   13.02 | 89-464,524-575    
  ...onToolGate.ts |     100 |    96.42 |     100 |     100 | 94                
  ...nGenerator.ts |    71.6 |    72.13 |   83.33 |    71.6 | ...88-246,316-318 
 src/generated     |       0 |        0 |       0 |       0 |                   
  git-commit.ts    |       0 |        0 |       0 |       0 | 1-10              
 src/goals         |   89.57 |    83.45 |   94.44 |   89.57 |                   
  ...eGoalStore.ts |    85.1 |    95.45 |   84.61 |    85.1 | ...63-166,174-182 
  goalHook.ts      |   97.26 |    91.48 |     100 |   97.26 | 100-105           
  goalJudge.ts     |   84.33 |    74.28 |     100 |   84.33 | ...57-358,366-368 
  index.ts         |     100 |      100 |     100 |     100 |                   
 src/hooks         |   86.48 |    85.19 |   87.59 |   86.48 |                   
  ...okRegistry.ts |   86.48 |    77.08 |     100 |   86.48 | ...41-344,362-369 
  ...terpolator.ts |   96.66 |    93.33 |     100 |   96.66 | 66-67             
  ...HookRunner.ts |   96.68 |    87.23 |     100 |   96.68 | 110-112,231-233   
  ...Aggregator.ts |   96.09 |       90 |     100 |   96.09 | ...97-298,371,373 
  ...entHandler.ts |   95.09 |    86.58 |   93.93 |   95.09 | ...26,883-884,894 
  hookPlanner.ts   |   87.91 |    85.07 |   84.61 |   87.91 | ...84-186,204-215 
  hookRegistry.ts  |   90.17 |    83.33 |     100 |   90.17 | ...33,352,356,360 
  hookRunner.ts    |   62.42 |    72.04 |   66.66 |   62.42 | ...64-765,774-775 
  hookSystem.ts    |   86.22 |      100 |   68.18 |   86.22 | ...83-684,690-691 
  ...HookRunner.ts |   75.51 |     61.9 |      80 |   75.51 | ...05-406,424-425 
  index.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.77 |       94 |    87.5 |   92.77 | ...67-468,553-557 
  urlValidator.ts  |     100 |      100 |     100 |     100 |                   
 src/ide           |   75.55 |    83.52 |   78.33 |   75.55 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  detect-ide.ts    |     100 |      100 |     100 |     100 |                   
  ide-client.ts    |   66.14 |    81.75 |   66.66 |   66.14 | ...7-968,997-1005 
  ide-installer.ts |   89.06 |    79.31 |     100 |   89.06 | ...36,143-147,160 
  ideContext.ts    |     100 |      100 |     100 |     100 |                   
  process-utils.ts |   84.84 |    71.79 |     100 |   84.84 | ...37,151,193-194 
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/lsp           |   42.41 |    52.21 |   52.14 |   42.41 |                   
  ...nfigLoader.ts |   70.27 |    35.89 |   94.73 |   70.27 | ...20-422,426-432 
  ...ionFactory.ts |   42.69 |    79.16 |      50 |   42.69 | ...62-413,419-436 
  ...Normalizer.ts |   23.09 |    13.72 |   30.43 |   23.09 | ...04-905,909-924 
  ...verManager.ts |   25.31 |    62.06 |   41.66 |   25.31 | ...85-704,710-740 
  ...eLspClient.ts |   32.77 |       80 |   17.64 |   32.77 | ...84-288,294-295 
  ...LspService.ts |   51.85 |    65.98 |   68.57 |   51.85 | ...1339,1399-1409 
  constants.ts     |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/mcp           |   78.75 |    75.45 |   75.92 |   78.75 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  ...h-provider.ts |   86.95 |      100 |   33.33 |   86.95 | ...,93,97,101-102 
  ...h-provider.ts |   73.82 |    53.92 |     100 |   73.82 | ...88-895,902-904 
  ...en-storage.ts |   98.64 |    97.72 |     100 |   98.64 | 88-89             
  oauth-utils.ts   |   70.58 |    85.29 |    90.9 |   70.58 | ...70-290,315-344 
  ...n-provider.ts |   89.83 |       96 |   45.45 |   89.83 | ...43,147,151-152 
 .../token-storage |   79.72 |    87.05 |   86.36 |   79.72 |                   
  ...en-storage.ts |     100 |      100 |     100 |     100 |                   
  ...en-storage.ts |   83.44 |    84.21 |   92.85 |   83.44 | ...68-178,186-187 
  ...en-storage.ts |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...en-storage.ts |   68.14 |    82.35 |   64.28 |   68.14 | ...81-295,298-314 
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/memory        |    71.9 |    76.31 |   70.22 |    71.9 |                   
  const.ts         |     100 |      100 |     100 |     100 |                   
  dream.ts         |      66 |    73.33 |      50 |      66 | 51,108-149        
  ...entPlanner.ts |   57.84 |    72.72 |   33.33 |   57.84 | ...35,140-147,152 
  entries.ts       |   63.77 |    79.16 |      50 |   63.77 | ...72-180,183-189 
  extract.ts       |   95.23 |    79.16 |     100 |   95.23 | 82-87,126         
  ...entPlanner.ts |   63.08 |    65.71 |   41.17 |   63.08 | ...17,222-223,332 
  ...ionPlanner.ts |       0 |        0 |       0 |       0 | 1                 
  forget.ts        |      46 |    61.53 |   44.44 |      46 | ...05,212,215-347 
  indexer.ts       |   84.61 |    45.45 |     100 |   84.61 | ...51,57-58,70-71 
  manager.ts       |   75.34 |    81.04 |    75.6 |   75.34 | ...1279,1292-1294 
  memoryAge.ts     |   90.47 |    77.77 |     100 |   90.47 | 50-51             
  paths.ts         |   75.83 |    93.93 |     100 |   75.83 | 25-26,42-79       
  prompt.ts        |   93.36 |    71.42 |     100 |   93.36 | ...58,161,228-229 
  recall.ts        |   77.54 |    69.38 |   88.88 |   77.54 | ...53-258,282-293 
  ...ceSelector.ts |   91.86 |    77.27 |     100 |   91.86 | ...15,117-118,126 
  scan.ts          |   87.91 |    68.42 |     100 |   87.91 | ...47-48,58,82-87 
  ...entPlanner.ts |   58.02 |    66.66 |   56.25 |   58.02 | ...47-268,344-389 
  status.ts        |   10.52 |      100 |       0 |   10.52 | 41-98             
  store.ts         |   94.44 |    83.33 |     100 |   94.44 | 56-57,92-93       
  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.91 |    86.88 |   88.15 |   89.91 |                   
  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 |       44 |   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  |   85.99 |       85 |   82.92 |   85.99 | ...1312,1341-1342 
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/output        |     100 |      100 |     100 |     100 |                   
  ...-formatter.ts |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/permissions   |   82.65 |    91.86 |   68.32 |   82.65 |                   
  autoMode.ts      |   97.83 |    94.21 |     100 |   97.83 | 521-522,543-550   
  ...transcript.ts |      98 |       84 |     100 |      98 | 200-201           
  classifier.ts    |   93.95 |    94.44 |     100 |   93.95 | 158-165,383-387   
  ...erousRules.ts |     100 |    89.36 |     100 |     100 | 110,133,147,175   
  ...alTracking.ts |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...on-manager.ts |   84.86 |    89.03 |      80 |   84.86 | ...1024,1130-1134 
  rule-parser.ts   |   97.37 |    93.82 |     100 |   97.37 | ...-875,1024-1026 
  ...-semantics.ts |   70.28 |    90.69 |   46.21 |   70.28 | ...2214,2277-2280 
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...sifier-prompts |   99.04 |    95.23 |     100 |   99.04 |                   
  system-prompt.ts |   99.04 |    95.23 |     100 |   99.04 | 219               
 src/prompts       |   83.63 |      100 |    87.5 |   83.63 |                   
  mcp-prompts.ts   |   18.18 |      100 |       0 |   18.18 | 11-19             
  ...t-registry.ts |     100 |      100 |     100 |     100 |                   
 src/providers     |   79.44 |    64.39 |   64.28 |   79.44 |                   
  all-providers.ts |      68 |      100 |       0 |      68 | 68-69,73-79,83-89 
  index.ts         |     100 |      100 |     100 |     100 |                   
  install.ts       |   98.87 |    87.27 |     100 |   98.87 | 268-269           
  ...der-config.ts |   69.73 |    47.29 |   68.42 |   69.73 | ...10-411,418-427 
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 ...viders/presets |   97.29 |    86.36 |      50 |   97.29 |                   
  ...oding-plan.ts |   87.17 |      100 |       0 |   87.17 | 81-83,86-88,90-93 
  ...a-standard.ts |     100 |      100 |     100 |     100 |                   
  ...token-plan.ts |     100 |      100 |     100 |     100 |                   
  ...m-provider.ts |   97.01 |    81.25 |      75 |   97.01 | 120-121           
  deepseek.ts      |     100 |      100 |     100 |     100 |                   
  idealab.ts       |     100 |      100 |     100 |     100 |                   
  minimax.ts       |     100 |      100 |     100 |     100 |                   
  modelscope.ts    |     100 |      100 |     100 |     100 |                   
  openrouter.ts    |     100 |      100 |     100 |     100 |                   
  zai.ts           |     100 |      100 |     100 |     100 |                   
 src/qwen          |   84.48 |    77.37 |   95.83 |   84.48 |                   
  ...tGenerator.ts |   98.64 |    98.18 |     100 |   98.64 | 105-106           
  qwenOAuth2.ts    |   80.85 |    70.27 |   90.32 |   80.85 | ...1169-1185,1215 
  ...kenManager.ts |   85.36 |    76.61 |     100 |   85.36 | ...52-757,778-783 
 src/services      |   85.44 |    83.69 |   90.97 |   85.44 |                   
  ...ionTrailer.ts |     100 |      100 |     100 |     100 |                   
  ...llRegistry.ts |     100 |      100 |     100 |     100 |                   
  ...ionService.ts |   98.19 |    94.94 |     100 |   98.19 | 493,495-499,602   
  ...ingService.ts |   83.88 |    83.44 |   83.33 |   83.88 | ...1268,1285-1286 
  ...ttribution.ts |   91.73 |    87.71 |      90 |   91.73 | ...80-685,826-827 
  ...utSlimming.ts |     100 |    97.43 |     100 |     100 | 215,268           
  cronScheduler.ts |   97.56 |    92.98 |     100 |   97.56 | 62-63,77,155      
  ...eryService.ts |   80.43 |    95.45 |      75 |   80.43 | ...19-134,140-141 
  ...oryService.ts |   86.18 |    76.76 |   91.17 |   86.18 | ...1150,1191-1194 
  fileReadCache.ts |     100 |      100 |     100 |     100 |                   
  ...temService.ts |   91.27 |    82.69 |    90.9 |   91.27 | ...94,196,294-301 
  ...ratedFiles.ts |      96 |    88.23 |     100 |      96 | 119-120,146-147   
  gitInit.ts       |     100 |      100 |     100 |     100 |                   
  gitService.ts    |   68.75 |     92.3 |   55.55 |   68.75 | ...12-122,125-129 
  ...reeService.ts |   68.91 |    68.85 |   91.11 |   68.91 | ...2065,2092-2093 
  ...ionService.ts |   98.13 |     97.8 |   95.45 |   98.13 | ...32-333,380-381 
  ...ticsDumper.ts |   98.18 |    95.23 |     100 |   98.18 | 165-166           
  ...ureMonitor.ts |   95.27 |     91.6 |      96 |   95.27 | ...02,603,617-619 
  ...orRegistry.ts |     100 |      100 |     100 |     100 |                   
  ...ttachments.ts |   97.24 |    90.39 |     100 |   97.24 | ...08,646,661-662 
  sessionRecap.ts  |   12.65 |      100 |       0 |   12.65 | 44-150            
  ...ionService.ts |   90.47 |     79.2 |   96.87 |   90.47 | ...1324,1328-1329 
  sessionTitle.ts  |   93.87 |    71.15 |     100 |   93.87 | ...33-236,267-268 
  ...ionService.ts |   81.29 |    78.31 |   89.28 |   81.29 | ...1926,1932-1937 
  ...pInhibitor.ts |   97.02 |    90.56 |     100 |   97.02 | ...14-115,283-284 
  ...Estimation.ts |     100 |      100 |     100 |     100 |                   
  ...UseSummary.ts |   94.63 |    88.46 |     100 |   94.63 | ...62-164,214-215 
  ...reeCleanup.ts |   14.56 |      100 |   33.33 |   14.56 | 58-185            
  ...ionService.ts |   84.21 |    79.41 |     100 |   84.21 | ...18-219,235-236 
 ...icrocompaction |   98.05 |     91.8 |     100 |   98.05 |                   
  microcompact.ts  |   98.05 |     91.8 |     100 |   98.05 | ...19,289,293,391 
 src/skills        |   87.82 |    85.75 |   89.65 |   87.82 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...activation.ts |     100 |     93.1 |     100 |     100 | 93,112            
  skill-load.ts    |      94 |    86.56 |     100 |      94 | ...08,228,240-242 
  skill-manager.ts |   83.24 |    80.87 |   82.35 |   83.24 | ...1212,1219-1223 
  skill-paths.ts   |   89.15 |    86.36 |     100 |   89.15 | ...00-101,106-107 
  symlinkScope.ts  |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/subagents     |   82.61 |    78.89 |   95.23 |   82.61 |                   
  ...tin-agents.ts |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...nt-manager.ts |   77.15 |    71.36 |    93.1 |   77.15 | ...1178,1200-1201 
  types.ts         |     100 |      100 |     100 |     100 |                   
  validation.ts    |   92.46 |    95.18 |     100 |   92.46 | 51-56,69-74,78-83 
 src/tasks         |   86.25 |    83.72 |   83.96 |   86.25 |                   
  agent-task.ts    |   85.65 |    79.72 |   82.85 |   85.65 | ...,994,1015-1016 
  dispatcher.ts    |   36.84 |      100 |   33.33 |   36.84 | 90-99,107-110     
  dream-task.ts    |   17.64 |      100 |       0 |   17.64 | ...45-173,191-198 
  index.ts         |     100 |      100 |     100 |     100 |                   
  monitor-task.ts  |   91.89 |    88.67 |    93.1 |   91.89 | ...85-686,728-729 
  registry.ts      |   90.69 |    76.19 |   91.66 |   90.69 | ...81-182,215-218 
  shell-task.ts    |    95.8 |    85.45 |   95.23 |    95.8 | ...60-564,576-577 
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/telemetry     |   77.93 |    88.57 |   81.15 |   77.93 |                   
  config.ts        |     100 |      100 |     100 |     100 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  ...attributes.ts |   98.13 |       88 |     100 |   98.13 | 185-187           
  ...-exporters.ts |   46.37 |      100 |   44.44 |   46.37 | ...85,88-89,92-93 
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...t.circular.ts |       0 |        0 |       0 |       0 | 1-111             
  ...-processor.ts |   99.09 |    95.61 |      95 |   99.09 | 141,365-366       
  ...t.circular.ts |       0 |        0 |       0 |       0 | 1-128             
  loggers.ts       |   54.08 |    65.85 |   60.86 |   54.08 | ...1250,1267-1287 
  metrics.ts       |      75 |    81.52 |   75.43 |      75 | ...1018,1021-1032 
  ...attributes.ts |     100 |      100 |     100 |     100 |                   
  sanitize.ts      |      80 |    83.33 |     100 |      80 | 35-36,41-42       
  sdk.ts           |   93.06 |     88.4 |   81.81 |   93.06 | ...72-573,593-597 
  ...on-context.ts |     100 |      100 |     100 |     100 |                   
  ...on-tracing.ts |   88.47 |    87.39 |   96.29 |   88.47 | ...1345,1376-1379 
  ...etry-utils.ts |     100 |      100 |     100 |     100 |                   
  ...l-decision.ts |     100 |      100 |     100 |     100 |                   
  ...e-id-utils.ts |     100 |      100 |     100 |     100 |                   
  tracer.ts        |   98.61 |    89.36 |     100 |   98.61 | 53,108            
  types.ts         |   80.89 |    93.91 |   85.33 |   80.89 | ...1215,1218-1247 
  uiTelemetry.ts   |   92.97 |    96.96 |   81.25 |   92.97 | ...93-194,200-207 
 ...ry/qwen-logger |   68.17 |     80.2 |   65.51 |   68.17 |                   
  event-types.ts   |       0 |        0 |       0 |       0 |                   
  qwen-logger.ts   |   68.17 |       80 |   64.91 |   68.17 | ...1077,1115-1116 
 src/test-utils    |   93.16 |    95.91 |   76.47 |   93.16 |                   
  config.ts        |     100 |      100 |     100 |     100 |                   
  ...st-helpers.ts |   94.11 |       90 |     100 |   94.11 | 69-70             
  index.ts         |     100 |      100 |     100 |     100 |                   
  mock-tool.ts     |   91.19 |    97.14 |   72.41 |   91.19 | ...38,202-203,216 
  ...aceContext.ts |     100 |      100 |     100 |     100 |                   
 src/tools         |   79.54 |    82.05 |   86.15 |   79.54 |                   
  ...erQuestion.ts |   88.93 |    76.74 |    90.9 |   88.93 | ...39-340,347-348 
  cron-create.ts   |   88.11 |    88.88 |    62.5 |   88.11 | ...,43-44,165-172 
  cron-delete.ts   |   96.82 |      100 |   83.33 |   96.82 | 26-27             
  cron-list.ts     |   96.66 |      100 |   83.33 |   96.66 | 25-26             
  diffOptions.ts   |     100 |      100 |     100 |     100 |                   
  edit.ts          |   81.02 |    84.07 |      75 |   81.02 | ...15-716,826-876 
  ...r-worktree.ts |   83.14 |    67.56 |    87.5 |   83.14 | ...84-187,278-279 
  exit-worktree.ts |   84.23 |    85.96 |   91.66 |   84.23 | ...92-293,298-312 
  exitPlanMode.ts  |   85.09 |    85.71 |     100 |   85.09 | ...60-163,177-189 
  glob.ts          |   90.63 |    88.33 |   84.61 |   90.63 | ...28,171,302,305 
  grep.ts          |   79.19 |    85.71 |   78.94 |   79.19 | ...20,560,569-576 
  ls.ts            |   96.74 |    90.27 |     100 |   96.74 | 176-181,212,216   
  lsp.ts           |   72.77 |    60.09 |   90.32 |   72.77 | ...1211,1213-1214 
  ...nt-manager.ts |   84.36 |    82.74 |   84.21 |   84.36 | ...2099-2103,2142 
  mcp-client.ts    |   39.91 |    83.82 |   69.44 |   39.91 | ...1618,1622-1625 
  mcp-tool.ts      |   90.98 |    88.88 |   96.42 |   90.98 | ...95-596,646-647 
  memory-config.ts |       0 |        0 |       0 |       0 | 1-47              
  ...iable-tool.ts |     100 |    84.61 |     100 |     100 | 102,109           
  monitor.ts       |   91.63 |    84.05 |   88.46 |   91.63 | ...93,606,802-807 
  notebook-edit.ts |   85.11 |    76.42 |   81.25 |   85.11 | ...54-870,916-917 
  ...nforcement.ts |   82.57 |       90 |     100 |   82.57 | 174-185,234-247   
  read-file.ts     |    95.4 |    90.32 |      90 |    95.4 | ...99,298-301,304 
  ripGrep.ts       |   94.59 |    85.71 |   93.33 |   94.59 | ...60,463,541-542 
  ...-transport.ts |    6.34 |        0 |       0 |    6.34 | 47-145            
  send-message.ts  |   84.82 |    91.66 |    62.5 |   84.82 | ...,83-91,168-171 
  shell.ts         |    74.4 |    80.89 |   91.78 |    74.4 | ...4258,4325-4326 
  skill-utils.ts   |     100 |      100 |     100 |     100 |                   
  skill.ts         |   89.51 |    92.07 |      90 |   89.51 | ...41,545,568-590 
  ...eticOutput.ts |   95.12 |      100 |      80 |   95.12 | 87-88             
  task-stop.ts     |   93.18 |    96.15 |   85.71 |   93.18 | 42-43,58-68       
  todoWrite.ts     |   89.27 |    82.05 |   92.85 |   89.27 | ...50-555,577-578 
  tool-error.ts    |     100 |      100 |     100 |     100 |                   
  tool-names.ts    |     100 |      100 |     100 |     100 |                   
  tool-registry.ts |   74.85 |    76.85 |   80.95 |   74.85 | ...30-831,839-840 
  tool-search.ts   |   95.19 |    86.48 |    92.3 |   95.19 | ...47-153,208-213 
  tools.ts         |   92.14 |    90.38 |   89.47 |   92.14 | ...78-479,495-501 
  web-fetch.ts     |   88.84 |       80 |   92.85 |   88.84 | ...12-313,315-316 
  write-file.ts    |   82.65 |    80.45 |   84.61 |   82.65 | ...65-668,696-731 
 src/tools/agent   |   74.39 |    80.37 |   69.33 |   74.39 |                   
  agent.ts         |   74.56 |    80.44 |   69.11 |   74.56 | ...2924,2933-2936 
  fork-subagent.ts |   70.73 |    77.77 |   71.42 |   70.73 | ...22-123,158-169 
 ...s/computer-use |   85.21 |     87.9 |   76.31 |   85.21 |                   
  bootstrap.ts     |   72.09 |    92.85 |   66.66 |   72.09 | 137-191,302-303   
  client.ts        |      38 |      100 |      50 |      38 | ...48-178,182-191 
  constants.ts     |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  install-state.ts |   94.44 |       75 |     100 |   94.44 | 40-41             
  ...n-detector.ts |     100 |     87.5 |     100 |     100 | 43                
  schemas.ts       |     100 |      100 |     100 |     100 |                   
  tool.ts          |   95.67 |    82.97 |    92.3 |   95.67 | 49-50,159-165     
 src/utils         |   89.75 |    88.09 |   94.39 |   89.75 |                   
  LruCache.ts      |       0 |        0 |       0 |       0 | 1-41              
  ...Controller.ts |     100 |      100 |     100 |     100 |                   
  ...ssageQueue.ts |     100 |      100 |     100 |     100 |                   
  ...cFileWrite.ts |   94.76 |    93.06 |     100 |   94.76 | ...30-531,634-638 
  bareMode.ts      |   27.27 |      100 |       0 |   27.27 | 9-15,18-19        
  browser.ts       |    7.69 |      100 |       0 |    7.69 | 17-56             
  bundlePaths.ts   |     100 |      100 |     100 |     100 |                   
  ...igResolver.ts |     100 |      100 |     100 |     100 |                   
  ...engthError.ts |      90 |    87.71 |     100 |      90 | ...54-155,158-159 
  cronDisplay.ts   |   42.85 |    23.07 |     100 |   42.85 | 26-31,33-45,47-54 
  cronParser.ts    |   89.74 |    85.71 |     100 |   89.74 | ...,63-64,183-186 
  debugLogger.ts   |    95.9 |    93.93 |   94.73 |    95.9 | 106-107,222-226   
  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 |     100 |    95.45 |     100 |     100 | 83                
  errorParsing.ts  |    97.7 |    97.05 |     100 |    97.7 | 72-73             
  ...rReporting.ts |   88.46 |       90 |     100 |   88.46 | 69-74             
  errors.ts        |   70.54 |    79.59 |      50 |   70.54 | ...15-231,235-241 
  fetch.ts         |   70.18 |    71.42 |   71.42 |   70.18 | ...42,148,161,186 
  fileUtils.ts     |    91.5 |    86.13 |   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        |    12.5 |      100 |       0 |    12.5 | 21-34             
  gitDiff.ts       |   92.36 |    79.53 |     100 |   92.36 | ...55-856,928-929 
  ...noreParser.ts |    92.3 |    89.36 |     100 |    92.3 | ...15-116,186-187 
  gitUtils.ts      |   73.64 |    90.32 |   83.33 |   73.64 | ...,78-79,103-154 
  iconvHelper.ts   |     100 |      100 |     100 |     100 |                   
  ...rePatterns.ts |     100 |      100 |     100 |     100 |                   
  ...ionManager.ts |     100 |     90.9 |     100 |     100 | 27                
  ...lPromptIds.ts |     100 |      100 |     100 |     100 |                   
  jsonl-utils.ts   |   88.98 |    90.66 |   91.66 |   88.98 | ...46-349,359-365 
  ...-detection.ts |     100 |      100 |     100 |     100 |                   
  ...iagnostics.ts |    96.4 |     94.2 |     100 |    96.4 | ...66,293-294,376 
  ...yDiscovery.ts |   88.27 |    83.87 |     100 |   88.27 | ...76,279,407-410 
  ...tProcessor.ts |    93.2 |    89.18 |     100 |    93.2 | ...82-288,370-371 
  ...Inspectors.ts |   61.53 |      100 |      50 |   61.53 | 18-23             
  modelId.ts       |   98.95 |    98.21 |     100 |   98.95 | 148               
  ...kerChecker.ts |   90.78 |    91.66 |     100 |   90.78 | 73-79             
  notebook.ts      |   94.57 |    89.83 |   95.83 |   94.57 | ...21,333,385-387 
  openaiLogger.ts  |   90.85 |    87.87 |     100 |   90.85 | ...97-199,222-227 
  partUtils.ts     |     100 |    98.61 |     100 |     100 | 206               
  pathReader.ts    |     100 |      100 |     100 |     100 |                   
  paths.ts         |   93.21 |    91.95 |     100 |   93.21 | ...89-390,392-394 
  pdf.ts           |   93.68 |    87.05 |     100 |   93.68 | ...96-297,321-325 
  projectPath.ts   |     100 |      100 |     100 |     100 |                   
  projectRoot.ts   |   71.73 |    78.57 |     100 |   71.73 | 54-66             
  ...ectSummary.ts |   89.62 |    72.41 |     100 |   89.62 | ...40-145,196-199 
  ...tIdContext.ts |     100 |      100 |     100 |     100 |                   
  proxyUtils.ts    |     100 |      100 |     100 |     100 |                   
  ...rDetection.ts |   58.57 |       76 |     100 |   58.57 | ...4,88-89,95-100 
  ...noreParser.ts |   85.45 |    85.18 |     100 |   85.45 | ...59,65-66,72-73 
  rateLimit.ts     |   92.55 |    85.92 |     100 |   92.55 | ...70-272,309-310 
  readManyFiles.ts |   87.59 |       84 |     100 |   87.59 | ...09-211,227-238 
  retry.ts         |   91.86 |    87.17 |     100 |   91.86 | ...30,451,458-459 
  retryContext.ts  |     100 |      100 |     100 |     100 |                   
  ripgrepUtils.ts  |   46.79 |    84.37 |   66.66 |   46.79 | ...45-246,258-335 
  ...sDiscovery.ts |   97.42 |    92.85 |     100 |   97.42 | ...04,182-183,202 
  ...iagnostics.ts |   83.08 |     67.5 |   92.59 |   83.08 | ...23,543-544,550 
  ...tchOptions.ts |   82.18 |    85.18 |   95.23 |   82.18 | ...24,549,578-587 
  runtimeStatus.ts |    97.5 |    88.57 |     100 |    97.5 | 162-163           
  safeJsonParse.ts |   74.07 |    83.33 |     100 |   74.07 | 40-46             
  ...nStringify.ts |     100 |      100 |     100 |     100 |                   
  ...aConverter.ts |   90.78 |    88.23 |     100 |   90.78 | ...41-42,93,95-96 
  ...aValidator.ts |      95 |    82.75 |     100 |      95 | ...07,216-219,273 
  ...r-launcher.ts |   76.92 |     91.3 |   66.66 |   76.92 | ...34,136,157-195 
  ...orageUtils.ts |   96.89 |    85.84 |     100 |   96.89 | ...51,367,447,466 
  shell-utils.ts   |   84.39 |    90.46 |     100 |   84.39 | ...1583,1590-1594 
  ...lAstParser.ts |   95.58 |    85.79 |     100 |   95.58 | ...1067-1069,1079 
  ...ContextEnv.ts |     100 |      100 |     100 |     100 |                   
  ...nlyChecker.ts |    95.1 |    91.66 |     100 |    95.1 | ...16-317,325-326 
  sideQuery.ts     |   86.17 |    86.53 |     100 |   86.17 | ...55-161,163-169 
  ...pEventSink.ts |     100 |       80 |     100 |     100 | 61                
  ...tGenerator.ts |     100 |      100 |     100 |     100 |                   
  ...ameContext.ts |     100 |      100 |     100 |     100 |                   
  symlink.ts       |   81.48 |       75 |     100 |   81.48 | 54-59             
  ...emEncoding.ts |   96.36 |    91.17 |     100 |   96.36 | 59-60,124-125     
  terminalSafe.ts  |     100 |      100 |     100 |     100 |                   
  ...Serializer.ts |   98.72 |       90 |     100 |   98.72 | 42-43,134,201-203 
  testUtils.ts     |   53.33 |      100 |   33.33 |   53.33 | ...53,59-64,70-72 
  textUtils.ts     |      60 |      100 |   66.66 |      60 | 36-55             
  thoughtUtils.ts  |     100 |    92.85 |     100 |     100 | 71                
  ...-converter.ts |   94.59 |    85.71 |     100 |   94.59 | 35-36             
  tool-utils.ts    |    93.6 |     91.3 |     100 |    93.6 | ...58-159,162-163 
  truncation.ts    |     100 |       92 |     100 |     100 | 52,71             
  windowsPath.ts   |   89.47 |    79.31 |     100 |   89.47 | ...57-58,62,90-91 
  ...aceContext.ts |   93.71 |    89.28 |   93.33 |   93.71 | ...24-225,249-251 
  xml.ts           |     100 |      100 |     100 |     100 |                   
  yaml-parser.ts   |      92 |     84.9 |     100 |      92 | 49-53,65-69       
 ...ils/filesearch |   86.35 |    81.76 |   96.42 |   86.35 |                   
  crawlCache.ts    |     100 |      100 |     100 |     100 |                   
  crawler.ts       |   83.07 |    77.74 |   94.82 |   83.07 | ...1468,1502-1503 
  fileSearch.ts    |   93.58 |    87.32 |     100 |   93.58 | ...46-247,249-250 
  ignore.ts        |     100 |      100 |     100 |     100 |                   
  result-cache.ts  |     100 |     92.3 |     100 |     100 | 46                
 ...uest-tokenizer |   56.63 |    74.52 |   74.19 |   56.63 |                   
  ...eTokenizer.ts |   41.86 |    76.47 |   69.23 |   41.86 | ...70-443,453-507 
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...tTokenizer.ts |   68.39 |    69.49 |    90.9 |   68.39 | ...24-325,327-328 
  ...ageFormats.ts |      76 |      100 |   33.33 |      76 | 45-48,55-56       
  textTokenizer.ts |     100 |      100 |     100 |     100 |                   
  types.ts         |       0 |        0 |       0 |       0 | 1                 
-------------------|---------|----------|---------|---------|-------------------

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

@wenshao

wenshao commented Jun 1, 2026

Copy link
Copy Markdown
Collaborator

✅ Local build + test + runtime verification — PR #3982

结论 / Verdict: 行为保持型大重构,构建/类型/测试/运行时接线均通过,建议合并。 Large behaviour-preserving refactor; builds, types, both test suites and runtime wiring all pass — recommend merge.

这是一个把三个 per-kind registry 合并成单一 TaskRegistry + 调度器的大重构(53 文件,净删 ~2400 行),声称"无用户可见行为变化"。所以验证重点是:两个包真的能构建+类型干净、改写后的测试套件全绿(这才是"无行为变化"的安全网)、API 表面与向后兼容 shim 正确、以及真实启动时调度器注册不产生 import cycle。全部本地实跑。

For a "no user-observable behavior change" refactor of this size, the authoritative test is: clean build/typecheck, the rewritten suites green (the real safety net), correct API surface + back-compat shims, and a runtime check that the dispatcher's register-on-startup doesn't hit the import cycle it was designed to avoid.


Method

  • pr-3982 = current main (1c48e4121) + 3 commits (collapse registries → move tasks/ top-level → fold in agent concurrency cap). refactor(core): TaskBase envelope + foreground subagent persistence #3970 (the "stacked on" dep) is already merged into main, and the branch is rebased on current main (0 behind). Deps unchanged (lockfile delta empty), so the existing node_modules is valid.
  • Clean-rebuilt core then cli (the PR touches only these two packages), then ran both suites + a runtime TUI smoke.

Builds & typecheck ✅

  • core and cli both tsc --build clean (emit + full typecheck). PR touches only core/cli, so this covers the affected packages.

Test suites ✅ (the behavioural safety net)

Suite Result
packages/core 9653 passed, 5 skipped, 0 failed
packages/cli 6973 passed, 9 skipped, 2 failed — both failures pre-existing on main (see below)

The rewritten task tests run green: agent-task / shell-task / monitor-task / dispatcher / task-stop (core) and useBackgroundTaskView / BackgroundTasksDialog / tasksCommand / clearCommand (cli) — i.e. the exact creation, status-transition and per-kind cancel-routing behaviours this refactor reshapes.

The 2 cli failures are NOT caused by this PR. Both are in src/serve/ daemon routes — unrelated to task registries, and neither file is in the 53-file changeset:

  • workspaceAgents.test.ts › returns 500 agent_delete_partial when one level unlink silently fails
  • workspaceMemory.test.ts › omits errorMessage + filePath in 500/413 responses unless QWEN_SERVE_DEBUG is on

I checked out main (1c48e4121) and ran the same two files: they fail identically there (2 failed | 53 passed). Root cause is an environment artifact — the sandbox runs as root: the test forces an unlink to "silently fail" and expects HTTP 500, but as root the unlink succeeds, so the route returns 204 (expected 204 to be 500). So PR-attributable test failures: zero — the cli failure set is identical with and without this PR.

Note: the PR body quotes 7115 (core) / 5283 (cli). Those are stale — the PR was authored 2026-05-09 and main has since grown ~2.5k tests; rebased on today's main the counts are higher. All green either way.

API surface & back-compat ✅

  • Config.getTaskRegistry(): TaskRegistry added (config.ts:3714); the three old getters (getBackgroundTaskRegistry / getBackgroundShellRegistry / getMonitorRegistry) are dropped — a documented atomic breaking change for Config holders.
  • Type-level re-export shims preserved at the old paths (services/backgroundShellRegistry.ts, services/monitorRegistry.ts) → re-export ShellTask / BackgroundShellStatus / MonitorEntry / MonitorStatus / … from the new tasks/* modules. Confirmed present in the built .d.ts surface (these are type re-exports, so 0 runtime exports — correct). core/index.ts also adds export * from './tasks/index.js', so the new surface is reachable from the package root.
  • Zero dangling references to the dropped getters anywhere in src.

Runtime smoke (tmux, real CLI) ✅

Launched the built CLI in an isolated tmux sandbox:

  • Clean boot, no crash — confirms the dispatcher's register-on-startup in Config works at runtime (the import-cycle risk the PR flags as reviewer focus does not manifest).
  • /tasks
> /tasks
● No background tasks.

i.e. the migrated command subscribes to the new TaskRegistry and renders correctly. (Spawning live background subagents/monitors/shells requires an LLM-driven tool call, out of scope for a no-network smoke; the interactive dialog + per-kind cancel routing is covered by the rewritten suites above.)

Notes for reviewers

  • PR body test counts are stale (see above) — not a concern.
  • Documented breaking change: Config holders using getBackgroundTaskRegistry() etc. must switch to getTaskRegistry() + per-kind helpers. Type-only imports of the old public types keep working via the shims for one release.
  • Module-level singletons for agent/monitor notify+register callbacks (PR's stated tradeoff) — fine for single-Config processes; flagged for future multi-session SDK work.

Environment note (unrelated to this PR)

This checkout's dist was drifted; I clean-rebuilt core+cli on the branch before testing. Deps unchanged from main, so no reinstall was needed.


Bottom line: clean builds + typecheck, core fully green, cli green except 2 pre-existing root-environment failures that are identical on main and unrelated to this PR (zero PR-attributable failures), correct new API surface with type-level back-compat shims, and a clean runtime boot proving the dispatcher registration avoids the import cycle. Consistent with "no user-observable behavior change." 👍

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

A couple of additional findings that don't map to a single changed diff line:

[Suggestion] packages/core/src/config/config.ts:3729 & :3738 — the AgentTask type is still imported from the deprecated re-export shim ../agents/background-tasks.js, whose own header says "New code should import from '../tasks/agent-task.js' directly" and that it's "scheduled for removal one release after this lands." Line 87 of the same file already switched to the canonical ../tasks/agent-task.js. Pointing these two type references at the canonical module keeps config.ts internally consistent and lets the shim be removed atomically as planned.

[Suggestion] Test coverage — this PR deletes the three registry test suites (background-tasks.test.ts, backgroundShellRegistry.test.ts, monitorRegistry.test.ts, ~2,900 lines). Two gaps in the replacement suites are now exercised only through mocks: (1) the new dispatcher's kind→kill dispatch (tasks/dispatcher.ts + TaskRegistry.kill in tasks/registry.ts) — the centerpiece of the refactor — has no direct test (its only production caller, the dialog cancel, mocks getTaskByType); (2) the agent terminal-notification XML builder (tasks/agent-task.ts emitNotification) lost the cases the deleted suite had (XML escaping, <output-file>/<usage>/<tool-use-id> tags, foreground-suppression, double-notify guard) and now only runs against mockRegistry. A small dispatcher / registry.kill unit test plus porting the notification-XML cases would restore confidence in the parts the refactor changed most.

— claude-opus-4-8 via Claude Code /qreview

Comment on lines +1911 to +1914
/subagents\/test-session-id\/agent-file-search-.*\.jsonl$/,
),
metaPath: expect.stringMatching(
/subagents[\\/]test-session-id[\\/]agent-file-search-.*\.meta\.json$/,
/subagents\/test-session-id\/agent-file-search-.*\.meta\.json$/,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Critical] Windows CI is red on this test (Test (windows-latest, Node 22.x)). This PR narrowed both path regexes from the cross-platform character class [\\/] (used on main) to forward-slash-only \/. On Windows the reserved outputFile / metaPath use \ separators, so subagents\test-session-id\… no longer matches and the mockRegistry.register objectContaining assertion fails. The sibling agent-monitor test at line 1741 still uses [\\/], confirming this was an accidental narrowing rather than intentional.

Suggested change
/subagents\/test-session-id\/agent-file-search-.*\.jsonl$/,
),
metaPath: expect.stringMatching(
/subagents[\\/]test-session-id[\\/]agent-file-search-.*\.meta\.json$/,
/subagents\/test-session-id\/agent-file-search-.*\.meta\.json$/,
/subagents[\\/]test-session-id[\\/]agent-file-search-.*\.jsonl$/,
),
metaPath: expect.stringMatching(
/subagents[\\/]test-session-id[\\/]agent-file-search-.*\.meta\.json$/,

— claude-opus-4-8 via Claude Code /qreview

const registry = config.getBackgroundTaskRegistry();
const onActivity = (entry: AgentTask) => {
if (entry.agentId !== selectedAgentIdForActivity) return;
if (!dialogOpen || dialogMode !== 'detail' || !selectedLiveEntityId) return;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Suggestion] Behavioral regression vs. the pre-refactor code. This per-entry live-refresh subscription gates on dialogMode !== 'detail', so it never registers when the detail view is entered from the LiveAgentPanel (dialogMode === 'detail-from-panel'). The detail body renders in both modes, and every sibling effect (lines 985, 1007) gates on isDetailMode (=== 'detail' || === 'detail-from-panel'). In detail-from-panel mode the selected agent's recentActivities / a monitor's eventCount no longer refresh on each event — for a running entry the 1s wall-clock tick masks it to ~1s lag; for a paused/terminal-but-mutating entry there's no compensating timer, so the body can appear frozen. For a refactor billed as behavior-preserving this is an unintended divergence.

Suggested change
if (!dialogOpen || dialogMode !== 'detail' || !selectedLiveEntityId) return;
if (!dialogOpen || !isDetailMode || !selectedLiveEntityId) return;

Also add isDetailMode to this effect's dependency array (line 979), mirroring the sibling effect at 985-995, so eslint react-hooks/exhaustive-deps (enforced by lint:ci --max-warnings 0) stays clean.

— claude-opus-4-8 via Claude Code /qreview

const registry = config.getBackgroundTaskRegistry();
const onActivity = (entry: AgentTask) => {
if (entry.agentId !== selectedAgentIdForActivity) return;
if (!dialogOpen || dialogMode !== 'detail' || !selectedLiveEntityId) return;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Critical] dialogMode !== 'detail' should be !isDetailMode. The old code used !isDetailMode (which includes dialogMode === 'detail' || dialogMode === 'detail-from-panel'); this rewrite narrowed the guard to only 'detail', silently dropping the 'detail-from-panel' path.

When the user navigates into detail from the live agent panel, this subscription effect short-circuits — activityTick never bumps, so the detail view's activity display and monitor event counts freeze at the moment the detail view opened. The wall-clock effect at line 989 correctly uses !isDetailMode, confirming this is an unintended regression.

Suggested change
if (!dialogOpen || dialogMode !== 'detail' || !selectedLiveEntityId) return;
if (!dialogOpen || !isDetailMode || !selectedLiveEntityId) return;

Also add isDetailMode to the dependency array:

Suggested change
if (!dialogOpen || dialogMode !== 'detail' || !selectedLiveEntityId) return;
}, [dialogOpen, dialogMode, isDetailMode, config, selectedLiveEntityId]);

— qwen3.7-max via Qwen Code /review

vi.fn().mockReturnValue([]),
);

import { vi, type Mock, type MockInstance } from 'vitest';

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Critical] Duplicate import { vi, type Mock, type MockInstance } from 'vitest' — the original import still exists at line 92. This produces 6 typecheck errors (TS2300 Duplicate identifier for vi, Mock, MockInstance) and causes tsc --noEmit to fail, blocking npm run build.

Suggested change
import { vi, type Mock, type MockInstance } from 'vitest';

(Remove this line — the import at line 92 already covers these types.)

— qwen3.7-max via Qwen Code /review

@@ -0,0 +1,20 @@
/**

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Critical] Missing test files for the new task subsystem modules. The old test suites (monitorRegistry.test.ts: 918 lines, background-tasks.test.ts: 1561 lines, backgroundShellRegistry.test.ts: 409 lines) were deleted without replacement:

  • monitor-task.ts (703 lines) — 0 tests. Critical untested paths: monitorEmitEvent auto-stop re-entrancy, idle-timeout auto-stop, owner-scoped notification routing, dual cancel ordering, terminal-entry retention cap (128).
  • registry.ts (218 lines) — 0 tests. Untested: duplicate-register warning, fireChange exception isolation across multiple listeners, evict/kill miss paths.
  • dispatcher.ts (110 lines) — 0 tests. Untested: getTaskByType throw on unregistered kind, re-register overwrite.
  • dream-task.ts (199 lines) — 0 tests. Untested: listDreamTasks filtering/cap, toDreamTask metadata mapping.
  • agent-task.ts (995 lines) — only concurrency cap test. Untested: cancel grace timer with fallback finalize, agentFinalizeCancelled, message queue/drain/wait, pruneTerminalEntries.

— qwen3.7-max via Qwen Code /review

registry: config.getTaskRegistry(),
memoryManager: config.getMemoryManager(),
};
void Promise.resolve(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Critical] getTaskByType(target.kind) is evaluated as an argument to Promise.resolve(...) before the Promise is constructed. If the kind is unregistered, getTaskByType throws synchronously during argument evaluation, which escapes the .catch() chain entirely and propagates into the React useCallback handler — crashing the component tree.

Suggested change
void Promise.resolve(
void Promise.resolve()
.then(() => getTaskByType(target.kind).kill(entryId(target), ctx))
.catch((err) => {

— qwen3.7-max via Qwen Code /review

Comment thread packages/core/src/tasks/monitor-task.ts Outdated
const entry = registry.get(monitorId) as MonitorTask | undefined;
if (!entry || entry.kind !== 'monitor' || entry.status !== 'running') return;

registry.update<MonitorTask>(monitorId, (current) => {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Critical] registry.update() wraps eventCount += 1, unconditionally firing fireChange() on every monitor stdout line. The old MonitorRegistry.emitEvent() deliberately excluded per-event mutations from statusChangeCallback — the old JSDoc was explicit: "per-event registry mutations (eventCount / droppedLines) are deliberately excluded so the footer pill or AppContainer don't churn under heavy event traffic."

The detail-view subscriber in BackgroundTasksDialog.tsx:966 bumps activityTick (triggering a full React re-render) on every fireChange. A busy monitor (tail -f /var/log/syslog, npm run watch) producing 100+ lines/sec causes 100+ React re-renders/sec on the detail view.

Suggested fix: mutate eventCount/lastEventTime directly on the entry reference without going through registry.update(), matching the old code's deliberate approach. Or add a silent option to registry.update() that suppresses fireChange.

— qwen3.7-max via Qwen Code /review

const registry = this.config.getMonitorRegistry();
const registry = this.config.getTaskRegistry();
const ownerAgentId = getCurrentAgentId() ?? undefined;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Suggestion] This manually filters registry.getByKind('monitor').filter(e => e.status === 'running') instead of using the already-exported getRunningMonitorTasks(registry) helper from monitor-task.ts. The helper was extracted precisely for this purpose.

Suggested change
const running = getRunningMonitorTasks(registry);

— qwen3.7-max via Qwen Code /review

Comment thread packages/core/src/tasks/monitor-task.ts Outdated

if (exitCode !== null) {
registry.update<MonitorTask>(monitorId, (current) => {
current.exitCode = exitCode;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Suggestion] monitorComplete makes two registry.update calls (one for exitCode, then settle() for status+endTime), firing fireChange twice per terminal transition. monitorFail has the same pattern. By contrast, shellComplete/shellFail in shell-task.ts combine all fields into a single registry.update call.

Consider merging into a single update to match the shell-task pattern:

registry.update<MonitorTask>(monitorId, (current) => {
  current.exitCode = exitCode ?? undefined;
  current.status = 'completed';
  current.endTime = Date.now();
  return current;
});

— qwen3.7-max via Qwen Code /review

* code should never call this — session shutdown uses per-kind
* `*AbortAll` helpers so each kind can run its own cleanup.
*/
_resetForTest(): void {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Suggestion] _resetForTest() clears entries and listeners but does not reset the module-level singletons in agent-task.ts (notificationCallback, registerCallback, messageWaiters) or monitor-task.ts (notificationCallback, registerCallback, agentNotificationCallbacks, agentLifecycleCallbacks). A test that sets a callback and then calls _resetForTest() in afterEach will leak the mock into the next test.

Consider adding per-kind reset exports (e.g., resetAgentCallbacksForTest()) or consolidating callbacks onto the TaskRegistry instance so _resetForTest covers them.

— qwen3.7-max via Qwen Code /review

tanzhenxin added a commit that referenced this pull request Jun 1, 2026
…th regex

`expect.stringMatching(/subagents\/test-session-id\/agent-...$/)`
fails on Windows because path.join() uses backslashes there.
Switch to `[\\/]` to accept either separator, matching the
existing pattern at line 1741.

The test (added in #3970) has been silently red on Windows since
that merge; nobody noticed until this PR's rebase made CI run.
Caught by the CI loop on PR #3982.
tanzhenxin added a commit that referenced this pull request Jun 1, 2026
Three real bugs + four polish items + a substantive test coverage
gap for the new monitor-task module.

## Critical (3 real bugs)

1. **BackgroundTasksDialog.tsx**: the per-entry live-refresh effect
   gated on `dialogMode !== 'detail'`, silently dropping the
   `detail-from-panel` path (the LiveAgentPanel → detail navigation).
   Restored to `!isDetailMode` so both detail modes route through the
   subscription. Same predicate sibling effects use.

2. **BackgroundTaskViewContext.tsx**: `getTaskByType(target.kind)`
   was evaluated as a Promise.resolve() argument; a sync throw from
   an unregistered kind escaped the .catch() chain into the React
   useCallback handler. Wrap the lookup in try/catch (sync path),
   keep the kill() dispatch synchronous-at-call-site (preserves the
   "pressing 'x' invokes kill before the next tick" test contract).

3. **monitor-task.ts**: `monitorEmitEvent` called `registry.update`
   which fires `fireChange`, churning the dialog list + footer pill
   on every monitor stdout line — perf regression vs the old
   `MonitorRegistry.emitEvent` which deliberately suppressed per-
   event mutations from the status-change callback. Introduce
   `TaskRegistry.mutateSilent` for in-place mutations whose change-
   listener fanout the dialog doesn't need (id/kind/status don't
   shift). Detail-view subscribers still see fresh data because
   they re-read on their own tick. Also applied to
   `agentAppendActivity` for the same reason (activity bursts
   shouldn't churn list-mode renderers).

## Critical (test coverage gap)

4. **monitor-task.ts had zero tests** — the deleted
   `monitorRegistry.test.ts` (918 lines) was not replaced. Added
   `packages/core/src/tasks/monitor-task.test.ts` covering the
   critical paths: cap enforcement, registration shape, silent
   per-event mutation, idle-timer reset, auto-stop re-entrancy,
   terminal transitions (single fireChange), notify:false /
   notify:true cancel ordering, owner-routed notifications +
   lifecycle wake, abortAll + reset clearing module-level callback
   Maps, and the kind-narrowing helpers. 24 cases, all green.

## Suggestions (4)

1. **config.ts**: `loadPausedBackgroundAgents` /
   `resumeBackgroundAgent` return-type imports now point at the
   canonical `../tasks/agent-task.js` instead of the deprecated
   re-export shim `../agents/background-tasks.js`.
2. **monitor.ts**: cap pre-check now uses the already-exported
   `getRunningMonitorTasks(registry)` helper instead of an inline
   filter.
3. **monitor-task.ts**: `monitorComplete` / `monitorFail` /
   `monitorEmitEvent` (auto-stop branch) no longer issue a second
   `registry.update` for status fields — the `settle()` helper
   now accepts `{ exitCode, error }` so the terminal transition
   fires exactly one `fireChange`. Mirrors the single-update
   pattern in `shellComplete` / `shellFail`.
4. **registry.ts** / per-kind modules: added
   `_resetAgentTaskModuleStateForTest` and
   `_resetMonitorTaskModuleStateForTest` to clear module-level
   singletons (callbacks, owner-routed Maps, the agent cap,
   messageWaiters). Composed into a single
   `_resetTaskKindModuleStateForTest(registry)` helper in
   `tasks/index.ts` for `afterEach` use.

## Test infra

Added `mutateSilent` to the registry stubs in `agent.test.ts`,
`shell.test.ts`, `nonInteractiveCli.test.ts`, and
`clearCommand.test.ts` so the new method on `TaskRegistry` doesn't
trip mocks.

## Verification

- `npm run typecheck`: clean across all packages
- `npm run lint:ci`: clean (--max-warnings 0)
- `npm run build && npm run bundle`: clean
- Targeted core suites (`src/tasks`, `src/agents`,
  `src/tools/agent`, shell, monitor, send-message, task-stop): 763
  passed, 2 skipped
- New monitor-task.test.ts: 24 / 24 passed
@tanzhenxin

Copy link
Copy Markdown
Collaborator Author

@wenshao Thanks for the second pass — caught real issues I'd missed. All 9 items addressed in c8ebf6bd.

Critical (4)

  1. BackgroundTasksDialog.tsx:966 dialogMode !== 'detail' regression — restored !isDetailMode (covers 'detail' AND 'detail-from-panel'). Added a comment noting the predicate matches every sibling effect's gate.
  2. BackgroundTaskViewContext.tsx:230 getTaskByType sync throw — wrapped the lookup in try/catch (sync path) and kept the kill() dispatch synchronous-at-call-site via Promise.resolve(taskKind.kill(...)). Preserves the "pressing x invokes kill before the next tick" test contract while still capturing both sync getTaskByType throws and async kill rejections.
  3. monitor-task.ts:299 monitorEmitEvent per-event fireChange — added TaskRegistry.mutateSilent as a sibling of update that mutates in place without firing the change listener. monitorEmitEvent and agentAppendActivity both moved to it. Detail-view subscribers re-read on their own per-entry tick, so live eventCount still surfaces.
  4. monitor-task.ts zero tests — added packages/core/src/tasks/monitor-task.test.ts (24 cases, all green). Covers: cap enforcement, registration shape, silent per-event mutation (asserts listener NOT called), idle-timer reset, auto-stop with re-entrancy guard, terminal transitions firing fireChange exactly once, notify:false vs notify:true cancel ordering (settle-first vs abort-first), owner-routed notifications + lifecycle wake, monitorAbortAll clearing owner-callback Maps, monitorReset, and the kind-narrowing in getMonitorTask.

Suggestions (4)

  1. config.ts:3729/3738AgentTask import paths flipped to canonical ../tasks/agent-task.js.
  2. monitor.ts:323 — cap pre-check now uses getRunningMonitorTasks(registry).
  3. monitor-task.ts double updatesettle() now accepts { exitCode?, error? } so monitorComplete/monitorFail/monitorEmitEvent's auto-stop branch each fire exactly one fireChange per terminal transition. Mirrors shellComplete/shellFail.
  4. registry.ts:214 _resetForTest — added _resetAgentTaskModuleStateForTest and _resetMonitorTaskModuleStateForTest to each per-kind module (clears the notification/register callbacks, owner-routed Maps, message waiters, and the agent cap). Composed into a single _resetTaskKindModuleStateForTest(registry) helper in tasks/index.tsregistry._resetForTest() itself stays narrowly-scoped (composition over coupling to per-kind modules avoids the import cycle the dispatcher was designed around).

Test infra

Added mutateSilent stubs to the registry mocks in agent.test.ts, shell.test.ts, nonInteractiveCli.test.ts, and clearCommand.test.ts so the new method doesn't trip on undefined is not a function.

Verification

  • npm run typecheck — clean
  • npm run lint:ci — clean (--max-warnings 0)
  • npm run build && npm run bundle — clean
  • Targeted core suites (src/tasks + src/agents + src/tools/agent + shell.test.ts + monitor.test.ts + send-message.test.ts + task-stop.test.ts): 763 passed, 2 skipped
  • New monitor-task.test.ts: 24 / 24 passed

Ready for re-review.

tanzhenxin added a commit that referenced this pull request Jun 8, 2026
…ask module

Folds PR #4324's per-instance BackgroundTaskRegistry cap into the
collapsed tasks/agent-task.ts module as kind-local module state.
The new architecture's per-kind module is the natural home for an
agent-only behavior — the generic TaskRegistry no longer needs
to carry it.

What moves into tasks/agent-task.ts:

  - MAX_CONCURRENT_BACKGROUND_AGENTS and the env-var resolver
  - agentAssertCanStartBackground(registry) free function
  - The race-guard inside agentRegister() (skips re-registers of
    already-running entries so resume can recover)
  - setAgentBackgroundCapForTest() for test override (mirrors the
    existing setAgentNotificationCallback pattern)

What moves out of agent.ts:

  - The early preflight calls agentAssertCanStartBackground instead
    of registry.assertCanStartBackgroundAgent().
  - The post-register error path is unchanged structurally — it still
    aborts the bgAbortController, fires SubagentStop, cleans up the
    worktree, and returns the cap message to the model.

Resume path (background-agent-resume.ts) now wraps agentRegister
in the same try/catch #4324 added, but routes to the new free
function.

Also addresses wenshao's review on #3982:

  1. config.ts — moves the four registerTaskKind(...) calls below
     all imports, instead of dangling between two import groups.
  2. dispatcher.ts — comment updated to describe actual init order
     (module-load side effect in config.ts), removes the
     fictional registerAllTaskKinds() / Config.initialize()
     references.
  3. monitor.ts — fixes a stale comment that still referred to
     monitorRegister(registry, ) (dangling comma).
  4. monitor-task.ts — monitorAbortAll now clears the module-level
     owner-routed callbacks so a daemon process recycling sessions
     doesn't leak handlers to dead owner agents.
  5. useBackgroundTaskView.ts — moves the registry shape probe to
     getAll() BEFORE buildMerged() so activity bursts and
     monitor event bumps don't pay the listDreamTasks cost.

Tests added:

  - tasks/agent-task.test.ts — covers env resolution, cap
    enforcement (running-only, foreground exclusion, paused
    exclusion, resume race exception), and module-level cap reset.

Tests fixed (rebase fallout):

  - nonInteractiveCli.test.ts — six structured-output assertions
    migrated from mockBackgroundTaskRegistry.abortAll to the
    module-level mockAgentAbortAll mock.
  - shell.test.ts — 13 assertions migrated from
    registry.{cancel,complete,fail} to
    shellTaskModule.shell{Cancel,Complete,Fail} (called with
    (registry, ...)).
  - useBackgroundTaskView.test.ts — sort assertions updated to the
    new descending-startTime active-bucket order.
  - agent.test.ts — adds the getStopHookBlockingCap mock that
    was lost in the auto-merge with PR #4208.
  - clearCommand.test.ts — drops the SessionStart assertion that
    was lost in the auto-merge with PR #4115.
  - background-agent-resume.test.ts — monitorRegistry is now a
    set of vi.spyOn against the new module-level free functions.
  - InlineParallelAgentsDisplay.test.tsx — makeRegistryConfig
    exposes getTaskRegistry (matching the renamed Config method).
@tanzhenxin tanzhenxin force-pushed the refactor/task-registry-collapse branch from c8ebf6b to a20c24f Compare June 8, 2026 05:55
tanzhenxin added a commit that referenced this pull request Jun 8, 2026
…th regex

`expect.stringMatching(/subagents\/test-session-id\/agent-...$/)`
fails on Windows because path.join() uses backslashes there.
Switch to `[\\/]` to accept either separator, matching the
existing pattern at line 1741.

The test (added in #3970) has been silently red on Windows since
that merge; nobody noticed until this PR's rebase made CI run.
Caught by the CI loop on PR #3982.
tanzhenxin added a commit that referenced this pull request Jun 8, 2026
Three real bugs + four polish items + a substantive test coverage
gap for the new monitor-task module.

## Critical (3 real bugs)

1. **BackgroundTasksDialog.tsx**: the per-entry live-refresh effect
   gated on `dialogMode !== 'detail'`, silently dropping the
   `detail-from-panel` path (the LiveAgentPanel → detail navigation).
   Restored to `!isDetailMode` so both detail modes route through the
   subscription. Same predicate sibling effects use.

2. **BackgroundTaskViewContext.tsx**: `getTaskByType(target.kind)`
   was evaluated as a Promise.resolve() argument; a sync throw from
   an unregistered kind escaped the .catch() chain into the React
   useCallback handler. Wrap the lookup in try/catch (sync path),
   keep the kill() dispatch synchronous-at-call-site (preserves the
   "pressing 'x' invokes kill before the next tick" test contract).

3. **monitor-task.ts**: `monitorEmitEvent` called `registry.update`
   which fires `fireChange`, churning the dialog list + footer pill
   on every monitor stdout line — perf regression vs the old
   `MonitorRegistry.emitEvent` which deliberately suppressed per-
   event mutations from the status-change callback. Introduce
   `TaskRegistry.mutateSilent` for in-place mutations whose change-
   listener fanout the dialog doesn't need (id/kind/status don't
   shift). Detail-view subscribers still see fresh data because
   they re-read on their own tick. Also applied to
   `agentAppendActivity` for the same reason (activity bursts
   shouldn't churn list-mode renderers).

## Critical (test coverage gap)

4. **monitor-task.ts had zero tests** — the deleted
   `monitorRegistry.test.ts` (918 lines) was not replaced. Added
   `packages/core/src/tasks/monitor-task.test.ts` covering the
   critical paths: cap enforcement, registration shape, silent
   per-event mutation, idle-timer reset, auto-stop re-entrancy,
   terminal transitions (single fireChange), notify:false /
   notify:true cancel ordering, owner-routed notifications +
   lifecycle wake, abortAll + reset clearing module-level callback
   Maps, and the kind-narrowing helpers. 24 cases, all green.

## Suggestions (4)

1. **config.ts**: `loadPausedBackgroundAgents` /
   `resumeBackgroundAgent` return-type imports now point at the
   canonical `../tasks/agent-task.js` instead of the deprecated
   re-export shim `../agents/background-tasks.js`.
2. **monitor.ts**: cap pre-check now uses the already-exported
   `getRunningMonitorTasks(registry)` helper instead of an inline
   filter.
3. **monitor-task.ts**: `monitorComplete` / `monitorFail` /
   `monitorEmitEvent` (auto-stop branch) no longer issue a second
   `registry.update` for status fields — the `settle()` helper
   now accepts `{ exitCode, error }` so the terminal transition
   fires exactly one `fireChange`. Mirrors the single-update
   pattern in `shellComplete` / `shellFail`.
4. **registry.ts** / per-kind modules: added
   `_resetAgentTaskModuleStateForTest` and
   `_resetMonitorTaskModuleStateForTest` to clear module-level
   singletons (callbacks, owner-routed Maps, the agent cap,
   messageWaiters). Composed into a single
   `_resetTaskKindModuleStateForTest(registry)` helper in
   `tasks/index.ts` for `afterEach` use.

## Test infra

Added `mutateSilent` to the registry stubs in `agent.test.ts`,
`shell.test.ts`, `nonInteractiveCli.test.ts`, and
`clearCommand.test.ts` so the new method on `TaskRegistry` doesn't
trip mocks.

## Verification

- `npm run typecheck`: clean across all packages
- `npm run lint:ci`: clean (--max-warnings 0)
- `npm run build && npm run bundle`: clean
- Targeted core suites (`src/tasks`, `src/agents`,
  `src/tools/agent`, shell, monitor, send-message, task-stop): 763
  passed, 2 skipped
- New monitor-task.test.ts: 24 / 24 passed
Comment thread packages/cli/src/nonInteractiveCli.test.ts
Comment thread packages/core/src/tasks/agent-task.test.ts
Comment thread packages/core/src/tasks/monitor-task.ts Outdated
Replaces BackgroundTaskRegistry, BackgroundShellRegistry, and
MonitorRegistry with a single thin TaskRegistry over the polymorphic
TaskState union, plus per-kind modules that hold each kind's lifecycle
helpers as free functions and register a small Task implementation
with a polymorphic dispatcher.

The CLI side collapses with it: useBackgroundTaskView goes from a
four-source merge with dream-signature dedup to one registry
subscription plus a thin dream adapter, and BackgroundTaskViewContext's
cancel switch becomes a single getTaskByType(target.kind).kill(...)
call.

Old class files become one-release re-export shims so SDK consumers
keep their import paths working through the deprecation window.

Net: ~3950 lines deleted, no user-observable behavior change.
The new task abstraction holds shells, monitors, and dreams alongside
agents. Living under agents/ misnamed the boundary — three of the
four kinds aren't agents at all. Move to packages/core/src/tasks/
to match what the abstraction actually represents.
…ask module

Folds PR #4324's per-instance BackgroundTaskRegistry cap into the
collapsed tasks/agent-task.ts module as kind-local module state.
The new architecture's per-kind module is the natural home for an
agent-only behavior — the generic TaskRegistry no longer needs
to carry it.

What moves into tasks/agent-task.ts:

  - MAX_CONCURRENT_BACKGROUND_AGENTS and the env-var resolver
  - agentAssertCanStartBackground(registry) free function
  - The race-guard inside agentRegister() (skips re-registers of
    already-running entries so resume can recover)
  - setAgentBackgroundCapForTest() for test override (mirrors the
    existing setAgentNotificationCallback pattern)

What moves out of agent.ts:

  - The early preflight calls agentAssertCanStartBackground instead
    of registry.assertCanStartBackgroundAgent().
  - The post-register error path is unchanged structurally — it still
    aborts the bgAbortController, fires SubagentStop, cleans up the
    worktree, and returns the cap message to the model.

Resume path (background-agent-resume.ts) now wraps agentRegister
in the same try/catch #4324 added, but routes to the new free
function.

Also addresses wenshao's review on #3982:

  1. config.ts — moves the four registerTaskKind(...) calls below
     all imports, instead of dangling between two import groups.
  2. dispatcher.ts — comment updated to describe actual init order
     (module-load side effect in config.ts), removes the
     fictional registerAllTaskKinds() / Config.initialize()
     references.
  3. monitor.ts — fixes a stale comment that still referred to
     monitorRegister(registry, ) (dangling comma).
  4. monitor-task.ts — monitorAbortAll now clears the module-level
     owner-routed callbacks so a daemon process recycling sessions
     doesn't leak handlers to dead owner agents.
  5. useBackgroundTaskView.ts — moves the registry shape probe to
     getAll() BEFORE buildMerged() so activity bursts and
     monitor event bumps don't pay the listDreamTasks cost.

Tests added:

  - tasks/agent-task.test.ts — covers env resolution, cap
    enforcement (running-only, foreground exclusion, paused
    exclusion, resume race exception), and module-level cap reset.

Tests fixed (rebase fallout):

  - nonInteractiveCli.test.ts — six structured-output assertions
    migrated from mockBackgroundTaskRegistry.abortAll to the
    module-level mockAgentAbortAll mock.
  - shell.test.ts — 13 assertions migrated from
    registry.{cancel,complete,fail} to
    shellTaskModule.shell{Cancel,Complete,Fail} (called with
    (registry, ...)).
  - useBackgroundTaskView.test.ts — sort assertions updated to the
    new descending-startTime active-bucket order.
  - agent.test.ts — adds the getStopHookBlockingCap mock that
    was lost in the auto-merge with PR #4208.
  - clearCommand.test.ts — drops the SessionStart assertion that
    was lost in the auto-merge with PR #4115.
  - background-agent-resume.test.ts — monitorRegistry is now a
    set of vi.spyOn against the new module-level free functions.
  - InlineParallelAgentsDisplay.test.tsx — makeRegistryConfig
    exposes getTaskRegistry (matching the renamed Config method).
The conflict resolution during the rebase added a second
`import { vi, type Mock, type MockInstance } from 'vitest';`
line. Local lint missed it because `npm run lint` doesn't
enforce `--max-warnings 0`, but CI does.
…th regex

`expect.stringMatching(/subagents\/test-session-id\/agent-...$/)`
fails on Windows because path.join() uses backslashes there.
Switch to `[\\/]` to accept either separator, matching the
existing pattern at line 1741.

The test (added in #3970) has been silently red on Windows since
that merge; nobody noticed until this PR's rebase made CI run.
Caught by the CI loop on PR #3982.
Three real bugs + four polish items + a substantive test coverage
gap for the new monitor-task module.

## Critical (3 real bugs)

1. **BackgroundTasksDialog.tsx**: the per-entry live-refresh effect
   gated on `dialogMode !== 'detail'`, silently dropping the
   `detail-from-panel` path (the LiveAgentPanel → detail navigation).
   Restored to `!isDetailMode` so both detail modes route through the
   subscription. Same predicate sibling effects use.

2. **BackgroundTaskViewContext.tsx**: `getTaskByType(target.kind)`
   was evaluated as a Promise.resolve() argument; a sync throw from
   an unregistered kind escaped the .catch() chain into the React
   useCallback handler. Wrap the lookup in try/catch (sync path),
   keep the kill() dispatch synchronous-at-call-site (preserves the
   "pressing 'x' invokes kill before the next tick" test contract).

3. **monitor-task.ts**: `monitorEmitEvent` called `registry.update`
   which fires `fireChange`, churning the dialog list + footer pill
   on every monitor stdout line — perf regression vs the old
   `MonitorRegistry.emitEvent` which deliberately suppressed per-
   event mutations from the status-change callback. Introduce
   `TaskRegistry.mutateSilent` for in-place mutations whose change-
   listener fanout the dialog doesn't need (id/kind/status don't
   shift). Detail-view subscribers still see fresh data because
   they re-read on their own tick. Also applied to
   `agentAppendActivity` for the same reason (activity bursts
   shouldn't churn list-mode renderers).

## Critical (test coverage gap)

4. **monitor-task.ts had zero tests** — the deleted
   `monitorRegistry.test.ts` (918 lines) was not replaced. Added
   `packages/core/src/tasks/monitor-task.test.ts` covering the
   critical paths: cap enforcement, registration shape, silent
   per-event mutation, idle-timer reset, auto-stop re-entrancy,
   terminal transitions (single fireChange), notify:false /
   notify:true cancel ordering, owner-routed notifications +
   lifecycle wake, abortAll + reset clearing module-level callback
   Maps, and the kind-narrowing helpers. 24 cases, all green.

## Suggestions (4)

1. **config.ts**: `loadPausedBackgroundAgents` /
   `resumeBackgroundAgent` return-type imports now point at the
   canonical `../tasks/agent-task.js` instead of the deprecated
   re-export shim `../agents/background-tasks.js`.
2. **monitor.ts**: cap pre-check now uses the already-exported
   `getRunningMonitorTasks(registry)` helper instead of an inline
   filter.
3. **monitor-task.ts**: `monitorComplete` / `monitorFail` /
   `monitorEmitEvent` (auto-stop branch) no longer issue a second
   `registry.update` for status fields — the `settle()` helper
   now accepts `{ exitCode, error }` so the terminal transition
   fires exactly one `fireChange`. Mirrors the single-update
   pattern in `shellComplete` / `shellFail`.
4. **registry.ts** / per-kind modules: added
   `_resetAgentTaskModuleStateForTest` and
   `_resetMonitorTaskModuleStateForTest` to clear module-level
   singletons (callbacks, owner-routed Maps, the agent cap,
   messageWaiters). Composed into a single
   `_resetTaskKindModuleStateForTest(registry)` helper in
   `tasks/index.ts` for `afterEach` use.

## Test infra

Added `mutateSilent` to the registry stubs in `agent.test.ts`,
`shell.test.ts`, `nonInteractiveCli.test.ts`, and
`clearCommand.test.ts` so the new method on `TaskRegistry` doesn't
trip mocks.

## Verification

- `npm run typecheck`: clean across all packages
- `npm run lint:ci`: clean (--max-warnings 0)
- `npm run build && npm run bundle`: clean
- Targeted core suites (`src/tasks`, `src/agents`,
  `src/tools/agent`, shell, monitor, send-message, task-stop): 763
  passed, 2 skipped
- New monitor-task.test.ts: 24 / 24 passed
… onto main

Port the shell notification feature (#4355) from the old
BackgroundShellRegistry class into the shell-task.ts free-function
module. Update all call sites (Session.ts, useGeminiStream.ts,
chatCompressionService.ts) and their tests to use the new
module-level setters and unified TaskRegistry API.

Also integrates AgentTerminateMode.SHUTDOWN grouping with CANCELLED
(#4410) and fork-subagent feature gate (#4574) into the free-function
architecture.
…fication tests

shellAbortAll now passes { notify: false } to shellCancel, matching
the original BackgroundShellRegistry.abortAll behavior that used a
private settleAsCancelled helper to avoid leaking notifications
across /clear boundaries or during session shutdown.

Ports all 14 notification tests from the deleted
backgroundShellRegistry.test.ts into shell-task.test.ts, covering
XML structure, command truncation, escaping, output-tail reading,
symlink security, idempotency, and the abortAll suppression.
@tanzhenxin tanzhenxin force-pushed the refactor/task-registry-collapse branch from a20c24f to 8f9b205 Compare June 8, 2026 06:32
The registry collapse swapped all four monitor notification call sites from
stripDisplayControlChars to stripTerminalControlSequences. The latter strips
ANSI/OSC/CSI escape sequences and C0/C1 controls but not Unicode bidi
override/isolate characters (U+202A-202E, U+2066-2069), silently dropping the
Trojan Source (CVE-2021-42574) defense that the sibling shell notification
surface still applies.

Add a sanitizeForNotification helper that composes both functions so monitor
notifications keep the improved ANSI-sequence stripping and regain bidi
stripping, and a regression test covering the description and detail surfaces.
The registry collapse removed the dedicated lifecycle coverage that lived in
the deleted background-tasks.test.ts, leaving agent-task.test.ts with only the
concurrency-cap suite. The lifecycle state machine was exercised only
indirectly by caller tests.

Add focused unit coverage for the high-risk paths the collapse touched:
terminal transitions and the double-terminal / notified short-circuit guards,
the cancel-then-natural-complete race, notify:false suppression, the 5s cancel
grace-timer fallback, agentAbandon, and the terminal retention cap eviction
(including that running and not-yet-notified cancelled entries are retained).
… mutateSilent

The round-2 fixes added a mutateSilent property to the mockTaskRegistry object
literal but not to its type annotation, leaving the two inconsistent. (The file
is in the tsconfig exclude list for TODO 5691, so this never surfaced as a build
error, but the mock should still match its declared type.) Add the property to
the annotation and fix the literal's indentation.

Also correct the detail-view refresh comment in BackgroundTasksDialog: agent
recentActivities is reassigned via mutateSilent, which deliberately does not
fire the registry subscription — both agent activity and monitor events rely on
the 1s wall-clock tick, not the subscription.
let mockBackgroundTaskRegistry: {
setNotificationCallback: ReturnType<typeof vi.fn>;
setRegisterCallback: ReturnType<typeof vi.fn>;
let mockTaskRegistry: {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Critical] (Carried from R3 — still present at this SHA.) The mockTaskRegistry type annotation (lines 151–160) is still missing the mutateSilent property that was added to TaskRegistry. This produces a tsc error at the assignment site (line 213): Object literal may only specify known properties, and 'mutateSilent' does not exist in type ....

Suggested change
let mockTaskRegistry: {
let mockTaskRegistry: {
getAll: ReturnType<typeof vi.fn>;
getByKind: ReturnType<typeof vi.fn>;
get: ReturnType<typeof vi.fn>;
register: ReturnType<typeof vi.fn>;
update: ReturnType<typeof vi.fn>;
evict: ReturnType<typeof vi.fn>;
kill: ReturnType<typeof vi.fn>;
subscribe: ReturnType<typeof vi.fn>;
mutateSilent: ReturnType<typeof vi.fn>;
};

— qwen3.7-max via Qwen Code /review

const entry = registry.get(agentId) as AgentTask | undefined;
if (!entry || entry.kind !== 'agent' || entry.status !== 'running') return;

registry.mutateSilent<AgentTask>(agentId, (current) => {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Critical] Behavioral regression: agentAppendActivity uses registry.mutateSilent which does NOT fire fireChange. The detail view's subscription in BackgroundTasksDialog.tsx:974 uses registry.subscribe(...), so it never fires on agent activity bursts. The Progress section in the detail view is now driven solely by the 1-second setInterval wall-clock tick — it no longer updates immediately on each tool call as the old setActivityChangeCallback mechanism did.

The old code had a dedicated BackgroundActivityChangeCallback / setActivityChangeCallback channel that fired immediately on every appendActivity call. This PR removed it and replaced it with registry.subscribe, but mutateSilent was intentionally designed to skip subscribers — creating a gap between the producer and the consumer.

Suggested fix options (either):

  1. Add a second subscription channel (e.g. registry.subscribeDetail(id, listener) or per-kind setAgentActivityChangeCallback) that fires on mutateSilent paths, restoring the dual-channel behavior without regressing list-mode fan-out.
  2. Have the detail view poll recentActivities.length on the existing 1-second interval — simpler but adds up to 1s latency.

— qwen3.7-max via Qwen Code /review

@@ -0,0 +1,194 @@
/**

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Critical] (Carried from R1–R3 — partially addressed.) Tests have been added for the concurrency cap, monitor lifecycle, and shell lifecycle, but significant coverage gaps remain:

  • No test files exist for registry.ts (the central new abstraction), dispatcher.ts (the kill() routing table), or dream-task.ts (the MemoryManager adapter).
  • agent-task.test.ts (194 lines) only covers the concurrency cap. 17 exported functions remain untested: agentComplete, agentFail, agentCancel (including the 5s grace timer), agentFinalizeCancelled, agentAppendActivity (rolling buffer cap), agentQueueMessage/agentDrainMessages/agentWaitForMessages (the async waiter mechanism), agentAbortAll, agentReset, and emitNotification.
  • pruneTerminalEntries eviction logic is untested across all three kinds (agent/shell/monitor).
  • Monitor idle timeout auto-stop path is untested (no vi.advanceTimersByTime call in monitor-task.test.ts).

The deleted test suites (background-tasks.test.ts: 1561 lines, monitorRegistry.test.ts: 918 lines, backgroundShellRegistry.test.ts: 409 lines) covered 20+ scenarios including cancel grace timers, state machine transitions, and notification emission — all now untested.

— qwen3.7-max via Qwen Code /review

// Persist the reason so the dialog detail view can show it after
// settle. Same pattern as the max-events branch in
// `monitorEmitEvent`.
registry.update<MonitorTask>(entry.monitorId, (current) => {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Suggestion] The idle timeout path does two registry.update calls (one to set error, one inside settle to set status+endTime), firing fireChange twice for a single terminal transition. The sibling max-events branch at line 344 correctly uses settle with extras.error for a single update.

Suggested change
registry.update<MonitorTask>(entry.monitorId, (current) => {
settle(registry, entry, 'completed', { error: 'Idle timeout' });
emitTerminalNotification(entry, 'Idle timeout');

— qwen3.7-max via Qwen Code /review

* Strip C0 control characters (except tab) and C1 control characters from
* terminal/UI display strings.
*/
function stripDisplayControlChars(text: string): string {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Suggestion] This private stripDisplayControlChars is a divergent copy of the shared utility at packages/core/src/utils/terminalSafe.ts. The shared version additionally strips Unicode bidirectional control characters (U+202A–U+202E LRE/RLE/PDF/LRO/RLO and U+2066–U+2069 LRI/RLI/FSI/PDI), defending against Trojan Source attacks (CVE-2021-42574). This private copy omits those ranges.

monitor-task.ts correctly imports stripTerminalControlSequences from the shared utility (line 22). Shell notification XML (command labels, cwd, error messages) passes through the weaker sanitizer.

Not a regression from main (the old BackgroundShellRegistry also had the weaker copy), but the PR is an opportunity to converge on the shared utility.

Suggested change
function stripDisplayControlChars(text: string): string {
import { stripDisplayControlChars } from '../utils/terminalSafe.js';

(Delete the private copy below and keep the private stripOutputControlChars which has no shared equivalent.)

— qwen3.7-max via Qwen Code /review

Comment thread packages/core/src/tasks/monitor-task.ts Outdated
}

/** Emit a terminal notification (completed/failed/cancelled). */
function emitTerminalNotification(entry: MonitorTask, detail?: string): void {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Suggestion] emitTerminalNotification never sets entry.notified = true. Both agent-task.ts and shell-task.ts set this flag after emitting their terminal notification, fulfilling the TaskBase contract ("True once the kind's terminal notification has fired"). The monitor kind silently opts out — notified stays false forever on every monitor entry.

The monitor kind's own pruneTerminalEntries filters on status !== 'running' rather than notified === true, so eviction still works today. But any future consumer that reads entry.notified polymorphically across kinds will silently misclassify monitors as "not yet notified."

Suggested fix: Set entry.notified = true inside emitTerminalNotification (or in settle()), mirroring the pattern used by the other two kinds.

— qwen3.7-max via Qwen Code /review

if (entry.notified) return;

// Mark notified silently — no need to trigger change listeners.
entry.notified = true;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Suggestion] emitShellNotification sets entry.notified = true via direct mutation, bypassing registry.update(). The agent-task equivalent (emitNotification in agent-task.ts) uses registry.update<AgentTask>() to set notified, which fires the change listener.

This means the shell's notified transition is invisible to registry subscribers. Today no consumer keys off notified through the subscription, so there is no user-visible bug. But the inconsistency between kinds means a future feature that tracks notified via change events would silently miss shell notifications.

Suggested fix: Either route through registry.update() (matching agent-task) or document the intentional silence on TaskBase.notified so the next engineer doesn't assume symmetry.

— qwen3.7-max via Qwen Code /review

Comment thread packages/core/src/tasks/agent-task.ts Outdated
* points each install exactly one of these per session, and a list
* would invite drift in error-handling.
*/
let notificationCallback: BackgroundNotificationCallback | undefined;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Critical] Cross-session notification leak — the per-Config notification callbacks became process-global singletons, so concurrent ACP sessions collide.

This PR demotes notificationCallback/registerCallback from per-Config-instance fields to module-level lets here (same in monitor-task.ts:161-162 and shell-task.ts:60). On main, ACP registered them per session via this.config.getBackgroundTaskRegistry().setNotificationCallback(...). Now Session.#registerBackgroundNotificationCallbacks() calls the global setAgentNotificationCallback(...), and emitNotification reads the single module slot (agent-task.ts:917) — last writer wins.

AcpAgent keeps sessions: Map<string, Session> and builds a fresh Config per newSession (loadCliConfignew Session(...)), holding multiple sessions live at once. Each constructor overwrites the global callback; each dispose() nulls it globally. Session B's closure (Session.ts:1655) enqueues onto this.notificationQueue with no agentId ownership check.

Concrete failure (reachable via the Zed ACP integration): Session A launches a background subagent → user opens Session B → A's subagent completes → A's terminal <task-notification> (carrying <result> agent output / shell <output-tail>) is delivered to Session B's client, not A's. If B is disposed first, A's notification is silently dropped.

The Scope/Risk note says "No qwen-code production use case hits this today" — ACP multi-session is that case. Suggest re-scoping the callbacks per TaskRegistry (e.g. a WeakMap<TaskRegistry, Callbacks> keyed off the entry's owning registry, or restore a per-Config field) so a notification fired for one session can only reach that session.

— claude-opus-4-8 via Claude Code /qreview

…essions

The agent/monitor/shell notification and register callbacks were demoted
to bare module-level singletons during the registry collapse. The ACP
agent runs concurrent sessions in one process, each with its own Config
and TaskRegistry, so the most-recently-started session's callback
overwrote the others — one session's background-task notifications could
be delivered to a different session's connection.

Key the callbacks by TaskRegistry instance via a WeakMap so each session
is isolated again, restoring the per-instance behavior the old per-kind
registries had. The owner-scoped monitor maps stay keyed by ownerAgentId
(globally unique), so they don't share the collision hazard. Callers in
Session, the non-interactive session/CLI, and useGeminiStream now pass
the session's registry to the setters.

Adds a per-registry isolation regression test for the agent kind.
The registry collapse deleted the three per-kind registry test suites but
left the new central modules without direct coverage. Add suites for
TaskRegistry's narrow surface (register/get/update/mutateSilent/evict/
subscribe/kill dispatch), the kind dispatcher (registration, lookup,
unregistered-kind error), and the dream adapter (filtering, terminal cap,
field mapping, subscribe filter, kill delegation).
@tanzhenxin

Copy link
Copy Markdown
Collaborator Author

Closing this for now — deprioritizing the task-registry collapse rather than carrying a large refactor in the background-task subsystem at this stage. This is a prioritization call, not a problem with the branch: the work is in good shape and has been pushed (HEAD fa430d2dc) so it can be reopened and finished quickly later.

State at close

Addressed

  • Cross-session callback isolation (the CHANGES_REQUESTED blocker): the agent/monitor/shell notification + register callbacks are now keyed by TaskRegistry instance instead of module-level singletons, so concurrent ACP sessions (each with its own Config/registry) no longer overwrite each other's callbacks. Added a per-registry isolation regression test. Owner-scoped monitor callbacks stay keyed by ownerAgentId (globally unique), so they don't share the hazard.
  • Test coverage: added unit suites for registry.ts, dispatcher.ts, and dream-task.ts — the central new modules that had no direct coverage after the collapse.
  • Earlier rounds' carried "still present at this SHA" items (duplicate vitest import, missing mutateSilent annotation) were already fixed at HEAD; those threads were reviewing pre-rebase SHAs.

Verified

Remaining if reopened (suggestion-level, none blocking):

  • Detail-view agent activity refreshes via the 1s wall-clock tick rather than per-tool-call — intentional, to avoid list-mode churn under activity bursts.
  • Minor consistency items: shell stripDisplayControlChars → shared bidi-safe util; monitor notified flag; single-update terminal transitions.

To resume: reopen, rerun CI, optionally address the suggestions above, merge.

@tanzhenxin tanzhenxin closed this Jun 8, 2026
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.

2 participants