Skip to content

Consolidate agentic turn loop into engine (Fixes #2034)#2050

Merged
acoliver merged 5 commits into
mainfrom
issue2034
Jun 16, 2026
Merged

Consolidate agentic turn loop into engine (Fixes #2034)#2050
acoliver merged 5 commits into
mainfrom
issue2034

Conversation

@acoliver

Copy link
Copy Markdown
Collaborator

Summary

  • Adds an engine-owned AgenticLoop in packages/agents that owns multi-turn send, stream, tool scheduling, approval, function response, and continuation flow.
  • Rewires CLI gemini stream submission to consume the engine loop while preserving display, slash/client tool scheduling, cancellation, confirmation UI, memory refresh, and subagent display behavior.
  • Moves pure continuation helpers into packages/agents, hardens confirmation bus scoping, scheduler isolation, cancellation/finalization, and prompt id correlation.
  • Adds behavioral coverage for approval outcomes, no-handler ASK_USER safety, cancellation, scheduler isolation, prompt id collisions, display callbacks, no-op scheduling, terminal stream outcomes, and CLI event/buffer lifecycle.

fixes #2034

Verification

  • packages/agents full suite: 90 files / 1588 tests passed
  • impacted CLI geminiStream suite: 11 files / 159 tests passed
  • packages/providers direct suite: 332 files / 3285 tests passed, 1 file / 18 tests skipped
  • npm run typecheck: passed
  • npm run lint: passed with 0 errors and existing warnings
  • npm run build: passed
  • smoke: node scripts/start.js --profile-load ollamaglm51 "write me a haiku and nothing else" passed

Note: workspace-level npm run test repeatedly terminated the providers workspace under npm orchestration with exit code 143, while the direct packages/providers suite passed. I found no implementation-related failure in that direct run.

@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 26e2fcd0-8b83-40c1-9a4c-b69f3582aadc

📥 Commits

Reviewing files that changed from the base of the PR and between eae12b1 and d3ad639.

📒 Files selected for processing (1)
  • packages/agents/src/core/agenticLoop/AgenticLoop.ts
📜 Recent review details
⏰ Context from checks skipped due to timeout of 270000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: E2E Test (Linux) - sandbox:docker
  • GitHub Check: E2E Test (macOS)
  • GitHub Check: E2E Test (Linux) - sandbox:none
  • GitHub Check: Lint (Javascript)
  • GitHub Check: CodeQL
  • GitHub Check: Interactive UI (tmux)
  • GitHub Check: Run LLxprt review
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2026-02-06T15:52:42.315Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1305
File: scripts/generate-keybindings-doc.ts:1-5
Timestamp: 2026-02-06T15:52:42.315Z
Learning: In reviews of vybestack/llxprt-code, do not suggest changing existing copyright headers from 'Google LLC' to 'Vybestack LLC' for files that originated from upstream. Preserve upstream copyrights in files that came from upstream, and only apply 'Vybestack LLC' copyright on newly created, original LLxprt files. If a file is clearly LLxprt-original, it may carry the Vybestack header; if it is upstream-originated, keep the original sponsor header.

Applied to files:

  • packages/agents/src/core/agenticLoop/AgenticLoop.ts
📚 Learning: 2026-03-31T02:12:43.093Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1854
File: packages/core/src/core/subagentRuntimeSetup.test.ts:77-84
Timestamp: 2026-03-31T02:12:43.093Z
Learning: In this codebase, tool declarations should follow the single required contract `parametersJsonSchema`; do not ask to preserve or reintroduce the legacy `parameters` fallback field. Reviewers should not flag assertions/checks for missing `parameters` or suggest backward-compatibility behavior for `parameters`. Schema converters/providers are expected to error if `parametersJsonSchema` is absent instead of falling back to `parameters`.

Applied to files:

  • packages/agents/src/core/agenticLoop/AgenticLoop.ts
📚 Learning: 2026-06-10T18:18:08.545Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1983
File: packages/policy/src/policy-engine.ts:156-156
Timestamp: 2026-06-10T18:18:08.545Z
Learning: In this repo, ESLint rule `sonarjs/too-many-break-or-continue-in-loop` is set to fail loops that contain more than 1 `break`/`continue` total per loop (or both present). When a loop violates this (e.g., it contains a `break` and a `continue`, or has multiple `break`s/`continue`s), the code will not lint unless the violating line includes `// eslint-disable-next-line sonarjs/too-many-break-or-continue-in-loop`. In code reviews, do not suggest removing these `eslint-disable-next-line` directives (use refactoring only if it eliminates the underlying >1 break/continue pattern).

Applied to files:

  • packages/agents/src/core/agenticLoop/AgenticLoop.ts
📚 Learning: 2026-06-10T18:18:09.253Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1983
File: packages/policy/src/policy-engine.ts:263-263
Timestamp: 2026-06-10T18:18:09.253Z
Learning: In this repository, the ESLint rule `sonarjs/too-many-break-or-continue-in-loop` is configured to allow at most 1 `break`/`continue` per loop (it is stricter than the SonarJS default). During code review, treat `// eslint-disable-next-line sonarjs/too-many-break-or-continue-in-loop` on loops with 2+ `break`/`continue` as intentional and do not suggest removing or changing those directives. Only consider a change if the rule is violated without an appropriate intentional disable.

Applied to files:

  • packages/agents/src/core/agenticLoop/AgenticLoop.ts
🔇 Additional comments (1)
packages/agents/src/core/agenticLoop/AgenticLoop.ts (1)

543-543: LGTM!


Summary by CodeRabbit

Release Notes

New Features

  • Added an engine-owned multi-turn agentic loop that streams model output, executes tools, and automatically continues tool→model turns.
  • Added an interactive approval flow (including modify-with-editor) with reliable proceed/deny behavior.

Bug Fixes

  • Improved shutdown sequencing and completion handling.
  • Hardened cancellation and approval routing to prevent hangs and late tool execution.
  • Fixed terminal stream buffering to avoid cross-turn carryover.
  • Improved prompt/correlation tracking and external/subagent tool cleanup.

Refactor

  • Updated stream handling to per-event dispatch with clearer tool completion and UI update routing.

Tests

  • Added/expanded integration and CLI hook coverage for multi-turn, approvals, abort, and isolation scenarios.

Walkthrough

Introduces an engine-owned AgenticLoop class in packages/agents that drives the full model→tool→model conversation cycle as an async event stream. The CLI's React hooks are migrated to consume this loop via a new useAgenticLoop hook, removing duplicate continuation logic from useSubmitQuery, toolCompletionHandler, and useStreamEventHandlers. ConfirmationCoordinator is extended to preserve original onConfirm handlers across correlationId changes and propagate callId for bus-scoped approval routing.

Changes

Engine-owned AgenticLoop and CLI migration

Layer / File(s) Summary
Engine types, helpers, and policy context
packages/agents/src/core/agenticLoop/types.ts, packages/agents/src/core/agenticLoop/loopHelpers.ts, packages/core/src/scheduler/types.ts, packages/core/src/policy/policy-helpers.ts
Defines AgenticLoopEvent (discriminated union), ApprovalResult/ApprovalHandler, DisplayCallbacks, AgenticLoopOptions, AgenticLoopMessage, and pure helpers splitPartsByRole, classifyCompletedTools, buildToolResponses, recordCancelledToolHistory. Adds optional callId to PolicyContext and includes it in published confirmation requests.
AgenticLoop core implementation
packages/agents/src/core/agenticLoop/AgenticLoop.ts, packages/agents/src/core/coreToolScheduler.ts
Implements the AgenticLoop class with internal EventQueue, per-instance schedulerSessionId isolation, run() async generator, runTurn()streamAndCollect()scheduleAndAwait()buildNextMessage() pipeline, AbortSignal cancellation with completion/abort racing, and optional approvalHandler wiring via MessageBus subscription. Fixes CoreToolScheduler._schedule to await checkAndNotifyCompletion().
ConfirmationCoordinator callId-scoped approval routing
packages/agents/src/scheduler/confirmation-coordinator.ts, packages/agents/src/scheduler/confirmation-coordinator.test.ts
Adds pendingOriginalConfirmHandlers map to preserve onConfirm across correlationId changes. setupConfirmationPrompt wraps onConfirm to respond on MessageBus then route via handleConfirmationResponse with skipBusPublish=true. handleModifyWithEditor re-correlates under a new correlationId while retaining the original handler. publishOutcome and reset clean up mappings.
Scheduler result tuple extension
packages/agents/src/core/agenticLoop/index.ts, packages/agents/src/index.ts, packages/cli/src/ui/hooks/useReactToolScheduler.ts
Creates the agenticLoop barrel export and publishes it through the agents package root. Extends ReactToolSchedulerResult tuple with ReplaceToolCallsFn and UpdateToolOutputFn via new useDerivedToolCallState and useBoundDisplayUpdaters hooks.
CLI stream dispatcher buffer lifecycle and simplification
packages/cli/src/ui/hooks/geminiStream/streamEventDispatcher.ts, packages/cli/src/ui/hooks/geminiStream/streamUtils.ts
Removes toolCallRequests parameter and scheduleDedupedToolCalls from streamEventDispatcher; adds flushPendingGeminiContent helper and resetBufferAfterTerminal. Deletes splitPartsByRole from streamUtils (moved to engine). Simplifies handleEarlyReturnEvent and dispatchStreamEvent signatures.
useStreamEventHandlers per-event synchronous routing
packages/cli/src/ui/hooks/geminiStream/useStreamEventHandlers.ts
Transforms from async stream-consuming processGeminiStreamEvents to synchronous per-event processStreamEvent. Introduces useProcessStreamEvent hook with ref-backed buffer accumulation. Removes stream-iteration, idle-timeout, tool-scheduling, and stream-processing-status logic.
Tool completion handling and lifecycle refactor
packages/cli/src/ui/hooks/geminiStream/toolCompletionHandler.ts, packages/cli/src/ui/hooks/geminiStream/useGeminiStreamLifecycle.ts
Refactors toolCompletionHandler to delegate classification to engine classifier. Adds classifyCompletedTools import to useGeminiStreamLifecycle; converts primary-completion callback from async ref-based to synchronous markToolsAsSubmitted parameter; adds external (subagent) tool classification and marking. Extends useCancellation gating to WaitingForConfirmation state.
useAgenticLoop hook as CLI loop consumer
packages/cli/src/ui/hooks/geminiStream/useAgenticLoop.ts
Introduces useAgenticLoop React hook: creates stable loop instance, maintains ref-backed handler wrappers, exposes runLoop(message, signal, promptId) to iterate engine events. Routes stream_event to caller's router; processes tools_complete (history flush, tool-group display, todo-pause, memory post-processing, external tool submission clearing); forwards other events via displayCallbacks refs.
CLI orchestration and submit query refactor
packages/cli/src/ui/hooks/geminiStream/useGeminiStreamOrchestration.ts, packages/cli/src/ui/hooks/geminiStream/useSubmitQuery.ts
Rewrites useGeminiStreamOrchestration to break circular dependency using processStreamEventRef/runLoopRef synchronous refs; introduces useLoopForStream wrapper. Extends ToolSchedulerState with display updaters. Refactors useSubmitQuery to call runLoop via runLoopRef instead of processGeminiStreamEvents; removes continuation/options threading; simplifies queue and message logic.
Integration, hook, and unit tests
packages/agents/src/core/agenticLoop/__tests__/agenticLoop.integration.test.ts, packages/cli/src/ui/hooks/geminiStream/__tests__/useAgenticLoop.test.tsx, packages/cli/src/ui/hooks/geminiStream/streamEventDispatcher.test.ts, packages/cli/src/ui/hooks/geminiStream/__tests__/toolCompletionHandler.test.ts, packages/cli/src/ui/hooks/useGeminiStream*.tsx, packages/agents/src/scheduler/confirmation-coordinator.test.ts
Adds full AgenticLoop integration suite (7 test groups: ASK_USER, auto-policy, abort, display callbacks, scheduler isolation, promptId correlation, terminal hardening). Adds useAgenticLoop hook behavioral tests. Updates dispatcher, completion handler, and confirmation coordinator tests. Aligns scheduler tuple mocks. Removes deleted watchdog test file.

Sequence Diagram(s)

sequenceDiagram
  participant useSubmitQuery
  participant useGeminiStreamOrchestration
  participant useAgenticLoop
  participant AgenticLoop
  participant AgentClient
  participant CoreToolScheduler

  useSubmitQuery->>AgenticLoop: runLoop(message, signal, promptId)
  AgenticLoop->>AgentClient: sendMessageStream(message)
  AgentClient-->>AgenticLoop: stream events
  AgenticLoop->>AgenticLoop: streamAndCollect()
  AgenticLoop-->>useAgenticLoop: yield stream_event
  useAgenticLoop-->>useSubmitQuery: streamEventRouter(event)
  AgenticLoop->>CoreToolScheduler: getOrCreateScheduler(schedulerSessionId)
  CoreToolScheduler-->>AgenticLoop: tool_update / tool_output callbacks
  AgenticLoop-->>useAgenticLoop: yield tool_update / tool_output
  useAgenticLoop->>useGeminiStreamOrchestration: displayCallbacks.onToolCallsUpdate()
  CoreToolScheduler-->>AgenticLoop: onAllToolCallsComplete(results)
  AgenticLoop-->>useAgenticLoop: yield tools_complete
  useAgenticLoop->>useAgenticLoop: handleToolsComplete() - history, display, memory
  AgenticLoop->>AgentClient: sendMessageStream(functionResponse parts)
  Note over AgenticLoop,AgentClient: continuation turn
  AgenticLoop-->>useAgenticLoop: yield stream_event (continuation)
  useAgenticLoop-->>useSubmitQuery: streamEventRouter(continuation event)
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

  • vybestack/llxprt-code#1060: Introduces Config/CoreToolScheduler session lifecycle management that AgenticLoop depends on for per-loop scheduler isolation via config.getOrCreateScheduler.
  • vybestack/llxprt-code#1780: Decomposes CLI tool-response helpers; this PR relocates shared utilities like classifyCompletedTools, buildToolResponses, recordCancelledToolHistory, and splitPartsByRole to engine-owned AgenticLoop/loopHelpers.
  • vybestack/llxprt-code#1913: Both PRs update buffer-lifecycle handling in streamEventDispatcher and useStreamEventHandlers, managing pending Gemini content flushing and buffer clearing on stream completion or context state changes.

Poem

🐇 A loop now lives inside the engine's core,
No more React hooks managing turn after turn!
The model streams in, tools spin and complete,
functionResponse flows back, the cycle's neat.
Hop hop hooray, the CLI's set free—
One agentic loop rules, as it ought to be! 🎉

📋 Issue Planner

Built with CodeRabbit's Coding Plans for faster development and fewer bugs.

View plan used: #2034

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch issue2034

@github-actions github-actions Bot added the maintainer:e2e:ok Trusted contributor; maintainer-approved E2E run label Jun 16, 2026
@github-actions

github-actions Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

LLxprt PR Review – PR #2050

Title: Consolidate agentic turn loop into engine (Fixes #2034)
Author: acoliver
Changes: +4825 −1829 across 29 files


Issue Alignment

Evidence the implementation satisfies #2034 requirements:

  • REQ-LOOP-001 (engine-owned multi-turn loop): AgenticLoop lives in packages/agents/src/core/agenticLoop/ with a proper async *run() generator that drives sendMessageStream → stream → schedule → execute → feed-back → repeat. The loop yields a flat AgenticLoopEvent discriminated union covering stream events, tool updates, tool output, tool completion, and awaiting-approval.

  • REQ-LOOP-002 (two injection points): Policy is injected via config (carrying PolicyEngine + ApprovalMode). The approvalHandler is optional and invoked only when policy returns ASK_USER, resolving a ToolConfirmationOutcome forwarded over the confirmation bus. Pure engine logic never touches UI.

  • REQ-LOOP-005 (cancellation via AbortSignal): scheduleAndAwait races completion against the abort signal, calls scheduler.cancelAll() on abort, and unconditionally disposes the scheduler in finally. A regression test proves a never-settling tool does not hang the loop.

  • REQ-LOOP-006 (CLI consumes the single loop): useAgenticLoop.ts wraps the engine loop, routing events to React state. executeStream now calls runLoop() and no longer manages continuation. The CLI's tool-completion display, memory refresh, and subagent display behavior are preserved.

  • REQ-LOOP-007 (no second loop / no shims): splitPartsByRole, buildToolResponses, classifyCompletedTools, recordCancelledToolHistory moved from CLI into packages/agents/src/core/agenticLoop/loopHelpers.ts. Import sites updated directly; no re-export shims remain. The a2a-server is explicitly out of scope per the plan.

Side Effects

  • coreToolScheduler.ts: checkAndNotifyCompletion() changed from void to await — a 1-line fix that corrects a pre-existing fire-and-forget race where completion could fire before the scheduler's internal state settled. This is a correctness fix that aligns with the intended semantics.

  • confirmation-coordinator.ts: pendingOriginalConfirmHandlers map added to preserve the original onConfirm callback across ModifyWithEditor re-confirmation cycles. callId added to PolicyContext and propagated through publishConfirmationRequest. These changes harden the confirmation bus scoping (preventing cross-request interference) and are directly required by the loop's approval handler wiring.

  • policy-helpers.ts: callId forwarded into FunctionCall published on the confirmation bus — needed so the CLI's UI can correlate confirmation requests to specific tool calls.

  • packages/cli/src/ui/hooks/geminiStream/__tests__/useStreamEventHandlers.watchdog.test.ts: Deleted (−860 lines). The watchdog/stalled-stream behavior it tested (processGeminiStreamEvents with idle timeout over an async iterator) is now owned by the loop. The coverage is preserved by the loop's own cancellation and terminal-outcome integration tests. Flag: the deletion removes real behavioral coverage for the stream idle timeout path; the loop tests cover cancellation but not the idle timeout trigger specifically. However, the loop's abortPromise pattern is functionally equivalent for the practical case of a provider stall.

Code Quality

Strengths:

  • The EventQueue callback-to-generator bridge is well-designed; it resolves the tension between the callback-driven scheduler and the async generator control flow.
  • Isolated schedulerSessionId (config.getSessionId()#agentic-loop#${randomUUID()}) prevents the transient per-turn scheduler from clobbering the CLI's long-lived main scheduler callbacks — a subtle and correct architectural decision.
  • The wireApprovalHandler subscription is properly cleaned up via the unsubscribe returned and called in finally.
  • drainWhileRunning correctly continues draining until completionSettled (not merely until scheduling resolves), preventing tool_output races.
  • The approval handler's rejection path responds with a safe denial rather than hanging — defensive and correct.
  • Prompt ID correlation (initialPromptId, generateContinuationPromptId) ensures continuation turns use namespaced IDs outside the CLI's session counter.

Concerns:

  • The 608-line AgenticLoop.ts has one eslint-disable max-lines-per-function on scheduleAndAwait. The method manages scheduler lifecycle, live event draining, and teardown atomically — the co-location is intentional and justified by the comment, but worth noting.
  • coreToolScheduler.ts makes checkAndNotifyCompletion() return Promise (was void) — a subtle API change on an internal method. No type signature changed publicly, but the behavioral difference (await vs. fire-forget) is material. Correct and aligned with intended semantics.

Tests and Coverage

Coverage impact: Increase (substantial)

  • New engine integration tests (agenticLoop.integration.test.ts, 2094 lines): 7 suites covering CLI-style ASK_USER, a2a-style auto policy, AbortSignal cancellation, caller display callbacks, scheduler isolation, promptId correlation, and terminal stream outcomes. These are genuine behavioral tests — they assert event sequences, history contents, tool execution side effects, and observable output, not mock call counts. This is the strongest test file in the PR.

  • New CLI hook tests (useAgenticLoop.test.tsx, 584 lines): 5 tests proving the React hook correctly routes loop events to display state, that continuation is loop-driven (not CLI re-submitted), that abort tears down cleanly, that external/subagent tools are marked submitted, and that runLoop remains stable across renders.

  • ConfirmationCoordinator tests updated: Two new tests verify ProceedOnce publishes one bus response and invokes originalOnConfirm once, and that ModifyWithEditor re-confirmation chains correctly.

  • toolCompletionHandler.test.ts: 291 lines removed (pure helper tests moved to engine; CLI tests adapted to import from agents). The removed tests asserted CLI-internal mock interactions; the engine integration tests provide stronger behavioral coverage at the correct boundary.

  • Mock theater assessment: The engine integration tests use a scripted LLM provider boundary mock (appropriate — it's infrastructure) and real MockTool/CoreToolScheduler/ConfirmationCoordinator. The CLI hook tests use real scheduler/bus/coordinator infrastructure. No test asserts "method was called on a mock" without also asserting the observable behavioral consequence. Compliant with RULES.md behavioral test requirements.

Verdict

Ready

PR #2050 is well-structured, thoroughly tested, and correctly implements the engine-owned agentic loop with policy + approval injection points as required by issue #2034. The CLI is rewired to consume the loop while preserving all user-facing behavior. The checkAndNotifyCompletion await fix resolves a latent race in CoreToolScheduler. Scheduler isolation via the random-UUID session key is a particularly careful piece of engineering. The test suite provides genuine behavioral coverage without mock theater.

Minor notes for reviewers:

  • The useStreamEventHandlers.watchdog.test.ts deletion removes idle-timeout-specific test coverage; the loop's abort handling covers the practical case but not the timeout trigger path specifically.
  • scheduleAndAwait's max-lines-per-function disable is justified by its atomic control-flow responsibility but is worth a second look during review.
  • coreToolScheduler.ts's checkAndNotifyCompletion behavior change (void → await) should be verified as intentional by the author, as it changes fire-and-forget semantics to synchronous waiting.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/agents/src/core/agenticLoop/AgenticLoop.ts`:
- Around line 107-130: The waitForNext method has a race condition where the
signal can be aborted between the initial signal.aborted check on line 108 and
the addEventListener call on line 124. If abort occurs in this window, the abort
event listener is never triggered and the promise never resolves, causing the
wait to hang. Fix this by adding another check for signal.aborted immediately
after the addEventListener call at line 124, and if the signal is already
aborted, invoke resolve() directly to ensure the promise resolves even if the
abort occurred in the race window.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: f0fe9cf8-bc0c-486f-92a6-67e8ac9c4c37

📥 Commits

Reviewing files that changed from the base of the PR and between 0173274 and 52e3edc.

⛔ Files ignored due to path filters (1)
  • project-plans/issue2034/PLAN.md is excluded by !project-plans/**
📒 Files selected for processing (28)
  • packages/agents/src/core/agenticLoop/AgenticLoop.ts
  • packages/agents/src/core/agenticLoop/__tests__/agenticLoop.integration.test.ts
  • packages/agents/src/core/agenticLoop/index.ts
  • packages/agents/src/core/agenticLoop/loopHelpers.ts
  • packages/agents/src/core/agenticLoop/types.ts
  • packages/agents/src/core/coreToolScheduler.ts
  • packages/agents/src/index.ts
  • packages/agents/src/scheduler/confirmation-coordinator.test.ts
  • packages/agents/src/scheduler/confirmation-coordinator.ts
  • packages/cli/src/ui/hooks/geminiStream/__tests__/streamUtils.test.ts
  • packages/cli/src/ui/hooks/geminiStream/__tests__/toolCompletionHandler.test.ts
  • packages/cli/src/ui/hooks/geminiStream/__tests__/useAgenticLoop.test.tsx
  • packages/cli/src/ui/hooks/geminiStream/__tests__/useStreamEventHandlers.watchdog.test.ts
  • packages/cli/src/ui/hooks/geminiStream/streamEventDispatcher.test.ts
  • packages/cli/src/ui/hooks/geminiStream/streamEventDispatcher.ts
  • packages/cli/src/ui/hooks/geminiStream/streamUtils.ts
  • packages/cli/src/ui/hooks/geminiStream/toolCompletionHandler.ts
  • packages/cli/src/ui/hooks/geminiStream/useAgenticLoop.ts
  • packages/cli/src/ui/hooks/geminiStream/useGeminiStreamLifecycle.ts
  • packages/cli/src/ui/hooks/geminiStream/useGeminiStreamOrchestration.ts
  • packages/cli/src/ui/hooks/geminiStream/useStreamEventHandlers.ts
  • packages/cli/src/ui/hooks/geminiStream/useSubmitQuery.ts
  • packages/cli/src/ui/hooks/useGeminiStream.dedup.test.tsx
  • packages/cli/src/ui/hooks/useGeminiStream.subagent.spec.tsx
  • packages/cli/src/ui/hooks/useGeminiStream.thinking.test.tsx
  • packages/cli/src/ui/hooks/useReactToolScheduler.ts
  • packages/core/src/policy/policy-helpers.ts
  • packages/core/src/scheduler/types.ts
💤 Files with no reviewable changes (2)
  • packages/cli/src/ui/hooks/geminiStream/tests/useStreamEventHandlers.watchdog.test.ts
  • packages/cli/src/ui/hooks/geminiStream/streamUtils.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 270000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Run LLxprt review
🧰 Additional context used
🧠 Learnings (8)
📚 Learning: 2026-02-06T15:52:42.315Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1305
File: scripts/generate-keybindings-doc.ts:1-5
Timestamp: 2026-02-06T15:52:42.315Z
Learning: In reviews of vybestack/llxprt-code, do not suggest changing existing copyright headers from 'Google LLC' to 'Vybestack LLC' for files that originated from upstream. Preserve upstream copyrights in files that came from upstream, and only apply 'Vybestack LLC' copyright on newly created, original LLxprt files. If a file is clearly LLxprt-original, it may carry the Vybestack header; if it is upstream-originated, keep the original sponsor header.

Applied to files:

  • packages/core/src/policy/policy-helpers.ts
  • packages/agents/src/index.ts
  • packages/core/src/scheduler/types.ts
  • packages/agents/src/scheduler/confirmation-coordinator.test.ts
  • packages/agents/src/core/agenticLoop/index.ts
  • packages/agents/src/core/agenticLoop/loopHelpers.ts
  • packages/agents/src/core/coreToolScheduler.ts
  • packages/cli/src/ui/hooks/geminiStream/__tests__/streamUtils.test.ts
  • packages/cli/src/ui/hooks/useReactToolScheduler.ts
  • packages/cli/src/ui/hooks/geminiStream/__tests__/toolCompletionHandler.test.ts
  • packages/agents/src/core/agenticLoop/types.ts
  • packages/cli/src/ui/hooks/geminiStream/useAgenticLoop.ts
  • packages/cli/src/ui/hooks/geminiStream/useGeminiStreamLifecycle.ts
  • packages/agents/src/scheduler/confirmation-coordinator.ts
  • packages/cli/src/ui/hooks/geminiStream/useStreamEventHandlers.ts
  • packages/cli/src/ui/hooks/geminiStream/toolCompletionHandler.ts
  • packages/cli/src/ui/hooks/geminiStream/useGeminiStreamOrchestration.ts
  • packages/agents/src/core/agenticLoop/AgenticLoop.ts
  • packages/cli/src/ui/hooks/geminiStream/streamEventDispatcher.test.ts
  • packages/cli/src/ui/hooks/geminiStream/useSubmitQuery.ts
  • packages/agents/src/core/agenticLoop/__tests__/agenticLoop.integration.test.ts
  • packages/cli/src/ui/hooks/geminiStream/streamEventDispatcher.ts
📚 Learning: 2026-03-31T02:12:43.093Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1854
File: packages/core/src/core/subagentRuntimeSetup.test.ts:77-84
Timestamp: 2026-03-31T02:12:43.093Z
Learning: In this codebase, tool declarations should follow the single required contract `parametersJsonSchema`; do not ask to preserve or reintroduce the legacy `parameters` fallback field. Reviewers should not flag assertions/checks for missing `parameters` or suggest backward-compatibility behavior for `parameters`. Schema converters/providers are expected to error if `parametersJsonSchema` is absent instead of falling back to `parameters`.

Applied to files:

  • packages/core/src/policy/policy-helpers.ts
  • packages/agents/src/index.ts
  • packages/core/src/scheduler/types.ts
  • packages/agents/src/scheduler/confirmation-coordinator.test.ts
  • packages/agents/src/core/agenticLoop/index.ts
  • packages/agents/src/core/agenticLoop/loopHelpers.ts
  • packages/agents/src/core/coreToolScheduler.ts
  • packages/cli/src/ui/hooks/geminiStream/__tests__/streamUtils.test.ts
  • packages/cli/src/ui/hooks/useReactToolScheduler.ts
  • packages/cli/src/ui/hooks/geminiStream/__tests__/toolCompletionHandler.test.ts
  • packages/agents/src/core/agenticLoop/types.ts
  • packages/cli/src/ui/hooks/geminiStream/useAgenticLoop.ts
  • packages/cli/src/ui/hooks/geminiStream/useGeminiStreamLifecycle.ts
  • packages/agents/src/scheduler/confirmation-coordinator.ts
  • packages/cli/src/ui/hooks/geminiStream/useStreamEventHandlers.ts
  • packages/cli/src/ui/hooks/geminiStream/toolCompletionHandler.ts
  • packages/cli/src/ui/hooks/geminiStream/useGeminiStreamOrchestration.ts
  • packages/agents/src/core/agenticLoop/AgenticLoop.ts
  • packages/cli/src/ui/hooks/geminiStream/streamEventDispatcher.test.ts
  • packages/cli/src/ui/hooks/geminiStream/useSubmitQuery.ts
  • packages/agents/src/core/agenticLoop/__tests__/agenticLoop.integration.test.ts
  • packages/cli/src/ui/hooks/geminiStream/streamEventDispatcher.ts
📚 Learning: 2026-06-10T18:18:08.545Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1983
File: packages/policy/src/policy-engine.ts:156-156
Timestamp: 2026-06-10T18:18:08.545Z
Learning: In this repo, ESLint rule `sonarjs/too-many-break-or-continue-in-loop` is set to fail loops that contain more than 1 `break`/`continue` total per loop (or both present). When a loop violates this (e.g., it contains a `break` and a `continue`, or has multiple `break`s/`continue`s), the code will not lint unless the violating line includes `// eslint-disable-next-line sonarjs/too-many-break-or-continue-in-loop`. In code reviews, do not suggest removing these `eslint-disable-next-line` directives (use refactoring only if it eliminates the underlying >1 break/continue pattern).

Applied to files:

  • packages/core/src/policy/policy-helpers.ts
  • packages/cli/src/ui/hooks/useGeminiStream.subagent.spec.tsx
  • packages/agents/src/index.ts
  • packages/cli/src/ui/hooks/useGeminiStream.dedup.test.tsx
  • packages/core/src/scheduler/types.ts
  • packages/agents/src/scheduler/confirmation-coordinator.test.ts
  • packages/agents/src/core/agenticLoop/index.ts
  • packages/cli/src/ui/hooks/useGeminiStream.thinking.test.tsx
  • packages/agents/src/core/agenticLoop/loopHelpers.ts
  • packages/agents/src/core/coreToolScheduler.ts
  • packages/cli/src/ui/hooks/geminiStream/__tests__/streamUtils.test.ts
  • packages/cli/src/ui/hooks/geminiStream/__tests__/useAgenticLoop.test.tsx
  • packages/cli/src/ui/hooks/useReactToolScheduler.ts
  • packages/cli/src/ui/hooks/geminiStream/__tests__/toolCompletionHandler.test.ts
  • packages/agents/src/core/agenticLoop/types.ts
  • packages/cli/src/ui/hooks/geminiStream/useAgenticLoop.ts
  • packages/cli/src/ui/hooks/geminiStream/useGeminiStreamLifecycle.ts
  • packages/agents/src/scheduler/confirmation-coordinator.ts
  • packages/cli/src/ui/hooks/geminiStream/useStreamEventHandlers.ts
  • packages/cli/src/ui/hooks/geminiStream/toolCompletionHandler.ts
  • packages/cli/src/ui/hooks/geminiStream/useGeminiStreamOrchestration.ts
  • packages/agents/src/core/agenticLoop/AgenticLoop.ts
  • packages/cli/src/ui/hooks/geminiStream/streamEventDispatcher.test.ts
  • packages/cli/src/ui/hooks/geminiStream/useSubmitQuery.ts
  • packages/agents/src/core/agenticLoop/__tests__/agenticLoop.integration.test.ts
  • packages/cli/src/ui/hooks/geminiStream/streamEventDispatcher.ts
📚 Learning: 2026-06-10T18:18:09.253Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1983
File: packages/policy/src/policy-engine.ts:263-263
Timestamp: 2026-06-10T18:18:09.253Z
Learning: In this repository, the ESLint rule `sonarjs/too-many-break-or-continue-in-loop` is configured to allow at most 1 `break`/`continue` per loop (it is stricter than the SonarJS default). During code review, treat `// eslint-disable-next-line sonarjs/too-many-break-or-continue-in-loop` on loops with 2+ `break`/`continue` as intentional and do not suggest removing or changing those directives. Only consider a change if the rule is violated without an appropriate intentional disable.

Applied to files:

  • packages/core/src/policy/policy-helpers.ts
  • packages/cli/src/ui/hooks/useGeminiStream.subagent.spec.tsx
  • packages/agents/src/index.ts
  • packages/cli/src/ui/hooks/useGeminiStream.dedup.test.tsx
  • packages/core/src/scheduler/types.ts
  • packages/agents/src/scheduler/confirmation-coordinator.test.ts
  • packages/agents/src/core/agenticLoop/index.ts
  • packages/cli/src/ui/hooks/useGeminiStream.thinking.test.tsx
  • packages/agents/src/core/agenticLoop/loopHelpers.ts
  • packages/agents/src/core/coreToolScheduler.ts
  • packages/cli/src/ui/hooks/geminiStream/__tests__/streamUtils.test.ts
  • packages/cli/src/ui/hooks/geminiStream/__tests__/useAgenticLoop.test.tsx
  • packages/cli/src/ui/hooks/useReactToolScheduler.ts
  • packages/cli/src/ui/hooks/geminiStream/__tests__/toolCompletionHandler.test.ts
  • packages/agents/src/core/agenticLoop/types.ts
  • packages/cli/src/ui/hooks/geminiStream/useAgenticLoop.ts
  • packages/cli/src/ui/hooks/geminiStream/useGeminiStreamLifecycle.ts
  • packages/agents/src/scheduler/confirmation-coordinator.ts
  • packages/cli/src/ui/hooks/geminiStream/useStreamEventHandlers.ts
  • packages/cli/src/ui/hooks/geminiStream/toolCompletionHandler.ts
  • packages/cli/src/ui/hooks/geminiStream/useGeminiStreamOrchestration.ts
  • packages/agents/src/core/agenticLoop/AgenticLoop.ts
  • packages/cli/src/ui/hooks/geminiStream/streamEventDispatcher.test.ts
  • packages/cli/src/ui/hooks/geminiStream/useSubmitQuery.ts
  • packages/agents/src/core/agenticLoop/__tests__/agenticLoop.integration.test.ts
  • packages/cli/src/ui/hooks/geminiStream/streamEventDispatcher.ts
📚 Learning: 2026-04-23T23:33:11.797Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1907
File: packages/cli/src/ui/App.test.tsx:1583-1586
Timestamp: 2026-04-23T23:33:11.797Z
Learning: In UI test files under packages/cli/src/ui, prefer test titles/descriptions that state the feature being tested (what behavior the user cares about), even if the assertions specifically exercise a guard/edge path. For example, if the test covers the “empty queue ⇒ no auto-send” branch, a title like “auto-send queued messages” is acceptable; aligning the title perfectly to the exact assertion is optional and not required for lint/enforcement batches.

Applied to files:

  • packages/cli/src/ui/hooks/useGeminiStream.subagent.spec.tsx
  • packages/cli/src/ui/hooks/useGeminiStream.dedup.test.tsx
  • packages/cli/src/ui/hooks/useGeminiStream.thinking.test.tsx
  • packages/cli/src/ui/hooks/geminiStream/__tests__/useAgenticLoop.test.tsx
📚 Learning: 2026-03-25T12:57:21.017Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1768
File: packages/cli/src/ui/hooks/useCoreEventHandlers.ts:71-78
Timestamp: 2026-03-25T12:57:21.017Z
Learning: In files under `packages/cli/src/ui/hooks/`, it is OK for a `useEffect` to register process-level cleanup via `registerCleanup(consolePatcher.cleanup)` without returning a React cleanup function (e.g., without `return () => consolePatcher.cleanup()`). Treat this as an intentional pattern: `registerCleanup()` is the project’s mechanism for cleanup that is meant to persist beyond React unmount/re-render, so do not flag the missing `return` as a leak/bug.

Applied to files:

  • packages/cli/src/ui/hooks/geminiStream/__tests__/streamUtils.test.ts
  • packages/cli/src/ui/hooks/useReactToolScheduler.ts
  • packages/cli/src/ui/hooks/geminiStream/__tests__/toolCompletionHandler.test.ts
  • packages/cli/src/ui/hooks/geminiStream/useAgenticLoop.ts
  • packages/cli/src/ui/hooks/geminiStream/useGeminiStreamLifecycle.ts
  • packages/cli/src/ui/hooks/geminiStream/useStreamEventHandlers.ts
  • packages/cli/src/ui/hooks/geminiStream/toolCompletionHandler.ts
  • packages/cli/src/ui/hooks/geminiStream/useGeminiStreamOrchestration.ts
  • packages/cli/src/ui/hooks/geminiStream/streamEventDispatcher.test.ts
  • packages/cli/src/ui/hooks/geminiStream/useSubmitQuery.ts
  • packages/cli/src/ui/hooks/geminiStream/streamEventDispatcher.ts
📚 Learning: 2026-03-26T00:49:43.150Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1778
File: packages/cli/src/auth/__tests__/auth-flow-orchestrator.spec.ts:309-324
Timestamp: 2026-03-26T00:49:43.150Z
Learning: In this repository’s Jest (or Jest-like) test files, it is acceptable to use `expect(promiseReturningFunction).resolves.not.toThrow()` when the function returns `Promise<void>`. Do not flag this as an incorrect or suboptimal matcher; for `Promise<void>` it is functionally equivalent to using `resolves.toBeUndefined()` to assert successful resolution.

Applied to files:

  • packages/cli/src/ui/hooks/geminiStream/__tests__/streamUtils.test.ts
  • packages/cli/src/ui/hooks/geminiStream/__tests__/toolCompletionHandler.test.ts
  • packages/agents/src/core/agenticLoop/__tests__/agenticLoop.integration.test.ts
📚 Learning: 2026-03-26T22:12:58.549Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1780
File: packages/cli/src/ui/hooks/geminiStream/useStreamEventHandlers.ts:1-5
Timestamp: 2026-03-26T22:12:58.549Z
Learning: When reviewing this repo, do not flag these files for missing "upstream" Google LLC copyright. For `useGeminiStream.ts` and the extracted geminiStream-hook modules (under `packages/cli/src/ui/hooks/geminiStream/`), ensure the copyright header is `Copyright 2025 Vybestack LLC`—these files were already updated to Vybestack LLC before PR `#1780` and the decomposition outputs correctly use Vybestack LLC.

Applied to files:

  • packages/cli/src/ui/hooks/geminiStream/__tests__/streamUtils.test.ts
  • packages/cli/src/ui/hooks/geminiStream/__tests__/toolCompletionHandler.test.ts
  • packages/cli/src/ui/hooks/geminiStream/useAgenticLoop.ts
  • packages/cli/src/ui/hooks/geminiStream/useGeminiStreamLifecycle.ts
  • packages/cli/src/ui/hooks/geminiStream/useStreamEventHandlers.ts
  • packages/cli/src/ui/hooks/geminiStream/toolCompletionHandler.ts
  • packages/cli/src/ui/hooks/geminiStream/useGeminiStreamOrchestration.ts
  • packages/cli/src/ui/hooks/geminiStream/streamEventDispatcher.test.ts
  • packages/cli/src/ui/hooks/geminiStream/useSubmitQuery.ts
  • packages/cli/src/ui/hooks/geminiStream/streamEventDispatcher.ts
🔇 Additional comments (36)
packages/cli/src/ui/hooks/geminiStream/streamEventDispatcher.ts (3)

132-153: LGTM!


234-260: LGTM!


262-293: LGTM!

Also applies to: 313-316

packages/cli/src/ui/hooks/geminiStream/useStreamEventHandlers.ts (2)

11-18: LGTM!

Also applies to: 88-96


545-584: LGTM!

packages/cli/src/ui/hooks/geminiStream/useGeminiStreamOrchestration.ts (8)

7-17: LGTM!


29-29: LGTM!


74-85: LGTM!


114-150: LGTM!


163-198: LGTM!


218-239: LGTM!


241-270: LGTM!


305-359: LGTM!

packages/cli/src/ui/hooks/geminiStream/useSubmitQuery.ts (9)

38-38: LGTM!


89-102: LGTM!


115-141: LGTM!


143-177: LGTM!


268-308: LGTM!


310-354: LGTM!


356-365: LGTM!


367-381: LGTM!


414-437: LGTM!

packages/agents/src/core/agenticLoop/index.ts (1)

11-24: LGTM!

packages/agents/src/index.ts (1)

48-48: LGTM!

packages/cli/src/ui/hooks/useReactToolScheduler.ts (1)

99-118: LGTM!

Also applies to: 734-751, 760-772, 775-801, 864-867, 874-877, 886-887

packages/agents/src/core/agenticLoop/__tests__/agenticLoop.integration.test.ts (1)

1-1974: LGTM!

packages/cli/src/ui/hooks/geminiStream/__tests__/useAgenticLoop.test.tsx (1)

1-543: LGTM!

packages/cli/src/ui/hooks/geminiStream/streamEventDispatcher.test.ts (1)

8-8: LGTM!

Also applies to: 96-96, 125-125, 139-139, 159-159, 185-185, 208-208, 212-212, 235-235, 258-258, 283-283, 308-308, 333-333, 357-357, 384-384, 391-505

packages/cli/src/ui/hooks/geminiStream/__tests__/streamUtils.test.ts (1)

36-36: LGTM!

packages/cli/src/ui/hooks/geminiStream/__tests__/toolCompletionHandler.test.ts (1)

10-14: LGTM!

Also applies to: 29-29

packages/cli/src/ui/hooks/useGeminiStream.dedup.test.tsx (1)

89-90: LGTM!

Also applies to: 152-170

packages/cli/src/ui/hooks/useGeminiStream.subagent.spec.tsx (1)

234-235: LGTM!

Also applies to: 266-267

packages/cli/src/ui/hooks/useGeminiStream.thinking.test.tsx (1)

299-300: LGTM!

Also applies to: 336-337

packages/cli/src/ui/hooks/geminiStream/toolCompletionHandler.ts (1)

8-12: LGTM!

Also applies to: 14-17, 19-21, 39-48, 53-57, 59-64, 72-72

packages/cli/src/ui/hooks/geminiStream/useAgenticLoop.ts (1)

1-293: LGTM!

packages/cli/src/ui/hooks/geminiStream/useGeminiStreamLifecycle.ts (1)

30-31: LGTM!

Also applies to: 86-93, 109-110, 112-118, 137-144, 225-230

Comment thread packages/agents/src/core/agenticLoop/AgenticLoop.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/agents/src/core/agenticLoop/AgenticLoop.ts (1)

486-494: 🧹 Nitpick | 🔵 Trivial | 💤 Low value

Consider applying the same abort-recheck pattern for consistency.

The abort promise setup doesn't include the post-listener signal.aborted recheck that was added to EventQueue.waitForNext. While this is less critical here because:

  1. The drainWhileRunning loop exits via signal.aborted check
  2. The explicit abort handling block (lines 521-527) calls cancelAll() triggering completion
  3. Multiple fallback resolution paths exist

For defense-in-depth consistency, the same pattern could be applied:

Suggested improvement
     const abortPromise = new Promise<null>((resolve) => {
       if (signal.aborted) {
         resolve(null);
         return;
       }
       const onAbort = () => resolve(null);
       signal.addEventListener('abort', onAbort, { once: true });
       cleanupAbortListener = () => signal.removeEventListener('abort', onAbort);
+      // Close check→subscribe race window
+      if (signal.aborted) {
+        resolve(null);
+      }
     });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/agents/src/core/agenticLoop/AgenticLoop.ts` around lines 486 - 494,
The abort promise setup in abortPromise at lines 486-494 is missing the
post-listener signal.aborted recheck pattern that was applied to
EventQueue.waitForNext for consistency. After registering the 'abort' event
listener via signal.addEventListener, add another check for signal.aborted to
catch the edge case where the signal is aborted between the initial check (line
488) and the listener registration completing. If signal.aborted is true at that
point, resolve the promise immediately. This provides defense-in-depth
consistency with the same pattern used elsewhere in the codebase.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@packages/agents/src/core/agenticLoop/AgenticLoop.ts`:
- Around line 486-494: The abort promise setup in abortPromise at lines 486-494
is missing the post-listener signal.aborted recheck pattern that was applied to
EventQueue.waitForNext for consistency. After registering the 'abort' event
listener via signal.addEventListener, add another check for signal.aborted to
catch the edge case where the signal is aborted between the initial check (line
488) and the listener registration completing. If signal.aborted is true at that
point, resolve the promise immediately. This provides defense-in-depth
consistency with the same pattern used elsewhere in the codebase.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: ff8a27ad-5c5a-451b-8e6f-55a5079d7845

📥 Commits

Reviewing files that changed from the base of the PR and between 52e3edc and b3c3e71.

📒 Files selected for processing (1)
  • packages/agents/src/core/agenticLoop/AgenticLoop.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 270000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Run LLxprt review
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2026-02-06T15:52:42.315Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1305
File: scripts/generate-keybindings-doc.ts:1-5
Timestamp: 2026-02-06T15:52:42.315Z
Learning: In reviews of vybestack/llxprt-code, do not suggest changing existing copyright headers from 'Google LLC' to 'Vybestack LLC' for files that originated from upstream. Preserve upstream copyrights in files that came from upstream, and only apply 'Vybestack LLC' copyright on newly created, original LLxprt files. If a file is clearly LLxprt-original, it may carry the Vybestack header; if it is upstream-originated, keep the original sponsor header.

Applied to files:

  • packages/agents/src/core/agenticLoop/AgenticLoop.ts
📚 Learning: 2026-03-31T02:12:43.093Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1854
File: packages/core/src/core/subagentRuntimeSetup.test.ts:77-84
Timestamp: 2026-03-31T02:12:43.093Z
Learning: In this codebase, tool declarations should follow the single required contract `parametersJsonSchema`; do not ask to preserve or reintroduce the legacy `parameters` fallback field. Reviewers should not flag assertions/checks for missing `parameters` or suggest backward-compatibility behavior for `parameters`. Schema converters/providers are expected to error if `parametersJsonSchema` is absent instead of falling back to `parameters`.

Applied to files:

  • packages/agents/src/core/agenticLoop/AgenticLoop.ts
📚 Learning: 2026-06-10T18:18:08.545Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1983
File: packages/policy/src/policy-engine.ts:156-156
Timestamp: 2026-06-10T18:18:08.545Z
Learning: In this repo, ESLint rule `sonarjs/too-many-break-or-continue-in-loop` is set to fail loops that contain more than 1 `break`/`continue` total per loop (or both present). When a loop violates this (e.g., it contains a `break` and a `continue`, or has multiple `break`s/`continue`s), the code will not lint unless the violating line includes `// eslint-disable-next-line sonarjs/too-many-break-or-continue-in-loop`. In code reviews, do not suggest removing these `eslint-disable-next-line` directives (use refactoring only if it eliminates the underlying >1 break/continue pattern).

Applied to files:

  • packages/agents/src/core/agenticLoop/AgenticLoop.ts
📚 Learning: 2026-06-10T18:18:09.253Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1983
File: packages/policy/src/policy-engine.ts:263-263
Timestamp: 2026-06-10T18:18:09.253Z
Learning: In this repository, the ESLint rule `sonarjs/too-many-break-or-continue-in-loop` is configured to allow at most 1 `break`/`continue` per loop (it is stricter than the SonarJS default). During code review, treat `// eslint-disable-next-line sonarjs/too-many-break-or-continue-in-loop` on loops with 2+ `break`/`continue` as intentional and do not suggest removing or changing those directives. Only consider a change if the rule is violated without an appropriate intentional disable.

Applied to files:

  • packages/agents/src/core/agenticLoop/AgenticLoop.ts
🔇 Additional comments (9)
packages/agents/src/core/agenticLoop/AgenticLoop.ts (9)

62-82: LGTM!


107-132: LGTM!


163-200: LGTM!


208-246: LGTM!


260-296: LGTM!


303-363: LGTM!


366-390: LGTM!


544-555: LGTM!


558-589: LGTM!

@acoliver

Copy link
Copy Markdown
Collaborator Author

Deep Thinker's Assessment

Overall Soundness: Directionally correct. The engine-owned AgenticLoop correctly owns send → stream → collect tool requests → schedule/execute → build functionResponse parts → feed back → repeat. The EventQueue bridge, scheduler isolation, and ConfirmationCoordinator changes are mostly correct.

Issues Found (by severity):

┌───────┬─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Sever │ Issue │
│ ity │ │
├───────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ High │ scheduleAndAwait() doesn't wrap scheduler lifecycle cleanup in finally. If the async generator is closed early (e.g., consumer breaks after abort while tools are │
│ │ running), forwardingActive may remain true, the queue may not close, the isolated scheduler may not be disposed, and the abort listener may leak. │
│ Med │ approvalHandler promises are fire-and-forget with no AbortSignal. If a handler never resolves, the promise remains dangling — it can later publish a stale │
│ ium │ confirmation response after the loop has moved on. │
│ /Hi │ │
│ gh │ │
│ Med │ Abort while waiting for ASK_USER approval with a never-resolving handler is not tested. │
│ ium │ │
│ Med │ ConfirmationCoordinator's wrapped onConfirm publishes to the bus synchronously and then calls handleConfirmationResponse — the bus path may process first, and the │
│ ium │ UI-facing promise may resolve before real handling finishes (double-publish risk). │
│ Med │ useAgenticLoop's runLoop captures the whole args object. In-flight loops can use stale addItem, flushPendingHistoryItem, processStreamEventRef references if those │
│ ium │ change during a turn. │
│ Low │ EventQueue is described as "bounded" but is unbounded — high-volume tool output can grow memory if the consumer is slow. │
│ /Me │ │
│ dium │ │
│ Low │ ownedToolCallIds scoping relies on confirmation requests including toolCall.id; older publishers without id would be ignored. │
│ Low │ promptCount is per-AgenticLoop instance, not per run() — surprising if callers reuse instances across runs. │
└───────┴─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘

Acceptance Criteria Gaps: REQ-LOOP-001, 002, 004, 005 have strong coverage. Missing/under-covered: abort during pending ASK_USER approval; early async-generator return while scheduleAndAwait is mid-flight; explicit disposal assertions after early-return paths; approval handler subscription cleanup after abort.


Architect's Assessment

Verdict: APPROVE with non-blocking follow-ups.

┌───────────────────┬────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Dimension │ Rating │
├───────────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Dependency │ [OK] Clean. Loop imports only core/tools/genai; depends on AgentClientContract interface, not concrete class. No React/CLI leakage. Typecheck passes │
│ direction │ across all packages (no cycles). │
│ Separation of │ [OK] Clean. Flat AgenticLoopEvent discriminated union; useAgenticLoop is the sole React translation layer. │
│ concerns │ │
│ Injection │ [OK] Strong. Policy (synchronous, UI-free), Approval (optional, bus-native, callId-filtered, fails-safe), Display (composes with loop's completion │
│ point design │ ownership). │
│ EventQueue │ [OK] Correct. The no-stop-on-schedule-resolution subtlety is documented and tested. │
│ pattern │ │
│ Scheduler key │ [OK] Correct and well-justified. Verified against schedulerSingleton's last-writer-wins / no-restore-on-dispose semantics. │
│ isolation │ │
│ CLI cleanup │ [OK] Genuinely removed, not shimmed. scheduleDedupedToolCalls/shouldSkipToolScheduling deleted; no re-export shims. Residual scheduler wiring │
│ │ legitimately serves client-initiated slash-tool path. │
│ Extensibility │ [OK] Headless consumers can use the loop with no React dependency. a2a correctly left as documented future beneficiary. │
│ Plan compliance │ [OK] High. All REQ-LOOP-001..008 satisfied; files created/modified match plan's Phase 1 + Phase 2 lists. │
└───────────────────┴────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘


Agreed Follow-ups (non-blocking, but recommended before merge)

  1. Should-fix (highest blast radius): Add try/finally in scheduleAndAwait to guarantee forwardingActive = false, queue.close(), config.disposeScheduler(sessionId), and abort-listener cleanup — even if the generator is closed early. Add regression tests for early generator return while tools are running.

  2. Should-fix: Add dedicated ConfirmationCoordinator-level tests asserting: (a) a normal ProceedOnce does not double-publish to the bus, and (b) ModifyWithEditor → re-confirm → ProceedOnce invokes the original tool onConfirm exactly once. This component routes ALL confirmation flows (CLI, subagents, a2a), so coverage matters.

  3. Nice-to-have: Make ApprovalHandler abort-aware (pass the AbortSignal or track pending approvals and respond Cancel on abort).

  4. Nice-to-have: Use latest-ref forwarding for the non-display callbacks in useAgenticLoop (addItem, flushPendingHistoryItem, etc.) to avoid stale closures during long-running turns.

  5. Trivial: Remove the dead TurnToolResult.events field and the void result.events; statement in runTurn.

  6. Trivial: The EventQueue comment says "bounded" but it's unbounded — either fix the comment or consider a bound.

@acoliver

Copy link
Copy Markdown
Collaborator Author

@CodeRabbit assess this:

Deep Thinker's Assessment

Overall Soundness: Directionally correct. The engine-owned AgenticLoop correctly owns send → stream → collect tool requests → schedule/execute → build functionResponse parts → feed back → repeat. The EventQueue bridge, scheduler isolation, and ConfirmationCoordinator changes are mostly correct.

Issues Found (by severity):

┌───────┬─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Sever │ Issue │
│ ity │ │
├───────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ High │ scheduleAndAwait() doesn't wrap scheduler lifecycle cleanup in finally. If the async generator is closed early (e.g., consumer breaks after abort while tools are │
│ │ running), forwardingActive may remain true, the queue may not close, the isolated scheduler may not be disposed, and the abort listener may leak. │
│ Med │ approvalHandler promises are fire-and-forget with no AbortSignal. If a handler never resolves, the promise remains dangling — it can later publish a stale │
│ ium │ confirmation response after the loop has moved on. │
│ /Hi │ │
│ gh │ │
│ Med │ Abort while waiting for ASK_USER approval with a never-resolving handler is not tested. │
│ ium │ │
│ Med │ ConfirmationCoordinator's wrapped onConfirm publishes to the bus synchronously and then calls handleConfirmationResponse — the bus path may process first, and the │
│ ium │ UI-facing promise may resolve before real handling finishes (double-publish risk). │
│ Med │ useAgenticLoop's runLoop captures the whole args object. In-flight loops can use stale addItem, flushPendingHistoryItem, processStreamEventRef references if those │
│ ium │ change during a turn. │
│ Low │ EventQueue is described as "bounded" but is unbounded — high-volume tool output can grow memory if the consumer is slow. │
│ /Me │ │
│ dium │ │
│ Low │ ownedToolCallIds scoping relies on confirmation requests including toolCall.id; older publishers without id would be ignored. │
│ Low │ promptCount is per-AgenticLoop instance, not per run() — surprising if callers reuse instances across runs. │
└───────┴─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘

Acceptance Criteria Gaps: REQ-LOOP-001, 002, 004, 005 have strong coverage. Missing/under-covered: abort during pending ASK_USER approval; early async-generator return while scheduleAndAwait is mid-flight; explicit disposal assertions after early-return paths; approval handler subscription cleanup after abort.


Architect's Assessment

Verdict: APPROVE with non-blocking follow-ups.

┌───────────────────┬────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Dimension │ Rating │
├───────────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Dependency │ [OK] Clean. Loop imports only core/tools/genai; depends on AgentClientContract interface, not concrete class. No React/CLI leakage. Typecheck passes │
│ direction │ across all packages (no cycles). │
│ Separation of │ [OK] Clean. Flat AgenticLoopEvent discriminated union; useAgenticLoop is the sole React translation layer. │
│ concerns │ │
│ Injection │ [OK] Strong. Policy (synchronous, UI-free), Approval (optional, bus-native, callId-filtered, fails-safe), Display (composes with loop's completion │
│ point design │ ownership). │
│ EventQueue │ [OK] Correct. The no-stop-on-schedule-resolution subtlety is documented and tested. │
│ pattern │ │
│ Scheduler key │ [OK] Correct and well-justified. Verified against schedulerSingleton's last-writer-wins / no-restore-on-dispose semantics. │
│ isolation │ │
│ CLI cleanup │ [OK] Genuinely removed, not shimmed. scheduleDedupedToolCalls/shouldSkipToolScheduling deleted; no re-export shims. Residual scheduler wiring │
│ │ legitimately serves client-initiated slash-tool path. │
│ Extensibility │ [OK] Headless consumers can use the loop with no React dependency. a2a correctly left as documented future beneficiary. │
│ Plan compliance │ [OK] High. All REQ-LOOP-001..008 satisfied; files created/modified match plan's Phase 1 + Phase 2 lists. │
└───────────────────┴────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘


Agreed Follow-ups (non-blocking, but recommended before merge)

  1. Should-fix (highest blast radius): Add try/finally in scheduleAndAwait to guarantee forwardingActive = false, queue.close(), config.disposeScheduler(sessionId), and abort-listener cleanup — even if the generator is closed early. Add regression tests for early generator return while tools are running.

  2. Should-fix: Add dedicated ConfirmationCoordinator-level tests asserting: (a) a normal ProceedOnce does not double-publish to the bus, and (b) ModifyWithEditor → re-confirm → ProceedOnce invokes the original tool onConfirm exactly once. This component routes ALL confirmation flows (CLI, subagents, a2a), so coverage matters.

  3. Nice-to-have: Make ApprovalHandler abort-aware (pass the AbortSignal or track pending approvals and respond Cancel on abort).

  4. Nice-to-have: Use latest-ref forwarding for the non-display callbacks in useAgenticLoop (addItem, flushPendingHistoryItem, etc.) to avoid stale closures during long-running turns.

  5. Trivial: Remove the dead TurnToolResult.events field and the void result.events; statement in runTurn.

  6. Trivial: The EventQueue comment says "bounded" but it's unbounded — either fix the comment or consider a bound.

@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Read the AgenticLoop implementation
fd -e ts 'AgenticLoop.ts' --exclude '__tests__' | xargs cat

echo "=== SEPARATOR ==="

# Read confirmation-coordinator.ts
fd -e ts 'confirmation-coordinator.ts' --exclude '.test.' | xargs cat

echo "=== SEPARATOR2 ==="

# Read useAgenticLoop.ts
fd -e ts 'useAgenticLoop.ts' --exclude '.test.' --exclude '.spec.' | xargs cat

Length of output: 71273



@acoliver Here is my validation of the Deep Thinker's and Architect's findings against the actual code:


Findings Validation

🔴 HIGH: scheduleAndAwait() missing try/finallyCONFIRMED

The cleanup block after yield* this.drainWhileRunning(...) is not inside a try/finally:

yield* this.drainWhileRunning(completionTask, state, queue, signal);
// ← If consumer breaks here via for-await `break` or early return...
forwardingActive = false;   // ← ...this never runs
queue.close();              // ← ...nor this
this.config.disposeScheduler(sessionId); // ← ...nor this
cleanupAbortListener();     // ← ...nor this

When a consumer breaks out of the outer for await (... of loop.run(...)), the generator protocol's return() propagates through the yield* chain. The run() method's own finally block fires (cleaning up unsubscribe() and isRunning), but scheduleAndAwait's post-drain cleanup is unreachable. The scheduler session leaks, the queue stays open, and the abort listener is never removed.

The recommended fix is to wrap the scheduleAndAwait body in a try/finally:

try {
  yield* this.drainWhileRunning(completionTask, state, queue, signal);
  // ...abort handling...
} finally {
  forwardingActive = false;
  queue.close();
  this.config.disposeScheduler(sessionId);
  cleanupAbortListener();
}

🟠 MED/HIGH: Fire-and-forget approvalHandlerCONFIRMED

void handler(request)
  .then((result) => { bus.respondToConfirmation(...); })
  .catch((error) => { bus.respondToConfirmation(..., Cancel); });

No AbortSignal is passed to the handler, and the promise is untracked. If the loop is aborted while a handler is pending, the respondToConfirmation call fires on a stale/completed loop. The risk is concrete: a stale Cancel response could land on a subsequent loop's fresh correlationId if IDs collide or the bus isn't torn down first.


🟡 MED: ConfirmationCoordinator double-publish — PARTIALLY MITIGATED

The wrappedDetails.onConfirm path in setupConfirmationPrompt does:

  1. messageBus.respondToConfirmation(correlationId, outcome) — fires handleMessageBusResponse synchronously → calls handleConfirmationResponse(..., skipBusPublish=true)
  2. Then also calls handleConfirmationResponse(..., skipBusPublish=true) directly

However, the processedConfirmations guard (has(callId) check + add(callId)) prevents double-execution — whichever path arrives second exits immediately. So the execution concern is mitigated, but the surprising ordering (bus subscriber wins the race) and the redundant call structure remain. The assessment is correct that this is worth dedicated tests.


🟡 MED: useAgenticLoop stale closures — PARTIALLY VALID

Display callbacks (onToolCallsUpdate, outputUpdateHandler, etc.) are correctly latest-ref'd via latestCallbacks.current. However, non-display callbacks — addItem, flushPendingHistoryItem, clearPendingHistoryItem, performMemoryRefresh, onTodoPause, markToolsAsSubmitted — are captured directly from args in the runLoop closure. If args changes between turns of an in-flight multi-turn run, the running for await uses the stale reference. In practice these callbacks are typically stable in React, so blast radius is low, but it's inconsistent with the display-callback pattern.


🟡 LOW/MED: EventQueue "bounded" comment is wrong — CONFIRMED

/** A bounded buffer... */
class EventQueue {
  private readonly buffered: AgenticLoopEvent[] = [];  // unbounded

The comment is inaccurate — no capacity limit exists. This is trivial to fix (either cap it or correct the JSDoc).


🟢 LOW: ownedToolCallIds requires toolCall.idCONFIRMED, mostly self-mitigated

Publishers without id are silently ignored by the approval handler. The PR's own policy-helpers.ts change already adds id: context.callId to all new confirmation requests, so new publishers are covered. Older or external publishers remain a silent-failure edge case.


🟢 LOW: promptCount per-instance — CONFIRMED, functionally harmless

promptCount is never reset between run() calls. Continuation prompt IDs remain globally unique (they're keyed off initialPromptId which is fresh per run), so this is cosmetically surprising but not a correctness issue.


Overall Verdict

The Deep Thinker's severity ratings are well-calibrated against the code. The highest-priority actionable item is the scheduleAndAwait try/finally gap — it's a genuine resource leak path that a break in any consumer's for await loop can trigger. The Architect's "APPROVE with non-blocking follow-ups" verdict is sound: the core loop logic, scheduler isolation, and dependency boundaries are all correct.

The two "should-fix" follow-ups (the try/finally in scheduleAndAwait and ConfirmationCoordinator double-publish tests) have real blast-radius and are worth addressing before or shortly after merge. Would you like me to open tracking issues for these?

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/cli/src/ui/hooks/geminiStream/useStreamEventHandlers.ts (1)

573-600: 🧹 Nitpick | 🔵 Trivial | 💤 Low value

Consider destructuring dependencies for consistency and robustness.

The dependency array [deps, handlers] relies on the caller memoizing the deps object. If deps is a new object reference each render, this callback will be recreated on every render, defeating useCallback's memoization.

Other hooks in this file (e.g., useUserCancelledHandler at lines 290-300, useErrorEventHandler at lines 341-350) destructure the specific properties they use and list them individually in the dependency array. This pattern is more robust because it doesn't depend on object reference stability.

♻️ Suggested refactor to match file's established pattern
 function useProcessStreamEvent(
   deps: StreamEventHandlerDeps,
   handlers: HandlerMap,
 ) {
+  const {
+    config,
+    addItem,
+    sanitizeContent,
+    flushPendingHistoryItem,
+    pendingHistoryItemRef,
+    thinkingBlocksRef,
+    turnCancelledRef,
+    loopDetectedRef,
+    lastModelInfoRef,
+    lastModelIdentityRef,
+    setPendingHistoryItem,
+    setLastGeminiActivityTime,
+    setThought,
+    scheduleToolCalls,
+  } = deps;
+
   const bufferRef = useRef('');
   return useCallback(
     (event: GeminiEvent, userMessageTimestamp: number) => {
       const result = dispatchStreamEvent(
         event,
         {
-          config: deps.config,
-          addItem: deps.addItem,
-          sanitizeContent: deps.sanitizeContent,
-          flushPendingHistoryItem: deps.flushPendingHistoryItem,
-          pendingHistoryItemRef: deps.pendingHistoryItemRef,
-          thinkingBlocksRef: deps.thinkingBlocksRef,
-          turnCancelledRef: deps.turnCancelledRef,
-          loopDetectedRef: deps.loopDetectedRef,
-          lastModelInfoRef: deps.lastModelInfoRef,
-          lastModelIdentityRef: deps.lastModelIdentityRef,
-          setPendingHistoryItem: deps.setPendingHistoryItem,
-          setLastGeminiActivityTime: deps.setLastGeminiActivityTime,
-          setThought: deps.setThought,
+          config,
+          addItem,
+          sanitizeContent,
+          flushPendingHistoryItem,
+          pendingHistoryItemRef,
+          thinkingBlocksRef,
+          turnCancelledRef,
+          loopDetectedRef,
+          lastModelInfoRef,
+          lastModelIdentityRef,
+          setPendingHistoryItem,
+          setLastGeminiActivityTime,
+          setThought,
           ...handlers,
-          scheduleToolCalls: deps.scheduleToolCalls,
+          scheduleToolCalls,
         },
         bufferRef.current,
         userMessageTimestamp,
       );
       bufferRef.current = result.geminiMessageBuffer;
     },
-    [deps, handlers],
+    [
+      config,
+      addItem,
+      sanitizeContent,
+      flushPendingHistoryItem,
+      pendingHistoryItemRef,
+      thinkingBlocksRef,
+      turnCancelledRef,
+      loopDetectedRef,
+      lastModelInfoRef,
+      lastModelIdentityRef,
+      setPendingHistoryItem,
+      setLastGeminiActivityTime,
+      setThought,
+      scheduleToolCalls,
+      handlers,
+    ],
   );
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/cli/src/ui/hooks/geminiStream/useStreamEventHandlers.ts` around
lines 573 - 600, The useCallback hook in this function relies on the entire deps
object reference for its dependency array, which is fragile if the caller
doesn't properly memoize it. Instead, follow the pattern used elsewhere in the
file by destructuring the specific properties from deps that are actually used
(such as config, addItem, sanitizeContent, flushPendingHistoryItem,
pendingHistoryItemRef, thinkingBlocksRef, turnCancelledRef, loopDetectedRef,
lastModelInfoRef, lastModelIdentityRef, setPendingHistoryItem,
setLastGeminiActivityTime, setThought, and scheduleToolCalls), and then list
each of these individual properties along with handlers in the dependency array
instead of passing the entire deps object. This ensures the callback only
recreates when the actual dependencies it uses change, regardless of whether
deps itself is a new reference.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@packages/cli/src/ui/hooks/geminiStream/useStreamEventHandlers.ts`:
- Around line 573-600: The useCallback hook in this function relies on the
entire deps object reference for its dependency array, which is fragile if the
caller doesn't properly memoize it. Instead, follow the pattern used elsewhere
in the file by destructuring the specific properties from deps that are actually
used (such as config, addItem, sanitizeContent, flushPendingHistoryItem,
pendingHistoryItemRef, thinkingBlocksRef, turnCancelledRef, loopDetectedRef,
lastModelInfoRef, lastModelIdentityRef, setPendingHistoryItem,
setLastGeminiActivityTime, setThought, and scheduleToolCalls), and then list
each of these individual properties along with handlers in the dependency array
instead of passing the entire deps object. This ensures the callback only
recreates when the actual dependencies it uses change, regardless of whether
deps itself is a new reference.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 1069427c-9f22-4254-a89a-a400d0f17d00

📥 Commits

Reviewing files that changed from the base of the PR and between b3c3e71 and ee2ccee.

📒 Files selected for processing (5)
  • packages/agents/src/core/agenticLoop/AgenticLoop.ts
  • packages/agents/src/core/agenticLoop/__tests__/agenticLoop.integration.test.ts
  • packages/agents/src/scheduler/confirmation-coordinator.test.ts
  • packages/agents/src/scheduler/confirmation-coordinator.ts
  • packages/cli/src/ui/hooks/geminiStream/useStreamEventHandlers.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 270000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: E2E Test (Linux) - sandbox:docker
  • GitHub Check: E2E Test (Linux) - sandbox:none
  • GitHub Check: E2E Test (macOS)
  • GitHub Check: Lint (Javascript)
  • GitHub Check: CodeQL
  • GitHub Check: Interactive UI (tmux)
  • GitHub Check: Run LLxprt review
🧰 Additional context used
🧠 Learnings (7)
📚 Learning: 2026-02-06T15:52:42.315Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1305
File: scripts/generate-keybindings-doc.ts:1-5
Timestamp: 2026-02-06T15:52:42.315Z
Learning: In reviews of vybestack/llxprt-code, do not suggest changing existing copyright headers from 'Google LLC' to 'Vybestack LLC' for files that originated from upstream. Preserve upstream copyrights in files that came from upstream, and only apply 'Vybestack LLC' copyright on newly created, original LLxprt files. If a file is clearly LLxprt-original, it may carry the Vybestack header; if it is upstream-originated, keep the original sponsor header.

Applied to files:

  • packages/agents/src/scheduler/confirmation-coordinator.test.ts
  • packages/agents/src/core/agenticLoop/AgenticLoop.ts
  • packages/agents/src/core/agenticLoop/__tests__/agenticLoop.integration.test.ts
  • packages/cli/src/ui/hooks/geminiStream/useStreamEventHandlers.ts
  • packages/agents/src/scheduler/confirmation-coordinator.ts
📚 Learning: 2026-03-31T02:12:43.093Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1854
File: packages/core/src/core/subagentRuntimeSetup.test.ts:77-84
Timestamp: 2026-03-31T02:12:43.093Z
Learning: In this codebase, tool declarations should follow the single required contract `parametersJsonSchema`; do not ask to preserve or reintroduce the legacy `parameters` fallback field. Reviewers should not flag assertions/checks for missing `parameters` or suggest backward-compatibility behavior for `parameters`. Schema converters/providers are expected to error if `parametersJsonSchema` is absent instead of falling back to `parameters`.

Applied to files:

  • packages/agents/src/scheduler/confirmation-coordinator.test.ts
  • packages/agents/src/core/agenticLoop/AgenticLoop.ts
  • packages/agents/src/core/agenticLoop/__tests__/agenticLoop.integration.test.ts
  • packages/cli/src/ui/hooks/geminiStream/useStreamEventHandlers.ts
  • packages/agents/src/scheduler/confirmation-coordinator.ts
📚 Learning: 2026-06-10T18:18:08.545Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1983
File: packages/policy/src/policy-engine.ts:156-156
Timestamp: 2026-06-10T18:18:08.545Z
Learning: In this repo, ESLint rule `sonarjs/too-many-break-or-continue-in-loop` is set to fail loops that contain more than 1 `break`/`continue` total per loop (or both present). When a loop violates this (e.g., it contains a `break` and a `continue`, or has multiple `break`s/`continue`s), the code will not lint unless the violating line includes `// eslint-disable-next-line sonarjs/too-many-break-or-continue-in-loop`. In code reviews, do not suggest removing these `eslint-disable-next-line` directives (use refactoring only if it eliminates the underlying >1 break/continue pattern).

Applied to files:

  • packages/agents/src/scheduler/confirmation-coordinator.test.ts
  • packages/agents/src/core/agenticLoop/AgenticLoop.ts
  • packages/agents/src/core/agenticLoop/__tests__/agenticLoop.integration.test.ts
  • packages/cli/src/ui/hooks/geminiStream/useStreamEventHandlers.ts
  • packages/agents/src/scheduler/confirmation-coordinator.ts
📚 Learning: 2026-06-10T18:18:09.253Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1983
File: packages/policy/src/policy-engine.ts:263-263
Timestamp: 2026-06-10T18:18:09.253Z
Learning: In this repository, the ESLint rule `sonarjs/too-many-break-or-continue-in-loop` is configured to allow at most 1 `break`/`continue` per loop (it is stricter than the SonarJS default). During code review, treat `// eslint-disable-next-line sonarjs/too-many-break-or-continue-in-loop` on loops with 2+ `break`/`continue` as intentional and do not suggest removing or changing those directives. Only consider a change if the rule is violated without an appropriate intentional disable.

Applied to files:

  • packages/agents/src/scheduler/confirmation-coordinator.test.ts
  • packages/agents/src/core/agenticLoop/AgenticLoop.ts
  • packages/agents/src/core/agenticLoop/__tests__/agenticLoop.integration.test.ts
  • packages/cli/src/ui/hooks/geminiStream/useStreamEventHandlers.ts
  • packages/agents/src/scheduler/confirmation-coordinator.ts
📚 Learning: 2026-03-26T00:49:43.150Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1778
File: packages/cli/src/auth/__tests__/auth-flow-orchestrator.spec.ts:309-324
Timestamp: 2026-03-26T00:49:43.150Z
Learning: In this repository’s Jest (or Jest-like) test files, it is acceptable to use `expect(promiseReturningFunction).resolves.not.toThrow()` when the function returns `Promise<void>`. Do not flag this as an incorrect or suboptimal matcher; for `Promise<void>` it is functionally equivalent to using `resolves.toBeUndefined()` to assert successful resolution.

Applied to files:

  • packages/agents/src/core/agenticLoop/__tests__/agenticLoop.integration.test.ts
📚 Learning: 2026-03-25T12:57:21.017Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1768
File: packages/cli/src/ui/hooks/useCoreEventHandlers.ts:71-78
Timestamp: 2026-03-25T12:57:21.017Z
Learning: In files under `packages/cli/src/ui/hooks/`, it is OK for a `useEffect` to register process-level cleanup via `registerCleanup(consolePatcher.cleanup)` without returning a React cleanup function (e.g., without `return () => consolePatcher.cleanup()`). Treat this as an intentional pattern: `registerCleanup()` is the project’s mechanism for cleanup that is meant to persist beyond React unmount/re-render, so do not flag the missing `return` as a leak/bug.

Applied to files:

  • packages/cli/src/ui/hooks/geminiStream/useStreamEventHandlers.ts
📚 Learning: 2026-03-26T22:12:58.549Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1780
File: packages/cli/src/ui/hooks/geminiStream/useStreamEventHandlers.ts:1-5
Timestamp: 2026-03-26T22:12:58.549Z
Learning: When reviewing this repo, do not flag these files for missing "upstream" Google LLC copyright. For `useGeminiStream.ts` and the extracted geminiStream-hook modules (under `packages/cli/src/ui/hooks/geminiStream/`), ensure the copyright header is `Copyright 2025 Vybestack LLC`—these files were already updated to Vybestack LLC before PR `#1780` and the decomposition outputs correctly use Vybestack LLC.

Applied to files:

  • packages/cli/src/ui/hooks/geminiStream/useStreamEventHandlers.ts
🔇 Additional comments (21)
packages/agents/src/core/agenticLoop/AgenticLoop.ts (7)

62-82: LGTM!


89-140: LGTM!


142-200: LGTM!


202-296: LGTM!


298-390: LGTM!


519-543: The try/finally pattern correctly ensures cleanup on early generator exit.

The normalExit flag combined with the finally block guarantees that:

  • If the consumer abandons the generator early (e.g., break from for await...of), scheduler.cancelAll() is called and resources are cleaned up
  • forwardingActive, queue.close(), cleanupAbortListener(), and disposeScheduler() always execute regardless of exit path

This addresses the high-severity resource leak concern identified in the PR discussion.


546-598: LGTM!

packages/agents/src/scheduler/confirmation-coordinator.ts (8)

54-114: LGTM!


126-199: LGTM!


200-300: LGTM!


346-378: Simplified onConfirm delegation removes redundant bus response path.

The wrapped onConfirm now directly delegates to handleConfirmationResponse(), which centralizes outcome handling and bus publishing. This eliminates the previous pattern where the callback would publish to the bus before calling the response handler.


380-472: LGTM!


520-522: Correctly defers originalOnConfirm invocation for ModifyWithEditor.

The condition prevents calling the tool's original confirmation callback during ModifyWithEditor, which is a transitional state. The callback is preserved via pendingOriginalConfirmHandlers and invoked only when the user makes a final decision (approve/cancel) after editing.


606-707: LGTM!


709-876: LGTM!

packages/agents/src/core/agenticLoop/__tests__/agenticLoop.integration.test.ts (1)

1076-1123: LGTM!

packages/agents/src/scheduler/confirmation-coordinator.test.ts (3)

83-118: LGTM!


269-304: LGTM!


932-1055: LGTM!

packages/cli/src/ui/hooks/geminiStream/useStreamEventHandlers.ts (2)

112-127: LGTM!


446-446: LGTM!

@github-actions

github-actions Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Summary

Package Lines Statements Functions Branches
CLI 55.3% 55.3% 56.75% 81.77%
Core 75.87% 75.87% 71.97% 82.69%
CLI Package - Full Text Report
-------------------|---------|----------|---------|---------|-------------------
File               | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-------------------|---------|----------|---------|---------|-------------------
All files          |    55.3 |    81.77 |   56.75 |    55.3 |                   
 src               |   70.26 |     65.9 |   89.09 |   70.26 |                   
  cli.tsx          |   57.15 |    60.12 |   78.57 |   57.15 | ...1264,1272-1291 
  ...st-helpers.ts |     100 |       60 |     100 |     100 | 23-34             
  ...ractiveCli.ts |   90.37 |     84.9 |   86.66 |   90.37 | ...04-209,282-284 
  ...liCommands.ts |   97.18 |    63.63 |     100 |   97.18 | 39-40             
  ...CliSupport.ts |   80.04 |    65.04 |      95 |   80.04 | ...76-478,500-501 
  ...ActiveAuth.ts |      60 |    68.42 |     100 |      60 | ...91-106,110-119 
 src/auth          |   98.07 |       80 |     100 |   98.07 |                   
  ...gs-adapter.ts |   98.07 |       80 |     100 |   98.07 | 76                
 src/commands      |   78.35 |      100 |   44.44 |   78.35 |                   
  extensions.tsx   |   55.88 |      100 |       0 |   55.88 | 25-38,42          
  hooks.ts         |   61.53 |      100 |       0 |   61.53 | 14-17,20          
  mcp.ts           |   94.11 |      100 |      50 |   94.11 | 26                
  skills.tsx       |     100 |      100 |     100 |     100 |                   
  utils.ts         |     100 |      100 |     100 |     100 |                   
 ...nds/extensions |    74.1 |    92.93 |   67.18 |    74.1 |                   
  config.ts        |   94.61 |    91.83 |     100 |   94.61 | ...66-167,196-201 
  disable.ts       |     100 |      100 |     100 |     100 |                   
  enable.ts        |     100 |      100 |     100 |     100 |                   
  install.ts       |   80.48 |    76.92 |    87.5 |   80.48 | ...63,199,202-209 
  link.ts          |   64.81 |    83.33 |      25 |   64.81 | 31,54-65,67-72    
  list.ts          |      90 |      100 |   33.33 |      90 | 35-37             
  new.ts           |     100 |      100 |     100 |     100 |                   
  settings.ts      |   72.13 |      100 |      70 |   72.13 | 32-80,218-222,225 
  uninstall.ts     |   78.43 |      100 |   66.66 |   78.43 | 54-59,62-66       
  update.ts        |   10.19 |      100 |       0 |   10.19 | ...71-190,192-197 
  utils.ts         |   13.33 |      100 |       0 |   13.33 | 29-60             
  validate.ts      |   89.36 |     87.5 |      75 |   89.36 | 50-53,60,112-116  
 .../hooks/scripts |       0 |        0 |       0 |       0 |                   
  on-start.js      |       0 |        0 |       0 |       0 | 1-8               
 ...les/mcp-server |       0 |        0 |       0 |       0 |                   
  example.js       |       0 |        0 |       0 |       0 | 1-60              
 ...commands/hooks |    7.59 |      100 |       0 |    7.59 |                   
  migrate.ts       |    7.59 |      100 |       0 |    7.59 | ...90-200,202-204 
 src/commands/mcp  |   96.95 |    86.15 |   94.44 |   96.95 |                   
  add.ts           |   99.56 |    93.33 |     100 |   99.56 | 142               
  list.ts          |   90.51 |    82.14 |      80 |   90.51 | ...13-115,148-150 
  remove.ts        |     100 |    71.42 |     100 |     100 | 21-25             
 ...ommands/skills |   60.98 |     92.3 |   31.25 |   60.98 |                   
  disable.ts       |      54 |      100 |   33.33 |      54 | 40-52,54-63       
  enable.ts        |   72.22 |      100 |   33.33 |   72.22 | 33-37,39-43       
  install.ts       |   42.69 |      100 |      25 |   42.69 | ...71-100,102-109 
  list.ts          |   84.93 |       80 |   33.33 |   84.93 | ...9,92-96,98-100 
  uninstall.ts     |   57.89 |      100 |   33.33 |   57.89 | 47-64,66-71       
 src/config        |   86.44 |    84.76 |    86.9 |   86.44 |                   
  ...deResolver.ts |   94.54 |    95.23 |     100 |   94.54 | 50-52             
  auth.ts          |   84.61 |    82.35 |     100 |   84.61 | 18-19,22-23,53-54 
  cliArgParser.ts  |   92.85 |    89.36 |     100 |   92.85 | ...24,285,287-290 
  config.ts        |     100 |      100 |     100 |     100 |                   
  configBuilder.ts |   95.41 |    95.52 |   66.66 |   95.41 | ...18-219,260-261 
  ...mentLoader.ts |   83.78 |    60.86 |     100 |   83.78 | ...23-125,133-136 
  extension.ts     |   75.07 |    88.07 |   78.04 |   75.07 | ...12-913,916-917 
  ...iveContext.ts |   93.75 |    91.66 |     100 |   93.75 | 79,81,87-92,232   
  ...iateConfig.ts |   96.39 |    97.05 |     100 |   96.39 | 53,150-152        
  keyBindings.ts   |     100 |      100 |     100 |     100 |                   
  ...rverConfig.ts |   83.33 |    94.44 |     100 |   83.33 | 23-39             
  paths.ts         |     100 |      100 |     100 |     100 |                   
  policy.ts        |   80.76 |      100 |      50 |   80.76 | 47-51             
  ...figRuntime.ts |   88.65 |    84.21 |     100 |   88.65 | ...22-429,440-443 
  ...eBootstrap.ts |   91.78 |     87.8 |   97.22 |   91.78 | ...00-802,811-812 
  ...Resolution.ts |   44.01 |    72.41 |    62.5 |   44.01 | ...65-284,296-304 
  ...pplication.ts |   85.03 |       65 |     100 |   85.03 | ...46,148-154,178 
  ...elResolver.ts |   90.38 |    73.68 |     100 |   90.38 | 40,42-43,70,79    
  sandboxConfig.ts |   69.81 |    51.48 |   88.46 |   69.81 | ...80-581,593-594 
  ...oxProfiles.ts |    8.53 |      100 |       0 |    8.53 | 47-48,51-129      
  settingPaths.ts  |     100 |      100 |     100 |     100 |                   
  ...validation.ts |   86.95 |    80.62 |     100 |   86.95 | ...02,404,406,408 
  settings.ts      |   81.81 |    82.29 |   65.21 |   81.81 | ...40-441,496-497 
  ...ingsLegacy.ts |    70.9 |    81.81 |     100 |    70.9 | 48-52,56-67       
  ...ingsLoader.ts |   94.11 |    81.39 |     100 |   94.11 | ...78,108-109,137 
  settingsMerge.ts |   99.51 |    95.65 |     100 |   99.51 | 128-129           
  ...Migrations.ts |   95.67 |    91.48 |     100 |   95.67 | 22-24,48-49,55-56 
  ...ingsSchema.ts |     100 |      100 |     100 |     100 |                   
  ...Governance.ts |   95.83 |    90.62 |     100 |   95.83 | 54,126-129        
  ...tedFolders.ts |   95.58 |       96 |     100 |   95.58 | 93,120-126        
  welcomeConfig.ts |   22.41 |      100 |       0 |   22.41 | ...71,74-79,82-83 
  yargsOptions.ts  |   98.65 |    94.44 |   85.71 |   98.65 | 116,125-128       
 ...fig/extensions |   76.18 |    84.44 |   87.61 |   76.18 |                   
  consent.ts       |   88.03 |    85.71 |     100 |   88.03 | ...77-378,381-382 
  ...ionConsent.ts |   87.38 |    76.66 |     100 |   87.38 | ...,64-67,113-116 
  ...Enablement.ts |    93.9 |       96 |     100 |    93.9 | ...08-214,277-279 
  ...sionLoader.ts |   93.33 |    89.36 |     100 |   93.33 | ...86-187,195-199 
  ...onSettings.ts |     100 |      100 |     100 |     100 |                   
  github.ts        |   62.19 |    81.73 |   70.83 |   62.19 | ...41-642,652-655 
  hookSchema.ts    |     100 |      100 |     100 |     100 |                   
  ...ntegration.ts |   55.31 |    84.78 |      50 |   55.31 | ...61,402,426-427 
  ...ingsPrompt.ts |      73 |    94.73 |      80 |      73 | 92-121            
  ...ngsStorage.ts |   84.77 |    75.92 |     100 |   84.77 | ...90-291,309-312 
  update.ts        |   69.52 |    52.94 |   85.71 |   69.52 | ...73-201,218-226 
  ...ableSchema.ts |     100 |      100 |     100 |     100 |                   
  variables.ts     |   95.55 |       90 |     100 |   95.55 | 33-34             
 ...ettings-schema |   99.78 |       60 |     100 |   99.78 |                   
  schema-core.ts   |     100 |      100 |     100 |     100 |                   
  ...extensions.ts |     100 |      100 |     100 |     100 |                   
  ...a-security.ts |   99.44 |       50 |     100 |   99.44 | 16-17             
  schema-tail.ts   |   99.52 |       50 |     100 |   99.52 | 13-14             
  schema-ui.ts     |     100 |      100 |     100 |     100 |                   
  schema.ts        |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/constants     |     100 |      100 |     100 |     100 |                   
  historyLimits.ts |     100 |      100 |     100 |     100 |                   
 src/extensions    |   66.86 |    61.81 |      75 |   66.86 |                   
  ...utoUpdater.ts |   66.86 |    61.81 |      75 |   66.86 | ...56-457,466,468 
 src/generated     |     100 |      100 |     100 |     100 |                   
  git-commit.ts    |     100 |      100 |     100 |     100 |                   
 ...egration-tests |   91.93 |     86.2 |    92.3 |   91.93 |                   
  test-utils.ts    |   91.93 |     86.2 |    92.3 |   91.93 | ...45,263-264,274 
 src/patches       |       0 |        0 |       0 |       0 |                   
  is-in-ci.ts      |       0 |        0 |       0 |       0 | 1-17              
 ...viders/logging |   89.31 |     92.5 |   69.23 |   89.31 |                   
  ...rvice-impl.ts |   44.44 |      100 |       0 |   44.44 | 21-22,25-30,36-37 
  git-stats.ts     |   96.46 |     92.5 |     100 |   96.46 | 154-155,195-196   
 src/runtime       |   97.65 |       92 |     100 |   97.65 |                   
  ...imeAdapter.ts |   97.65 |       92 |     100 |   97.65 | ...18-219,308-309 
 src/services      |   84.56 |    83.63 |   93.93 |   84.56 |                   
  ...mandLoader.ts |   79.75 |       75 |   83.33 |   79.75 | ...10-124,168-186 
  ...andService.ts |     100 |      100 |     100 |     100 |                   
  ...mandLoader.ts |   91.77 |    86.53 |     100 |   91.77 | ...10-215,300-307 
  ...omptLoader.ts |   74.52 |    77.08 |     100 |   74.52 | ...87,202,259-260 
  performResume.ts |   89.11 |    89.18 |     100 |   89.11 | ...61-264,270-271 
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 ...mpt-processors |      98 |    92.98 |     100 |      98 |                   
  ...tProcessor.ts |     100 |      100 |     100 |     100 |                   
  ...lProcessor.ts |   97.88 |    92.45 |     100 |   97.88 | 80-81,265-266     
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...o-continuation |   86.56 |    84.09 |   94.73 |   86.56 |                   
  ...ionService.ts |   86.56 |    84.09 |   94.73 |   86.56 | ...08,575,601-602 
 src/test-utils    |    76.7 |     90.9 |   27.27 |    76.7 |                   
  async.ts         |       0 |        0 |       0 |       0 | 1-34              
  ...eExtension.ts |     100 |      100 |     100 |     100 |                   
  ...omMatchers.ts |   18.75 |      100 |       0 |   18.75 | 17-45             
  ...andContext.ts |     100 |      100 |     100 |     100 |                   
  render.tsx       |   94.84 |    96.66 |      25 |   94.84 | ...51-156,259-260 
  ...e-testing.tsx |       0 |        0 |       0 |       0 | 1-56              
  ...iderConfig.ts |       0 |        0 |       0 |       0 | 1-19              
 src/ui            |   37.77 |    93.44 |   30.48 |   37.77 |                   
  App.tsx          |   37.25 |      100 |       0 |   37.25 | 64-91,97-104      
  AppContainer.tsx |     100 |      100 |     100 |     100 |                   
  ...erRuntime.tsx |   14.28 |      100 |   16.66 |   14.28 | 66-399            
  ...tionNudge.tsx |       8 |      100 |       0 |       8 | 29-104            
  colors.ts        |   37.14 |      100 |   20.33 |   37.14 | ...03-304,306-307 
  constants.ts     |     100 |      100 |     100 |     100 |                   
  debug.ts         |     100 |      100 |     100 |     100 |                   
  ...derOptions.ts |     100 |      100 |     100 |     100 |                   
  keyMatchers.ts   |   88.63 |       84 |     100 |   88.63 | 18,20-21,28-29    
  ...ntsEnabled.ts |     100 |      100 |     100 |     100 |                   
  ...submission.ts |     100 |      100 |     100 |     100 |                   
  ...tic-colors.ts |   78.94 |      100 |      60 |   78.94 | 15-16,24-25       
  textConstants.ts |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/ui/commands   |   70.02 |    75.23 |   76.53 |   70.02 |                   
  aboutCommand.ts  |   82.84 |    51.51 |   91.66 |   82.84 | ...92-193,195-196 
  authCommand.ts   |   49.52 |    77.33 |   58.33 |   49.52 | ...51-654,665-707 
  ...urlCommand.ts |      30 |      100 |       0 |      30 | 20-40             
  bugCommand.ts    |   71.23 |    30.76 |     100 |   71.23 | ...99-110,145-153 
  chatCommand.ts   |   69.72 |    74.62 |   66.66 |   69.72 | ...50-551,599-610 
  clearCommand.ts  |   88.88 |    88.88 |     100 |   88.88 | 96-103            
  ...essCommand.ts |    97.7 |    89.28 |     100 |    97.7 | 41,63-64          
  ...nueCommand.ts |     100 |      100 |     100 |     100 |                   
  copyCommand.ts   |     100 |      100 |     100 |     100 |                   
  debugCommands.ts |   13.29 |      100 |       0 |   13.29 | ...50,457,464,471 
  ...icsCommand.ts |   74.63 |    49.52 |   94.11 |   74.63 | ...62-565,580-585 
  ...ryCommand.tsx |    89.5 |    84.84 |     100 |    89.5 | ...29-137,204-212 
  docsCommand.ts   |     100 |      100 |     100 |     100 |                   
  ...extCommand.ts |   96.27 |       90 |     100 |   96.27 | 216-221           
  editorCommand.ts |     100 |      100 |     100 |     100 |                   
  ...onsCommand.ts |   41.27 |    88.09 |    62.5 |   41.27 | ...24-381,391-539 
  ...ionSection.ts |   83.33 |    93.33 |     100 |   83.33 | 28-34             
  helpCommand.ts   |     100 |      100 |     100 |     100 |                   
  hooksCommand.ts  |   89.62 |    87.27 |     100 |   89.62 | ...54,344-345,459 
  ideCommand.ts    |   69.87 |    73.52 |   69.23 |   69.87 | ...36-237,240-255 
  initCommand.ts   |   80.26 |    71.42 |   66.66 |   80.26 | 36-40,42-89       
  keyCommand.ts    |   89.87 |    80.76 |     100 |   89.87 | ...92,415-416,515 
  ...ileCommand.ts |    10.9 |      100 |       0 |    10.9 | 22-46,53-141      
  ...ingCommand.ts |   10.27 |      100 |       0 |   10.27 | ...19-572,589-601 
  logoutCommand.ts |   15.87 |      100 |       0 |   15.87 | 21-84             
  lspCommand.ts    |    90.9 |    87.17 |     100 |    90.9 | ...18-123,147-149 
  mcpCommand.ts    |    86.9 |     82.3 |    91.3 |    86.9 | ...65-666,748-753 
  memoryCommand.ts |   87.45 |    75.47 |     100 |   87.45 | ...48,236-250,299 
  modelCommand.ts  |   98.92 |    93.02 |     100 |   98.92 | 120               
  mouseCommand.ts  |     100 |      100 |     100 |     100 |                   
  ...onsCommand.ts |    93.9 |    88.88 |     100 |    93.9 | 58-62             
  ...iesCommand.ts |   97.05 |    80.55 |     100 |   97.05 | 27,40-41          
  ...acyCommand.ts |   61.53 |      100 |       0 |   61.53 | 22-26             
  ...ileCommand.ts |   57.43 |    62.74 |   73.07 |   57.43 | ...1114,1135-1151 
  ...derCommand.ts |   56.96 |    31.57 |   88.88 |   56.96 | ...89-290,299-304 
  quitCommand.ts   |   36.66 |      100 |       0 |   36.66 | 17-36             
  ...oreCommand.ts |   90.16 |    82.85 |     100 |   90.16 | ...69-174,207-212 
  setCommand.ts    |   76.12 |       75 |   81.25 |   76.12 | ...46-551,628-641 
  ...ngsCommand.ts |     100 |      100 |     100 |     100 |                   
  setupCommand.ts  |     100 |      100 |     100 |     100 |                   
  ...hubCommand.ts |   90.47 |    82.85 |     100 |   90.47 | ...13-216,223-227 
  skillsCommand.ts |   82.78 |       75 |     100 |   82.78 | ...91-292,305-306 
  statsCommand.ts  |    71.4 |       70 |      80 |    71.4 | ...57-566,574-655 
  ...entCommand.ts |   76.72 |    69.73 |   81.81 |   76.72 | ...10-616,627-633 
  tasksCommand.ts  |   78.53 |    78.78 |     100 |   78.53 | ...78-186,247-254 
  ...tupCommand.ts |     100 |      100 |     100 |     100 |                   
  themeCommand.ts  |     100 |      100 |     100 |     100 |                   
  todoCommand.ts   |   76.42 |    72.72 |   88.23 |   76.42 | ...1100,1108-1112 
  ...matCommand.ts |   26.66 |      100 |       0 |   26.66 | 33-92             
  ...keyCommand.ts |   98.88 |     92.3 |     100 |   98.88 | 34                
  ...ileCommand.ts |    99.1 |    94.11 |     100 |    99.1 | 36                
  toolsCommand.ts  |   86.56 |    76.47 |     100 |   86.56 | ...59,294,325-326 
  types.ts         |     100 |      100 |     100 |     100 |                   
  ...ileCommand.ts |   27.77 |        0 |       0 |   27.77 | 11-23             
  vimCommand.ts    |   44.44 |      100 |       0 |   44.44 | 15-25             
 ...ommands/schema |   96.27 |    92.99 |    92.3 |   96.27 |                   
  index.ts         |   96.49 |    93.58 |     100 |   96.49 | ...16-420,431-432 
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 src/ui/components |   11.69 |    39.31 |    7.58 |   11.69 |                   
  AboutBox.tsx     |   12.19 |      100 |       0 |   12.19 | ...,76-98,102-130 
  AnsiOutput.tsx   |    8.33 |      100 |       0 |    8.33 | 25-90             
  AppHeader.tsx    |   21.87 |      100 |       0 |   21.87 | 26-56             
  AsciiArt.ts      |     100 |      100 |     100 |     100 |                   
  AuthDialog.tsx   |    4.36 |      100 |       0 |    4.36 | ...38-263,266-347 
  ...nProgress.tsx |       0 |        0 |       0 |       0 | 1-63              
  ...Indicator.tsx |   15.15 |      100 |       0 |   15.15 | 17-47             
  ...firmation.tsx |   15.38 |      100 |       0 |   15.38 | 59-134,143-208    
  ...tsDisplay.tsx |   10.37 |      100 |       0 |   10.37 | ...70-110,114-168 
  CliSpinner.tsx   |       0 |        0 |       0 |       0 | 1-22              
  Composer.tsx     |    7.14 |      100 |       0 |    7.14 | 16-29,42-97       
  ...entPrompt.tsx |   18.75 |      100 |       0 |   18.75 | 21-51             
  ...ryDisplay.tsx |   21.05 |      100 |       0 |   21.05 | 17-35             
  ...ryDisplay.tsx |    4.65 |      100 |       0 |    4.65 | 29-107,110-174    
  ...geDisplay.tsx |       0 |        0 |       0 |       0 | 1-37              
  ...gProfiler.tsx |   16.86 |      100 |       0 |   16.86 | ...73-118,122-224 
  ...esDisplay.tsx |   10.52 |      100 |       0 |   10.52 | 24-82             
  ...ogManager.tsx |    5.54 |      100 |       0 |    5.54 | 71-782,786-810    
  ...ngsDialog.tsx |   12.56 |      100 |       0 |   12.56 | ...48-172,176-247 
  ...rBoundary.tsx |   10.16 |      100 |       0 |   10.16 | ...19-164,182-195 
  ...ustDialog.tsx |   16.34 |      100 |       0 |   16.34 | ...2,70-81,84-143 
  Footer.tsx       |   11.06 |        0 |       0 |   11.06 | ...24-693,698-715 
  ...ngSpinner.tsx |    40.9 |      100 |       0 |    40.9 | 31-47             
  Header.tsx       |    17.5 |      100 |       0 |    17.5 | 22-62             
  Help.tsx         |    6.84 |      100 |       0 |    6.84 | ...87-190,194-206 
  ...emDisplay.tsx |   12.01 |      100 |       0 |   12.01 | 55-239,242-280    
  ...usDisplay.tsx |       0 |        0 |       0 |       0 | 1-47              
  InputPrompt.tsx  |   53.38 |     42.1 |   67.34 |   53.38 | ...1639-1644,1662 
  ...tsDisplay.tsx |    4.36 |      100 |       0 |    4.36 | ...32-226,229-292 
  ...utManager.tsx |       0 |        0 |       0 |       0 | 1-99              
  ...ileDialog.tsx |    8.33 |      100 |       0 |    8.33 | ...8,72-81,85-152 
  ...Indicator.tsx |   13.84 |      100 |       0 |   13.84 | 20-24,34-96       
  ...ingDialog.tsx |    4.92 |      100 |       0 |    4.92 | ...65-382,386-435 
  ...geDisplay.tsx |       0 |        0 |       0 |       0 | 1-41              
  ModelDialog.tsx  |     3.6 |      100 |       0 |     3.6 | ...66-739,743-829 
  ...tsDisplay.tsx |    3.82 |      100 |       0 |    3.82 | 32-205,208-259    
  ...fications.tsx |   17.32 |      100 |       0 |   17.32 | ...11-142,145-180 
  ...odeDialog.tsx |     7.4 |      100 |       0 |     7.4 | 32-141            
  ...ustDialog.tsx |    5.53 |      100 |       0 |    5.53 | ...36-273,278-313 
  PrepareLabel.tsx |   13.33 |      100 |       0 |   13.33 | 20-48             
  ...ailDialog.tsx |   14.15 |      100 |       0 |   14.15 | ...53-359,363-436 
  ...ineEditor.tsx |    4.15 |      100 |       0 |    4.15 | ...68-554,557-632 
  ...istDialog.tsx |     4.6 |      100 |       0 |     4.6 | ...88-525,528-614 
  ...derDialog.tsx |    2.63 |      100 |       0 |    2.63 | 60-408,411-426    
  ...Indicator.tsx |       0 |        0 |       0 |       0 | 1-21              
  ...eKeyInput.tsx |       0 |        0 |       0 |       0 | 1-149             
  ...serDialog.tsx |    9.56 |      100 |       0 |    9.56 | ...52-603,611-670 
  ...ryDisplay.tsx |      50 |      100 |       0 |      50 | 15-17             
  ...ngsDialog.tsx |    1.03 |      100 |       0 |    1.03 | ...1738,1743-2800 
  ...putPrompt.tsx |   14.28 |      100 |       0 |   14.28 | 19-58             
  ...Indicator.tsx |   44.44 |      100 |       0 |   44.44 | 12-17             
  ...MoreLines.tsx |   30.43 |      100 |       0 |   30.43 | 18-38             
  StatsDisplay.tsx |    8.98 |      100 |       0 |    8.98 | ...40-445,449-500 
  ...usDisplay.tsx |       0 |        0 |       0 |       0 | 1-59              
  StickyHeader.tsx |    7.14 |      100 |       0 |    7.14 | 20-78             
  ...nsDisplay.tsx |    5.83 |      100 |       0 |    5.83 | 39-91,105-181     
  Table.tsx        |    7.54 |      100 |       0 |    7.54 | 27-89             
  ThemeDialog.tsx  |    3.96 |      100 |       0 |    3.96 | 51-441,444-500    
  ...dGradient.tsx |      25 |      100 |       0 |      25 | 27-46             
  Tips.tsx         |      16 |      100 |       0 |      16 | 17-45             
  TodoPanel.tsx    |     5.9 |      100 |       0 |     5.9 | ...87-244,247-296 
  ...tsDisplay.tsx |   10.05 |      100 |       0 |   10.05 | ...88-227,230-259 
  ToolsDialog.tsx  |   10.63 |      100 |       0 |   10.63 | ...5,41-47,50-123 
  ...ification.tsx |   36.36 |      100 |       0 |   36.36 | 15-22             
  ...ionDialog.tsx |    6.08 |      100 |       0 |    6.08 | 18-104,110-161    
  todo-utils.ts    |       0 |        0 |       0 |       0 | 1-7               
 ...leCreateWizard |   18.43 |       50 |       0 |   18.43 |                   
  ...aramsStep.tsx |   11.34 |      100 |       0 |   11.34 | ...34-247,259-343 
  ...ationStep.tsx |    7.12 |      100 |       0 |    7.12 | ...08-544,556-624 
  ...onfigStep.tsx |   12.35 |      100 |       0 |   12.35 | 19-25,36-117      
  ...electStep.tsx |    9.73 |      100 |       0 |    9.73 | ...13-280,296-341 
  ...ationMenu.tsx |       0 |        0 |       0 |       0 | 1-102             
  ...eSaveStep.tsx |    7.45 |      100 |       0 |    7.45 | ...76-305,317-396 
  ...ssSummary.tsx |   12.12 |      100 |       0 |   12.12 | 23-88             
  ...electStep.tsx |   16.92 |      100 |       0 |   16.92 | 28-97             
  TextInput.tsx    |    6.56 |      100 |       0 |    6.56 | ...01-111,119-202 
  constants.ts     |     100 |      100 |     100 |     100 |                   
  index.tsx        |   14.51 |      100 |       0 |   14.51 | ...94-223,232-316 
  types.ts         |     100 |      100 |     100 |     100 |                   
  utils.ts         |    5.15 |      100 |       0 |    5.15 | ...53-356,361-378 
  validation.ts    |   11.23 |      100 |       0 |   11.23 | ...97-104,107-111 
 ...gentManagement |    4.22 |      100 |       0 |    4.22 |                   
  ...entWizard.tsx |    2.91 |      100 |       0 |    2.91 | 30-232,237-312    
  ...ionWizard.tsx |    1.44 |      100 |       0 |    1.44 | 30-592,595-676    
  ...eteDialog.tsx |    5.88 |      100 |       0 |    5.88 | 14-94,104-147     
  ...tEditForm.tsx |    1.77 |      100 |       0 |    1.77 | 30-619,622-640    
  ...tListMenu.tsx |    2.94 |      100 |       0 |    2.94 | 17-266,269-350    
  ...tMainMenu.tsx |   16.66 |      100 |       0 |   16.66 | 22-62             
  ...gerDialog.tsx |    2.39 |      100 |       0 |    2.39 | 29-601,604-680    
  ...tShowView.tsx |    4.76 |      100 |       0 |    4.76 | 25-183,186-243    
  index.ts         |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...comeOnboarding |   14.36 |        0 |       0 |   14.36 |                   
  ...ethodStep.tsx |   22.47 |      100 |       0 |   22.47 | 44-129            
  ...ationStep.tsx |    7.35 |      100 |       0 |    7.35 | ...1,59-95,98-177 
  ...etionStep.tsx |    9.84 |      100 |       0 |    9.84 | ...,89-99,103-179 
  ...electStep.tsx |   12.12 |      100 |       0 |   12.12 | ...3,67-75,79-143 
  ...electStep.tsx |   34.48 |      100 |       0 |   34.48 | 51-120            
  SkipExitStep.tsx |    12.5 |      100 |       0 |    12.5 | 18-59             
  ...omeDialog.tsx |   11.76 |      100 |       0 |   11.76 | 51-118,121-166    
  WelcomeStep.tsx  |    10.2 |      100 |       0 |    10.2 | 23-74             
  index.ts         |       0 |        0 |       0 |       0 | 1-13              
 ...nents/messages |   18.63 |    88.63 |   13.43 |   18.63 |                   
  ...onMessage.tsx |   12.28 |      100 |       0 |   12.28 | 24-86             
  DiffRenderer.tsx |    3.33 |      100 |       0 |    3.33 | ...76-407,410-428 
  ErrorMessage.tsx |   22.22 |      100 |       0 |   22.22 | 16-31             
  ...niMessage.tsx |   14.51 |      100 |       0 |   14.51 | 28-95             
  ...geContent.tsx |   20.83 |      100 |       0 |   20.83 | 26-46             
  InfoMessage.tsx  |   19.23 |      100 |       0 |   19.23 | 19-41             
  ...rlMessage.tsx |   11.36 |      100 |       0 |   11.36 | 18-65             
  ...geMessage.tsx |     100 |      100 |     100 |     100 |                   
  ...ckDisplay.tsx |      20 |      100 |       0 |      20 | 43-64             
  ...onMessage.tsx |    3.18 |      100 |       0 |    3.18 | 40-524,537-616    
  ...upMessage.tsx |     7.5 |      100 |       0 |     7.5 | ...73-270,274-349 
  ToolMessage.tsx  |    4.38 |      100 |       0 |    4.38 | 40-340,356-426    
  ...ltDisplay.tsx |   91.53 |    85.71 |     100 |   91.53 | 39-53,222-224     
  ToolShared.tsx   |   64.61 |       90 |   33.33 |   64.61 | 78-99,102-105     
  UserMessage.tsx  |     100 |      100 |     100 |     100 |                   
  ...llMessage.tsx |   36.36 |      100 |       0 |   36.36 | 17-25             
  ...ngMessage.tsx |   26.31 |      100 |       0 |   26.31 | 17-32             
 ...ponents/shared |   41.16 |    63.55 |   40.25 |   41.16 |                   
  ...ctionList.tsx |    4.31 |      100 |       0 |    4.31 | 36-123,128-206    
  MaxSizedBox.tsx  |   49.89 |     58.1 |      75 |   49.89 | ...63-666,670-673 
  ...tonSelect.tsx |   12.76 |      100 |       0 |   12.76 | 66-113            
  ...lableList.tsx |    5.15 |      100 |       0 |    5.15 | 40-267            
  ...ist.hooks.tsx |    3.84 |      100 |       0 |    3.84 | ...68-793,796-833 
  ...lizedList.tsx |   11.11 |      100 |       0 |   11.11 | 28-108            
  ...List.types.ts |     100 |      100 |     100 |     100 |                   
  ...operations.ts |   75.54 |    48.14 |     100 |   75.54 | ...32-233,256-265 
  ...er-reducer.ts |   28.25 |    51.11 |   33.33 |   28.25 | ...30,632,644,687 
  buffer-types.ts  |     100 |      100 |     100 |     100 |                   
  text-buffer.ts   |   71.75 |    89.18 |   27.86 |   71.75 | ...35-637,656-662 
  ...formations.ts |   42.42 |    71.42 |      80 |   42.42 | ...28-135,159-205 
  ...n-handlers.ts |   33.99 |    61.53 |   23.25 |   33.99 | ...47-755,758-762 
  ...er-actions.ts |   93.84 |     87.5 |     100 |   93.84 | 91-93,100         
  visual-layout.ts |    90.2 |    71.73 |     100 |    90.2 | ...48-350,372-373 
  ...navigation.ts |   53.01 |    60.93 |   73.68 |   53.01 | ...40-361,384-406 
 ...mponents/views |    8.89 |      100 |       0 |    8.89 |                   
  ChatList.tsx     |    14.7 |      100 |       0 |    14.7 | 18-53             
  ...sionsList.tsx |    7.59 |      100 |       0 |    7.59 | 19-103            
  HooksList.tsx    |    10.1 |      100 |       0 |    10.1 | ...15-126,129-144 
  SkillsList.tsx   |    5.79 |      100 |       0 |    5.79 | 18-103            
 src/ui/constants  |   55.78 |     90.9 |      50 |   55.78 |                   
  ...ollections.ts |     100 |      100 |     100 |     100 |                   
  tips.ts          |       0 |        0 |       0 |       0 | 1-164             
 src/ui/containers |       0 |        0 |       0 |       0 |                   
  ...ontroller.tsx |       0 |        0 |       0 |       0 | 1-362             
  UIStateShell.tsx |       0 |        0 |       0 |       0 | 1-15              
 ...ainer/builders |   98.38 |      100 |   83.33 |   98.38 |                   
  ...dUIActions.ts |     100 |      100 |     100 |     100 |                   
  buildUIState.ts  |     100 |      100 |     100 |     100 |                   
  ...onsBuilder.ts |   66.66 |      100 |       0 |   66.66 | 21-22             
  ...ateBuilder.ts |   66.66 |      100 |       0 |   66.66 | 21-22             
 ...ontainer/hooks |   55.17 |     87.1 |   56.52 |   55.17 |                   
  ...pBootstrap.ts |   94.71 |    58.33 |     100 |   94.71 | ...20-223,227-229 
  useAppDialogs.ts |   41.37 |      100 |   42.85 |   41.37 | ...63,182-398,418 
  ...ntHandlers.ts |     100 |      100 |     100 |     100 |                   
  useAppInput.ts   |    5.55 |      100 |       0 |    5.55 | 100-521,524-528   
  useAppLayout.ts  |    7.92 |      100 |       0 |    7.92 | 92-299,302-305    
  ...reenAction.ts |   13.63 |      100 |       0 |   13.63 | 23-42             
  ...nSelection.ts |      20 |      100 |       0 |      20 | 27-48             
  ...hestration.ts |     100 |      100 |     100 |     100 |                   
  ...references.ts |      10 |      100 |       0 |      10 | 51-104            
  ...itHandling.ts |   89.79 |      100 |     100 |   89.79 | 131-139,143       
  ...textBridge.ts |   33.33 |      100 |       0 |   33.33 | 23-30             
  ...tartHotkey.ts |   26.66 |      100 |       0 |   26.66 | 23-33             
  ...omptSubmit.ts |     100 |      100 |     100 |     100 |                   
  ...utHandling.ts |   98.37 |     91.3 |     100 |   98.37 | 53,167            
  ...yBootstrap.ts |      30 |      100 |       0 |      30 | 28-34             
  ...eybindings.ts |   86.28 |    78.18 |     100 |   86.28 | ...06-208,252-253 
  ...easurement.ts |   15.38 |      100 |       0 |   15.38 | 45-95             
  ...reshAction.ts |   79.16 |     37.5 |     100 |   79.16 | 51,82-85,87-96    
  ...untimeSync.ts |     100 |      100 |     100 |     100 |                   
  ...elTracking.ts |   26.22 |      100 |      50 |   26.22 | 20-24,60-113      
  ...laceholder.ts |      15 |      100 |       0 |      15 | 13-18,21-34       
  ...rorTimeout.ts |   17.64 |      100 |       0 |   17.64 | 24-39             
  ...astructure.ts |   73.91 |      100 |      20 |   73.91 | 53,57,61,75-83    
  ...ebugLogger.ts |   17.24 |      100 |       0 |   17.24 | 23-51             
  ...ialization.ts |   70.45 |    84.61 |   66.66 |   70.45 | ...,72-94,127-128 
  ...sAutoReset.ts |     100 |       90 |     100 |     100 | 44                
  ...andActions.ts |     100 |      100 |     100 |     100 |                   
  ...eshManager.ts |     100 |      100 |     100 |     100 |                   
  ...uationFlow.ts |    7.93 |      100 |       0 |    7.93 | 54-150            
  ...csTracking.ts |    95.8 |    80.64 |     100 |    95.8 | ...32-133,184-185 
  ...uthBridges.ts |   17.94 |      100 |   33.33 |   17.94 | ...13-138,142-146 
 src/ui/contexts   |   52.76 |    79.45 |   51.68 |   52.76 |                   
  ...chContext.tsx |   88.23 |    66.66 |     100 |   88.23 | 27-28             
  FocusContext.tsx |       0 |        0 |       0 |       0 | 1-11              
  ...ssContext.tsx |   83.75 |    86.62 |    87.5 |   83.75 | ...19-522,575-576 
  MouseContext.tsx |   78.82 |       75 |      80 |   78.82 | ...00-101,111-117 
  ...erContext.tsx |       0 |        0 |       0 |       0 | 1-127             
  ...owContext.tsx |   21.42 |      100 |   33.33 |   21.42 | 34,40-88          
  ...meContext.tsx |   52.34 |       40 |   57.14 |   52.34 | ...95-196,201-202 
  ...lProvider.tsx |   92.05 |    73.84 |     100 |   92.05 | ...85-486,498-499 
  ...onContext.tsx |     4.4 |      100 |       0 |     4.4 | ...40-395,400-407 
  ...teContext.tsx |       0 |        0 |       0 |       0 | 1-57              
  ...gsContext.tsx |      50 |      100 |       0 |      50 | 15-20             
  ...ngContext.tsx |   42.85 |      100 |       0 |   42.85 | 15-22             
  TodoContext.tsx  |   54.54 |      100 |       0 |   54.54 | 28-31,33-36,39-40 
  TodoProvider.tsx |    3.37 |      100 |       0 |    3.37 | 27-167,170-200    
  ...llContext.tsx |     100 |      100 |       0 |     100 |                   
  ...lProvider.tsx |    6.75 |      100 |       0 |    6.75 | 24-118            
  ...nsContext.tsx |      25 |      100 |       0 |      25 | 203-214,217-222   
  ...teContext.tsx |      50 |       50 |      50 |      50 | 251-260,265-266   
  ...deContext.tsx |   11.11 |      100 |       0 |   11.11 | 30-82,85-90       
 src/ui/editors    |   98.18 |     87.5 |     100 |   98.18 |                   
  ...ngsManager.ts |   98.18 |     87.5 |     100 |   98.18 | 59                
 src/ui/hooks      |   67.29 |    86.56 |   72.29 |   67.29 |                   
  ...dProcessor.ts |    88.2 |    87.03 |   83.33 |    88.2 | ...73-175,236-248 
  ...sorHelpers.ts |    78.8 |     77.5 |   88.88 |    78.8 | ...22-823,851-857 
  ...etionUtils.ts |   53.36 |    88.23 |   64.28 |   53.36 | 57-207,335        
  index.ts         |       0 |        0 |       0 |       0 | 1-9               
  keyToAnsi.ts     |    3.92 |      100 |       0 |    3.92 | 21-79             
  ...etionUtils.ts |     100 |    66.66 |     100 |     100 | 49                
  ...dProcessor.ts |   96.29 |       80 |     100 |   96.29 | ...74-275,407-411 
  ...ndHandlers.ts |    1.63 |      100 |       0 |    1.63 | 77-660            
  ...dPathUtils.ts |    95.7 |    90.21 |     100 |    95.7 | ...25-227,271-272 
  ...dProcessor.ts |     100 |      100 |     100 |     100 |                   
  ...sorSupport.ts |   68.72 |    70.83 |   66.66 |   68.72 | ...82-285,303-310 
  ...tionEffect.ts |   90.76 |     91.3 |   92.85 |   90.76 | ...04-405,418-419 
  ...etionTypes.ts |       0 |        0 |       0 |       0 | 1                 
  toolMapping.ts   |   90.76 |    93.33 |   93.33 |   90.76 | ...95-207,226-228 
  ...nateBuffer.ts |      50 |      100 |       0 |      50 | 16-18             
  ...dScrollbar.ts |   97.82 |      100 |     100 |   97.82 | 153-155           
  ...Completion.ts |   92.52 |    89.43 |     100 |   92.52 | ...02-603,606-607 
  ...uthCommand.ts |   96.42 |    66.66 |     100 |   96.42 | 21                
  ...tIndicator.ts |     100 |     92.3 |     100 |     100 | 57                
  useBanner.ts     |     100 |    83.33 |     100 |     100 | 22,48             
  ...chedScroll.ts |   16.66 |      100 |       0 |   16.66 | 14-32             
  ...ketedPaste.ts |      20 |      100 |       0 |      20 | 20-38             
  ...ompletion.tsx |   97.24 |    82.75 |    90.9 |   97.24 | ...04-206,209-210 
  useCompletion.ts |    92.4 |     87.5 |     100 |    92.4 | 68-69,93-94,98-99 
  ...leMessages.ts |   96.15 |       90 |     100 |   96.15 | 56-57,63          
  ...ntHandlers.ts |   31.25 |      100 |     100 |   31.25 | 43-70,74-82       
  ...fileDialog.ts |   16.12 |      100 |       0 |   16.12 | 17-47             
  ...orSettings.ts |   11.86 |      100 |       0 |   11.86 | 31-87             
  ...AutoUpdate.ts |    8.33 |      100 |       0 |    8.33 | 18-64             
  ...ionUpdates.ts |   75.17 |    80.64 |   77.77 |   75.17 | ...60-261,289-303 
  ...erDetector.ts |     100 |      100 |     100 |     100 |                   
  useFocus.ts      |     100 |      100 |     100 |     100 |                   
  ...olderTrust.ts |   87.09 |     91.3 |     100 |   87.09 | 50-63,135-136     
  ...BranchName.ts |     100 |    89.47 |     100 |     100 | 60,63             
  ...oryManager.ts |   96.61 |    93.18 |     100 |   96.61 | ...70-171,214-215 
  ...splayState.ts |     100 |      100 |     100 |     100 |                   
  ...stListener.ts |   12.12 |      100 |       0 |   12.12 | 17-50             
  ...ivityTimer.ts |   76.19 |    66.66 |     100 |   76.19 | 30-35             
  ...putHistory.ts |    92.5 |    85.71 |     100 |    92.5 | 62-63,71,93-95    
  ...storyStore.ts |     100 |    94.11 |     100 |     100 | 67                
  useKeypress.ts   |   22.22 |      100 |       0 |   22.22 | 21-36             
  ...rdProtocol.ts |       0 |        0 |       0 |       0 | 1-26              
  ...fileDialog.ts |     5.3 |      100 |       0 |     5.3 | 26-72,75-148      
  ...gIndicator.ts |     100 |      100 |     100 |     100 |                   
  useLogger.ts     |   93.75 |      100 |     100 |   93.75 | 27                
  useMcpStatus.ts  |   90.69 |    66.66 |     100 |   90.69 | 19,33-35          
  ...oryMonitor.ts |     100 |      100 |     100 |     100 |                   
  ...ssageQueue.ts |     100 |      100 |     100 |     100 |                   
  useMouse.ts      |   77.77 |    66.66 |     100 |   77.77 | 31-34             
  useMouseClick.ts |     100 |      100 |     100 |     100 |                   
  ...eSelection.ts |     2.2 |      100 |       0 |     2.2 | 36-367,370-416    
  ...hestration.ts |     100 |      100 |     100 |     100 |                   
  ...oviderInfo.ts |       0 |        0 |       0 |       0 | 1-86              
  ...odifyTrust.ts |    9.09 |      100 |       0 |    9.09 | 43-134            
  ...raseCycler.ts |   79.72 |    73.33 |     100 |   79.72 | ...69,75-76,92-94 
  ...cySettings.ts |   86.72 |    83.33 |     100 |   86.72 | ...,95-99,127-138 
  ...Management.ts |    1.53 |      100 |       0 |    1.53 | 24-570,573-665    
  ...Completion.ts |   42.85 |    55.55 |      50 |   42.85 | ...89-302,333-342 
  ...iderDialog.ts |    5.66 |      100 |       0 |    5.66 | 45-83,86-158      
  ...lScheduler.ts |   80.27 |    82.19 |   78.78 |   80.27 | ...22-638,789,796 
  ...oryCommand.ts |       0 |        0 |       0 |       0 | 1-7               
  useResponsive.ts |     100 |      100 |     100 |     100 |                   
  ...ompletion.tsx |   69.56 |      100 |     100 |   69.56 | 45-47,51-66,78-81 
  useRewind.ts     |     100 |      100 |     100 |     100 |                   
  ...ectionList.ts |   89.78 |    88.88 |     100 |   89.78 | ...19-425,445-449 
  useSession.ts    |       0 |        0 |       0 |       0 | 1-23              
  ...ionBrowser.ts |     100 |      100 |     100 |     100 |                   
  ...serHelpers.ts |   95.79 |    85.21 |   97.36 |   95.79 | ...39-641,764-765 
  ...erKeypress.ts |   89.87 |    97.14 |   94.11 |   89.87 | 101-108,130-145   
  ...ngsCommand.ts |   18.75 |      100 |       0 |   18.75 | 10-25             
  ...ellHistory.ts |   92.03 |    78.78 |     100 |   92.03 | ...77,125-126,136 
  ...Completion.ts |   97.04 |    81.25 |     100 |   97.04 | 71-73,101-102     
  ...oryCommand.ts |       0 |        0 |       0 |       0 | 1-63              
  ...cessorCore.ts |   73.91 |       60 |     100 |   73.91 | ...18,154,174-201 
  ...ompletion.tsx |   96.73 |    81.39 |     100 |   96.73 | ...,92-93,335-343 
  ...leCallback.ts |     100 |      100 |     100 |     100 |                   
  ...tateAndRef.ts |   59.09 |      100 |     100 |   59.09 | 23-31             
  ...oryRefresh.ts |     100 |      100 |     100 |     100 |                   
  ...rminalSize.ts |   10.34 |      100 |       0 |   10.34 | 15-44,49-85       
  ...emeCommand.ts |    4.29 |      100 |       0 |    4.29 | 25-122,125-199    
  useTimer.ts      |    87.5 |    85.71 |     100 |    87.5 | 44-45,50-52       
  ...ntinuation.ts |   91.28 |    89.74 |     100 |   91.28 | ...25-126,153-163 
  ...ePreserver.ts |   57.14 |      100 |      80 |   57.14 | 58-76             
  ...oolsDialog.ts |    3.44 |      100 |       0 |    3.44 | 23-106,109-193    
  ...Onboarding.ts |    1.92 |      100 |       0 |    1.92 | 77-402,405-486    
  ...eMigration.ts |   11.66 |      100 |       0 |   11.66 | 15-74             
  vim.ts           |   85.73 |    87.17 |    90.9 |   85.73 | ...09-718,834-836 
 ...s/geminiStream |   86.84 |       81 |   87.03 |   86.84 |                   
  ...ersistence.ts |   98.29 |    95.12 |     100 |   98.29 | 162-164           
  ...tProcessor.ts |   77.85 |    69.56 |      80 |   77.85 | ...48-159,162-164 
  index.ts         |     100 |      100 |     100 |     100 |                   
  queryPreparer.ts |   63.15 |    18.18 |     100 |   63.15 | ...26-127,130-143 
  ...Dispatcher.ts |   90.14 |    85.45 |   91.66 |   90.14 | ...19,321-325,410 
  streamUtils.ts   |   98.98 |    94.87 |     100 |   98.98 | 349-351           
  thoughtState.ts  |   93.33 |    61.53 |     100 |   93.33 | 71-72,77-78       
  ...ionHandler.ts |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
  ...genticLoop.ts |   96.77 |    84.61 |   55.55 |   96.77 | 177-178,215,297   
  ...miniStream.ts |   99.33 |    88.23 |   85.71 |   99.33 | 87                
  ...mLifecycle.ts |   70.75 |    73.33 |   55.55 |   70.75 | ...25-240,257-262 
  ...hestration.ts |   99.18 |    81.81 |   88.88 |   99.18 | 255,276           
  ...ntHandlers.ts |   73.63 |    89.28 |     100 |   73.63 | ...30-436,445-454 
  ...treamState.ts |   79.76 |    52.17 |     100 |   79.76 | ...79,200,237-238 
  ...ubmitQuery.ts |      86 |    66.66 |   81.81 |      86 | ...30-432,434-436 
 src/ui/layouts    |   83.46 |    55.17 |   82.75 |   83.46 |                   
  ...AppLayout.tsx |   80.98 |    71.42 |   83.33 |   80.98 | ...88-202,318-356 
  ...utHelpers.tsx |    84.6 |    52.94 |    82.6 |    84.6 | ...02-803,824-852 
 ...noninteractive |      75 |      100 |    6.66 |      75 |                   
  ...eractiveUi.ts |      75 |      100 |    6.66 |      75 | 17-19,23-24,27-28 
 src/ui/privacy    |   19.41 |        0 |       0 |   19.41 |                   
  ...acyNotice.tsx |       0 |        0 |       0 |       0 | 1-139             
  ...acyNotice.tsx |       0 |        0 |       0 |       0 | 1-59              
  ...acyNotice.tsx |   12.19 |      100 |       0 |   12.19 | 16-62             
  ...acyNotice.tsx |   35.42 |      100 |       0 |   35.42 | 77-172,180-235    
  ...acyNotice.tsx |   19.35 |      100 |       0 |   19.35 | 21-52,55-57       
 src/ui/reducers   |    79.5 |    91.66 |      50 |    79.5 |                   
  appReducer.ts    |     100 |      100 |     100 |     100 |                   
  ...ionReducer.ts |       0 |        0 |       0 |       0 | 1-52              
 src/ui/state      |   54.34 |    30.76 |     100 |   54.34 |                   
  extensions.ts    |   54.34 |    30.76 |     100 |   54.34 | ...30,132-144,146 
 src/ui/themes     |   99.03 |    84.74 |   97.22 |   99.03 |                   
  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 |                   
  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 |                   
  green-screen.ts  |     100 |      100 |     100 |     100 |                   
  no-color.ts      |     100 |      100 |     100 |     100 |                   
  ...c-resolver.ts |     100 |      100 |     100 |     100 |                   
  ...tic-tokens.ts |     100 |      100 |     100 |     100 |                   
  ...-of-purple.ts |     100 |      100 |     100 |     100 |                   
  theme-compat.ts  |     100 |       50 |     100 |     100 | 79                
  theme-manager.ts |   88.55 |    82.81 |     100 |   88.55 | ...03-312,317-318 
  theme.ts         |   98.96 |       80 |    90.9 |   98.96 | 284-285,642-643   
  xcode.ts         |     100 |      100 |     100 |     100 |                   
 src/ui/types      |       0 |        0 |       0 |       0 |                   
  ...ngMetadata.ts |       0 |        0 |       0 |       0 |                   
 src/ui/utils      |   53.61 |     86.9 |   66.22 |   53.61 |                   
  ...Colorizer.tsx |    5.64 |      100 |       0 |    5.64 | ...27-168,180-249 
  ...olePatcher.ts |   72.09 |      100 |   83.33 |   72.09 | 51-62             
  ...nRenderer.tsx |   10.77 |      100 |      10 |   10.77 | 28-210,213-278    
  ...wnDisplay.tsx |     3.4 |      100 |       0 |     3.4 | ...06-731,742-746 
  ...eRenderer.tsx |   10.46 |      100 |       0 |   10.46 | ...29-380,387-420 
  ...tGenerator.ts |    76.4 |    53.84 |      60 |    76.4 | ...63,69-72,84-85 
  ...ketedPaste.ts |      60 |      100 |       0 |      60 | 13-14,17-18       
  clipboard.ts     |   97.29 |    84.61 |     100 |   97.29 | 40                
  ...boardUtils.ts |   63.09 |    76.74 |   83.33 |   63.09 | ...52-264,334-336 
  commandUtils.ts  |   93.08 |     95.4 |   95.83 |   93.08 | ...36-240,321-329 
  computeStats.ts  |     100 |      100 |     100 |     100 |                   
  displayUtils.ts  |     100 |      100 |     100 |     100 |                   
  formatters.ts    |   90.47 |    95.23 |     100 |   90.47 | 57-60             
  fuzzyFilter.ts   |     100 |    96.55 |     100 |     100 | 84                
  highlight.ts     |   77.51 |    97.29 |      60 |   77.51 | 145-171,175-180   
  ...xportUtils.ts |   98.03 |    91.66 |     100 |   98.03 | 113-114           
  ...storyItems.ts |   99.04 |    94.44 |     100 |   99.04 | 72                
  input.ts         |   64.51 |    85.71 |   33.33 |   64.51 | 20-27,53-60       
  isNarrowWidth.ts |      50 |      100 |       0 |      50 | 13-14             
  ...nUtilities.ts |   66.66 |    85.71 |     100 |   66.66 | 75-94,103-104     
  mouse.ts         |   83.51 |    71.92 |     100 |   83.51 | ...01,208,221-222 
  ...mConstants.ts |     100 |      100 |     100 |     100 |                   
  ...opDetector.ts |       0 |        0 |       0 |       0 | 1-210             
  responsive.ts    |    69.9 |    73.33 |      80 |    69.9 | ...99-107,110-125 
  rewindFileOps.ts |   91.84 |    66.66 |     100 |   91.84 | ...15-218,262-266 
  ...putHandler.ts |   83.21 |    86.79 |     100 |   83.21 | ...32-141,235-236 
  ...ityManager.ts |    94.8 |    85.71 |    90.9 |    94.8 | ...24,348,376,387 
  ...alContract.ts |     100 |      100 |     100 |     100 |                   
  terminalLinks.ts |     100 |      100 |     100 |     100 |                   
  ...colCleanup.ts |   95.45 |       75 |     100 |   95.45 | 39                
  ...lSequences.ts |     100 |      100 |     100 |     100 |                   
  terminalSetup.ts |    3.69 |      100 |       0 |    3.69 | 44-398            
  textUtils.ts     |   95.27 |    92.15 |   88.88 |   95.27 | 20-25             
  ...Formatters.ts |       0 |        0 |       0 |       0 | 1-50              
  ...icsTracker.ts |     100 |    94.44 |     100 |     100 | 38                
  ui-sizing.ts     |      16 |      100 |       0 |      16 | 11-23,26-36       
  updateCheck.ts   |     100 |    94.11 |     100 |     100 | 34,45             
 src/utils         |   61.08 |    89.27 |   74.57 |   61.08 |                   
  ...ionContext.ts |   76.92 |       75 |     100 |   76.92 | 38-41,63-66,81-84 
  ...Formatting.ts |     100 |      100 |     100 |     100 |                   
  bootstrap.ts     |     100 |      100 |     100 |     100 |                   
  checks.ts        |   33.33 |      100 |       0 |   33.33 | 23-28             
  cleanup.ts       |   67.74 |       80 |      60 |   67.74 | ...66-68,71,85-94 
  commands.ts      |      50 |    63.63 |     100 |      50 | 25-26,45,57-85    
  commentJson.ts   |    92.3 |     92.5 |     100 |    92.3 | 94-102            
  ...ScopeUtils.ts |   27.58 |      100 |       0 |   27.58 | 24-41,58-86       
  ...icSettings.ts |   92.53 |    91.66 |     100 |   92.53 | 55-56,61-64,67-70 
  ...arResolver.ts |   96.66 |    96.29 |     100 |   96.66 | 116-117           
  errors.ts        |   94.87 |       88 |     100 |   94.87 | 54-55,96-97       
  events.ts        |     100 |      100 |     100 |     100 |                   
  ...lativeTime.ts |     100 |      100 |     100 |     100 |                   
  gitUtils.ts      |   93.54 |       85 |     100 |   93.54 | 63-64,79-82       
  ...AutoUpdate.ts |   69.25 |    80.76 |   77.77 |   69.25 | ...65-266,280-345 
  ...lationInfo.ts |   99.49 |     98.3 |     100 |   99.49 | 61                
  math.ts          |   66.66 |      100 |       0 |   66.66 | 15                
  ...stentState.ts |   95.31 |    84.21 |     100 |   95.31 | 42,63-64          
  readStdin.ts     |   81.03 |    91.66 |   83.33 |   81.03 | 32-39,51-53       
  relaunch.ts      |     100 |      100 |     100 |     100 |                   
  resolvePath.ts   |   66.66 |       25 |     100 |   66.66 | 12-13,16,18-19    
  sandbox.ts       |   27.99 |    88.13 |   41.89 |   27.99 | ...0-961,979-2425 
  ...ionCleanup.ts |   86.64 |       84 |     100 |   86.64 | ...48-249,332-333 
  sessionUtils.ts  |     8.1 |      100 |       0 |     8.1 | 51-118,125-139    
  settingsUtils.ts |   85.67 |    91.34 |   94.28 |   85.67 | ...61-489,528-529 
  ...ttingSaver.ts |    1.92 |      100 |       0 |    1.92 | 11-32,40-85       
  skillSettings.ts |   86.13 |       88 |     100 |   86.13 | 99-107,134-138    
  skillUtils.ts    |   64.51 |    63.33 |   83.33 |   64.51 | ...98-199,206-227 
  spawnWrapper.ts  |     100 |      100 |     100 |     100 |                   
  ...upWarnings.ts |     100 |      100 |     100 |     100 |                   
  stdinSafety.ts   |   91.39 |    86.48 |     100 |   91.39 | ...66-167,170,245 
  terminalTheme.ts |     100 |      100 |     100 |     100 |                   
  ...entEmitter.ts |     100 |      100 |     100 |     100 |                   
  ...upWarnings.ts |     100 |      100 |     100 |     100 |                   
  version.ts       |     100 |      100 |     100 |     100 |                   
  windowTitle.ts   |     100 |      100 |     100 |     100 |                   
 src/utils/privacy |   46.91 |    69.44 |      55 |   46.91 |                   
  ...taRedactor.ts |   60.96 |    71.42 |   57.89 |   60.96 | ...28-530,536-557 
  ...acyManager.ts |       0 |        0 |       0 |       0 | 1-176             
 ...ed-integration |    8.48 |     92.3 |   10.52 |    8.48 |                   
  ...temService.ts |     100 |      100 |     100 |     100 |                   
  ...ntegration.ts |    6.81 |     87.5 |    5.55 |    6.81 | ...2032,2047-2117 
-------------------|---------|----------|---------|---------|-------------------
Core Package - Full Text Report
-------------------|---------|----------|---------|---------|-------------------
File               | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-------------------|---------|----------|---------|---------|-------------------
All files          |   75.87 |    82.69 |   71.97 |   75.87 |                   
 src               |     100 |      100 |     100 |     100 |                   
  ...-factories.ts |     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/adapters      |     100 |      100 |     100 |     100 |                   
  ...eamAdapter.ts |     100 |      100 |     100 |     100 |                   
 src/code_assist   |   69.33 |    81.27 |   77.41 |   69.33 |                   
  codeAssist.ts    |   11.76 |      100 |       0 |   11.76 | 16-62,65-73,81-94 
  converter.ts     |   95.54 |    93.02 |     100 |   95.54 | 186-190,219-220   
  ...al-storage.ts |   97.39 |    76.31 |     100 |   97.39 | 76,103,132        
  oauth2.ts        |   65.16 |    79.59 |   81.81 |   65.16 | ...88-789,794-795 
  server.ts        |   48.16 |    72.72 |      50 |   48.16 | ...10-251,254-257 
  setup.ts         |   86.09 |    76.92 |     100 |   86.09 | ...60-162,187-193 
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/commands      |     100 |      100 |     100 |     100 |                   
  extensions.ts    |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/config        |   70.56 |    77.46 |   57.23 |   70.56 |                   
  config.ts        |   65.21 |    74.25 |   60.52 |   65.21 | ...49-858,884-888 
  configBase.ts    |    66.5 |    70.45 |   72.72 |    66.5 | ...58-265,267-271 
  ...igBaseCore.ts |   70.13 |    94.28 |    45.2 |   70.13 | ...54-755,757-758 
  ...onstructor.ts |   96.56 |     88.7 |     100 |   96.56 | ...58-459,462-463 
  configTypes.ts   |      58 |      100 |      50 |      58 | 196-236           
  constants.ts     |     100 |      100 |     100 |     100 |                   
  endpoints.ts     |     100 |      100 |     100 |     100 |                   
  ...ngsHelpers.ts |   62.16 |       40 |     100 |   62.16 | ...31,35-36,42-43 
  index.ts         |       0 |        0 |       0 |       0 | 1-41              
  ...ntegration.ts |   61.51 |    73.46 |   68.75 |   61.51 | ...82,399,408,417 
  models.ts        |     100 |      100 |     100 |     100 |                   
  ...rSingleton.ts |   76.22 |    70.37 |   56.25 |   76.22 | ...94,397-400,408 
  ...entManager.ts |   51.36 |     67.5 |   65.21 |   51.36 | ...94-695,713-737 
  ...tryFactory.ts |   82.54 |    75.92 |   69.23 |   82.54 | ...89-505,515-525 
  types.ts         |       0 |        0 |       0 |       0 |                   
 ...nfirmation-bus |   83.33 |       50 |      50 |   83.33 |                   
  index.ts         |       0 |        0 |       0 |       0 | 1-2               
  message-bus.ts   |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/core          |   80.26 |     76.2 |   82.08 |   80.26 |                   
  ...ssionTypes.ts |   68.42 |      100 |      20 |   68.42 | ...05-107,112-113 
  ...ntContract.ts |     100 |      100 |     100 |     100 |                   
  ...tGenerator.ts |     100 |       96 |     100 |     100 | 96                
  ...okTriggers.ts |   43.27 |    55.55 |      60 |   43.27 | ...76-277,301-306 
  geminiRequest.ts |      60 |      100 |       0 |      60 | 18-19             
  ...nAIWrapper.ts |   77.77 |      100 |   66.66 |   77.77 | 58-61,64-67       
  ...okTriggers.ts |   96.21 |     87.5 |     100 |   96.21 | ...19,165,219,268 
  logger.ts        |   81.06 |    81.81 |     100 |   81.06 | ...70-385,432-446 
  prompts.ts       |   81.96 |    52.94 |   89.47 |   81.96 | ...23,526,587-588 
  subagentTypes.ts |     100 |      100 |   83.33 |     100 |                   
  tokenLimits.ts   |   88.76 |     75.4 |     100 |   88.76 | ...87,101,105,115 
  ...erContract.ts |     100 |      100 |     100 |     100 |                   
  turn.ts          |     100 |      100 |     100 |     100 |                   
 ...re/compression |   33.55 |       50 |   16.66 |   33.55 |                   
  ...nDirective.ts |    6.25 |      100 |       0 |    6.25 | 22-62             
  types.ts         |   41.02 |       50 |      20 |   41.02 | ...43-377,388-389 
 src/debug         |   61.53 |        0 |       0 |   61.53 |                   
  ...ionManager.ts |     100 |      100 |     100 |     100 |                   
  DebugLogger.ts   |     100 |      100 |     100 |     100 |                   
  FileOutput.ts    |     100 |      100 |     100 |     100 |                   
  ...ionManager.ts |       0 |        0 |       0 |       0 | 1-6               
  ...FileOutput.ts |       0 |        0 |       0 |       0 | 1-6               
  index.ts         |     100 |      100 |     100 |     100 |                   
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 src/filters       |   99.19 |    98.78 |     100 |   99.19 |                   
  EmojiFilter.ts   |   99.19 |    98.78 |     100 |   99.19 | 208-209           
 src/hooks         |   83.28 |    84.44 |   80.12 |   83.28 |                   
  errors.ts        |     100 |      100 |     100 |     100 |                   
  ...Aggregator.ts |    90.4 |    81.33 |    87.5 |    90.4 | ...55,374,376,378 
  ...sContracts.ts |       0 |        0 |       0 |       0 | 1                 
  ...entHandler.ts |   91.45 |    84.73 |   93.75 |   91.45 | ...55,795-801,846 
  hookPlanner.ts   |   98.79 |    93.33 |     100 |   98.79 | 103               
  hookRegistry.ts  |   98.25 |    89.23 |     100 |   98.25 | 353,355,357,359   
  hookRunner.ts    |   86.34 |    88.23 |   90.47 |   86.34 | ...37-439,503-506 
  hookSystem.ts    |    64.2 |    88.88 |      65 |    64.2 | ...49-351,364-366 
  ...Translator.ts |   94.87 |    64.44 |     100 |   94.87 | ...01-302,313,362 
  ...Validators.ts |    92.4 |    89.83 |     100 |    92.4 | 57-59,78-80       
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...ssion-hook.ts |   88.88 |    33.33 |     100 |   88.88 | 24,30             
  trustedHooks.ts  |   20.77 |      100 |       0 |   20.77 | ...6,82-90,96-109 
  types.ts         |   52.19 |    87.09 |      50 |   52.19 | ...21-422,433-434 
 ...oks/test-utils |       0 |        0 |       0 |       0 |                   
  ...igWithHook.ts |       0 |        0 |       0 |       0 | 1-137             
 src/interfaces    |       0 |        0 |       0 |       0 |                   
  index.ts         |       0 |        0 |       0 |       0 |                   
  ....interface.ts |       0 |        0 |       0 |       0 |                   
 src/models        |   83.46 |    92.41 |    87.5 |   83.46 |                   
  hydration.ts     |    4.76 |      100 |       0 |    4.76 | 65-131,153-233    
  index.ts         |     100 |      100 |     100 |     100 |                   
  profiles.ts      |     100 |      100 |     100 |     100 |                   
  ...ntegration.ts |   95.31 |    89.74 |     100 |   95.31 | ...35-136,199-200 
  registry.ts      |   90.58 |    88.88 |      92 |   90.58 | ...72-273,393-406 
  schema.ts        |     100 |      100 |     100 |     100 |                   
  transformer.ts   |     100 |      100 |     100 |     100 |                   
 src/parsers       |   71.13 |    73.39 |   88.57 |   71.13 |                   
  ...CallParser.ts |   71.55 |    76.92 |    86.2 |   71.55 | ...5,982,988-1003 
  ...rser-utils.ts |   66.15 |    42.85 |     100 |   66.15 | ...59,67-68,72-77 
 src/policy        |   75.22 |    76.19 |      92 |   75.22 |                   
  config.ts        |   70.84 |    77.19 |   90.47 |   70.84 | ...13,369,446-447 
  index.ts         |     100 |      100 |     100 |     100 |                   
  policy-engine.ts |     100 |      100 |     100 |     100 |                   
  ...cy-helpers.ts |   88.88 |    66.66 |     100 |   88.88 | 31-39             
  ...-stringify.ts |     100 |      100 |     100 |     100 |                   
  toml-loader.ts   |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
  utils.ts         |     100 |      100 |     100 |     100 |                   
 src/prompt-config |   78.48 |    85.63 |   85.82 |   78.48 |                   
  ...lateEngine.ts |   93.83 |    87.36 |     100 |   93.83 | ...04-407,418-421 
  index.ts         |       0 |      100 |     100 |       0 | 5-41              
  prompt-cache.ts  |    99.1 |    97.46 |     100 |    99.1 | 227-228           
  ...-installer.ts |   87.87 |    84.04 |   97.61 |   87.87 | ...1266,1350-1351 
  prompt-loader.ts |   88.92 |       91 |   81.25 |   88.92 | ...30-447,457-458 
  ...t-resolver.ts |   40.42 |    74.11 |   57.69 |   40.42 | ...23-876,879-907 
  ...pt-service.ts |   85.28 |    83.18 |   80.95 |   85.28 | ...28,545-552,583 
  ...delegation.ts |   93.54 |     90.9 |     100 |   93.54 | 34-35             
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...onfig/defaults |   56.45 |    45.74 |   85.41 |   56.45 |                   
  core-defaults.ts |      48 |     41.5 |   78.57 |      48 | ...65,375,381-389 
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...est-loader.ts |   81.81 |    79.31 |     100 |   81.81 | ...02-108,116-120 
  ...t-warnings.ts |    92.3 |    33.33 |     100 |    92.3 | 18-19             
  ...r-defaults.ts |   52.51 |    35.29 |   84.61 |   52.51 | ...36,346,352-357 
  ...e-defaults.ts |     100 |      100 |     100 |     100 |                   
  tool-defaults.ts |   56.05 |     42.3 |   84.61 |   56.05 | ...92-293,305-310 
 src/prompts       |      30 |      100 |      25 |      30 |                   
  mcp-prompts.ts   |   28.57 |      100 |       0 |   28.57 | 11-15             
  ...t-registry.ts |   30.23 |      100 |   28.57 |   30.23 | ...43,49-56,69-74 
 src/recording     |   90.77 |    84.81 |   98.79 |   90.77 |                   
  ...ntegration.ts |    83.9 |    74.07 |     100 |    83.9 | ...31-132,143-144 
  ReplayEngine.ts  |    97.1 |     90.8 |     100 |    97.1 | 121-122,473-480   
  ...nDiscovery.ts |   92.12 |    84.69 |     100 |   92.12 | ...35,252-254,304 
  ...ockManager.ts |   89.41 |    81.25 |     100 |   89.41 | ...98,213,240-241 
  ...ingService.ts |   82.97 |    92.45 |   95.65 |   82.97 | ...57,390-391,395 
  index.ts         |     100 |      100 |     100 |     100 |                   
  resumeSession.ts |   93.19 |    89.65 |     100 |   93.19 | ...10-215,246-247 
  ...eanupUtils.ts |      90 |    69.23 |     100 |      90 | ...40-241,267,280 
  ...Management.ts |   88.23 |    85.71 |     100 |   88.23 | 94,108-112        
  types.ts         |       0 |        0 |       0 |       0 |                   
 src/resources     |   95.23 |     92.3 |     100 |   95.23 |                   
  ...e-registry.ts |   95.23 |     92.3 |     100 |   95.23 | 34-35             
 src/runtime       |   74.73 |    84.16 |   75.29 |   74.73 |                   
  ...imeContext.ts |     100 |      100 |     100 |     100 |                   
  ...timeLoader.ts |   84.37 |    71.18 |   83.33 |   84.37 | ...43,247,274-277 
  ...ntimeState.ts |   95.63 |    90.54 |     100 |   95.63 | ...01-502,542-543 
  ...ionContext.ts |   83.33 |    93.33 |   71.42 |   83.33 | ...51-152,163-170 
  ...imeContext.ts |   73.96 |    97.61 |   60.71 |   73.96 | ...60-265,267-274 
  index.ts         |       0 |        0 |       0 |       0 | 1-19              
  ...imeContext.ts |      70 |       90 |     100 |      70 | 88-108            
  ...meAdapters.ts |     4.8 |      100 |       0 |     4.8 | ...84-118,124-170 
  ...ateFactory.ts |   94.59 |    65.21 |     100 |   94.59 | 74,82,96,109      
  ...imeAdapter.ts |   80.55 |    86.66 |   88.88 |   80.55 | 52-59,67-68,71-76 
 ...time/contracts |       0 |        0 |       0 |       0 |                   
  ...lureReason.ts |       0 |        0 |       0 |       0 | 1                 
  ...kContracts.ts |       0 |        0 |       0 |       0 | 1                 
  ...ningOutput.ts |       0 |        0 |       0 |       0 | 1                 
  ...torFactory.ts |       0 |        0 |       0 |       0 | 1                 
  RuntimeModel.ts  |       0 |        0 |       0 |       0 | 1                 
  ...meProvider.ts |       0 |        0 |       0 |       0 | 1                 
  ...oviderChat.ts |       0 |        0 |       0 |       0 | 1                 
  ...derManager.ts |       0 |        0 |       0 |       0 | 1                 
  ...eTokenizer.ts |       0 |        0 |       0 |       0 | 1                 
  ...zerFactory.ts |       0 |        0 |       0 |       0 | 1                 
  ...tryContext.ts |       0 |        0 |       0 |       0 | 1                 
  index.ts         |       0 |        0 |       0 |       0 | 1                 
 ...runtime/errors |   94.87 |    85.71 |   66.66 |   94.87 |                   
  ...viderError.ts |     100 |      100 |     100 |     100 |                   
  index.ts         |       0 |        0 |       0 |       0 | 1-14              
 src/safety        |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  pathValidator.ts |     100 |      100 |     100 |     100 |                   
 src/scheduler     |       0 |        0 |       0 |       0 |                   
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 src/services      |   82.74 |    85.71 |    87.7 |   82.74 |                   
  ...ardService.ts |   94.23 |    93.75 |     100 |   94.23 | 70,74-75          
  ...utoTrigger.ts |   97.33 |    95.83 |     100 |   97.33 | 127-128           
  ...askManager.ts |   95.81 |    93.93 |     100 |   95.81 | 151-157,365-366   
  ...derService.ts |   98.98 |    97.05 |     100 |   98.98 | 173               
  ...y-analyzer.ts |   76.32 |    81.17 |   77.77 |   76.32 | ...88-516,522-523 
  ...extManager.ts |     100 |    96.29 |     100 |     100 | 63                
  ...nitization.ts |   98.62 |    96.66 |     100 |   98.62 | 176-177           
  ...eryService.ts |     100 |      100 |     100 |     100 |                   
  ...temService.ts |     100 |      100 |     100 |     100 |                   
  ...ts-service.ts |      50 |      100 |       0 |      50 | 41-42,48-49       
  gitService.ts    |    86.6 |    86.95 |      80 |    86.6 | ...35-138,142-146 
  index.ts         |       0 |        0 |       0 |       0 | 1-23              
  ...ionService.ts |   95.86 |    93.05 |     100 |   95.86 | ...06-307,317-318 
  ...ionService.ts |   82.77 |     82.8 |   84.48 |   82.77 | ...1511,1520-1548 
  ...xt-tracker.ts |   94.87 |       90 |    87.5 |   94.87 | 54-55             
  ...er-service.ts |       0 |        0 |       0 |       0 | 1-161             
  ...er-service.ts |   68.47 |    48.48 |      80 |   68.47 | ...85-289,311-314 
 ...rvices/history |   81.17 |    83.77 |   84.78 |   81.17 |                   
  ...Converters.ts |   83.77 |    81.89 |   83.33 |   83.77 | ...45-446,552-575 
  HistoryEvents.ts |       0 |        0 |       0 |       0 |                   
  ...oryService.ts |   78.88 |    84.39 |   83.33 |   78.88 | ...1777,1839-1840 
  IContent.ts      |    89.7 |       76 |     100 |    89.7 | ...42,252-253,264 
  ...calToolIds.ts |   96.82 |     92.3 |     100 |   96.82 | 36-37             
 src/skills        |   74.27 |    86.17 |   73.07 |   74.27 |                   
  skillLoader.ts   |   55.55 |    86.11 |   71.42 |   55.55 | ...99-235,238-274 
  skillManager.ts  |   91.28 |     86.2 |   73.68 |   91.28 | ...58-359,365-366 
 src/storage       |    98.7 |    96.96 |     100 |    98.7 |                   
  ...FileWriter.ts |     100 |      100 |     100 |     100 |                   
  ...nceService.ts |   98.67 |    96.96 |     100 |   98.67 | 294-295           
  ...ey-storage.ts |     100 |      100 |     100 |     100 |                   
  secure-store.ts  |     100 |      100 |     100 |     100 |                   
  sessionTypes.ts  |     100 |      100 |     100 |     100 |                   
 src/telemetry     |   15.17 |        0 |       0 |   15.17 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  ...-exporters.ts |       0 |        0 |       0 |       0 | 1-6               
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...t.circular.ts |       0 |        0 |       0 |       0 | 1-17              
  ...t.circular.ts |       0 |        0 |       0 |       0 | 1-115             
  loggers.ts       |     100 |      100 |     100 |     100 |                   
  metrics.ts       |     100 |      100 |     100 |     100 |                   
  sdk.ts           |     100 |      100 |     100 |     100 |                   
  ...l-decision.ts |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
  uiTelemetry.ts   |     100 |      100 |     100 |     100 |                   
 src/test-utils    |      50 |       60 |   18.18 |      50 |                   
  config.ts        |   65.38 |      100 |   13.04 |   65.38 | ...,91-96,155-193 
  index.ts         |       0 |        0 |       0 |       0 | 1-9               
  mock-tool.ts     |       0 |        0 |       0 |       0 | 1-158             
  ...aceContext.ts |       0 |        0 |       0 |       0 | 1-32              
  ...allOptions.ts |   81.62 |    51.61 |   54.54 |   81.62 | ...83,196,225-228 
  runtime.ts       |   47.03 |    33.33 |    8.82 |   47.03 | ...13-276,284-347 
  tools.ts         |   43.02 |      100 |   31.25 |   43.02 | ...99-211,214-221 
 src/todo          |   13.04 |      100 |       0 |   13.04 |                   
  todoFormatter.ts |   13.04 |      100 |       0 |   13.04 | ...64,170-211,214 
 src/tools         |   79.33 |    83.33 |   91.66 |   79.33 |                   
  ...ey-storage.ts |   79.33 |    83.33 |   91.66 |   79.33 | ...05-310,319-324 
 ...tools-adapters |   35.88 |    47.87 |      26 |   35.88 |                   
  ...iceAdapter.ts |   61.22 |       80 |   57.14 |   61.22 | ...52,55-60,65-68 
  ...iceAdapter.ts |   27.58 |      100 |      25 |   27.58 | 21-26,29-37,40-45 
  ...iceAdapter.ts |   22.58 |      100 |      25 |   22.58 | 18-25,28-43,46-47 
  ...iceAdapter.ts |      30 |      100 |       0 |      30 | 16-18,21-22,25-33 
  ...BusAdapter.ts |   11.76 |      100 |      20 |   11.76 | ...07-120,123-129 
  ...iceAdapter.ts |      60 |      100 |       0 |      60 | ...27,36-37,40-41 
  ...iceAdapter.ts |   53.84 |      100 |      25 |   53.84 | 17-18,21-22,26-27 
  ...ostAdapter.ts |   19.88 |      100 |    4.76 |   19.88 | ...16-222,225-239 
  ...iceAdapter.ts |   15.58 |        0 |       0 |   15.58 | ...9,82-84,87-102 
  ...iceAdapter.ts |   52.94 |      100 |       0 |   52.94 | ...18,21-22,25-26 
  ...iceAdapter.ts |   39.72 |    37.03 |   60.86 |   39.72 | ...09-752,757-760 
  ...iceAdapter.ts |   68.18 |       50 |      50 |   68.18 | 32-36,39-40       
  ...ostAdapter.ts |    29.9 |      100 |    9.09 |    29.9 | ...48-154,157-158 
  ...ageAdapter.ts |   46.15 |      100 |       0 |   46.15 | ...33,36-37,40-41 
  ...ostAdapter.ts |   67.74 |      100 |      50 |   67.74 | ...57,60-61,64-65 
  ...iceAdapter.ts |      50 |      100 |      50 |      50 | 19-23             
  ...iceHelpers.ts |   36.79 |    35.29 |    37.5 |   36.79 | ...81-286,289-294 
  index.ts         |     100 |      100 |     100 |     100 |                   
 src/utils         |   82.52 |     86.7 |   82.94 |   82.52 |                   
  LruCache.ts      |    82.6 |      100 |   71.42 |    82.6 | 29-30,33-34       
  ...grep-utils.ts |   98.03 |     87.5 |     100 |   98.03 | 137-138           
  asyncIterator.ts |   73.07 |    84.61 |   66.66 |   73.07 | ...71,75-86,93-94 
  bfsFileSearch.ts |   93.61 |    92.85 |     100 |   93.61 | 36-44             
  browser.ts       |    8.69 |      100 |       0 |    8.69 | 17-53             
  channel.ts       |     100 |      100 |     100 |     100 |                   
  ...pointUtils.ts |   95.58 |    95.23 |     100 |   95.58 | 150-155           
  debugLogger.ts   |     100 |      100 |     100 |     100 |                   
  delay.ts         |     100 |      100 |     100 |     100 |                   
  editor.ts        |   96.46 |    90.38 |    90.9 |   96.46 | ...27-228,230-231 
  ...entContext.ts |     100 |      100 |     100 |     100 |                   
  errorParsing.ts  |   93.23 |    85.14 |   95.23 |   93.23 | ...73,213,297-298 
  ...rReporting.ts |   84.44 |    86.66 |     100 |   84.44 | 47-51,117-125     
  errors.ts        |   74.67 |       95 |   46.66 |   74.67 | ...27-128,189-213 
  events.ts        |   65.74 |      100 |    62.5 |   65.74 | ...04-309,315-318 
  exitCodes.ts     |     100 |      100 |     100 |     100 |                   
  ...sionLoader.ts |   80.98 |    62.85 |    92.3 |   80.98 | ...70-171,224-232 
  fetch.ts         |   24.32 |      100 |       0 |   24.32 | 23-28,32-86,89-90 
  fileDiffUtils.ts |     100 |      100 |     100 |     100 |                   
  fileUtils.ts     |    93.8 |    89.93 |      95 |    93.8 | ...82,452,486-492 
  formatters.ts    |   18.18 |      100 |       0 |   18.18 | 8-16              
  ...eUtilities.ts |   91.25 |       90 |   93.75 |   91.25 | ...95-299,347-357 
  ...rStructure.ts |   96.35 |       95 |     100 |   96.35 | 98-101,387-392    
  getPty.ts        |    12.5 |      100 |       0 |    12.5 | 21-36             
  ...noreParser.ts |   89.28 |    89.58 |      80 |   89.28 | ...30-231,236-250 
  ...ineChanges.ts |       0 |        0 |       0 |       0 | 1-276             
  gitUtils.ts      |   42.55 |    71.42 |      50 |   42.55 | 32-33,40-44,53-80 
  googleErrors.ts  |   77.24 |    72.72 |     100 |   77.24 | ...01,348,354-355 
  ...uotaErrors.ts |    95.5 |    86.59 |     100 |    95.5 | ...69-270,308-309 
  ide-trust.ts     |      60 |      100 |       0 |      60 | 14-15             
  ...rePatterns.ts |     100 |    96.55 |     100 |     100 | 249               
  ...ionManager.ts |     100 |    88.88 |     100 |     100 | 24                
  ...edit-fixer.ts |       0 |        0 |       0 |       0 | 1-156             
  ...yDiscovery.ts |    83.6 |    78.26 |    87.5 |    83.6 | ...60-761,764-765 
  ...tProcessor.ts |   95.79 |    89.41 |   93.75 |   95.79 | ...17-318,413-414 
  ...Inspectors.ts |       0 |        0 |       0 |       0 | 1-23              
  output-format.ts |   36.36 |      100 |       0 |   36.36 | ...53-154,164-185 
  package.ts       |     100 |      100 |     100 |     100 |                   
  ...erCoercion.ts |   86.66 |    82.89 |     100 |   86.66 | ...10-211,273-274 
  partUtils.ts     |   95.31 |    94.59 |     100 |   95.31 | 28,101-102        
  pathReader.ts    |   22.58 |      100 |       0 |   22.58 | ...22,28-29,41-60 
  paths.ts         |    87.5 |    85.18 |   92.85 |    87.5 | ...50-251,266-276 
  ...rDetection.ts |   53.62 |    83.33 |   83.33 |   53.62 | ...01-102,112-113 
  ...archTarget.ts |   89.58 |    69.23 |     100 |   89.58 | 45-47,65-66       
  retry.ts         |   82.24 |    86.82 |   91.66 |   82.24 | ...72-975,980-981 
  ...thResolver.ts |     100 |      100 |     100 |     100 |                   
  ...nStringify.ts |     100 |      100 |     100 |     100 |                   
  sanitization.ts  |     100 |      100 |     100 |     100 |                   
  ...aValidator.ts |   93.67 |    76.31 |     100 |   93.67 | ...95-296,313-324 
  ...r-launcher.ts |   88.88 |    79.48 |     100 |   88.88 | ...81-186,191-192 
  session.ts       |     100 |      100 |     100 |     100 |                   
  shell-parser.ts  |   23.82 |    45.45 |   42.85 |   23.82 | ...97-411,436-475 
  shell-utils.ts   |   84.74 |    88.88 |   95.45 |   84.74 | ...49-555,724-733 
  ...Completion.ts |   94.16 |     92.3 |     100 |   94.16 | 69-75             
  stdio.ts         |   84.21 |    59.09 |     100 |   84.21 | ...21-125,134-138 
  ...dleTimeout.ts |   98.57 |    92.59 |     100 |   98.57 | 79                
  summarizer.ts    |     100 |    88.88 |     100 |     100 | 91                
  ...emEncoding.ts |   97.16 |    91.42 |     100 |   97.16 | 116-117,169       
  terminal.ts      |   34.09 |      100 |       0 |   34.09 | ...55,58-59,62-66 
  ...Serializer.ts |   98.16 |    92.18 |     100 |   98.16 | ...,98-99,153-155 
  testUtils.ts     |      50 |      100 |   33.33 |      50 | ...47,53-58,64-66 
  textUtils.ts     |    12.5 |      100 |       0 |    12.5 | 15-34             
  thoughtUtils.ts  |     100 |      100 |     100 |     100 |                   
  tool-utils.ts    |   66.94 |    76.92 |      75 |   66.94 | ...36-137,158-182 
  ...putLimiter.ts |   95.14 |    81.63 |     100 |   95.14 | ...5-66,78-79,113 
  unicodeUtils.ts  |     100 |      100 |     100 |     100 |                   
  ...untManager.ts |   89.83 |    88.57 |     100 |   89.83 | ...0,78-83,99-101 
  version.ts       |     100 |      100 |     100 |     100 |                   
  ...aceContext.ts |   96.85 |    95.23 |    92.3 |   96.85 | 95-96,110-111     
 ...ils/filesearch |   88.24 |     89.8 |   93.54 |   88.24 |                   
  crawlCache.ts    |     100 |      100 |     100 |     100 |                   
  crawler.ts       |   83.15 |     82.6 |      60 |   83.15 | ...,97-99,111-116 
  fileSearch.ts    |   83.05 |     86.2 |     100 |   83.05 | ...06-307,309-310 
  ignore.ts        |     100 |      100 |     100 |     100 |                   
  result-cache.ts  |     100 |      100 |     100 |     100 |                   
-------------------|---------|----------|---------|---------|-------------------

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

@acoliver

Copy link
Copy Markdown
Collaborator Author

@CodeRabbit evaluate this critique from another model:

Summary of Most Important Issues| # | Severity | Issue |
|---|----------|-------|
|3 | Medium | Events pushed between cancelAll() and forwardingActive=false in scheduleAndAwait's abort path may not be drained to the consumer, potentially losing display updates for cancelled tools. |
|5 | Medium | handleConfirmationResponse now skips calling the tool's onConfirm for ModifyWithEditor — tools that relied on their callback being invoked for all outcomes won't see the editor-modify event. |
|7 | Low-Medium | Profile-change-during-stream is a new behavior (deferred chat invalidation) that could surprise callers expecting immediate model switches. |
|1 | Low | runLoop callback in useAgenticLoop recreates on every render (deps include the unstable args object); currently masked by the ref pattern but fragile for future maintainers. |

@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Read the AgenticLoop scheduleAndAwait and abort path
fd -e ts 'AgenticLoop.ts' --exclude '__tests__' | xargs grep -n "cancelAll\|forwardingActive\|drainWhileRunning\|scheduleAndAwait\|abort" | head -80

echo "=== FULL scheduleAndAwait ==="
fd -e ts 'AgenticLoop.ts' --exclude '__tests__' | xargs cat | grep -A 80 "scheduleAndAwait"

echo "=== SEPARATOR ==="

# handleConfirmationResponse and ModifyWithEditor
fd -e ts 'confirmation-coordinator.ts' --exclude '.test.' | xargs grep -n "ModifyWithEditor\|handleConfirmationResponse\|onConfirm\|skipBusPublish" | head -60

echo "=== FULL handleConfirmationResponse ==="
fd -e ts 'confirmation-coordinator.ts' --exclude '.test.' | xargs cat | grep -A 40 "handleConfirmationResponse"

echo "=== SEPARATOR2 ==="

# Profile-change-during-stream - check streamEventDispatcher
fd -e ts 'streamEventDispatcher.ts' --exclude '.test.' | xargs grep -n "profile\|model\|invalidat\|chat\|ModelInfo\|Finished" | head -40

echo "=== SEPARATOR3 ==="

# useAgenticLoop runLoop callback recreation
fd -e ts 'useAgenticLoop.ts' --exclude '.test.' --exclude '.spec.' | xargs grep -n "runLoop\|useCallback\|useMemo\|useRef\|args\." | head -50

Length of output: 21774



@acoliver Here's my evaluation of each of the four issues against the actual code:


Issue #3 (Medium): Events lost between cancelAll() and forwardingActive=falseCONFIRMED

This is a real gap. The abort path in scheduleAndAwait is:

drainWhileRunning exits (signal.aborted = true → loop condition fails)
↓
scheduler.cancelAll()        ← callbacks fire → push events to queue
↓
await Promise.race([completionTask, abortPromise])
↓
forwardingActive = false
queue.close()                ← events pushed above are never drained

drainWhileRunning exits as soon as signal.aborted is true. The cancelAll() call then synchronously triggers onToolCallsUpdate / outputUpdateHandler callbacks which push tool_update and tool_output events into the queue. But there is no drain pass between cancelAll() and queue.close(), so those final cancelled-tool display updates are silently dropped. The severity (Medium) is well-calibrated — it's a real consumer-visible issue but only affects the visual tail of abort flows, not correctness of results.


Issue #5 (Medium): handleConfirmationResponse skips onConfirm for ModifyWithEditorPARTIALLY VALID, but intentional

The skip is real:

if (outcome !== ToolConfirmationOutcome.ModifyWithEditor) {
  await originalOnConfirm(outcome, payload);
}

However, the critique's framing ("tools that relied on their callback being invoked for all outcomes") mischaracterizes the design. onConfirm here is an execution trigger, not an all-outcome observer. For ModifyWithEditor, calling onConfirm immediately would execute the tool with unmodified args before the editor workflow completes. The correct final onConfirm call happens after the editor session ends and the user re-confirms. The AI summary also explicitly calls this out as intentional: "preventing an extra callback execution for that outcome."

This is a deliberate, correct change — not a regression. Medium severity overstates the risk.


Issue #7 (Low-Medium): Profile-change-during-stream deferred chat invalidation — WEAKLY FOUNDED

I can't find evidence for "deferred chat invalidation" in the code. The ModelInfo event handling in streamEventDispatcher.ts calls handleModelInfoEvent which adds a profile_change display notification. The function is display-only — no chat invalidation or deferred model-switch logic is visible. The key changes to streamEventDispatcher.ts in this PR are about buffer reset on terminal events, and the ModelInfo path appears unchanged. This concern looks speculative; the critique may be inferring behavior that isn't there.


Issue #1 (Low): runLoop recreates on every render — CONFIRMED at the stale-closure level, framing is imprecise

The runLoop = useCallback(...) body at lines 167–186 directly references args.addItem, args.flushPendingHistoryItem, args.clearPendingHistoryItem, args.onTodoPause, etc. — none of these are latest-ref'd the way display callbacks are. Whether runLoop itself re-creates every render depends on the deps array (not fully visible in the snippet), but regardless, any render where args stabilizes will leave a stale non-display callback captured. This is exactly the same finding as Medium issue #4 from the prior assessment. The critique's "recreates on every render" framing is slightly off (the deps array may use individual fields, not args), but the underlying stale-closure concern is valid and consistent.


Summary

Issue Verdict Assessment quality
#3 – Events lost after cancelAll() ✅ Confirmed real Accurate and well-targeted
#5onConfirm skipped for ModifyWithEditor ⚠️ Intentional design, not a bug Overstates risk; misreads the callback contract
#7 – Deferred chat invalidation ❌ Not supported by code Speculative; no evidence found
#1runLoop stale closures ✅ Confirmed (same as prior Medium #4) Real issue, framing slightly imprecise

Issue #3 is the only genuinely new finding here worth adding to the follow-up list. Issues #5 and #7 don't warrant action, and #1 is a duplicate of an already-identified concern.

@acoliver

Copy link
Copy Markdown
Collaborator Author

@CodeRabbit evaluate these as well

Issues I've Spotted###1. useAgenticLoop.runLoop has a stale-closure risk via args in its dependency array

In useAgenticLoop.ts line ~249, the runLoop callback has [loop, args, processedMemoryTools] as deps. Since args is an object literal passed from the parent, it gets a new identity on every render, which means runLoop is recreated on every render. But runLoopRef.current = agenticLoop.runLoop is set during render in the orchestrator, so this is patched over by the ref pattern. However, it partially defeats the purpose of the useMemo on loop (which deliberately uses stable deps). The runLoop callback closes over args fields that change every render (addItem, onTodoPause, etc.), but since it's consumed via a ref, stale closures are avoided at call time. This is functional but fragile — a future maintainer who uses runLoop directly (not via ref) will get a stale closure.

###2. EventQueue.waitForNext — potential lost-wakeup race between the fast-path check and promise creation

In AgenticLoop.ts ~line103-106, waitForNext checks this.buffered.length >0 synchronously, then returns a Promise. Between that check and the new Promise executor running (which sets this.resolveWait), the JS event loop won't interleave (single-threaded), so this is actually safe in practice. However, if push() is ever called from a different microtask context before the executor runs... Actually, in JS this is fine because the executor runs synchronously during new Promise. No issue.

###3. drainWhileRunning can miss events on abort path

In AgenticLoop.ts, drainWhileRunning loops while (!state.completionSettled && !signal.aborted). On abort, it exits the loop, and the final yield* flushBuffered(queue) runs. Then control returns to scheduleAndAwait which does scheduler.cancelAll() and await Promise.race([scheduleTask, completionTask]). Events pushed between cancelAll() and queue.close() in the finally block are not yielded to the consumer. The forwardingActive = false flag prevents new pushes after the finally starts, but there's a window between drainWhileRunning returning and forwardingActive being set to false where cancelAll triggers callbacks that push into the queue but are never drained. The onAllToolCallsComplete callback explicitly pushes a final tool_update: [] if forwardingActive is still true. This is a potential display-state leak — the loop's consumer might miss the final tool cancellation display update. In practice the CLI display may not update cancelled tools correctly during abort.

###4. handleModifyWithEditorpendingOriginalConfirmHandlers can grow unboundedly in edge cases

In confirmation-coordinator.ts, when handleModifyWithEditor re-publishes with a new correlationId, it sets pendingOriginalConfirmHandlers.set(newCorrelationId, originalOnConfirm) but the old correlationId's entry is cleaned up via registerStaleCorrelationId → cleanupCorrelationId. This cleanup path does this.pendingOriginalConfirmHandlers.delete(correlationId) (line ~835). So this is properly handled. No issue.

###5. handleConfirmationResponse skips originalOnConfirm on ModifyWithEditor — potential dead code concern

In confirmation-coordinator.ts ~line519-520:

tsif (outcome !== ToolConfirmationOutcome.ModifyWithEditor) { await originalOnConfirm(outcome, payload); } The ModifyWithEditorcase is handled separately (it callshandleModifyWithEditor). But originalOnConfirmis the **tool implementation's** callback, not the coordinator's. Skipping it forModifyWithEditormeans the tool's own confirmation handler never sees theModifyWithEditoroutcome. This was presumably intentional (the coordinator handles the editor flow itself), but it means the tool implementation can't react to the editor-modification event. The old code always calledonConfirmbefore this change (withfalseas the last arg, now removed). **This is a behavior change that could affect tools that relied on theironConfirm` being called for all outcomes.**

###6. coreToolScheduler.ts: void this.checkAndNotifyCompletion()await — potential deadlock if completion notification blocks

The change from void (fire-and-forget) to await means schedule() now blocks until checkAndNotifyCompletion resolves. The comment says this ensures the scheduler notifies before schedule() resolves, which the loop relies on for its fallback logic. But if onAllToolCallsComplete (the notification callback) does heavy synchronous work, schedule() will now be slower. The loop's fallback (resolveCompletion([]) when !acceptedToolUpdateSeen) depends on schedule() resolving first, so this ordering is critical. This looks correct but is a subtle coupling — the loop assumes schedule() resolves only after tools are accepted or the scheduling is a no-op.

###7. AgentClient.handleModelProfileChanged — deferred invalidation doesn't restore history service correctly

In client.ts, invalidateChatForProfileChange sets this._previousHistory = undefined (discarding any previous history). If a profile change happens mid-stream, the deferred path saves the HistoryService via this._storedHistoryService = this.chat.getHistoryService(), but loses _previousHistory. The non-deferred (immediate) path does the same. This is consistent behavior but means any unflushed _previousHistory is lost on profile change — which appears to be the original behavior as well (the old handleModelProfileChanged just set currentSequenceModel = null and didn't touch chat at all). This is actually a new behavior — before this branch, a profile change mid-stream did NOT invalidate the chat. Now it defers invalidation until streams complete. This could cause subtle issues if the profile change should take effect immediately.

###8. streamEventDispatcher.tsFinished event now flushes pending gemini content, but the buffer reset logic is new

resetBufferAfterTerminal resets geminiMessageBuffer to '' on terminal events. But the old code managed the buffer externally in consumeStreamEvents and didn't reset it on Finished (it just continued). With the new single-event processStreamEvent, the buffer is in a useRef, so it persists across events. The reset on Finished is correct (each turn should start fresh). However, Finished is now in BUFFER_RESET_EVENTS, and the Finished case in handleNotificationStreamEvent calls flushPendingGeminiContent before the buffer is reset by resetBufferAfterTerminal. Since resetBufferAfterTerminal wraps the return value, the flush happens first (good), then the buffer is cleared (good). This ordering is correct.

###9. useGeminiStreamLifecycle.ts — cancellation now allows WaitingForConfirmation state, but abort behavior may differ

The cancelOngoingRequest now also triggers on WaitingForConfirmation. This means pressing Ctrl+C during a tool confirmation will now abort the controller. But the AgenticLoop owns the abort signal — if the loop is waiting for an approval handler (which it manages via wireApprovalHandler), aborting the signal will cause the loop to exit its drainWhileRunning loop. The approval handler's pending promise will still be in-flight, and the wireApprovalHandler unsubscribe in the finally block will prevent the response from reaching the bus. This should be fine (the tool will be cancelled), but there's a question of whether the confirmation bus has a dangling unanswered request.

###10. ConfirmationCoordinator.handleConfirmationResponseprocessedConfirmations guard before finding waiting tool

At line ~501-505, processedConfirmations.has(callId) returns early. But in handleModifyWithEditor, processedConfirmations.delete(callId) is called to allow re-confirmation. If the editor flow races with a duplicate confirmation (e.g., user double-presses enter), the delete + re-add could allow a duplicate to slip through. The stale-correlation-id mechanism should guard this, but the timing window exists.

@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Issue `#1`: useAgenticLoop runLoop deps array
fd -e ts 'useAgenticLoop.ts' --exclude '__tests__' --exclude '.spec.' | xargs grep -n "useCallback\|useMemo\|deps\|runLoop\|processedMemoryTools\|\[loop" | head -40

echo "=== SEPARATOR ==="
# Issue `#6`: coreToolScheduler await change and coupling
fd -e ts 'coreToolScheduler.ts' | xargs grep -n "checkAndNotifyCompletion\|acceptedToolUpdateSeen\|resolveCompletion\|schedule\b" | head -50

echo "=== SEPARATOR2 ==="
# Issue `#7`: AgentClient handleModelProfileChanged
fd -e ts 'client.ts' --exclude '.test.' --exclude '.spec.' | xargs grep -n "handleModelProfileChanged\|invalidateChatForProfileChange\|_previousHistory\|_storedHistoryService\|deferred\|profileChange" | head -50

echo "=== SEPARATOR3 ==="
# Issue `#9`: useGeminiStreamLifecycle WaitingForConfirmation cancellation + bus dangling
fd -e ts 'useGeminiStreamLifecycle.ts' | xargs grep -n "WaitingForConfirmation\|cancelOngoingRequest\|abort\|Confirmation" | head -40

echo "=== SEPARATOR4 ==="
# Issue `#10`: processedConfirmations guard + handleModifyWithEditor race
fd -e ts 'confirmation-coordinator.ts' --exclude '.test.' | xargs grep -n "processedConfirmations\|handleModifyWithEditor\|delete\|has(callId\|add(callId" | head -60

echo "=== SEPARATOR5 ==="
# Issue `#5`: originalOnConfirm skip for ModifyWithEditor - get full handleConfirmationResponse
fd -e ts 'confirmation-coordinator.ts' --exclude '.test.' | xargs cat | grep -A 60 "async handleConfirmationResponse"

Length of output: 8691


🏁 Script executed:

#!/bin/bash
# Get the full scheduleAndAwait and drainWhileRunning to validate `#3` more precisely
fd -e ts 'AgenticLoop.ts' --exclude '__tests__' | xargs cat | grep -n "" | head -300

Length of output: 11562


🏁 Script executed:

#!/bin/bash
# Get scheduleAndAwait and drainWhileRunning from AgenticLoop.ts
fd -e ts 'AgenticLoop.ts' --exclude '__tests__' | xargs cat | grep -n "" | sed -n '300,598p'

echo "=== CLIENT ==="
# Get handleModelProfileChanged and invalidateChatForProfileChange
fd -e ts 'client.ts' --exclude '.test.' --exclude '.spec.' | xargs cat | grep -n "" | sed -n '230,320p'

Length of output: 15256



@acoliver Here is my evaluation of all 10 issues against the actual code:


Issue #1: runLoop stale-closure via args deps — CONFIRMED, duplicate of prior finding

Line 259: [loop, args, processedMemoryTools]. args gets a new object identity on every render, so runLoop recreates every render. As noted before, this is masked at call time by the runLoopRef.current indirection, so it's functional. The fragility concern for future maintainers who use runLoop directly is valid and consistent with the prior Medium #4 finding.


Issue #2: EventQueue.waitForNext lost-wakeup race — CORRECTLY SELF-RESOLVED

The submitter is correct that this is safe. The new Promise executor runs synchronously, so this.resolveWait is set before any microtask interleaving is possible. No issue.


Issue #3: drainWhileRunning misses events after cancelAll()CONFIRMED

Reading the abort path in scheduleAndAwait (lines 519–543):

drainWhileRunning exits (signal.aborted → loop condition fails)
→ flushBuffered(queue) runs on line 563 (drains what was in queue before cancelAll)
→ scheduler.cancelAll() fires (line 525) → callbacks push tool_update/tool_output to queue
→ await Promise.race([scheduleTask, completionTask])  ← waits, but does NOT drain
→ completed = abortPromise resolves null immediately  ← no drain here either
→ normalExit = true → return
→ finally: forwardingActive = false; queue.close() ← events from cancelAll silently dropped

This is real. The final cancelled-tool display updates from cancelAll() callbacks are pushed into the queue but never yielded to the consumer before queue.close(). The onAllToolCallsComplete empty tool_update: [] push is also in this window. This is the same gap as the prior model's Issue #3.


Issue #4: pendingOriginalConfirmHandlers unbounded growth — CORRECTLY SELF-RESOLVED

Cleanup happens via registerStaleCorrelationId → cleanupCorrelationId → pendingOriginalConfirmHandlers.delete. No issue.


Issue #5: handleConfirmationResponse skips originalOnConfirm for ModifyWithEditorINTENTIONAL DESIGN

The code at line ~527: if (outcome !== ToolConfirmationOutcome.ModifyWithEditor) { await originalOnConfirm(outcome, payload); }. For ModifyWithEditor, the correct originalOnConfirm call happens after the editor session completes (inside handleModifyWithEditor). Calling it immediately would execute the tool with unmodified args. The AI summary explicitly flags this as intentional. Same conclusion as the prior assessment — not a bug.


Issue #6: await checkAndNotifyCompletion() potential deadlock — NOT A DEADLOCK

The onAllToolCallsComplete callback in scheduleAndAwait only does:

queue.push({ kind: 'tool_update', toolCalls: [] });
display?.onToolCallsUpdate?.([]);
resolveCompletion(completed);

No circular awaiting of schedule(). The coupling is intentional and documented (lines 496–501): scheduleTask must resolve only after tools are accepted or no-op, so the fallback resolveCompletion([]) fires correctly. This makes schedule() slightly slower but is required for correctness. Low risk.


Issue #7: handleModelProfileChanged deferred invalidation — BEHAVIOR CHANGE, PARTIALLY VALID

The concern is real: this is genuinely new behavior. Before this branch, handleModelProfileChanged set currentSequenceModel = null and did nothing to the chat. Now it sets profileChangePendingChatInvalidation = true and defers invalidateChatForProfileChange() until the stream completes (line 728–730). The consequence of _previousHistory = undefined on line 252 is consistent between deferred and immediate paths, so that specific sub-concern is not a regression. But the deferred invalidation itself is new — callers expecting an immediate model switch will be surprised. Worth a comment in the code or a follow-up test, but not a correctness bug given the deferral is bounded by stream completion.


Issue #8: Finished buffer reset ordering — CORRECTLY SELF-RESOLVED

flushPendingGeminiContent fires before resetBufferAfterTerminal clears the buffer. Ordering is correct.


Issue #9: WaitingForConfirmation abort + dangling bus request — REAL CONCERN

The AI summary confirms cancelOngoingRequest now also aborts on WaitingForConfirmation. When that happens:

  1. AbortController.abort() fires → drainWhileRunning exits → run()'s finally calls unsubscribe(), removing the bus subscription.
  2. The fire-and-forget approvalHandler promise (from wireApprovalHandler) is still in-flight.
  3. When it resolves, it calls bus.respondToConfirmation(request.correlationId, ...).
  4. The ConfirmationCoordinator still has that correlationId in pendingConfirmations — it will receive the stale response and attempt to call the original onConfirm.

This makes the fire-and-forget approval handler concern concrete rather than theoretical. The new WaitingForConfirmation cancellation path is the trigger condition. This should be treated as additive evidence for the prior Medium/High #2 fire-and-forget finding — both need the same fix (abort-aware approval handlers or pending-approval tracking + Cancel response on abort).


Issue #10: processedConfirmations guard race — LOW RISK, defense in depth exists

processedConfirmations.add(callId) runs at line 513 before any outcome processing. Even after handleModifyWithEditor calls delete at line 686 to allow re-confirmation, the new correlationId path creates a fresh processedConfirmations entry on the re-confirm call. A double-press race would need to slip through both the stale-correlation-id check AND the processedConfirmations guard simultaneously. Theoretical, very low blast radius.


Summary

# Verdict Net assessment
#1 ✅ Confirmed Duplicate of prior Medium — fragile ref pattern, stale non-display closures
#2 ✅ Self-resolved No issue
#3 ✅ Confirmed Real gap — cancelAll() events lost after abort drain; same as prior Medium #3
#4 ✅ Self-resolved No issue
#5 ⚠️ Intentional Design-correct skip; same conclusion as prior
#6 ⚠️ Overstated Not a deadlock; coupling is intentional and safe
#7 ⚠️ Partially valid Real behavior change deserving a note; not a correctness regression
#8 ✅ Self-resolved Correct ordering
#9 ✅ New finding Concretizes the fire-and-forget risk via WaitingForConfirmation abort path
#10 ⚠️ Low risk Defense in depth guards it; theoretical only

The only genuinely new actionable finding beyond the prior rounds is #9: the WaitingForConfirmation cancellation change creates a concrete path that triggers the dangling approval-handler-promise scenario. It strengthens the case for the abort-aware approval handler recommendation (prior Nice-to-have #3) to be elevated to a Should-fix.

@acoliver

Copy link
Copy Markdown
Collaborator Author

Follow-up for the two linked CodeRabbit comments:

Addressed the actionable findings in commit eae12b1.

Actions taken:

  • Fixed the abort/cancel tail event gap: after abort-driven cancelAll, AgenticLoop now races against the abort promise and flushes queued cancel/update events before teardown. Added behavioral coverage that cancellation emits the final cancelled tool update.
  • Fixed the delayed approval response hazard: AgenticLoop now suppresses approvalHandler responses after the loop has unsubscribed or no longer owns the tool call. Added behavioral coverage where a pending approval resolves only after abort; no stale confirmation response is sent and the tool does not execute.
  • Fixed the useAgenticLoop stale-callback fragility: runLoop is now stable across rerenders and routes through the latest caller args via ref. Added hook coverage for stable runLoop identity plus latest callback routing.
  • Updated the EventQueue comment to avoid implying a bounded buffer.

Evaluated as intentional/no action:

  • ModifyWithEditor intentionally does not call the original execution callback until the final confirmation after editor changes; calling it on the intermediate outcome would execute unmodified args.
  • The profile-change note appears broader than this follow-up and not a direct correctness regression in the AgenticLoop changes.

Verification after the follow-up:

  • AgenticLoop plus ConfirmationCoordinator targeted tests: 58 passed.
  • useAgenticLoop hook tests: 5 passed.
  • npm run typecheck passed.
  • npm run lint passed.
  • npm run build passed.
  • npm run format passed.
  • Smoke test with ollamaglm51 passed.

Note: local npm run test was twice terminated by the shell tool with signal 15 before completion, but progressed through multiple packages with passing output; the impacted targeted suites above passed and CI will run the full matrix on this pushed commit.

@acoliver

Copy link
Copy Markdown
Collaborator Author

@CodeRabbit consider these from another agent:

Potential Issues I Spotted###1. Potential Race: scheduleTask Fallback for Empty Completion (AgenticLoop.ts)

In scheduleAndAwait(), the code resolves completion with [] if scheduler.schedule() finishes without any acceptedToolUpdateSeen:

`typescriptconst scheduleTask = scheduler .schedule(requests, signal)
.then(() => {
if (!acceptedToolUpdateSeen) {
resolveCompletion([]);
}
})

However, coreToolScheduler.ts was changed to await this.checkAndNotifyCompletion(). If schedule() now resolves after onAllToolCallsComplete fires (which it should, since the await was added), then acceptedToolUpdateSeen will be true and the fallback won't trigger. But if there's a path where onAllToolCallsComplete fires but the tool update callback hasn't set acceptedToolUpdateSeen yet (e.g. a tool that validates-and-deny-s immediately without ever entering the update path), the fallback resolveCompletion([]) is the safety net — which seems intentional and correct.

###2. completionPromise vs completionTask Confusion (AgenticLoop.ts)

There are two promises:

  • completionPromise — resolves with CompletedToolCall[] (never rejects)
  • completionTask — wraps completionPromise with .catch(() => null).finally(() => state.completionSettled = true)

The drainWhileRunning watches completionTask for the state.completionSettled flag, but resolveCompletion resolves completionPromise (not completionTask). Since completionTask is chained from completionPromise, the resolution propagates. This looks correct but is subtle — the .finally() on completionTask is what sets completionSettled, and since completionPromise never rejects, the .catch() is dead code (defensive).

###3. EventQueue.waitForNext — No Spurious Wakeup Guard After AwaitIn drainWhileRunning:

`typescriptawait Promise.race([completionTask, queue.waitForNext(signal)]);
yield* flushBuffered(queue);

After waitForNext resolves (due to a push), flushBuffered drains. But after completionTask resolves, state.completionSettled is set in the .finally() microtask. There's a theoretical window where Promise.race resolves on completionTask but state.completionSettled hasn't been set yet by the .finally() handler (finally runs in a separate microtask). This would cause the while (!state.completionSettled) check to loop one more iteration — but flushBuffered would be a no-op (queue empty), and waitForNext would return immediately (since closed or buffered.length >0 might not be true yet). Actually, the loop condition checks state.completionSettled at the top, and the .finally() runs before .then() handlers, so by the time Promise.race resolves, the finally should have run. This is likely fine but is subtle.

###4. buildNextMessage is async but Has No await (AgenticLoop.ts)

`typescriptprivate async buildNextMessage(completed: CompletedToolCall[]): Promise<{...}>

It calls recordCancelledToolHistory which is async and awaited — wait, actually the await is inside the if branch for all-cancelled. The function is async for that reason. This is fine.

###5. Double Tool Group Display in CLILooking at the flow: the engine loop emits tools_complete → useAgenticLoop.routeLoopEvent → handleToolsComplete → addItem(mapTrackedToolCallsToDisplay(completed), ...).But also: the CLI's useReactToolScheduler has its own onAllToolCallsComplete callback (via createMainSchedulerCallbacks) that calls processPrimaryCompletion → addItem(mapTrackedToolCallsToDisplay(...)).

However, the AgenticLoop uses its own scheduler session ID (schedulerSessionId), not the CLI main scheduler's session ID. So the loop's scheduler callbacks fire on the loop's scheduler, and the CLI main scheduler's onAllToolCallsComplete is separate. The display callbacks (onToolCallsUpdate, outputUpdateHandler) are forwarded to the CLI's replaceToolCalls/updateToolOutput which use the main scheduler ID's symbol.So: tool updates flow to the correct display state via the forwarded callbacks, and tools_complete events trigger addItem in the loop's event handler. The CLI main scheduler's own onAllToolCallsComplete should NOT fire for loop-scheduled tools because they use a different scheduler instance. This seems correct but the dual-path is fragile — if someone accidentally uses the same session ID, you'd get double display items.

###6. responseSubmittedToGemini Flag is Now Dead on the Loop PathThe TrackedToolCall types in useReactToolScheduler.ts still carry responseSubmittedToGemini, but with the engine loop owning continuation, this flag is no longer used for the primary flow. The markToolsAsSubmitted function still sets it for external/subagent tools (display-only clearing), which seems correct. But it's vestigial for the main continuation path. Not a bug, but technical debt.

###7. useSubmitQuery.ts Still Passes scheduleToolCalls Through DepsuseStreamEventHandlers still receives scheduleToolCalls in its deps and passes it to dispatchStreamEvent → StreamEventDeps.scheduleToolCalls. But looking at streamEventDispatcher.ts, the ToolCallRequest case just returns { geminiMessageBuffer } — it doesn't call scheduleToolCalls. The scheduler callback is in the deps but appears unused in the dispatcher itself. It may still be used by the queryPreparer.ts path. This is not a bug but the scheduleToolCalls wiring through StreamEventDeps is potentially unnecessary now.

###8. Deleted Watchdog Test (863 lines)

The file useStreamEventHandlers.watchdog.test.ts was deleted entirely (863 lines). This presumably tested the old CLI-owned watchdog/streaming flow that was replaced by the engine loop. If any watchdog behavior was supposed to be preserved, its test coverage needs to exist somewhere in the new test files. The new agenticLoop.integration.test.ts (2094 lines) and useAgenticLoop.test.tsx (584 lines) provide substantial coverage, but I can't verify all863 lines of watchdog scenarios are covered without comparing test cases.

###9. testBoundaryConfig in Integration Tests Uses as Config CastThe integration test creates a partial Config fixture and casts it via fixture as Config. The comment justifies this (Config is a large class), but this means if Config gains new methods that the loop calls, the tests won't catch the mismatch at compile time — they'd fail at runtime instead.

###10. Minor: void result.events in runTurn

`typescriptconst result = yield* this.scheduleAndAwait(dedupedRequests, signal);
completed = result.completed;
void result.events;

The events field of TurnToolResult is the EventQueue, which has already been drained and closed by the time scheduleAndAwait returns. The void result.events is explicitly discarding it, which is fine but slightly odd — it suggests the return type could just omit events.


SummaryThe branch is a well-structured refactoring with solid architectural decisions. The agentic loop consolidation is the centerpiece — moving multi-turn logic from CLI hooks into the engine with proper injection points. The bug fixes (#2035 OAuth loop, #2045 compression retry, #2040 context limit) are focused and well-documented. The cancellation hardening commits show iterative attention to race conditions.

The main risk areas are the subtle async coordination in scheduleAndAwait/EventQueue/drainWhileRunning, the dual-scheduler display path, and ensuring the deleted watchdog test coverage is fully replaced.

@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Issue `#1`, `#2`, `#3`: Get current scheduleAndAwait, drainWhileRunning, completionPromise/completionTask from AgenticLoop.ts
fd -e ts 'AgenticLoop.ts' --exclude '__tests__' | xargs cat | grep -n "" | sed -n '1,650p'

echo "=== TurnToolResult type ==="
fd -e ts 'AgenticLoop.ts' --exclude '__tests__' | xargs grep -n "TurnToolResult\|result\.events\|void result"

echo "=== SEPARATOR - queryPreparer ==="
fd -e ts 'queryPreparer.ts' --exclude '.test.' | xargs grep -n "scheduleToolCalls" | head -30

echo "=== SEPARATOR - StreamEventDeps scheduleToolCalls ==="
fd -e ts 'streamEventDispatcher.ts' --exclude '.test.' | xargs grep -n "scheduleToolCalls\|ToolCallRequest" | head -30

echo "=== SEPARATOR - useSubmitQuery scheduleToolCalls wiring ==="
fd -e ts 'useSubmitQuery.ts' --exclude '.test.' | xargs grep -n "scheduleToolCalls" | head -20

echo "=== SEPARATOR - watchdog test deleted, check if behavior covered elsewhere ==="
# Check if idle timeout / watchdog is covered in new test files
fd -e ts -e tsx '__tests__' | xargs grep -l "watchdog\|idle.*timeout\|LLXPRT_STREAM_IDLE_TIMEOUT\|stall\|AgentExecutionStopped\|AgentExecutionBlocked" 2>/dev/null | head -10

echo "=== SEPARATOR - scheduleToolCalls in StreamEventDeps type ==="
fd -e ts 'streamEventDispatcher.ts' --exclude '.test.' | xargs cat | head -80

Length of output: 30527


🏁 Script executed:

#!/bin/bash
# Check scheduleAndAwait current code after the follow-up commit fixes
fd -e ts 'AgenticLoop.ts' --exclude '__tests__' | xargs cat | grep -n "" | sed -n '380,600p'

echo "=== SEPARATOR - check TurnToolResult and void result.events ==="
fd -e ts 'AgenticLoop.ts' --exclude '__tests__' | xargs grep -n -A3 -B3 "TurnToolResult\|void result\|result\.events"

Length of output: 11629



@acoliver Here is my evaluation of all 10 issues against the current post-fix code:


Issue #1: scheduleTask fallback race — SELF-CORRECTED, intentional design

The submitter's own analysis is correct. Lines 510–512 explicitly document this: "CoreToolScheduler awaits its final completion notification before schedule() resolves, so this fallback only wins for no-op/error scheduling paths." The await checkAndNotifyCompletion() change in CoreToolScheduler means onAllToolCallsComplete fires before schedule() resolves, so acceptedToolUpdateSeen is true by the time .then() runs for normal paths. The fallback is correct and intentional.


Issue #2: completionPromise vs completionTask confusion — SELF-CORRECTED

The submitter's own conclusion is right. completionPromise never rejects (its resolve is only ever called, never reject), so the .catch(() => null) at line 486 is dead but defensive. The .finally() ordering is correct — it runs before any .then() handlers, so state.completionSettled is set before the Promise.race in drainWhileRunning can re-evaluate the loop condition. No issue.


Issue #3: cancelAll() events lost after abort drain — ALREADY FIXED by eae12b1ed

The current code (lines 535–538) shows the fix:

scheduler.cancelAll();
await Promise.race([scheduleTask, completionTask, abortPromise]);
yield* flushBuffered(queue);   // ← drain step added by follow-up commit

cancelAll() fires → callbacks push tool_update/tool_output events → Promise.race waits for schedule/completion → yield* flushBuffered(queue) drains those events before the finally closes the queue. The submitter is evaluating pre-fix state; this is resolved.


Issue #4: buildNextMessage async with no await — SELF-CORRECTED

The await recordCancelledToolHistory(...) at line 592 is the reason the function is async. The submitter correctly self-resolved this.


Issue #5: Double tool group display — NOT A CURRENT BUG, fragility note valid

The schedulerSessionId field (lines 180–191) is precisely ${sessionId}#agentic-loop#${uuid} — distinct from the CLI main scheduler's plain config.getSessionId(). The two schedulers have completely separate onAllToolCallsComplete callbacks; the loop's completion drives tools_complete events while the CLI main scheduler's completion path handles only client-initiated (slash-command) tools. No double display occurs. The fragility concern — what if someone accidentally reuses the same session ID — is a valid maintenance note given the current comment already documents this explicitly. No action needed beyond what's there.


Issue #6: responseSubmittedToGemini flag vestigial on primary path — CONFIRMED TECH DEBT

Correct. With the engine loop owning continuation, responseSubmittedToGemini is set on external/subagent tool calls (for display-state clearing) but is unused for the primary continuation path. Not a bug, but worth cleanup in a future pass.


Issue #7: scheduleToolCalls wiring through StreamEventDepsNOT DEAD

The script confirms queryPreparer.ts lines 41 and 114 still consume scheduleToolCalls. While streamEventDispatcher.ts's ToolCallRequest case no longer calls it directly (returning only { geminiMessageBuffer }), the dep is still actively used by the query-preparation path. The submitter's own caveat ("it may still be used by the queryPreparer.ts path") was correct. No action needed.


Issue #8: Deleted watchdog test coverage — REAL GAP, worth a follow-up

The script found no test files matching watchdog, idle.*timeout, LLXPRT_STREAM_IDLE_TIMEOUT, AgentExecutionStopped, or AgentExecutionBlocked. The deleted 863-line suite covered stall detection and environment-variable-driven timeout configuration. The isTerminalStreamOutcome() function does handle GeminiEventType.StreamIdleTimeout as a terminal event (line 78), but there are no behavioral tests for that path in the new suite. The agenticLoop.integration.test.ts suite (2094 lines) covers cancellation and terminal stream outcomes, but the idle-timeout idle-watchdog environment-config scenarios appear unrepresented. Worth a tracking note.


Issue #9: testBoundaryConfig as Config cast — LOW RISK, acknowledged

Correct that this is a runtime-failure-only cast. The comment in the test file justifies it (Config is a large class). Acceptable tradeoff for integration test fixtures; only becomes problematic if AgenticLoop calls a new Config method not in the fixture.


Issue #10: void result.events dead field — CONFIRMED TRIVIAL

TurnToolResult.events: EventQueue at lines 148–151 and void result.events at line 347 are dead. The queue is already drained and closed inside scheduleAndAwait before it returns; the field is never used by the caller. The void is a lint-suppressor for "unused return value property". The simplest cleanup is removing events from TurnToolResult and from the return { completed, events: queue } statement at line 545.


Summary

# Verdict
#1 ✅ Self-corrected — intentional safety net
#2 ✅ Self-corrected — defensive dead code, harmless
#3 Already fixed by eae12b1ed — drain step present at line 538
#4 ✅ Self-corrected — async needed for inner await
#5 ⚠️ Not a bug — scheduler isolation prevents double display; fragility note stands
#6 📝 Tech debt — responseSubmittedToGemini vestigial on primary path
#7 ✅ Not dead — queryPreparer.ts still consumes scheduleToolCalls
#8 🔴 Real gap — idle-timeout/watchdog test coverage not replaced in new suite
#9 ⚠️ Low risk — as Config cast is a known tradeoff
#10 📝 Trivial — events field in TurnToolResult can be removed

The only genuinely new actionable finding is #8: the deleted watchdog test suite's StreamIdleTimeout and environment-config scenarios have no coverage in the new integration suite. Would you like me to open a tracking issue for that gap, and/or for the #10 TurnToolResult.events cleanup?

@acoliver

Copy link
Copy Markdown
Collaborator Author

Follow-up for #2050 (comment):

Actions taken:

Evaluated and not changed here:

  • The abort cancelAll event gap was already addressed in eae12b1, with behavioral coverage for the final cancelled tool update.
  • The idle-timeout/watchdog concern appears broader than the deleted CLI wrapper test. Current coverage exists in core/agents for stream idle timeout resolution and StreamIdleTimeout terminal handling, including packages/core/src/utils/streamIdleTimeout.test.ts and packages/agents/src/core/turn.test.ts. The deleted CLI test targeted a removed CLI stream-consuming wrapper, so I am not reintroducing that wrapper test in this PR.

Verification for the new cleanup:

  • AgenticLoop integration test: 29 passed.
  • npm run typecheck passed.
  • npm run format passed.

@acoliver acoliver merged commit e0a12bd into main Jun 16, 2026
23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

maintainer:e2e:ok Trusted contributor; maintainer-approved E2E run

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Consolidate the agentic turn loop into the engine (agents package) with policy + approval injection points (Parent #1568)

1 participant