Skip to content

feat: holaOS-inspired agent improvements#90

Open
mabry1985 wants to merge 30 commits intomainfrom
dev
Open

feat: holaOS-inspired agent improvements#90
mabry1985 wants to merge 30 commits intomainfrom
dev

Conversation

@mabry1985
Copy link
Copy Markdown

@mabry1985 mabry1985 commented Apr 20, 2026

Summary

  • Cron persistence — scheduled jobs survive session restarts via cron-jobs.json on disk
  • Capability manifest — active MCP tools enumerated in system prompt to prevent hallucinated tool names
  • Memory staleness — per-type expiry windows (project=21d, reference=7d) with inline freshness warnings
  • Memory proposal lane — extractions routed through proposals/ dir; /memory proposals|accept|reject for explicit approval
  • Permission blocker persistence — repeated tool denials tracked in permission-blockers.json and injected into system prompt
  • Evolve pipeline — post-turn headless agent detects reusable workflow patterns every 3 turns, drafts SKILL.md candidates
  • Prompt volatility tagsPromptSection / assemblePromptSections() formalize stable → workspace → run ordering with CACHE_BOUNDARY_SENTINEL for provider-side prompt caching

Test plan

  • All 215 core test files pass (npx vitest run packages/core/src)
  • TypeScript clean across core and cli (npx tsc --noEmit)
  • Snapshot tests updated for cron docs and prompt content changes
  • client.test.ts mock updated for assemblePromptSections

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • New Features
    • Memory proposals workflow: propose, accept, or reject memory changes via new /memory subcommands
    • Cron jobs now persist across sessions and automatically resume
    • Automatic skill evolution learns workflow patterns from conversations
    • Permission blocking for tools after repeated user denials
    • Type-aware memory staleness warnings with guidance

Automaker and others added 30 commits April 14, 2026 16:22
- prepare-release.yml: fires on PR merge to dev (not main); version bump
  PR targets dev instead of main
- release.yml: triggers on dev→main PR merge instead of commit message
  on push; adds sync-back step to keep dev aligned with main after release

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(ui): apply ASCII logo gradient by X column, not string index

ink-gradient maps colors by character index across the whole string, so
the p descender (last two lines) always got the tail/pink color regardless
of its leftward visual position.

Fix: render each logo line separately with its own <Gradient>, padded to
logoWidth so column X maps to the same gradient fraction on every line.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(ui): remove Static windowing that caused messages to disappear

Ink's <Static> tracks rendered items by array INDEX, not React key.
It stores the last array length and slices from that index on each render.
When the array stops growing (constant length), the index overshoots
and nothing new is printed — causing streamed messages to vanish.

PR #45 introduced two patterns that broke this invariant:
1. STATIC_HISTORY_WINDOW=200 in MainContent.tsx — sliding window kept
   the array at a constant 204 items (3 fixed + 200 history + banner),
   so after the 201st history item nothing was ever printed by Static.
2. MAX_HISTORY_ITEMS=500 in useHistoryManager.ts — pruning the front
   of the array kept it at exactly 500 items, same effect.
3. Same AGENT_STATIC_HISTORY_WINDOW=200 windowing in AgentChatView.tsx.

Fix: pass all history items to Static (array only ever grows).
Remove TruncatedHistoryBanner from within Static (it can't update
once committed to the terminal anyway, and its conditional insertion
shifted existing indices on first appearance).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Automaker <automaker@localhost>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
…rotection)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… failure

- schemaValidator: add Array.isArray guard so array tool params return
  'Value of params must be an object' immediately instead of reaching AJV
- openai converter: return plain string content for text-only tool messages
  instead of [{type:'text',...}] array — LiteLLM and most OpenAI-compatible
  local providers only accept string content and crash on array content parts

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Single-text tool responses (validation errors, simple outputs) now return
content as a plain string instead of [{type:'text',text:'...'}] array.
Many OpenAI-compatible providers (LiteLLM, local models) only accept string
content in tool messages and crash with 'Can only get item pairs from a
mapping' on array content.

Multi-part responses (text+media, multi-text blocks, unsupported media
placeholders) keep array format to preserve all content parts.

Reverts the overly broad Array.isArray guard in schemaValidator — AJV already
rejects arrays for object-typed schemas, and the guard incorrectly blocked
valid array inputs for 2020-12 prefixItems schemas.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…on cascade

When a weak/local model hits max_tokens and produces empty responses,
tool errors accumulate in context causing subsequent calls to also fail
with NO_RESPONSE_TEXT. Add trimToolErrorsFromContext() to strip trailing
model-tool-call + user-tool-error pairs (up to 6 pairs), then attempt
one final recovery call with the cleaned context before giving up.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
When a model hits max_tokens mid-tool-call (producing Shell {}), the
truncation error gets re-added to context making the next turn also
overflow. At the start of each sendMessageStream, detect the cascade
(truncation-guidance marker in the last user turn) and pre-trim:
1. Remove the error tool-call pairs (trimToolErrorsFromContext)
2. Cap any large preceding tool responses to 10K chars

This prevents the Shell {} → error → Shell {} loop that affected both
weak models and frontier models (Claude Sonnet) on large tool outputs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
… history

When dev→main is squash-merged, the tag-to-tag git log only shows
"chore: release" commits which get filtered, silently skipping the
Discord post. Add a fallback that checks origin/dev (which retains the
individual commits at release time) and a post-discord.yml workflow
for manual backfill.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
ACP tests were hardcoded to use `methodId: 'openai'` and the e2e
workflow passed OPENAI_API_KEY, which is not configured in CI. Since
protoCLI uses Anthropic as its primary provider, update everything to
use Anthropic auth:

- authMethods.ts: expose USE_ANTHROPIC instead of USE_OPENAI
- acp-integration.test.ts: change authenticate to methodId 'anthropic',
  update openaiModel selector to anthropicModel, skip qwen-oauth test
  (Qwen-specific model type, no equivalent in protoCLI)
- acp-cron.test.ts: same authenticate change
- e2e.yml: pass ANTHROPIC_API_KEY instead of OpenAI secrets

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
The LiteLLM gateway uses USE_OPENAI auth (OPENAI_API_KEY + OPENAI_BASE_URL
+ OPENAI_MODEL). The v0.25.17 change to Anthropic auth was incorrect.

Reverts all test and workflow changes back to openai methodId and
OPENAI_* secrets. The actual fix required is adding the three gateway
secrets (OPENAI_API_KEY, OPENAI_BASE_URL, OPENAI_MODEL) to GitHub
repository secrets.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ACP tests require gateway credentials that are not configured in CI.
Since ACP is not currently in use, skip these tests automatically
when OPENAI_API_KEY is absent rather than failing the E2E job.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
- sdk.ts: route Langfuse-only log/metric exporters to OTLP endpoints
  instead of ConsoleLog/MetricExporter to prevent terminal spam
- loggingContentGenerator: wrap generateContentStream in llm.generate
  span; pass span into loggingStreamWrapper and close with token counts
  on success/error
- agent-headless: create agent.execute span under turn context; wrap
  runReasoningLoop in otelContext.with() for proper child span linkage
- harnessTelemetry: remove dead recordSprintContract() never called
- gemini.tsx: register shutdownTelemetry() in cleanup so OTel SDK
  flushes spans before interactive REPL exits

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
- Persist cron jobs to disk so scheduled tasks survive session restarts
- Inject capability manifest (active MCP tools) into system prompt to prevent hallucinated tool names
- Add per-type memory staleness thresholds (project=21d, reference=7d) with inline freshness warnings
- Route memory extractions through a proposal lane (/memory proposals|accept|reject) instead of writing directly
- Track repeated tool denials in permission-blockers.json and inject reminders into system prompt
- Add post-turn evolve pipeline: headless agent detects reusable workflow patterns every 3 turns and drafts SKILL.md candidates
- Formalize prompt section volatility tags (stable/workspace/run) with assemblePromptSections() and CACHE_BOUNDARY_SENTINEL for provider-side caching

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 20, 2026

Walkthrough

This pull request introduces a multi-layered memory and tool management system. It adds memory proposal workflows via CLI commands, implements permission blocking for repeatedly-denied tools, introduces an evolve service for periodic skill detection, refactors prompt assembly with volatility-aware caching, persists cron job state across sessions, and updates memory staleness tracking with type-specific thresholds.

Changes

Cohort / File(s) Summary
Memory Proposal Workflow
packages/cli/src/ui/commands/memoryCommand.ts, packages/core/src/memory/proposalStore.ts, packages/core/src/memory/index.ts
Added /memory proposals, /memory accept, and /memory reject subcommands that manage proposal workflow. New proposalStore.ts module handles listing, accepting, and rejecting proposals; proposals directory is resolved separately from main memory storage and files are moved to memory directory only upon acceptance.
Prompt Assembly & System Instructions
packages/core/src/core/prompts.ts, packages/core/src/core/client.ts, packages/core/src/core/client.test.ts
Introduced volatility-based prompt assembly with PromptSection types (stable/workspace/run), assemblePromptSections() function, and buildCapabilityManifest() for MCP tool enumeration. Refactored system prompt construction in client to use structured assembly pipeline with capability manifest and permission blocker notes inserted at appropriate volatility levels.
Permission Blocking & Tool Denials
packages/core/src/services/permissionBlockerService.ts, packages/core/src/core/coreToolScheduler.ts, packages/core/src/config/config.ts
New PermissionBlockerService persists and tracks tool denials; when denial threshold is reached, blocked tools are added to system prompt via blocker note. Wired into Config as lazy-initialized service and integrated into tool confirmation cancellation flow.
Session Persistence
packages/core/src/services/cronScheduler.ts, packages/core/src/config/storage.ts, packages/core/src/services/cronScheduler.test.ts
Extended CronScheduler with optional disk persistence path; loads/prunes expired jobs on init and persists state after modifications. Storage now provides project-specific and global cron job paths. Updated exit summary messaging to indicate jobs are "saved (will resume next session)".
Evolve Service
packages/core/src/services/evolveService.ts, packages/cli/src/ui/hooks/useGeminiStream.ts, packages/core/src/index.ts
New evolve service periodically analyzes recent conversation history to detect reusable multi-step workflow patterns and drafts skills. Triggered fire-and-forget after each completed Gemini turn; runs headless agent with bounded execution.
Memory Management & Staleness
packages/core/src/memory/memoryAge.ts, packages/core/src/memory/memoryExtractor.ts, packages/core/src/memory/memoryStore.ts, packages/core/src/services/memory-consolidation.ts
Updated memory staleness logic with type-specific thresholds and guidance; memoryExtractor now writes proposals instead of directly persisting memories; memoryStore includes staleness warnings in generated MEMORY.md index.

Sequence Diagrams

sequenceDiagram
    participant User
    participant CLI as Memory Command
    participant Store as Proposal Store
    participant MemDir as Memory Directory
    
    User->>CLI: /memory proposals
    CLI->>Store: listProposals(project & global)
    Store->>MemDir: scan proposals/ directory
    MemDir-->>Store: proposal files with frontmatter
    Store-->>CLI: formatted proposal list
    CLI-->>User: display proposals with IDs
    
    User->>CLI: /memory accept <id>
    CLI->>Store: find proposal by ID
    Store-->>CLI: matching proposal path
    CLI->>Store: acceptProposal(path)
    Store->>MemDir: move proposal to memory/
    Store->>MemDir: regenerateIndex()
    MemDir-->>Store: index updated
    Store-->>CLI: success
    CLI-->>User: "Accepted memory"
Loading
sequenceDiagram
    participant User
    participant Scheduler as Tool Scheduler
    participant Confirm as Confirmation UI
    participant Blocker as Permission Blocker
    participant Prompt as System Prompt
    
    Scheduler->>Scheduler: execute tool call
    Scheduler->>Confirm: present confirmation dialog
    User->>Confirm: cancel/deny
    Confirm->>Scheduler: ToolConfirmationOutcome.Cancel
    Scheduler->>Blocker: recordDenial(toolName)
    Blocker->>Blocker: increment denial count
    
    Note over Blocker: Check if threshold reached
    alt Threshold met
        Blocker->>Blocker: persist to disk
    end
    
    Scheduler->>Prompt: next turn starts
    Prompt->>Blocker: getBlockedTools()
    Blocker-->>Prompt: list of blocked tools
    Prompt->>Prompt: buildPromptNote()
    Prompt->>Prompt: include in system instruction
Loading
sequenceDiagram
    participant Chat as Gemini Chat
    participant Stream as useGeminiStream
    participant Evolve as Evolve Service
    participant Agent as Headless Agent
    participant SkillDir as Skills Directory
    
    Chat->>Stream: turn completed
    Stream->>Stream: finally block triggered
    Stream->>Evolve: runEvolvePass(config, recentMessages)
    
    Evolve->>Evolve: check turn counter vs SKILL_REVIEW_INTERVAL
    alt Trigger conditions met
        Evolve->>SkillDir: getExistingSkillNames()
        SkillDir-->>Evolve: skill names
        Evolve->>Evolve: buildEvolvePrompt(messages, skills)
        Evolve->>Agent: execute bounded headless agent
        Agent->>SkillDir: write drafted skill files
        SkillDir-->>Agent: success
        Agent-->>Evolve: completion
        Evolve->>Evolve: log completion
    else Trigger not met
        Evolve->>Evolve: skip this turn
    end
    
    Evolve-->>Stream: (fire-and-forget, errors suppressed)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: holaOS-inspired agent improvements' clearly identifies the main change as a feature addition focused on agent improvements inspired by holaOS, which aligns with the extensive changeset across core services, memory, CLI, and prompt assembly.
Description check ✅ Passed The PR description covers all major sections of the template: TLDR with a comprehensive summary of changes, test plan with passing test results, and linked issues reference. While screenshots/demo and detailed reviewer test plan are minimal, the description is substantially complete with actionable testing information.
Docstring Coverage ✅ Passed Docstring coverage is 84.62% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dev

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 10

Caution

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

⚠️ Outside diff range comments (2)
packages/core/src/core/coreToolScheduler.ts (1)

1193-1201: ⚠️ Potential issue | 🟠 Major

Don’t record blocker denials for generic aborts.

Line [1193] currently treats signal.aborted as equivalent to explicit user denial. That can incorrectly persist blockers for cancellations not initiated as denials.

[suggested fix: record denial only on explicit ToolConfirmationOutcome.Cancel]

💡 Proposed patch
-    if (outcome === ToolConfirmationOutcome.Cancel || signal.aborted) {
+    if (outcome === ToolConfirmationOutcome.Cancel || signal.aborted) {
       // Use custom cancel message from payload if provided, otherwise use default
       const cancelMessage =
         payload?.cancelMessage || 'User did not allow tool call';
       this.setStatusInternal(callId, 'cancelled', cancelMessage);
-      // Record the denial so persistent blockers can warn the agent next session
-      this.config
-        .getPermissionBlockerService?.()
-        ?.recordDenial(toolCall.request.name);
+      // Only explicit user denial should affect persistent blockers.
+      if (outcome === ToolConfirmationOutcome.Cancel) {
+        this.config
+          .getPermissionBlockerService?.()
+          ?.recordDenial(toolCall.request.name);
+      }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/core/coreToolScheduler.ts` around lines 1193 - 1201, The
code currently records a permission denial whenever outcome is
ToolConfirmationOutcome.Cancel OR signal.aborted; change the logic so the
persistent blocker denial
(this.config.getPermissionBlockerService?.()?.recordDenial(toolCall.request.name))
is executed only when the outcome is explicitly ToolConfirmationOutcome.Cancel.
Keep the existing cancel status handling (this.setStatusInternal(callId,
'cancelled', ...)) for both cases, but guard the recordDenial call behind
outcome === ToolConfirmationOutcome.Cancel in the method handling tool
confirmation results in coreToolScheduler (the block that uses callId,
setStatusInternal, payload?.cancelMessage and toolCall.request.name).
packages/core/src/services/cronScheduler.ts (1)

323-326: ⚠️ Potential issue | 🟠 Major

destroy() should persist the cleared state.

With disk persistence enabled, clearing jobs only in memory means destroyed jobs can reappear next session if the process exits before another save.

💡 Proposed patch
   destroy(): void {
     this.stop();
     this.jobs.clear();
+    this.saveToDisk();
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/services/cronScheduler.ts` around lines 323 - 326, The
destroy() method currently stops the scheduler and clears this.jobs only in
memory; update it to persist the cleared state to disk by invoking the same
persistence routine used elsewhere (e.g., the method that saves jobs to disk
such as saveJobs(), persistJobs(), save(), or persist()) right after
this.jobs.clear(); ensure you call it only when disk persistence is enabled,
await/handle it if it is async, and surface/log any errors so the empty state is
durably written.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/core/src/core/client.test.ts`:
- Around line 291-297: The current mock of assemblePromptSections in
client.test.ts flattens sections and loses volatility ordering and
cache-boundary behavior; update the test mock to either call the real
assemblePromptSections implementation or implement the same ordering and
cache-boundary logic so tests exercise real assembly semantics: ensure the mock
honors PromptSection.volatility ordering (stable sort/grouping by volatility)
and preserves cacheBoundary boundaries between sections before joining contents.
Target the vi.mocked(assemblePromptSections) replacement so it returns results
consistent with the real assemblePromptSections behavior rather than simply
filtering and joining content.

In `@packages/core/src/core/client.ts`:
- Around line 318-329: The override path wrongly places dynamic content from
getCustomSystemPrompt(overrideSystemPrompt, userMemory, appendSystemPrompt) into
the 'stable' bucket; change the assemblePromptSections call so the returned base
is treated as workspace (or split static vs memory if you can extract static
portion) rather than 'stable' — update the mapping in the override branch that
currently returns [{ volatility: 'stable', content: base }, ...] to use
'workspace' for the dynamic parts (reference: overrideSystemPrompt,
getCustomSystemPrompt, assemblePromptSections, userMemory, appendSystemPrompt).
- Around line 300-312: The capabilityManifest call is passing an empty
activeSkills array (hardcoded `[]`), so skills are never included; update the
block that builds capabilityManifest to compute an activeSkills array from the
tools returned by toolRegistry.getAllTools() (filtering for skill-type tools —
e.g., instances or flags that identify skills) and pass that array to
buildCapabilityManifest instead of `[]` (refer to toolRegistry.getAllTools,
DiscoveredMCPTool, capabilityManifest and buildCapabilityManifest to locate the
code to change).

In `@packages/core/src/core/prompts.ts`:
- Around line 1278-1294: Sanitize all externally-provided capability metadata
before adding to the system prompt: when building the MCP tools block
(mcpToolsByServer) and the skills block (activeSkills), escape or strip
newline/control characters and markdown-special characters from server names
(server), tool names (tools elements), skill names (skill.name) and skill
descriptions (skill.description), and enforce reasonable length limits (e.g.,
truncate descriptions and names) so that interpolated values cannot inject
newlines or markup that would alter the prompt structure; apply this filtering
inside the same prompt-construction flow where mcpToolsByServer and activeSkills
are iterated (the block that builds lines and pushes to sections).

In `@packages/core/src/memory/proposalStore.ts`:
- Around line 87-93: The current rename to destPath (path.join(memoryDir,
path.basename(proposalFilePath))) can overwrite an existing file; modify the
accept/rename logic in this module (where destPath, memoryDir, and
proposalFilePath are used, and regenerateIndex(scope, cwd) is called) to first
check if destPath already exists and then either (a) fail with a clear
error/exception to avoid silent overwrite, or (b) generate a unique
non-colliding destination (e.g., append a numeric or timestamp suffix to the
basename) before calling fs.rename, ensuring you preserve atomic behavior and
still call regenerateIndex(scope, cwd) only after a successful move.
- Around line 81-110: Ensure acceptProposal and rejectProposal validate that the
provided proposalFilePath is actually inside the proposals directory before
mutating files: compute proposalsDir = getProposalsDir(scope, cwd) and resolve
both proposalsDir and proposalFilePath to absolute/real paths, then verify the
proposal path is within proposalsDir (e.g., via path.relative and ensuring it
does not start with '..' and is not equal to '' when normalized) before calling
fs.rename or fs.unlink; if the check fails, return null from acceptProposal and
false from rejectProposal without performing any filesystem operations and do
not call regenerateIndex unless the move succeeded.

In `@packages/core/src/services/cronScheduler.ts`:
- Around line 106-130: Persisted one-shot jobs are dropped because
JSON.stringify turns expiresAt = Infinity into null and loadFromDisk rejects
nulls; update loadFromDisk to treat job.expiresAt === null or job.expiresAt ===
undefined as Infinity before comparing to now (i.e., set job.expiresAt =
Number.POSITIVE_INFINITY when null/undefined), and ensure destroy() calls
saveToDisk() after clearing this.jobs so the cleared state is persisted; adjust
references in loadFromDisk, saveToDisk, and destroy to use the CronJob.expiresAt
normalization and persistence call.

In `@packages/core/src/services/evolveService.ts`:
- Around line 37-50: The global turnsSinceLastReview counter causes
cross-session interference; make the cadence state per-project/session instead:
remove/stop using the module-global turnsSinceLastReview and track counts keyed
by a unique session/project identifier (e.g. a sessionId or projectId available
on Config) using a Map (e.g. evolveTurnsBySession) or store the counter on the
Config object, then update runEvolvePass to read/increment/reset the per-session
counter using SKILL_REVIEW_INTERVAL and the chosen key, and ensure the counter
is reset to 0 when the interval fires so each session's evolve cadence is
isolated.

In `@packages/core/src/services/permissionBlockerService.ts`:
- Around line 61-70: The recordDenial method currently only calls saveToDisk
when updated.count >= DENY_THRESHOLD causing sub-threshold denials to be lost
across restarts; update recordDenial (which updates this.denials and builds
DenialRecord) to persist every update by calling saveToDisk after
this.denials.set(toolName, updated) (or implement a short debounce/persist
strategy if needed) so each denial event is written to disk rather than only
when the threshold is reached.

---

Outside diff comments:
In `@packages/core/src/core/coreToolScheduler.ts`:
- Around line 1193-1201: The code currently records a permission denial whenever
outcome is ToolConfirmationOutcome.Cancel OR signal.aborted; change the logic so
the persistent blocker denial
(this.config.getPermissionBlockerService?.()?.recordDenial(toolCall.request.name))
is executed only when the outcome is explicitly ToolConfirmationOutcome.Cancel.
Keep the existing cancel status handling (this.setStatusInternal(callId,
'cancelled', ...)) for both cases, but guard the recordDenial call behind
outcome === ToolConfirmationOutcome.Cancel in the method handling tool
confirmation results in coreToolScheduler (the block that uses callId,
setStatusInternal, payload?.cancelMessage and toolCall.request.name).

In `@packages/core/src/services/cronScheduler.ts`:
- Around line 323-326: The destroy() method currently stops the scheduler and
clears this.jobs only in memory; update it to persist the cleared state to disk
by invoking the same persistence routine used elsewhere (e.g., the method that
saves jobs to disk such as saveJobs(), persistJobs(), save(), or persist())
right after this.jobs.clear(); ensure you call it only when disk persistence is
enabled, await/handle it if it is async, and surface/log any errors so the empty
state is durably written.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 8f91be83-55ce-42e1-b77a-a819a1f1a88e

📥 Commits

Reviewing files that changed from the base of the PR and between 27aee4d and f03a56d.

⛔ Files ignored due to path filters (1)
  • packages/core/src/core/__snapshots__/prompts.test.ts.snap is excluded by !**/*.snap
📒 Files selected for processing (19)
  • packages/cli/src/ui/commands/memoryCommand.ts
  • packages/cli/src/ui/hooks/useGeminiStream.ts
  • packages/core/src/config/config.ts
  • packages/core/src/config/storage.ts
  • packages/core/src/core/client.test.ts
  • packages/core/src/core/client.ts
  • packages/core/src/core/coreToolScheduler.ts
  • packages/core/src/core/prompts.ts
  • packages/core/src/index.ts
  • packages/core/src/memory/index.ts
  • packages/core/src/memory/memoryAge.ts
  • packages/core/src/memory/memoryExtractor.ts
  • packages/core/src/memory/memoryStore.ts
  • packages/core/src/memory/proposalStore.ts
  • packages/core/src/services/cronScheduler.test.ts
  • packages/core/src/services/cronScheduler.ts
  • packages/core/src/services/evolveService.ts
  • packages/core/src/services/memory-consolidation.ts
  • packages/core/src/services/permissionBlockerService.ts

Comment on lines +291 to +297
vi.mocked(assemblePromptSections).mockImplementation(
(sections: PromptSection[]) =>
sections
.filter((s) => s.content)
.map((s) => s.content)
.join('\n\n'),
);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Mock is too simplified for prompt-section behavior.

This mock drops volatility ordering and cache-boundary behavior, so tests can pass while real prompt assembly breaks.

💡 Proposed patch
-    vi.mocked(assemblePromptSections).mockImplementation(
-      (sections: PromptSection[]) =>
-        sections
-          .filter((s) => s.content)
-          .map((s) => s.content)
-          .join('\n\n'),
-    );
+    const actualPrompts = await vi.importActual<typeof import('./prompts.js')>(
+      './prompts.js',
+    );
+    vi.mocked(assemblePromptSections).mockImplementation(
+      (sections: PromptSection[]) =>
+        actualPrompts.assemblePromptSections(sections),
+    );
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/core/client.test.ts` around lines 291 - 297, The current
mock of assemblePromptSections in client.test.ts flattens sections and loses
volatility ordering and cache-boundary behavior; update the test mock to either
call the real assemblePromptSections implementation or implement the same
ordering and cache-boundary logic so tests exercise real assembly semantics:
ensure the mock honors PromptSection.volatility ordering (stable sort/grouping
by volatility) and preserves cacheBoundary boundaries between sections before
joining contents. Target the vi.mocked(assemblePromptSections) replacement so it
returns results consistent with the real assemblePromptSections behavior rather
than simply filtering and joining content.

Comment on lines +300 to 312
// --- workspace: capability manifest of session-specific MCP tools ---
let capabilityManifest = '';
if (toolRegistry && typeof toolRegistry.getAllTools === 'function') {
const mcpToolsByServer = new Map<string, string[]>();
for (const tool of toolRegistry.getAllTools()) {
if (tool instanceof DiscoveredMCPTool) {
const existing = mcpToolsByServer.get(tool.serverName) ?? [];
existing.push(tool.name);
mcpToolsByServer.set(tool.serverName, existing);
}
}
capabilityManifest = buildCapabilityManifest(mcpToolsByServer, []) ?? '';
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

The capability manifest never includes active skills from this path.

Line 311 hardcodes [] for activeSkills, so the skills section added in buildCapabilityManifest() can never render here. That means slash-command/skill capabilities are still invisible to the model even when they are available in the session.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/core/client.ts` around lines 300 - 312, The
capabilityManifest call is passing an empty activeSkills array (hardcoded `[]`),
so skills are never included; update the block that builds capabilityManifest to
compute an activeSkills array from the tools returned by
toolRegistry.getAllTools() (filtering for skill-type tools — e.g., instances or
flags that identify skills) and pass that array to buildCapabilityManifest
instead of `[]` (refer to toolRegistry.getAllTools, DiscoveredMCPTool,
capabilityManifest and buildCapabilityManifest to locate the code to change).

Comment on lines +314 to +316
// --- run: per-turn permission blockers ---
const blockerNote =
this.config.getPermissionBlockerService?.()?.buildPromptNote() ?? '';
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

blockerNote is labeled per-turn, but it won't refresh for ongoing chats.

getMainSessionSystemInstruction() is only used when the chat is created/reset and for one-off generateContent() calls. After a permission denial is recorded, this note will stay stale for the active GeminiChat, so the next streamed turn will not see the new blocker guidance unless the chat happens to be rebuilt.

Comment on lines +318 to +329
if (overrideSystemPrompt) {
const base = getCustomSystemPrompt(
overrideSystemPrompt,
userMemory,
this.config.getModel(),
appendSystemPrompt,
).full + mcpInstructions
);
return assemblePromptSections([
{ volatility: 'stable', content: base },
{ volatility: 'workspace', content: mcpInstructions },
{ volatility: 'workspace', content: capabilityManifest },
{ volatility: 'run', content: blockerNote },
]);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

The override path is caching dynamic memory as stable.

getCustomSystemPrompt() already appends userMemory and appendSystemPrompt, and Line 325 then places that combined string in the stable bucket. That regresses the volatility split you preserved in the core-prompt branch: session-specific memory and freshness warnings end up before the cache boundary instead of in the workspace section.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/core/client.ts` around lines 318 - 329, The override path
wrongly places dynamic content from getCustomSystemPrompt(overrideSystemPrompt,
userMemory, appendSystemPrompt) into the 'stable' bucket; change the
assemblePromptSections call so the returned base is treated as workspace (or
split static vs memory if you can extract static portion) rather than 'stable' —
update the mapping in the override branch that currently returns [{ volatility:
'stable', content: base }, ...] to use 'workspace' for the dynamic parts
(reference: overrideSystemPrompt, getCustomSystemPrompt, assemblePromptSections,
userMemory, appendSystemPrompt).

Comment on lines +1278 to +1294
if (mcpToolsByServer.size > 0) {
const lines: string[] = ['**MCP tools available this session:**'];
for (const [server, tools] of mcpToolsByServer) {
lines.push(` • ${server}: ${tools.join(', ')}`);
}
sections.push(lines.join('\n'));
}

if (activeSkills.length > 0) {
const lines: string[] = ['**Skills (invoke via /skill or agent tool):**'];
for (const skill of activeSkills) {
const desc = skill.description
? ` — ${skill.description.slice(0, 80)}${skill.description.length > 80 ? '…' : ''}`
: '';
lines.push(` • /${skill.name}${desc}`);
}
sections.push(lines.join('\n'));
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Sanitize capability metadata before putting it in the system prompt.

Lines 1281 and 1292 interpolate MCP server names, tool names, skill names, and descriptions verbatim into a high-privilege prompt. Those values are not inherently trusted, so a malicious server or crafted skill metadata can inject newlines/markdown/XML-looking content and steer the model with prompt text you did not author.

Suggested hardening
+function sanitizePromptValue(value: string): string {
+  return value.replace(/[\r\n]+/g, ' ').replace(/[<>]/g, '').trim();
+}
+
 export function buildCapabilityManifest(
   mcpToolsByServer: Map<string, string[]>,
   activeSkills: Array<{ name: string; description: string }>,
 ): string | null {
   const sections: string[] = [];
@@
   if (mcpToolsByServer.size > 0) {
     const lines: string[] = ['**MCP tools available this session:**'];
     for (const [server, tools] of mcpToolsByServer) {
-      lines.push(`  • ${server}: ${tools.join(', ')}`);
+      lines.push(
+        `  • ${sanitizePromptValue(server)}: ${tools.map(sanitizePromptValue).join(', ')}`,
+      );
     }
     sections.push(lines.join('\n'));
   }
@@
     for (const skill of activeSkills) {
-      const desc = skill.description
-        ? ` — ${skill.description.slice(0, 80)}${skill.description.length > 80 ? '…' : ''}`
+      const safeDescription = sanitizePromptValue(skill.description);
+      const desc = safeDescription
+        ? ` — ${safeDescription.slice(0, 80)}${safeDescription.length > 80 ? '…' : ''}`
         : '';
-      lines.push(`  • /${skill.name}${desc}`);
+      lines.push(`  • /${sanitizePromptValue(skill.name)}${desc}`);
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/core/prompts.ts` around lines 1278 - 1294, Sanitize all
externally-provided capability metadata before adding to the system prompt: when
building the MCP tools block (mcpToolsByServer) and the skills block
(activeSkills), escape or strip newline/control characters and markdown-special
characters from server names (server), tool names (tools elements), skill names
(skill.name) and skill descriptions (skill.description), and enforce reasonable
length limits (e.g., truncate descriptions and names) so that interpolated
values cannot inject newlines or markup that would alter the prompt structure;
apply this filtering inside the same prompt-construction flow where
mcpToolsByServer and activeSkills are iterated (the block that builds lines and
pushes to sections).

Comment on lines +81 to +110
export async function acceptProposal(
proposalFilePath: string,
scope: MemoryScope,
cwd?: string,
): Promise<string | null> {
const memoryDir = getMemoryDir(scope, cwd);
const destPath = path.join(memoryDir, path.basename(proposalFilePath));

try {
await fs.mkdir(memoryDir, { recursive: true });
await fs.rename(proposalFilePath, destPath);
await regenerateIndex(scope, cwd);
return destPath;
} catch {
return null;
}
}

/**
* Reject (delete) a proposal file.
*/
export async function rejectProposal(
proposalFilePath: string,
): Promise<boolean> {
try {
await fs.unlink(proposalFilePath);
return true;
} catch {
return false;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Enforce proposals-directory boundary before file mutations.

Lines 81-110 move/delete whichever path is passed in. Please validate that proposalFilePath resolves under getProposalsDir(scope, cwd) before rename/unlink.

🔒 Suggested fix
+function assertPathInsideDir(targetPath: string, baseDir: string): void {
+  const resolvedTarget = path.resolve(targetPath);
+  const resolvedBase = path.resolve(baseDir) + path.sep;
+  if (!resolvedTarget.startsWith(resolvedBase)) {
+    throw new Error('Proposal path is outside proposals directory');
+  }
+}

 export async function acceptProposal(
   proposalFilePath: string,
   scope: MemoryScope,
   cwd?: string,
 ): Promise<string | null> {
+  const proposalsDir = getProposalsDir(scope, cwd);
+  assertPathInsideDir(proposalFilePath, proposalsDir);
   const memoryDir = getMemoryDir(scope, cwd);
   const destPath = path.join(memoryDir, path.basename(proposalFilePath));

   try {
@@
 export async function rejectProposal(
   proposalFilePath: string,
+  scope: MemoryScope,
+  cwd?: string,
 ): Promise<boolean> {
   try {
+    const proposalsDir = getProposalsDir(scope, cwd);
+    assertPathInsideDir(proposalFilePath, proposalsDir);
     await fs.unlink(proposalFilePath);
     return true;
   } catch {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/memory/proposalStore.ts` around lines 81 - 110, Ensure
acceptProposal and rejectProposal validate that the provided proposalFilePath is
actually inside the proposals directory before mutating files: compute
proposalsDir = getProposalsDir(scope, cwd) and resolve both proposalsDir and
proposalFilePath to absolute/real paths, then verify the proposal path is within
proposalsDir (e.g., via path.relative and ensuring it does not start with '..'
and is not equal to '' when normalized) before calling fs.rename or fs.unlink;
if the check fails, return null from acceptProposal and false from
rejectProposal without performing any filesystem operations and do not call
regenerateIndex unless the move succeeded.

Comment on lines +87 to +93
const destPath = path.join(memoryDir, path.basename(proposalFilePath));

try {
await fs.mkdir(memoryDir, { recursive: true });
await fs.rename(proposalFilePath, destPath);
await regenerateIndex(scope, cwd);
return destPath;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Prevent accidental overwrite when accepting proposals.

Lines 87-93 rename to memoryDir/<basename>. If that file already exists, this can overwrite or fail depending on platform, risking silent data loss/ambiguous behavior.

🛡️ Suggested fix
 export async function acceptProposal(
   proposalFilePath: string,
   scope: MemoryScope,
   cwd?: string,
 ): Promise<string | null> {
   const memoryDir = getMemoryDir(scope, cwd);
   const destPath = path.join(memoryDir, path.basename(proposalFilePath));

   try {
     await fs.mkdir(memoryDir, { recursive: true });
+    const exists = await fs
+      .stat(destPath)
+      .then(() => true)
+      .catch(() => false);
+    if (exists) return null;
     await fs.rename(proposalFilePath, destPath);
     await regenerateIndex(scope, cwd);
     return destPath;
   } catch {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const destPath = path.join(memoryDir, path.basename(proposalFilePath));
try {
await fs.mkdir(memoryDir, { recursive: true });
await fs.rename(proposalFilePath, destPath);
await regenerateIndex(scope, cwd);
return destPath;
const destPath = path.join(memoryDir, path.basename(proposalFilePath));
try {
await fs.mkdir(memoryDir, { recursive: true });
const exists = await fs
.stat(destPath)
.then(() => true)
.catch(() => false);
if (exists) return null;
await fs.rename(proposalFilePath, destPath);
await regenerateIndex(scope, cwd);
return destPath;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/memory/proposalStore.ts` around lines 87 - 93, The current
rename to destPath (path.join(memoryDir, path.basename(proposalFilePath))) can
overwrite an existing file; modify the accept/rename logic in this module (where
destPath, memoryDir, and proposalFilePath are used, and regenerateIndex(scope,
cwd) is called) to first check if destPath already exists and then either (a)
fail with a clear error/exception to avoid silent overwrite, or (b) generate a
unique non-colliding destination (e.g., append a numeric or timestamp suffix to
the basename) before calling fs.rename, ensuring you preserve atomic behavior
and still call regenerateIndex(scope, cwd) only after a successful move.

Comment on lines +106 to +130
private loadFromDisk(): void {
if (!this.persistPath) return;
try {
const raw = fs.readFileSync(this.persistPath, 'utf-8');
const jobs = JSON.parse(raw) as CronJob[];
const now = Date.now();
for (const job of jobs) {
if (now < job.expiresAt) {
this.jobs.set(job.id, job);
}
}
} catch {
// File doesn't exist or is corrupt — start with empty store
}
}

private saveToDisk(): void {
if (!this.persistPath) return;
try {
fs.mkdirSync(path.dirname(this.persistPath), { recursive: true });
fs.writeFileSync(
this.persistPath,
JSON.stringify([...this.jobs.values()], null, 2),
'utf-8',
);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
node -e 'const raw = JSON.stringify([{expiresAt: Infinity}]); const parsed = JSON.parse(raw); console.log(raw); console.log("expiresAt:", parsed[0].expiresAt, "comparison:", Date.now() < parsed[0].expiresAt);'

Repository: protoLabsAI/protoCLI

Length of output: 118


🏁 Script executed:

find . -name "cronScheduler.ts" -type f

Repository: protoLabsAI/protoCLI

Length of output: 109


🏁 Script executed:

cat -n ./packages/core/src/services/cronScheduler.ts

Repository: protoLabsAI/protoCLI

Length of output: 11710


One-shot job persistence is broken by Infinity serialization.

One-shot jobs set expiresAt = Infinity at line 157, but line 128 persists with JSON.stringify(), which serializes Infinity to null. On load (line 113), the comparison now < job.expiresAt evaluates to false when expiresAt is null, so persisted one-shot jobs are silently dropped.

Additionally, the destroy() method (lines 323–326) clears jobs without calling saveToDisk(), violating the persistence contract—the next process will reload the cleared state.

Proposed patch
+type PersistedCronJob = Omit<CronJob, 'expiresAt'> & { expiresAt: number | null };

   private loadFromDisk(): void {
     if (!this.persistPath) return;
     try {
       const raw = fs.readFileSync(this.persistPath, 'utf-8');
-      const jobs = JSON.parse(raw) as CronJob[];
+      const jobs = JSON.parse(raw) as PersistedCronJob[];
       const now = Date.now();
       for (const job of jobs) {
-        if (now < job.expiresAt) {
-          this.jobs.set(job.id, job);
+        const expiresAt = job.expiresAt ?? Number.POSITIVE_INFINITY;
+        if (now < expiresAt) {
+          this.jobs.set(job.id, { ...job, expiresAt });
         }
       }
     } catch {
       // File doesn't exist or is corrupt — start with empty store
     }
   }

   private saveToDisk(): void {
     if (!this.persistPath) return;
     try {
       fs.mkdirSync(path.dirname(this.persistPath), { recursive: true });
+      const persisted: PersistedCronJob[] = [...this.jobs.values()].map((job) => ({
+        ...job,
+        expiresAt: Number.isFinite(job.expiresAt) ? job.expiresAt : null,
+      }));
       fs.writeFileSync(
         this.persistPath,
-        JSON.stringify([...this.jobs.values()], null, 2),
+        JSON.stringify(persisted, null, 2),
         'utf-8',
       );
     } catch {
       // Non-fatal — session continues without persistence
     }
   }

+  destroy(): void {
+    this.stop();
+    this.jobs.clear();
+    if (this.persistPath) this.saveToDisk();
+  }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/services/cronScheduler.ts` around lines 106 - 130,
Persisted one-shot jobs are dropped because JSON.stringify turns expiresAt =
Infinity into null and loadFromDisk rejects nulls; update loadFromDisk to treat
job.expiresAt === null or job.expiresAt === undefined as Infinity before
comparing to now (i.e., set job.expiresAt = Number.POSITIVE_INFINITY when
null/undefined), and ensure destroy() calls saveToDisk() after clearing
this.jobs so the cleared state is persisted; adjust references in loadFromDisk,
saveToDisk, and destroy to use the CronJob.expiresAt normalization and
persistence call.

Comment on lines +37 to +50
let turnsSinceLastReview = 0;

/**
* Call after each agent turn completes. Runs skill candidate detection every
* SKILL_REVIEW_INTERVAL turns. Fire-and-forget; errors are logged only.
*/
export async function runEvolvePass(
config: Config,
recentMessages: Array<{ role: string; text: string }>,
): Promise<void> {
turnsSinceLastReview++;
if (turnsSinceLastReview < SKILL_REVIEW_INTERVAL) return;
turnsSinceLastReview = 0;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Scope evolve cadence state per project/session.

Line 37 with Lines 47-50 uses a module-global counter. If multiple sessions/projects share the same process, one stream can trigger/skip another stream’s evolve pass.

🔧 Suggested fix
-let turnsSinceLastReview = 0;
+const turnsSinceLastReviewByProject = new Map<string, number>();

 export async function runEvolvePass(
   config: Config,
   recentMessages: Array<{ role: string; text: string }>,
 ): Promise<void> {
-  turnsSinceLastReview++;
-  if (turnsSinceLastReview < SKILL_REVIEW_INTERVAL) return;
-  turnsSinceLastReview = 0;
+  const projectRoot = config.getProjectRoot();
+  const turnsSinceLastReview =
+    (turnsSinceLastReviewByProject.get(projectRoot) ?? 0) + 1;
+  turnsSinceLastReviewByProject.set(projectRoot, turnsSinceLastReview);
+  if (turnsSinceLastReview < SKILL_REVIEW_INTERVAL) return;
+  turnsSinceLastReviewByProject.set(projectRoot, 0);

   if (recentMessages.length < 4) return;

-  const projectRoot = config.getProjectRoot();
   const evolveSkilsDir = path.join(
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
let turnsSinceLastReview = 0;
/**
* Call after each agent turn completes. Runs skill candidate detection every
* SKILL_REVIEW_INTERVAL turns. Fire-and-forget; errors are logged only.
*/
export async function runEvolvePass(
config: Config,
recentMessages: Array<{ role: string; text: string }>,
): Promise<void> {
turnsSinceLastReview++;
if (turnsSinceLastReview < SKILL_REVIEW_INTERVAL) return;
turnsSinceLastReview = 0;
const turnsSinceLastReviewByProject = new Map<string, number>();
/**
* Call after each agent turn completes. Runs skill candidate detection every
* SKILL_REVIEW_INTERVAL turns. Fire-and-forget; errors are logged only.
*/
export async function runEvolvePass(
config: Config,
recentMessages: Array<{ role: string; text: string }>,
): Promise<void> {
const projectRoot = config.getProjectRoot();
const turnsSinceLastReview =
(turnsSinceLastReviewByProject.get(projectRoot) ?? 0) + 1;
turnsSinceLastReviewByProject.set(projectRoot, turnsSinceLastReview);
if (turnsSinceLastReview < SKILL_REVIEW_INTERVAL) return;
turnsSinceLastReviewByProject.set(projectRoot, 0);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/services/evolveService.ts` around lines 37 - 50, The global
turnsSinceLastReview counter causes cross-session interference; make the cadence
state per-project/session instead: remove/stop using the module-global
turnsSinceLastReview and track counts keyed by a unique session/project
identifier (e.g. a sessionId or projectId available on Config) using a Map (e.g.
evolveTurnsBySession) or store the counter on the Config object, then update
runEvolvePass to read/increment/reset the per-session counter using
SKILL_REVIEW_INTERVAL and the chosen key, and ensure the counter is reset to 0
when the interval fires so each session's evolve cadence is isolated.

Comment on lines +61 to +70
recordDenial(toolName: string): void {
const existing = this.denials.get(toolName) ?? { count: 0, lastSeenAt: 0 };
const updated: DenialRecord = {
count: existing.count + 1,
lastSeenAt: Date.now(),
};
this.denials.set(toolName, updated);
if (updated.count >= DENY_THRESHOLD) {
this.saveToDisk();
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Persist each denial event, not only post-threshold.

Current logic drops sub-threshold denials on restart, so repeated denials across sessions may never accumulate to blocked status.

💡 Proposed patch
   recordDenial(toolName: string): void {
     const existing = this.denials.get(toolName) ?? { count: 0, lastSeenAt: 0 };
     const updated: DenialRecord = {
       count: existing.count + 1,
       lastSeenAt: Date.now(),
     };
     this.denials.set(toolName, updated);
-    if (updated.count >= DENY_THRESHOLD) {
-      this.saveToDisk();
-    }
+    this.saveToDisk();
   }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
recordDenial(toolName: string): void {
const existing = this.denials.get(toolName) ?? { count: 0, lastSeenAt: 0 };
const updated: DenialRecord = {
count: existing.count + 1,
lastSeenAt: Date.now(),
};
this.denials.set(toolName, updated);
if (updated.count >= DENY_THRESHOLD) {
this.saveToDisk();
}
recordDenial(toolName: string): void {
const existing = this.denials.get(toolName) ?? { count: 0, lastSeenAt: 0 };
const updated: DenialRecord = {
count: existing.count + 1,
lastSeenAt: Date.now(),
};
this.denials.set(toolName, updated);
this.saveToDisk();
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/services/permissionBlockerService.ts` around lines 61 - 70,
The recordDenial method currently only calls saveToDisk when updated.count >=
DENY_THRESHOLD causing sub-threshold denials to be lost across restarts; update
recordDenial (which updates this.denials and builds DenialRecord) to persist
every update by calling saveToDisk after this.denials.set(toolName, updated) (or
implement a short debounce/persist strategy if needed) so each denial event is
written to disk rather than only when the threshold is reached.

@github-actions
Copy link
Copy Markdown

Code Coverage Summary

Package Lines Statements Functions Branches
CLI 54.53% 54.53% 66% 78.78%
Core 71.12% 71.12% 74.39% 80.38%
CLI Package - Full Text Report
-------------------|---------|----------|---------|---------|-------------------
File               | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-------------------|---------|----------|---------|---------|-------------------
All files          |   54.53 |    78.78 |      66 |   54.53 |                   
 src               |   66.54 |     64.8 |   73.68 |   66.54 |                   
  gemini.tsx       |   61.02 |    63.15 |      75 |   61.02 | ...06,514-517,526 
  ...ractiveCli.ts |   58.33 |    58.06 |      50 |   58.33 | ...20,435,439-562 
  ...liCommands.ts |   83.77 |    69.76 |     100 |   83.77 | ...12,247,249,377 
  ...ActiveAuth.ts |   94.11 |    82.35 |     100 |   94.11 | 27-30             
 ...cp-integration |    6.22 |    33.33 |    12.5 |    6.22 |                   
  acpAgent.ts      |    3.12 |        0 |       0 |    3.12 | 67-121,124-578    
  authMethods.ts   |   17.85 |      100 |       0 |   17.85 | 11-22,25-29,32-37 
  errorCodes.ts    |       0 |        0 |       0 |       0 | 1-22              
  ...DirContext.ts |     100 |      100 |     100 |     100 |                   
 ...ration/service |   68.65 |    83.33 |   66.66 |   68.65 |                   
  filesystem.ts    |   68.65 |    83.33 |   66.66 |   68.65 | ...32,77-94,97-98 
 ...ration/session |   63.91 |    60.61 |    74.5 |   63.91 |                   
  ...ryReplayer.ts |      76 |    79.41 |      90 |      76 | ...19-220,228-229 
  Session.ts       |   56.05 |    48.09 |    62.5 |   56.05 | ...1408,1414-1417 
  ...entTracker.ts |   90.85 |    84.84 |      90 |   90.85 | ...35,199,251-260 
  index.ts         |       0 |        0 |       0 |       0 | 1-40              
  ...ssionUtils.ts |   74.59 |    73.07 |     100 |   74.59 | ...73-189,204-206 
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 ...ssion/emitters |   92.48 |    87.12 |      92 |   92.48 |                   
  BaseEmitter.ts   |    82.6 |       75 |      80 |    82.6 | 23-24,50-51       
  ...ageEmitter.ts |     100 |    83.33 |     100 |     100 | 84-86             
  PlanEmitter.ts   |     100 |      100 |     100 |     100 |                   
  ...allEmitter.ts |   91.37 |    86.79 |     100 |   91.37 | ...28-229,318,326 
  index.ts         |       0 |        0 |       0 |       0 | 1-10              
 src/commands      |   69.02 |      100 |   18.18 |   69.02 |                   
  auth.ts          |      44 |      100 |       0 |      44 | ...50,59-63,66-67 
  extensions.tsx   |   96.55 |      100 |      50 |   96.55 | 37                
  hooks.tsx        |   66.66 |      100 |       0 |   66.66 | 20-24             
  mcp.ts           |   94.73 |      100 |      50 |   94.73 | 28                
 src/commands/auth |   45.07 |    95.65 |   64.28 |   45.07 |                   
  handler.ts       |   28.29 |    93.75 |   16.66 |   28.29 | 55-349            
  ...veSelector.ts |     100 |    96.66 |     100 |     100 | 58                
 ...nds/extensions |   84.53 |    88.95 |   81.81 |   84.53 |                   
  consent.ts       |   71.65 |    89.28 |   42.85 |   71.65 | ...85-141,156-162 
  disable.ts       |     100 |      100 |     100 |     100 |                   
  enable.ts        |     100 |      100 |     100 |     100 |                   
  install.ts       |    75.6 |    66.66 |   66.66 |    75.6 | ...39-142,145-153 
  link.ts          |     100 |      100 |     100 |     100 |                   
  list.ts          |     100 |      100 |     100 |     100 |                   
  new.ts           |     100 |      100 |     100 |     100 |                   
  settings.ts      |   99.15 |      100 |   83.33 |   99.15 | 151               
  uninstall.ts     |    37.5 |      100 |   33.33 |    37.5 | 23-45,57-64,67-70 
  update.ts        |   96.32 |      100 |     100 |   96.32 | 101-105           
  utils.ts         |   60.24 |    28.57 |     100 |   60.24 | ...81,83-87,89-93 
 ...les/mcp-server |       0 |        0 |       0 |       0 |                   
  example.ts       |       0 |        0 |       0 |       0 | 1-60              
 src/commands/mcp  |   91.28 |    82.97 |   88.88 |   91.28 |                   
  add.ts           |     100 |    96.66 |     100 |     100 | 213               
  list.ts          |   91.22 |    80.76 |      80 |   91.22 | ...19-121,146-147 
  reconnect.ts     |   76.72 |    71.42 |   85.71 |   76.72 | 35-48,153-175     
  remove.ts        |     100 |       80 |     100 |     100 | 21-25             
 src/config        |      91 |     80.3 |   84.12 |      91 |                   
  auth.ts          |   86.66 |    77.55 |     100 |   86.66 | ...92-193,209-210 
  config.ts        |   86.75 |    81.61 |   72.22 |   86.75 | ...1163,1185-1186 
  keyBindings.ts   |   95.95 |       50 |     100 |   95.95 | 160-163           
  ...idersScope.ts |      92 |       90 |     100 |      92 | 11-12             
  sandboxConfig.ts |   54.16 |    23.07 |   66.66 |   54.16 | ...44,54-68,73-89 
  settings.ts      |   80.69 |    82.05 |   81.81 |   80.69 | ...98-699,775-792 
  ...ingsSchema.ts |     100 |      100 |     100 |     100 |                   
  ...tedFolders.ts |   96.29 |       94 |     100 |   96.29 | ...88-190,205-206 
  webSearch.ts     |   42.37 |       25 |     100 |   42.37 | ...6,86-93,96-112 
 ...nfig/migration |   94.56 |    78.94 |   83.33 |   94.56 |                   
  index.ts         |   93.93 |    88.88 |     100 |   93.93 | 85-86             
  scheduler.ts     |   96.55 |    77.77 |     100 |   96.55 | 19-20             
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 ...ation/versions |   93.63 |     94.5 |     100 |   93.63 |                   
  ...-v2-shared.ts |     100 |      100 |     100 |     100 |                   
  v1-to-v2.ts      |   81.75 |    90.19 |     100 |   81.75 | ...28-229,231-247 
  v2-to-v3.ts      |     100 |      100 |     100 |     100 |                   
 src/constants     |   93.02 |    94.11 |   66.66 |   93.02 |                   
  ...dardApiKey.ts |     100 |      100 |     100 |     100 |                   
  codingPlan.ts    |   92.74 |    94.11 |   66.66 |   92.74 | ...00-301,309-321 
 src/core          |   51.51 |    33.33 |   33.33 |   51.51 |                   
  auth.ts          |    9.52 |      100 |       0 |    9.52 | 21-48             
  initializer.ts   |   84.37 |    33.33 |     100 |   84.37 | 41,55-58          
  theme.ts         |   38.46 |      100 |       0 |   38.46 | 17-24             
 src/generated     |     100 |      100 |     100 |     100 |                   
  git-commit.ts    |     100 |      100 |     100 |     100 |                   
 src/i18n          |   43.69 |    76.19 |   38.88 |   43.69 |                   
  index.ts         |   26.11 |    76.92 |   26.66 |   26.11 | ...35-236,246-257 
  languages.ts     |   98.27 |       75 |     100 |   98.27 | 88                
 src/i18n/locales  |       0 |        0 |       0 |       0 |                   
  de.js            |       0 |        0 |       0 |       0 | 1-1965            
  en.js            |       0 |        0 |       0 |       0 | 1-2006            
  ja.js            |       0 |        0 |       0 |       0 | 1-1459            
  pt.js            |       0 |        0 |       0 |       0 | 1-1957            
  ru.js            |       0 |        0 |       0 |       0 | 1-1964            
  zh.js            |       0 |        0 |       0 |       0 | 1-1811            
 ...nonInteractive |   68.34 |    71.68 |   68.88 |   68.34 |                   
  session.ts       |    73.1 |    69.52 |   81.81 |    73.1 | ...03-604,612-622 
  types.ts         |    42.5 |      100 |   33.33 |    42.5 | ...74-575,578-579 
 ...active/control |   77.48 |       88 |      80 |   77.48 |                   
  ...rolContext.ts |    7.69 |        0 |       0 |    7.69 | 47-79             
  ...Dispatcher.ts |   91.63 |    91.66 |   88.88 |   91.63 | ...54-372,387,390 
  ...rolService.ts |       8 |        0 |       0 |       8 | 46-179            
 ...ol/controllers |    7.32 |       80 |   13.79 |    7.32 |                   
  ...Controller.ts |   19.32 |      100 |      60 |   19.32 | 81-118,127-210    
  ...Controller.ts |       0 |        0 |       0 |       0 | 1-56              
  ...Controller.ts |    3.96 |      100 |   11.11 |    3.96 | ...61-379,389-494 
  ...Controller.ts |   14.06 |      100 |       0 |   14.06 | ...82-117,130-133 
  ...Controller.ts |    5.72 |      100 |       0 |    5.72 | ...72-384,393-418 
 .../control/types |       0 |        0 |       0 |       0 |                   
  serviceAPIs.ts   |       0 |        0 |       0 |       0 | 1                 
 ...Interactive/io |   97.57 |    92.91 |   96.15 |   97.57 |                   
  ...putAdapter.ts |    97.3 |    91.75 |     100 |    97.3 | ...1272,1297-1298 
  ...putAdapter.ts |      96 |    91.66 |   85.71 |      96 | 51-52             
  ...nputReader.ts |     100 |    94.73 |     100 |     100 | 67                
  ...putAdapter.ts |   98.23 |      100 |   89.47 |   98.23 | 70-71,111-112     
 src/patches       |       0 |        0 |       0 |       0 |                   
  is-in-ci.ts      |       0 |        0 |       0 |       0 | 1-17              
 src/services      |   89.22 |     87.2 |   96.87 |   89.22 |                   
  ...mandLoader.ts |     100 |      100 |     100 |     100 |                   
  ...killLoader.ts |     100 |      100 |     100 |     100 |                   
  ...andService.ts |     100 |      100 |     100 |     100 |                   
  ...mandLoader.ts |   86.61 |    82.14 |     100 |   86.61 | ...29-334,339-344 
  ...omptLoader.ts |    75.1 |    80.64 |   83.33 |    75.1 | ...03-204,270-271 
  audioCapture.ts  |   98.33 |    93.75 |     100 |   98.33 | 71                
  ...nd-factory.ts |    91.2 |    93.33 |     100 |    91.2 | 119-126           
  ...ation-tool.ts |     100 |    95.45 |     100 |     100 | 125               
  ...and-parser.ts |   89.74 |    85.71 |     100 |   89.74 | 59-62             
  sttClient.ts     |   93.33 |       75 |     100 |   93.33 | 28-29             
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...ght/generators |   85.95 |    86.42 |   90.47 |   85.95 |                   
  DataProcessor.ts |   85.68 |    86.46 |   92.85 |   85.68 | ...1110,1114-1121 
  ...tGenerator.ts |   98.21 |    85.71 |     100 |   98.21 | 46                
  ...teRenderer.ts |   45.45 |      100 |       0 |   45.45 | 13-51             
 .../insight/types |       0 |       50 |      50 |       0 |                   
  ...sightTypes.ts |       0 |        0 |       0 |       0 |                   
  ...sightTypes.ts |       0 |        0 |       0 |       0 | 1                 
 ...mpt-processors |   97.27 |    94.04 |     100 |   97.27 |                   
  ...tProcessor.ts |     100 |      100 |     100 |     100 |                   
  ...eProcessor.ts |   94.52 |    84.21 |     100 |   94.52 | 46-47,93-94       
  ...tionParser.ts |     100 |      100 |     100 |     100 |                   
  ...lProcessor.ts |   97.41 |    95.65 |     100 |   97.41 | 95-98             
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/test-utils    |   93.63 |    83.33 |      80 |   93.63 |                   
  ...omMatchers.ts |   69.69 |       50 |      50 |   69.69 | 32-35,37-39,45-47 
  ...andContext.ts |     100 |      100 |     100 |     100 |                   
  render.tsx       |     100 |      100 |     100 |     100 |                   
 src/ui            |   68.33 |    67.92 |   48.64 |   68.33 |                   
  App.tsx          |     100 |      100 |     100 |     100 |                   
  AppContainer.tsx |    73.6 |    57.52 |   42.85 |    73.6 | ...1250,1656-1662 
  ...tionNudge.tsx |    9.58 |      100 |       0 |    9.58 | 24-94             
  ...ackDialog.tsx |   29.23 |      100 |       0 |   29.23 | 25-75             
  ...tionNudge.tsx |    7.69 |      100 |       0 |    7.69 | 25-103            
  colors.ts        |   56.36 |      100 |   29.41 |   56.36 | ...49,51-52,60-61 
  constants.ts     |     100 |      100 |     100 |     100 |                   
  keyMatchers.ts   |   91.83 |    88.46 |     100 |   91.83 | 25-26,54-55       
  ...tic-colors.ts |     100 |      100 |     100 |     100 |                   
  textConstants.ts |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/ui/auth       |   29.54 |    46.34 |   26.08 |   29.54 |                   
  AuthDialog.tsx   |   51.95 |     47.5 |   28.57 |   51.95 | ...53,672,674,676 
  ...nProgress.tsx |       0 |        0 |       0 |       0 | 1-64              
  useAuth.ts       |     2.3 |      100 |       0 |     2.3 | 45-595            
 src/ui/commands   |   51.81 |    79.43 |   43.21 |   51.81 |                   
  aboutCommand.ts  |     100 |      100 |     100 |     100 |                   
  agentsCommand.ts |    64.7 |      100 |       0 |    64.7 | ...30,35-36,39-41 
  ...odeCommand.ts |     100 |      100 |     100 |     100 |                   
  arenaCommand.ts  |   32.65 |    67.64 |    37.5 |   32.65 | ...52-557,636-641 
  authCommand.ts   |     100 |      100 |     100 |     100 |                   
  btwCommand.ts    |     100 |    90.32 |     100 |     100 | 25,199,213        
  bugCommand.ts    |   76.47 |    66.66 |      50 |   76.47 | 21-22,57-66       
  clearCommand.ts  |   89.65 |    55.55 |      50 |   89.65 | 23-24,49-50,68-69 
  ...essCommand.ts |   63.15 |       50 |      50 |   63.15 | ...47-148,162-165 
  ...extCommand.ts |    4.65 |      100 |       0 |    4.65 | ...8,93-96,99-375 
  copyCommand.ts   |   96.22 |      100 |      50 |   96.22 | 15-16             
  ...ryCommand.tsx |   59.19 |    73.07 |    37.5 |   59.19 | ...15-216,224-232 
  docsCommand.ts   |   95.23 |       80 |      50 |   95.23 | 20-21             
  editorCommand.ts |     100 |      100 |     100 |     100 |                   
  exportCommand.ts |   55.97 |    91.66 |   33.33 |   55.97 | ...48-349,356-357 
  ...onsCommand.ts |   44.09 |    85.71 |   27.27 |   44.09 | ...35-236,244-245 
  helpCommand.ts   |     100 |      100 |     100 |     100 |                   
  hooksCommand.ts  |   42.72 |       60 |   33.33 |   42.72 | ...86-116,123-124 
  ideCommand.ts    |   41.91 |    69.23 |   21.42 |   41.91 | ...08-209,212-226 
  index.ts         |       0 |        0 |       0 |       0 | 1-20              
  initCommand.ts   |    81.7 |       70 |      50 |    81.7 | ...67,81-86,88-93 
  ...ghtCommand.ts |   69.23 |       40 |   66.66 |   69.23 | ...97-111,116-129 
  ...ageCommand.ts |   89.24 |    82.35 |   76.92 |   89.24 | ...20-323,345-346 
  mcpCommand.ts    |   85.71 |      100 |      50 |   85.71 | 14-15             
  memoryCommand.ts |   44.63 |    84.61 |   23.07 |   44.63 | ...69,574-575,593 
  modelCommand.ts  |   57.31 |       80 |   66.66 |   57.31 | 24-33,51-77       
  notesCommand.ts  |    9.32 |      100 |       0 |    9.32 | 27-30,33-151      
  ...onsCommand.ts |     100 |      100 |     100 |     100 |                   
  quitCommand.ts   |   93.75 |      100 |      50 |   93.75 | 15-16             
  ...oreCommand.ts |   92.24 |     87.5 |     100 |   92.24 | ...,83-88,129-130 
  resumeCommand.ts |     100 |      100 |     100 |     100 |                   
  rewindCommand.ts |    62.5 |      100 |       0 |    62.5 | 17-22             
  ...ngsCommand.ts |     100 |      100 |     100 |     100 |                   
  ...hubCommand.ts |   80.12 |    63.63 |      60 |   80.12 | ...69-172,175-178 
  skillsCommand.ts |   12.28 |      100 |       0 |   12.28 | ...91-109,112-139 
  statsCommand.ts  |   76.92 |       75 |      50 |   76.92 | ...36,50-51,65-66 
  ...aryCommand.ts |    4.61 |      100 |       0 |    4.61 | 21-24,27-322      
  teamCommand.ts   |   15.55 |      100 |       0 |   15.55 | ...70-271,274-298 
  ...tupCommand.ts |     100 |      100 |     100 |     100 |                   
  themeCommand.ts  |     100 |      100 |     100 |     100 |                   
  toolsCommand.ts  |   95.12 |      100 |      50 |   95.12 | 18-19             
  trustCommand.ts  |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
  vimCommand.ts    |   42.85 |      100 |       0 |   42.85 | 14-15,18-28       
  voiceCommand.ts  |   35.08 |      100 |       0 |   35.08 | 29-51,55-73       
 src/ui/components |   56.76 |    72.57 |   58.39 |   56.76 |                   
  AboutBox.tsx     |     100 |      100 |     100 |     100 |                   
  AnsiOutput.tsx   |     100 |      100 |     100 |     100 |                   
  ApiKeyInput.tsx  |   18.91 |      100 |       0 |   18.91 | 30-95             
  AppHeader.tsx    |   89.58 |       50 |     100 |   89.58 | 33-38             
  ...odeDialog.tsx |     9.7 |      100 |       0 |     9.7 | 35-47,50-182      
  AsciiArt.ts      |     100 |      100 |     100 |     100 |                   
  ...Indicator.tsx |   13.95 |      100 |       0 |   13.95 | 18-58             
  ...TextInput.tsx |   63.22 |    70.27 |      50 |   63.22 | ...12,220-222,240 
  Composer.tsx     |   89.89 |    58.33 |      50 |   89.89 | ...-55,73,112,125 
  ...itDisplay.tsx |   55.81 |      100 |      50 |   55.81 | 22-38,42-43       
  ...entPrompt.tsx |     100 |      100 |     100 |     100 |                   
  ...ryDisplay.tsx |   75.89 |    62.06 |     100 |   75.89 | ...,88,93-108,113 
  ...geDisplay.tsx |   90.47 |       75 |     100 |   90.47 | 20-21             
  ...ification.tsx |   28.57 |      100 |       0 |   28.57 | 16-36             
  ...gProfiler.tsx |       0 |        0 |       0 |       0 | 1-36              
  ...ogManager.tsx |    8.42 |      100 |       0 |    8.42 | 53-563            
  ...ngsDialog.tsx |    8.44 |      100 |       0 |    8.44 | 37-195            
  ExitWarning.tsx  |     100 |      100 |     100 |     100 |                   
  ...ustDialog.tsx |     100 |      100 |     100 |     100 |                   
  Footer.tsx       |   75.22 |       35 |     100 |   75.22 | ...74,87-91,93-97 
  ...ngSpinner.tsx |   54.28 |       50 |      50 |   54.28 | 31-48,61          
  Header.tsx       |   94.49 |    78.57 |     100 |   94.49 | 95,97,102-105     
  Help.tsx         |   98.74 |    68.75 |     100 |   98.74 | 74,129            
  ...emDisplay.tsx |    68.9 |     42.1 |     100 |    68.9 | ...19-225,228,231 
  ...ngeDialog.tsx |     100 |      100 |     100 |     100 |                   
  InputPrompt.tsx  |   79.19 |    75.08 |     100 |   79.19 | ...1306-1322,1364 
  ...Shortcuts.tsx |   21.11 |      100 |       0 |   21.11 | ...5,48-50,66-124 
  ...Indicator.tsx |     100 |      100 |     100 |     100 |                   
  ...firmation.tsx |   91.42 |      100 |      50 |   91.42 | 26-31             
  MainContent.tsx  |   18.05 |      100 |       0 |   18.05 | 25-92             
  ...geDisplay.tsx |       0 |        0 |       0 |       0 | 1-41              
  ModelDialog.tsx  |   75.13 |    40.98 |     100 |   75.13 | ...17-433,478-482 
  ...tsDisplay.tsx |     100 |      100 |     100 |     100 |                   
  ...fications.tsx |   18.18 |      100 |       0 |   18.18 | 15-58             
  ...onsDialog.tsx |    2.18 |      100 |       0 |    2.18 | 62-133,148-986    
  ...ryDisplay.tsx |     100 |      100 |     100 |     100 |                   
  ...icePrompt.tsx |   88.14 |    83.87 |     100 |   88.14 | ...01-105,133-138 
  PrepareLabel.tsx |   91.66 |    76.19 |     100 |   91.66 | 73-75,77-79,110   
  ...geDisplay.tsx |     100 |      100 |     100 |     100 |                   
  ...ngDisplay.tsx |   21.42 |      100 |       0 |   21.42 | 13-39             
  RewindDialog.tsx |       0 |        0 |       0 |       0 | 1-217             
  RewindPicker.tsx |    3.35 |      100 |       0 |    3.35 | 48-70,89-394      
  ...ionPicker.tsx |   94.18 |    92.85 |     100 |   94.18 | 79,194-202        
  ...ryDisplay.tsx |     100 |      100 |     100 |     100 |                   
  ...putPrompt.tsx |   72.56 |       80 |      40 |   72.56 | ...06-109,114-117 
  ...ngsDialog.tsx |   66.75 |    72.66 |     100 |   66.75 | ...72-780,786-787 
  ...ionDialog.tsx |    87.8 |      100 |   33.33 |    87.8 | 36-39,44-51       
  ...putPrompt.tsx |    15.9 |      100 |       0 |    15.9 | 20-63             
  ...Indicator.tsx |   44.44 |      100 |       0 |   44.44 | 12-17             
  ...MoreLines.tsx |      28 |      100 |       0 |      28 | 18-40             
  ...ionPicker.tsx |    7.86 |      100 |       0 |    7.86 | 21-131            
  StatsDisplay.tsx |   98.66 |    93.33 |     100 |   98.66 | 199-201           
  StatusBar.tsx    |      12 |      100 |       0 |      12 | ...4,44-49,66-163 
  ...nsDisplay.tsx |   84.09 |    57.14 |     100 |   84.09 | ...16-118,125-127 
  ...ffDisplay.tsx |   18.42 |      100 |       0 |   18.42 | 16-18,25-58       
  ThemeDialog.tsx  |   90.95 |    44.44 |      75 |   90.95 | ...16-117,159-161 
  Tips.tsx         |      75 |       60 |      75 |      75 | 23,48-49,52-62    
  TodoDisplay.tsx  |     100 |      100 |     100 |     100 |                   
  ...tsDisplay.tsx |     100 |     87.5 |     100 |     100 | 31-32             
  ...oryBanner.tsx |       0 |        0 |       0 |       0 | 1-26              
  TrustDialog.tsx  |     100 |    81.81 |     100 |     100 | 71-86             
  ...ification.tsx |   36.36 |      100 |       0 |   36.36 | 15-22             
  ...MicButton.tsx |   11.11 |      100 |       0 |   11.11 | 26-81             
  ...ackDialog.tsx |    7.84 |      100 |       0 |    7.84 | 24-134            
 ...nts/agent-view |   24.89 |    89.36 |    12.5 |   24.89 |                   
  ...tChatView.tsx |     8.1 |      100 |       0 |     8.1 | 53-283            
  ...tComposer.tsx |    9.95 |      100 |       0 |    9.95 | 57-308            
  AgentFooter.tsx  |   17.07 |      100 |       0 |   17.07 | 28-66             
  AgentHeader.tsx  |   15.38 |      100 |       0 |   15.38 | 27-64             
  AgentTabBar.tsx  |    8.25 |      100 |       0 |    8.25 | 35-55,60-167      
  ...oryAdapter.ts |     100 |     91.3 |     100 |     100 | 102,108-109,137   
  index.ts         |       0 |        0 |       0 |       0 | 1-12              
 ...mponents/arena |    5.89 |      100 |       0 |    5.89 |                   
  ArenaCards.tsx   |       4 |      100 |       0 |       4 | 24-129,134-290    
  ...ectDialog.tsx |    5.28 |      100 |       0 |    5.28 | 32-260            
  ...artDialog.tsx |   10.34 |      100 |       0 |   10.34 | 26-147            
  ...tusDialog.tsx |    5.63 |      100 |       0 |    5.63 | 33-75,80-288      
  ...topDialog.tsx |    6.17 |      100 |       0 |    6.17 | 33-213            
 ...nts/extensions |   45.28 |    33.33 |      60 |   45.28 |                   
  ...gerDialog.tsx |   44.31 |    34.14 |      75 |   44.31 | ...71-480,483-488 
  index.ts         |       0 |        0 |       0 |       0 | 1-9               
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...tensions/steps |   54.77 |    94.23 |   66.66 |   54.77 |                   
  ...ctionStep.tsx |   95.12 |    92.85 |   85.71 |   95.12 | 84-86,89          
  ...etailStep.tsx |    6.18 |      100 |       0 |    6.18 | 17-128            
  ...nListStep.tsx |   88.35 |    94.73 |      80 |   88.35 | 51-52,58-71,105   
  ...electStep.tsx |   13.46 |      100 |       0 |   13.46 | 20-70             
  ...nfirmStep.tsx |   19.56 |      100 |       0 |   19.56 | 23-65             
  index.ts         |     100 |      100 |     100 |     100 |                   
 ...mponents/hooks |   78.26 |    69.91 |      85 |   78.26 |                   
  ...etailStep.tsx |   96.52 |       75 |     100 |   96.52 | 33,37,50,59       
  ...etailStep.tsx |   98.13 |    82.35 |     100 |   98.13 | 41-42             
  ...abledStep.tsx |     100 |      100 |     100 |     100 |                   
  ...sListStep.tsx |     100 |      100 |     100 |     100 |                   
  ...entDialog.tsx |   47.66 |    51.85 |   66.66 |   47.66 | ...06,410-423,427 
  constants.ts     |     100 |      100 |     100 |     100 |                   
  index.ts         |       0 |        0 |       0 |       0 | 1-13              
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...components/mcp |   18.82 |    84.37 |   77.77 |   18.82 |                   
  ...entDialog.tsx |    3.64 |      100 |       0 |    3.64 | 41-717            
  constants.ts     |     100 |      100 |     100 |     100 |                   
  index.ts         |       0 |        0 |       0 |       0 | 1-30              
  types.ts         |     100 |      100 |     100 |     100 |                   
  utils.ts         |   96.42 |    87.09 |     100 |   96.42 | 21,96-97          
 ...ents/mcp/steps |    7.31 |      100 |       0 |    7.31 |                   
  ...icateStep.tsx |    7.58 |      100 |       0 |    7.58 | 27-197            
  ...electStep.tsx |   10.95 |      100 |       0 |   10.95 | 16-88             
  ...etailStep.tsx |    5.26 |      100 |       0 |    5.26 | 31-247            
  ...rListStep.tsx |    5.88 |      100 |       0 |    5.88 | 20-176            
  ...etailStep.tsx |   10.41 |      100 |       0 |   10.41 | ...1,67-79,82-139 
  ToolListStep.tsx |    7.14 |      100 |       0 |    7.14 | 16-146            
 ...nents/messages |   73.63 |    75.88 |   59.18 |   73.63 |                   
  ...ionDialog.tsx |   65.11 |       73 |   42.85 |   65.11 | ...20,538,556-558 
  BtwMessage.tsx   |   76.31 |       50 |     100 |   76.31 | 34-42             
  ...onMessage.tsx |   91.93 |    82.35 |     100 |   91.93 | 57-59,61,63       
  ...nMessages.tsx |   77.35 |      100 |      70 |   77.35 | ...31-244,248-260 
  DiffRenderer.tsx |   93.19 |    86.17 |     100 |   93.19 | ...09,237-238,304 
  ...ssMessage.tsx |    12.5 |      100 |       0 |    12.5 | 18-59             
  ...sMessages.tsx |   16.17 |      100 |       0 |   16.17 | ...1,85-95,99-104 
  ...ryMessage.tsx |   12.82 |      100 |       0 |   12.82 | 22-59             
  ...onMessage.tsx |   73.07 |    55.81 |   33.33 |   73.07 | ...34-436,443-445 
  ...upMessage.tsx |   95.09 |     87.5 |     100 |   95.09 | 40-43,55          
  ToolMessage.tsx  |   82.07 |    71.95 |      90 |   82.07 | ...13-418,492-494 
 ...ponents/shared |   77.03 |    76.86 |   90.56 |   77.03 |                   
  ...ctionList.tsx |   99.03 |    95.65 |     100 |   99.03 | 85                
  ...tonSelect.tsx |   97.14 |    66.66 |     100 |   97.14 | 72                
  EnumSelector.tsx |     100 |    96.42 |     100 |     100 | 58                
  MaxSizedBox.tsx  |   81.13 |    81.96 |   88.88 |   81.13 | ...12-513,618-619 
  MultiSelect.tsx  |    5.59 |      100 |       0 |    5.59 | 34-41,44-193      
  ...tonSelect.tsx |     100 |      100 |     100 |     100 |                   
  ...eSelector.tsx |     100 |       60 |     100 |     100 | 40-45             
  TextInput.tsx    |    7.14 |      100 |       0 |    7.14 | 39-222            
  text-buffer.ts   |   82.07 |    75.59 |   96.87 |   82.07 | ...1897,1924,1986 
  ...er-actions.ts |   86.71 |    67.79 |     100 |   86.71 | ...07-608,809-811 
 ...ents/subagents |    32.1 |      100 |       0 |    32.1 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  reducers.tsx     |    12.1 |      100 |       0 |    12.1 | 33-190            
  types.ts         |     100 |      100 |     100 |     100 |                   
  utils.ts         |   10.95 |      100 |       0 |   10.95 | ...1,56-57,60-102 
 ...bagents/create |    9.13 |      100 |       0 |    9.13 |                   
  ...ionWizard.tsx |    7.28 |      100 |       0 |    7.28 | 34-299            
  ...rSelector.tsx |   14.75 |      100 |       0 |   14.75 | 26-85             
  ...onSummary.tsx |    4.26 |      100 |       0 |    4.26 | 27-331            
  ...tionInput.tsx |    8.63 |      100 |       0 |    8.63 | 23-177            
  ...dSelector.tsx |   33.33 |      100 |       0 |   33.33 | 20-21,26-27,36-63 
  ...nSelector.tsx |    37.5 |      100 |       0 |    37.5 | 20-21,26-27,36-58 
  ...EntryStep.tsx |   12.76 |      100 |       0 |   12.76 | 34-78             
  ToolSelector.tsx |    4.16 |      100 |       0 |    4.16 | 31-253            
 ...bagents/manage |    8.43 |      100 |       0 |    8.43 |                   
  ...ctionStep.tsx |   10.25 |      100 |       0 |   10.25 | 21-103            
  ...eleteStep.tsx |   20.93 |      100 |       0 |   20.93 | 23-62             
  ...tEditStep.tsx |   25.53 |      100 |       0 |   25.53 | ...2,37-38,51-124 
  ...ctionStep.tsx |    2.29 |      100 |       0 |    2.29 | 28-449            
  ...iewerStep.tsx |   15.21 |      100 |       0 |   15.21 | 18-66             
  ...gerDialog.tsx |    6.74 |      100 |       0 |    6.74 | 35-341            
 ...agents/runtime |    7.83 |      100 |       0 |    7.83 |                   
  ...onDisplay.tsx |    7.83 |      100 |       0 |    7.83 | ...72-502,511-549 
 ...mponents/views |   48.59 |    69.23 |      30 |   48.59 |                   
  ContextUsage.tsx |    5.07 |      100 |       0 |    5.07 | ...30-145,148-424 
  ...sionsList.tsx |   87.69 |    73.68 |     100 |   87.69 | 65-72             
  McpStatus.tsx    |   89.53 |    60.52 |     100 |   89.53 | ...72,175-177,262 
  SkillsList.tsx   |   27.27 |      100 |       0 |   27.27 | 18-35             
  ToolsList.tsx    |     100 |      100 |     100 |     100 |                   
 src/ui/contexts   |   76.49 |    79.92 |    87.5 |   76.49 |                   
  ...ewContext.tsx |   65.77 |      100 |      75 |   65.77 | ...22-225,231-241 
  AppContext.tsx   |      40 |      100 |       0 |      40 | 17-22             
  ...igContext.tsx |   81.81 |       50 |     100 |   81.81 | 15-16             
  ...ssContext.tsx |   83.83 |       83 |     100 |   83.83 | ...1049,1054-1056 
  ...owContext.tsx |   89.28 |       80 |   66.66 |   89.28 | 34,47-48,60-62    
  ...onContext.tsx |   47.02 |     62.5 |   71.42 |   47.02 | ...36-239,243-246 
  ...gsContext.tsx |   83.33 |       50 |     100 |   83.33 | 17-18             
  ...usContext.tsx |     100 |      100 |     100 |     100 |                   
  ...ngContext.tsx |   71.42 |       50 |     100 |   71.42 | 17-20             
  ...nsContext.tsx |   89.47 |       50 |     100 |   89.47 | 117-118           
  ...teContext.tsx |   85.71 |       50 |     100 |   85.71 | 160-161           
  ...deContext.tsx |   76.08 |    72.72 |     100 |   76.08 | 47-48,52-59,77-78 
 src/ui/editors    |   93.33 |    85.71 |   66.66 |   93.33 |                   
  ...ngsManager.ts |   93.33 |    85.71 |   66.66 |   93.33 | 49,63-64          
 src/ui/hooks      |   75.51 |    78.97 |   79.53 |   75.51 |                   
  ...dProcessor.ts |   83.02 |     81.9 |     100 |   83.02 | ...86-387,406-433 
  keyToAnsi.ts     |    3.92 |      100 |       0 |    3.92 | 19-77             
  ...dProcessor.ts |   94.77 |    70.58 |     100 |   94.77 | ...75-276,281-282 
  ...dProcessor.ts |   76.08 |    58.33 |   66.66 |   76.08 | ...88,712,731-735 
  ...amingState.ts |   12.22 |      100 |       0 |   12.22 | 54-158            
  ...agerDialog.ts |   88.23 |      100 |     100 |   88.23 | 20,24             
  ...odeCommand.ts |   58.82 |      100 |     100 |   58.82 | 28,33-48          
  ...enaCommand.ts |      85 |      100 |     100 |      85 | 23-24,29          
  ...aInProcess.ts |   19.81 |    66.66 |      25 |   19.81 | 57-175            
  ...Completion.ts |   92.77 |    89.09 |     100 |   92.77 | ...86-187,220-223 
  ...ifications.ts |   88.05 |    94.73 |     100 |   88.05 | 84-93             
  ...tIndicator.ts |     100 |    93.75 |     100 |     100 | 63                
  ...ntProgress.ts |   38.37 |      100 |   16.66 |   38.37 | ...9,82-88,91-106 
  ...ketedPaste.ts |    23.8 |      100 |       0 |    23.8 | 19-38             
  ...lanUpdates.ts |     100 |       92 |     100 |     100 | 59,158            
  ...ompletion.tsx |   94.87 |    80.55 |     100 |   94.87 | ...02-203,205-206 
  ...dMigration.ts |   90.62 |       75 |     100 |   90.62 | 38-40             
  useCompletion.ts |    92.4 |     87.5 |     100 |    92.4 | 68-69,93-94,98-99 
  ...ialogClose.ts |   22.22 |      100 |     100 |   22.22 | 67-109            
  ...orSettings.ts |     100 |      100 |     100 |     100 |                   
  ...itHandling.ts |   45.16 |      100 |     100 |   45.16 | 46-98             
  ...ionUpdates.ts |   93.45 |     92.3 |     100 |   93.45 | ...83-287,300-306 
  ...agerDialog.ts |   88.88 |      100 |     100 |   88.88 | 21,25             
  ...backDialog.ts |   50.75 |    77.77 |   33.33 |   50.75 | ...56-171,192-193 
  useFocus.ts      |     100 |      100 |     100 |     100 |                   
  ...olderTrust.ts |     100 |      100 |     100 |     100 |                   
  ...ggestions.tsx |   89.15 |     64.7 |     100 |   89.15 | ...19-121,146-147 
  ...miniStream.ts |   70.32 |    68.09 |      80 |   70.32 | ...1951,1960-1962 
  ...BranchName.ts |    90.9 |     92.3 |     100 |    90.9 | 19-20,55-58       
  ...itDiffStat.ts |    7.69 |      100 |       0 |    7.69 | 26-79             
  ...oryManager.ts |   98.41 |    93.33 |     100 |   98.41 | 43                
  ...ooksDialog.ts |    87.5 |      100 |     100 |    87.5 | 19,23             
  ...stListener.ts |     100 |      100 |     100 |     100 |                   
  ...ssageDrain.ts |   72.72 |       40 |     100 |   72.72 | 25-26,28-31       
  ...nAuthError.ts |   76.19 |       50 |     100 |   76.19 | 39-40,43-45       
  ...ionEffects.ts |   30.58 |     37.5 |     100 |   30.58 | ...12-119,123-124 
  ...putHistory.ts |   92.59 |    85.71 |     100 |   92.59 | 63-64,72,94-96    
  ...storyStore.ts |     100 |    94.11 |     100 |     100 | 69                
  ...rdHandling.ts |   33.87 |      100 |      50 |   33.87 | 92,101-249        
  useKeypress.ts   |     100 |      100 |     100 |     100 |                   
  ...rdProtocol.ts |   36.36 |      100 |       0 |   36.36 | 24-31             
  ...unchEditor.ts |    8.97 |      100 |       0 |    8.97 | 20-67,74-125      
  ...gIndicator.ts |     100 |      100 |     100 |     100 |                   
  useLogger.ts     |   21.05 |      100 |       0 |   21.05 | 15-37             
  useMcpDialog.ts  |    87.5 |      100 |     100 |    87.5 | 19,23             
  ...oryMonitor.ts |     100 |      100 |     100 |     100 |                   
  ...ssageQueue.ts |     100 |      100 |     100 |     100 |                   
  ...delCommand.ts |     100 |       75 |     100 |     100 | 22                
  ...raseCycler.ts |   84.48 |    76.47 |     100 |   84.48 | ...47,50-51,67-69 
  ...uggestions.ts |   50.73 |       28 |     100 |   50.73 | ...81-183,201-203 
  ...lScheduler.ts |   85.06 |    94.73 |     100 |   85.06 | ...05-208,295-305 
  ...oryCommand.ts |       0 |        0 |       0 |       0 | 1-7               
  ...umeCommand.ts |   94.54 |    68.75 |     100 |   94.54 | 60-61,79          
  ...ompletion.tsx |   90.59 |    83.33 |     100 |   90.59 | ...01,104,137-140 
  ...ectionList.ts |   96.59 |    94.62 |     100 |   96.59 | ...82-183,237-240 
  ...moryStatus.ts |       0 |        0 |       0 |       0 | 1-29              
  ...sionPicker.ts |   91.66 |    72.34 |     100 |   91.66 | ...45-246,250-251 
  ...ngsCommand.ts |   18.75 |      100 |       0 |   18.75 | 10-25             
  ...ellHistory.ts |   91.74 |    79.41 |     100 |   91.74 | ...74,122-123,133 
  ...oryCommand.ts |       0 |        0 |       0 |       0 | 1-73              
  ...Completion.ts |   80.97 |     84.4 |   91.66 |   80.97 | ...69-471,479-487 
  ...tateAndRef.ts |     100 |      100 |     100 |     100 |                   
  ...eateDialog.ts |   88.23 |      100 |     100 |   88.23 | 14,18             
  ...rminalSize.ts |   76.19 |      100 |      50 |   76.19 | 21-25             
  ...emeCommand.ts |    8.04 |      100 |       0 |    8.04 | 25-112            
  useTimer.ts      |   88.09 |    85.71 |     100 |   88.09 | 44-45,51-53       
  ...lMigration.ts |       0 |        0 |       0 |       0 |                   
  ...rustModify.ts |     100 |      100 |     100 |     100 |                   
  useVoice.ts      |   93.24 |    77.77 |     100 |   93.24 | 58-62             
  ...elcomeBack.ts |   69.44 |    54.54 |     100 |   69.44 | ...85,89-90,96-98 
  ...indowTitle.ts |     100 |    91.66 |     100 |     100 | 42                
  vim.ts           |   83.54 |     79.5 |     100 |   83.54 | ...44,748-756,765 
 src/ui/layouts    |   79.24 |    38.46 |     100 |   79.24 |                   
  ...AppLayout.tsx |   81.94 |       40 |     100 |   81.94 | 42-44,50-57,75-77 
  ...AppLayout.tsx |   73.52 |    33.33 |     100 |   73.52 | 30-35,37-39       
 src/ui/models     |   56.25 |    85.71 |      40 |   56.25 |                   
  ...ableModels.ts |   56.25 |    85.71 |      40 |   56.25 | ...3,80-81,98-100 
 ...noninteractive |     100 |      100 |    7.69 |     100 |                   
  ...eractiveUi.ts |     100 |      100 |    7.69 |     100 |                   
 src/ui/state      |   94.91 |    81.81 |     100 |   94.91 |                   
  extensions.ts    |   94.91 |    81.81 |     100 |   94.91 | 68-69,88          
 src/ui/themes     |      99 |    58.66 |     100 |      99 |                   
  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 |                   
  no-color.ts      |     100 |      100 |     100 |     100 |                   
  qwen-dark.ts     |     100 |      100 |     100 |     100 |                   
  qwen-light.ts    |     100 |      100 |     100 |     100 |                   
  ...tic-tokens.ts |     100 |      100 |     100 |     100 |                   
  ...-of-purple.ts |     100 |      100 |     100 |     100 |                   
  theme-manager.ts |   87.08 |    79.68 |     100 |   87.08 | ...03-312,317-318 
  theme.ts         |     100 |    28.98 |     100 |     100 | 272-461           
  xcode.ts         |     100 |      100 |     100 |     100 |                   
 src/ui/utils      |   67.95 |    83.56 |   78.16 |   67.95 |                   
  ...Colorizer.tsx |   82.78 |    88.23 |     100 |   82.78 | ...10-111,197-223 
  ...nRenderer.tsx |   59.31 |    38.23 |     100 |   59.31 | ...33-139,149-151 
  ...wnDisplay.tsx |   85.75 |    88.05 |     100 |   85.75 | ...76-284,317-342 
  QueryGuard.ts    |   85.71 |      100 |   66.66 |   85.71 | 61-62,65-66       
  ...eRenderer.tsx |   77.88 |    76.19 |     100 |   77.88 | 54-82             
  ...boardUtils.ts |   59.61 |    58.82 |     100 |   59.61 | ...,86-88,107-149 
  commandUtils.ts  |   93.54 |    88.63 |     100 |   93.54 | ...43,147,149-150 
  computeStats.ts  |     100 |      100 |     100 |     100 |                   
  displayUtils.ts  |   60.46 |      100 |      50 |   60.46 | 19-35             
  formatters.ts    |    94.8 |    98.07 |     100 |    94.8 | 101-104           
  highlight.ts     |   98.63 |       95 |     100 |   98.63 | 93                
  isNarrowWidth.ts |     100 |      100 |     100 |     100 |                   
  ...olDetector.ts |    7.22 |      100 |       0 |    7.22 | ...24-125,128-129 
  layoutUtils.ts   |     100 |      100 |     100 |     100 |                   
  ...nUtilities.ts |   69.84 |    85.71 |     100 |   69.84 | 75-91,100-101     
  ...mConstants.ts |     100 |      100 |     100 |     100 |                   
  ...storyUtils.ts |   59.68 |    67.69 |      90 |   59.68 | ...40,388,393-415 
  ...ickerUtils.ts |     100 |      100 |     100 |     100 |                   
  terminalSetup.ts |    4.37 |      100 |       0 |    4.37 | 44-393            
  textUtils.ts     |   96.52 |    94.44 |    87.5 |   96.52 | 19-20,148-149     
  updateCheck.ts   |     100 |    80.95 |     100 |     100 | 30-42             
 ...i/utils/export |    2.38 |        0 |       0 |    2.38 |                   
  collect.ts       |    0.87 |      100 |       0 |    0.87 | 40-394,401-697    
  index.ts         |     100 |      100 |     100 |     100 |                   
  normalize.ts     |    1.23 |      100 |       0 |    1.23 | 17-336            
  types.ts         |       0 |        0 |       0 |       0 | 1                 
  utils.ts         |      40 |      100 |       0 |      40 | 11-13             
 ...ort/formatters |    3.38 |      100 |       0 |    3.38 |                   
  html.ts          |    9.61 |      100 |       0 |    9.61 | ...28,34-76,82-84 
  json.ts          |      50 |      100 |       0 |      50 | 14-15             
  jsonl.ts         |     3.5 |      100 |       0 |     3.5 | 14-76             
  markdown.ts      |    0.94 |      100 |       0 |    0.94 | 13-295            
 src/utils         |   68.67 |    89.61 |    93.7 |   68.67 |                   
  acpModelUtils.ts |     100 |      100 |     100 |     100 |                   
  ...tification.ts |   92.59 |    71.42 |     100 |   92.59 | 36-37             
  checks.ts        |   33.33 |      100 |       0 |   33.33 | 23-28             
  cleanup.ts       |   65.38 |      100 |   66.66 |   65.38 | 28-37             
  commands.ts      |     100 |      100 |     100 |     100 |                   
  commentJson.ts   |     100 |    93.75 |     100 |     100 | 30                
  deepMerge.ts     |     100 |       90 |     100 |     100 | 41-43,49          
  ...ScopeUtils.ts |   97.56 |    88.88 |     100 |   97.56 | 67                
  ...arResolver.ts |   94.28 |    88.46 |     100 |   94.28 | 28-29,125-126     
  errors.ts        |   98.27 |       95 |     100 |   98.27 | 44-45             
  events.ts        |     100 |      100 |     100 |     100 |                   
  gitUtils.ts      |   91.91 |    84.61 |     100 |   91.91 | 78-81,124-127     
  ...AutoUpdate.ts |    51.2 |       90 |      50 |    51.2 | 87-152            
  ...lationInfo.ts |     100 |      100 |     100 |     100 |                   
  languageUtils.ts |   97.87 |    96.42 |     100 |   97.87 | 132-133           
  math.ts          |       0 |        0 |       0 |       0 | 1-15              
  ...onfigUtils.ts |     100 |      100 |     100 |     100 |                   
  ...iveHelpers.ts |   96.84 |    93.28 |     100 |   96.84 | ...87-488,586,599 
  package.ts       |   88.88 |       80 |     100 |   88.88 | 33-34             
  processUtils.ts  |     100 |      100 |     100 |     100 |                   
  readStdin.ts     |   79.62 |       90 |      80 |   79.62 | 33-40,52-54       
  relaunch.ts      |   98.07 |    76.92 |     100 |   98.07 | 70                
  resolvePath.ts   |   66.66 |       25 |     100 |   66.66 | 12-13,16,18-19    
  sandbox.ts       |       0 |        0 |       0 |       0 | 1-984             
  settingsUtils.ts |   86.32 |    90.59 |   94.44 |   86.32 | ...38,569,632-644 
  spawnWrapper.ts  |     100 |      100 |     100 |     100 |                   
  ...upWarnings.ts |     100 |      100 |     100 |     100 |                   
  stdioHelpers.ts  |     100 |       60 |     100 |     100 | 23,32             
  systemInfo.ts    |      99 |     90.9 |     100 |      99 | 172               
  ...InfoFields.ts |   86.13 |    65.78 |     100 |   86.13 | ...10-111,132-133 
  ...entEmitter.ts |     100 |      100 |     100 |     100 |                   
  ...upWarnings.ts |   91.17 |    82.35 |     100 |   91.17 | 67-68,73-74,77-78 
  version.ts       |     100 |       50 |     100 |     100 | 11                
  windowTitle.ts   |     100 |      100 |     100 |     100 |                   
  ...WithBackup.ts |    62.1 |    77.77 |     100 |    62.1 | 93,107,118-157    
-------------------|---------|----------|---------|---------|-------------------
Core Package - Full Text Report
-------------------|---------|----------|---------|---------|-------------------
File               | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-------------------|---------|----------|---------|---------|-------------------
All files          |   71.12 |    80.38 |   74.39 |   71.12 |                   
 src               |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
 src/__mocks__/fs  |       0 |        0 |       0 |       0 |                   
  promises.ts      |       0 |        0 |       0 |       0 | 1-48              
 src/agents        |    59.6 |    83.33 |   56.75 |    59.6 |                   
  ...chestrator.ts |   75.83 |     82.6 |     100 |   75.83 | ...49-159,210-217 
  ...ound-store.ts |   97.95 |     90.9 |     100 |   97.95 | 61                
  index.ts         |     100 |      100 |     100 |     100 |                   
  mailbox.ts       |      80 |    78.57 |      80 |      80 | 55-57,74-75,89-97 
  team-config.ts   |    6.48 |      100 |       0 |    6.48 | 43-176            
  team-registry.ts |   45.45 |      100 |       0 |   45.45 | ...34,37-38,41-42 
 src/agents/arena  |   64.56 |    66.66 |   68.49 |   64.56 |                   
  ...gentClient.ts |   79.47 |    88.88 |   81.81 |   79.47 | ...68-183,189-204 
  ArenaManager.ts  |    61.9 |    63.09 |   67.27 |    61.9 | ...1611,1620-1630 
  arena-events.ts  |   64.44 |      100 |      50 |   64.44 | ...71-175,178-183 
  index.ts         |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...gents/backends |   76.77 |    85.23 |    72.6 |   76.77 |                   
  ITermBackend.ts  |   97.97 |    93.93 |     100 |   97.97 | ...78-180,255,307 
  ...essBackend.ts |   92.81 |     85.5 |   82.85 |   92.81 | ...15-235,294,390 
  TmuxBackend.ts   |    90.7 |    76.55 |   97.36 |    90.7 | ...87,697,743-747 
  detect.ts        |   31.25 |      100 |       0 |   31.25 | 34-88             
  index.ts         |     100 |      100 |     100 |     100 |                   
  iterm-it2.ts     |     100 |     92.1 |     100 |     100 | 37-38,106         
  tmux-commands.ts |    6.64 |      100 |    3.03 |    6.64 | ...93-363,386-503 
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...agents/runtime |   76.17 |     73.4 |   74.25 |   76.17 |                   
  agent-core.ts    |   62.88 |    62.73 |   56.52 |   62.88 | ...1309,1336-1382 
  agent-events.ts  |    87.5 |      100 |      75 |    87.5 | 259-263           
  ...t-headless.ts |    80.5 |    71.11 |      55 |    80.5 | ...87-388,391-392 
  ...nteractive.ts |   85.71 |    83.33 |   80.64 |   85.71 | ...18,720,722,725 
  ...statistics.ts |   98.19 |    82.35 |     100 |   98.19 | 127,151,192,225   
  agent-types.ts   |     100 |      100 |     100 |     100 |                   
  compaction.ts    |   88.76 |    66.66 |     100 |   88.76 | ...24-128,135-136 
  index.ts         |     100 |      100 |     100 |     100 |                   
 src/config        |   69.33 |    71.33 |   58.53 |   69.33 |                   
  config.ts        |   67.44 |    66.66 |   54.26 |   67.44 | ...2370,2377-2380 
  constants.ts     |     100 |      100 |     100 |     100 |                   
  models.ts        |     100 |      100 |     100 |     100 |                   
  storage.ts       |   79.74 |    92.72 |    75.6 |   79.74 | ...88-292,303-304 
 ...nfirmation-bus |   74.35 |    52.17 |      90 |   74.35 |                   
  message-bus.ts   |   72.22 |       50 |      90 |   72.22 | ...18-120,123-124 
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/core          |   78.44 |    80.16 |   89.34 |   78.44 |                   
  agentCore.ts     |   81.25 |    76.19 |     100 |   81.25 | ...21,162,168,171 
  baseLlmClient.ts |     100 |    96.42 |     100 |     100 | 113               
  ...pointStore.ts |     100 |      100 |     100 |     100 |                   
  client.ts        |   73.11 |    73.85 |   91.66 |   73.11 | ...1199,1251-1252 
  ...tGenerator.ts |   80.48 |    55.17 |     100 |   80.48 | ...13,315,322-325 
  ...lScheduler.ts |   70.46 |    77.14 |   89.65 |   70.46 | ...1722,1779-1783 
  geminiChat.ts    |   72.29 |    82.31 |   81.25 |   72.29 | ...56-867,901-904 
  geminiRequest.ts |     100 |      100 |     100 |     100 |                   
  logger.ts        |   82.25 |    81.81 |     100 |   82.25 | ...57-361,407-421 
  ...tyDefaults.ts |     100 |      100 |     100 |     100 |                   
  ...olExecutor.ts |   92.59 |       75 |      50 |   92.59 | 41-42             
  ...on-helpers.ts |   74.74 |    46.15 |     100 |   74.74 | ...86,192,197-206 
  prompts.ts       |   81.66 |    87.05 |   64.28 |   81.66 | ...1263,1273-1300 
  tokenLimits.ts   |     100 |    88.23 |     100 |     100 | 43-44             
  ...okTriggers.ts |   99.31 |     90.9 |     100 |   99.31 | 124,135           
  turn.ts          |   91.13 |    87.03 |     100 |   91.13 | ...85,398-399,447 
 ...ntentGenerator |   87.91 |    69.28 |   91.17 |   87.91 |                   
  ...tGenerator.ts |   87.25 |    64.66 |    87.5 |   87.25 | ...45-652,656-657 
  converter.ts     |   90.35 |    73.97 |     100 |   90.35 | ...99,542-557,580 
  index.ts         |       0 |        0 |       0 |       0 | 1-21              
 ...ntentGenerator |   75.87 |    61.84 |   94.11 |   75.87 |                   
  ...tGenerator.ts |   73.49 |    61.64 |   93.75 |   73.49 | ...57-463,481-482 
  index.ts         |     100 |    66.66 |     100 |     100 | 45                
 ...ntentGenerator |   91.06 |    67.96 |      85 |   91.06 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...tGenerator.ts |   91.02 |    67.96 |      85 |   91.02 | ...37,547-548,576 
 ...ntentGenerator |   75.61 |     82.6 |   91.78 |   75.61 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  converter.ts     |   73.29 |    80.29 |      90 |   73.29 | ...1483,1504-1513 
  errorHandler.ts  |     100 |      100 |     100 |     100 |                   
  index.ts         |       0 |        0 |       0 |       0 | 1-94              
  ...tGenerator.ts |   48.78 |    91.66 |   77.77 |   48.78 | ...10-163,166-167 
  pipeline.ts      |   83.75 |    78.78 |     100 |   83.75 | ...40-641,643-654 
  ...CallParser.ts |   90.66 |    88.57 |     100 |   90.66 | ...15-319,349-350 
 ...rator/provider |   96.07 |    87.73 |   93.75 |   96.07 |                   
  dashscope.ts     |   96.29 |    87.09 |   93.33 |   96.29 | ...10-211,287-288 
  deepseek.ts      |   90.76 |       75 |     100 |   90.76 | 40-41,45-46,59-60 
  default.ts       |   97.56 |      100 |   85.71 |   97.56 | 85-86             
  index.ts         |     100 |      100 |     100 |     100 |                   
  modelscope.ts    |     100 |      100 |     100 |     100 |                   
  openrouter.ts    |     100 |      100 |     100 |     100 |                   
  types.ts         |       0 |        0 |       0 |       0 |                   
 src/extension     |   60.36 |    79.75 |   78.22 |   60.36 |                   
  ...-converter.ts |   63.79 |    47.82 |      90 |   63.79 | ...86-787,796-828 
  ...ionManager.ts |    44.7 |    84.12 |   65.11 |    44.7 | ...1320,1341-1360 
  ...onSettings.ts |   93.46 |    93.05 |     100 |   93.46 | ...17-221,228-232 
  ...-converter.ts |   54.88 |    94.44 |      60 |   54.88 | ...35-146,158-192 
  github.ts        |   44.94 |    88.52 |      60 |   44.94 | ...53-359,398-451 
  index.ts         |     100 |      100 |     100 |     100 |                   
  marketplace.ts   |   97.29 |    93.75 |     100 |   97.29 | ...64,184-185,274 
  npm.ts           |   49.82 |    76.08 |      75 |   49.82 | ...05-407,414-418 
  override.ts      |   94.11 |    88.88 |     100 |   94.11 | 63-64,81-82       
  settings.ts      |   66.26 |      100 |      50 |   66.26 | 81-108,143-149    
  storage.ts       |   94.73 |       90 |     100 |   94.73 | 41-42             
  ...ableSchema.ts |     100 |      100 |     100 |     100 |                   
  variables.ts     |   88.75 |    83.33 |     100 |   88.75 | ...28-231,234-237 
 src/followup      |   44.88 |    92.71 |   68.42 |   44.88 |                   
  followupState.ts |   95.83 |    89.18 |     100 |   95.83 | 153-155,210-211   
  forkedQuery.ts   |      30 |      100 |      50 |      30 | 122-249           
  index.ts         |     100 |      100 |     100 |     100 |                   
  overlayFs.ts     |   95.06 |       84 |     100 |   95.06 | 78,108,122,133    
  speculation.ts   |    13.4 |      100 |   16.66 |    13.4 | 88-458,518-563    
  ...onToolGate.ts |     100 |    96.29 |     100 |     100 | 93                
  ...nGenerator.ts |   38.27 |    95.12 |   33.33 |   38.27 | ...00-302,337-367 
 src/generated     |       0 |        0 |       0 |       0 |                   
  git-commit.ts    |       0 |        0 |       0 |       0 | 1-10              
 src/hooks         |   77.44 |     84.8 |   85.24 |   77.44 |                   
  ...on-checker.ts |     100 |      100 |     100 |     100 |                   
  ...Aggregator.ts |   96.17 |       90 |     100 |   96.17 | ...74,276-277,350 
  ...entHandler.ts |   86.07 |       84 |   80.76 |   86.07 | ...88,641-642,652 
  hookPlanner.ts   |   78.18 |       72 |    90.9 |   78.18 | ...18-236,244-245 
  hookRegistry.ts  |   79.74 |    74.28 |     100 |   79.74 | ...59,361,363,365 
  hookRunner.ts    |   57.83 |    73.33 |   66.66 |   57.83 | ...47-557,610-611 
  hookSystem.ts    |   83.22 |      100 |   86.95 |   83.22 | ...46-362,368-384 
  index.ts         |     100 |      100 |     100 |     100 |                   
  trustedHooks.ts  |     9.3 |      100 |       0 |     9.3 | 24-122            
  types.ts         |   89.61 |    94.66 |   85.18 |   89.61 | ...45-346,406-410 
 src/ide           |   72.67 |    83.92 |   75.92 |   72.67 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  detect-ide.ts    |     100 |      100 |     100 |     100 |                   
  ide-client.ts    |    64.2 |    81.48 |   66.66 |    64.2 | ...9-970,999-1007 
  ideContext.ts    |     100 |      100 |     100 |     100 |                   
  process-utils.ts |   84.84 |    71.79 |     100 |   84.84 | ...37,151,193-194 
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/lsp           |   33.39 |    43.75 |   44.91 |   33.39 |                   
  ...nfigLoader.ts |   70.27 |    35.89 |   94.73 |   70.27 | ...20-422,426-432 
  ...ionFactory.ts |    4.29 |      100 |       0 |    4.29 | ...20-371,377-394 
  ...Normalizer.ts |   23.09 |    13.72 |   30.43 |   23.09 | ...04-905,909-924 
  ...verManager.ts |   10.47 |       75 |      25 |   10.47 | ...56-675,681-711 
  ...eLspClient.ts |   17.89 |      100 |       0 |   17.89 | ...37-244,254-258 
  ...LspService.ts |   45.87 |    62.13 |   66.66 |   45.87 | ...1282,1299-1309 
  constants.ts     |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/mcp           |   78.74 |    75.68 |   75.92 |   78.74 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  ...h-provider.ts |   86.95 |      100 |   33.33 |   86.95 | ...,93,97,101-102 
  ...h-provider.ts |   73.74 |    54.45 |     100 |   73.74 | ...64-871,878-880 
  ...en-storage.ts |   98.62 |    97.72 |     100 |   98.62 | 87-88             
  oauth-utils.ts   |   70.58 |    85.29 |    90.9 |   70.58 | ...70-290,315-344 
  ...n-provider.ts |   89.83 |    95.83 |   45.45 |   89.83 | ...43,147,151-152 
 .../token-storage |   79.48 |    86.66 |   86.36 |   79.48 |                   
  ...en-storage.ts |     100 |      100 |     100 |     100 |                   
  ...en-storage.ts |   82.75 |    82.35 |   92.85 |   82.75 | ...62-172,180-181 
  ...en-storage.ts |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...en-storage.ts |   68.14 |    82.35 |   64.28 |   68.14 | ...81-295,298-314 
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/memory        |   15.82 |       75 |    7.69 |   15.82 |                   
  ...tterParser.ts |   13.04 |      100 |       0 |   13.04 | 20-51,57-72       
  index.ts         |     100 |      100 |     100 |     100 |                   
  memoryAge.ts     |   32.07 |      100 |       0 |   32.07 | 36-46,53-68,75-84 
  ...yExtractor.ts |   13.68 |      100 |       0 |   13.68 | 35-189            
  memoryPrompt.ts  |     100 |      100 |     100 |     100 |                   
  memoryScan.ts    |   21.05 |      100 |       0 |   21.05 | 19-24,31-40       
  memoryStore.ts   |    7.75 |       75 |   18.18 |    7.75 | 52-364            
  proposalStore.ts |    9.87 |      100 |       0 |    9.87 | 20-111            
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/mocks         |       0 |        0 |       0 |       0 |                   
  msw.ts           |       0 |        0 |       0 |       0 | 1-9               
 src/models        |   88.44 |    81.65 |    87.3 |   88.44 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...nfigErrors.ts |   74.22 |       44 |   84.61 |   74.22 | ...,67-74,106-117 
  ...igResolver.ts |    99.3 |    87.09 |     100 |    99.3 | 127               
  modelRegistry.ts |     100 |    97.72 |     100 |     100 | 164               
  modelsConfig.ts  |   84.51 |    82.17 |   83.33 |   84.51 | ...1069,1098-1099 
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/output        |     100 |      100 |     100 |     100 |                   
  ...-formatter.ts |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/permissions   |   68.39 |    87.29 |   48.27 |   68.39 |                   
  ...classifier.ts |   30.88 |    57.14 |   33.33 |   30.88 | ...07-230,234-235 
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...on-manager.ts |   78.62 |       79 |      84 |   78.62 | ...65-772,792-801 
  rule-parser.ts   |   97.97 |     95.7 |     100 |   97.97 | ...23-824,968-970 
  ...-semantics.ts |   58.28 |    85.27 |    30.2 |   58.28 | ...1604-1614,1643 
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/prompts       |   29.09 |      100 |      25 |   29.09 |                   
  mcp-prompts.ts   |   18.18 |      100 |       0 |   18.18 | 11-19             
  ...t-registry.ts |   31.81 |      100 |   28.57 |   31.81 | ...45,51-58,71-76 
 src/services      |   65.41 |    79.13 |   77.72 |   65.41 |                   
  baselineCheck.ts |    3.65 |      100 |       0 |    3.65 | 25-93,100-132     
  ...VerifyGate.ts |   88.81 |    91.42 |     100 |   88.81 | 91-99,139-146     
  ...ionService.ts |   80.63 |    85.31 |   81.81 |   80.63 | ...78-813,828-861 
  ...ingService.ts |   68.39 |    48.38 |   85.71 |   68.39 | ...25-437,453-454 
  cronScheduler.ts |    86.2 |    90.32 |   94.11 |    86.2 | ...20,124-133,198 
  evolveService.ts |   15.78 |      100 |       0 |   15.78 | 43-190            
  ...eryService.ts |   80.43 |    95.45 |      75 |   80.43 | ...19-134,140-141 
  ...temService.ts |   89.76 |     85.1 |   88.88 |   89.76 | ...89,191,266-273 
  fileTracker.ts   |   98.21 |     90.9 |     100 |   98.21 | 43                
  gitService.ts    |   66.29 |     90.9 |   55.55 |   66.29 | ...03-113,116-120 
  ...reeService.ts |    67.5 |    65.21 |    87.5 |    67.5 | ...24,830-847,865 
  ...derService.ts |   42.85 |    22.22 |   66.66 |   42.85 | ...03-108,117-118 
  ...ionService.ts |   97.94 |    96.61 |     100 |   97.94 | 104-105,266-267   
  ...solidation.ts |     5.9 |      100 |       0 |     5.9 | 65-339            
  microcompact.ts  |   85.71 |       68 |     100 |   85.71 | ...59,76-77,79-80 
  ...leSelector.ts |   94.03 |       75 |     100 |   94.03 | ...40,243-244,285 
  ...kerService.ts |    5.63 |      100 |       0 |    5.63 | 21-109            
  ...EditVerify.ts |   11.11 |      100 |       0 |   11.11 | 19-76             
  ...MapService.ts |    83.2 |    79.31 |      90 |    83.2 | ...30,343,392-415 
  scopeLock.ts     |   31.91 |      100 |   14.28 |   31.91 | ...,87-88,104-116 
  sessionNotes.ts  |   33.89 |      100 |      40 |   33.89 | 89-147            
  ...ionService.ts |   79.23 |    73.19 |   88.88 |   79.23 | ...53-674,682-706 
  ...ionService.ts |   83.46 |    78.53 |   83.33 |   83.46 | ...1017,1023-1028 
  ...actService.ts |   28.04 |       50 |   33.33 |   28.04 | ...20-121,128-142 
  task-store.ts    |     8.2 |      100 |       0 |     8.2 | 106-586           
 .../sessionMemory |   32.89 |    95.23 |    37.5 |   32.89 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  prompts.ts       |    6.77 |      100 |       0 |    6.77 | ...65-166,179-221 
  sessionMemory.ts |   13.18 |      100 |       0 |   13.18 | 58-176            
  ...emoryUtils.ts |   85.22 |    95.23 |   64.28 |   85.22 | ...68-172,176-177 
 src/skills        |   76.46 |    80.14 |   77.77 |   76.46 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  skill-load.ts    |   90.83 |    77.77 |     100 |   90.83 | ...28,148,160-162 
  skill-manager.ts |   71.68 |    80.76 |   73.91 |   71.68 | ...95-703,706-715 
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/subagents     |    80.7 |    82.74 |    92.1 |    80.7 |                   
  ...tin-agents.ts |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...nt-manager.ts |    71.6 |    73.88 |      88 |    71.6 | ...-932,1008-1009 
  types.ts         |     100 |      100 |     100 |     100 |                   
  validation.ts    |   92.34 |    96.51 |     100 |   92.34 | 50-55,59-64,68-73 
 src/telemetry     |   65.04 |    83.33 |    69.9 |   65.04 |                   
  config.ts        |     100 |      100 |     100 |     100 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  ...-exporters.ts |   36.76 |      100 |   22.22 |   36.76 | ...84,87-88,91-92 
  ...sTelemetry.ts |    7.25 |      100 |       0 |    7.25 | ...59-177,186-203 
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...t.circular.ts |       0 |        0 |       0 |       0 | 1-111             
  ...t.circular.ts |       0 |        0 |       0 |       0 | 1-128             
  loggers.ts       |    49.4 |     61.4 |   52.38 |    49.4 | ...1123,1126-1150 
  metrics.ts       |   75.93 |    86.74 |   76.92 |   75.93 | ...09-846,849-878 
  sanitize.ts      |      80 |    83.33 |     100 |      80 | 35-36,41-42       
  sdk.ts           |   86.31 |    65.51 |     100 |   86.31 | ...27,233-234,240 
  ...etry-utils.ts |     100 |      100 |     100 |     100 |                   
  ...l-decision.ts |     100 |      100 |     100 |     100 |                   
  ...panContext.ts |     100 |      100 |     100 |     100 |                   
  types.ts         |   77.31 |    85.08 |   81.81 |   77.31 | ...1105,1108-1137 
  uiTelemetry.ts   |   91.87 |    96.15 |   78.57 |   91.87 | ...67-168,174-181 
 ...ry/qwen-logger |    68.3 |    81.52 |   64.91 |    68.3 |                   
  event-types.ts   |       0 |        0 |       0 |       0 |                   
  qwen-logger.ts   |    68.3 |    81.31 |   64.28 |    68.3 | ...1040,1078-1079 
 src/test-utils    |   92.85 |    94.28 |   77.41 |   92.85 |                   
  config.ts        |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  mock-tool.ts     |   91.02 |    93.54 |   75.86 |   91.02 | ...31,195-196,209 
  ...aceContext.ts |     100 |      100 |     100 |     100 |                   
 src/tools         |   71.46 |    77.48 |   74.24 |   71.46 |                   
  agent.ts         |   76.12 |     86.5 |   76.19 |   76.12 | ...1032,1041-1046 
  ...erQuestion.ts |   87.89 |     73.8 |    90.9 |   87.89 | ...44-345,349-350 
  browser-tool.ts  |   55.51 |    44.44 |   94.11 |   55.51 | ...77-978,980-981 
  cron-create.ts   |   97.61 |    88.88 |   83.33 |   97.61 | 30-31             
  cron-delete.ts   |   96.55 |      100 |   83.33 |   96.55 | 26-27             
  cron-list.ts     |   96.36 |      100 |   83.33 |   96.36 | 25-26             
  diffOptions.ts   |     100 |      100 |     100 |     100 |                   
  edit.ts          |   80.03 |    83.83 |      75 |   80.03 | ...49-550,633-683 
  exitPlanMode.ts  |   85.81 |    86.95 |     100 |   85.81 | ...24-129,157-169 
  glob.ts          |   91.57 |    88.33 |   84.61 |   91.57 | ...20,163,293,296 
  grep.ts          |    71.3 |    87.34 |   68.42 |    71.3 | ...90,530,538-545 
  ls.ts            |   96.72 |    90.14 |     100 |   96.72 | 169-174,205,209   
  lsp.ts           |   72.58 |    60.29 |   90.32 |   72.58 | ...1202,1204-1205 
  mailbox-tools.ts |   96.42 |      100 |   83.33 |   96.42 | 39-40,117-118     
  ...nt-manager.ts |   46.44 |       60 |    42.1 |   46.44 | ...89-507,510-547 
  mcp-client.ts    |   29.34 |    70.83 |   45.45 |   29.34 | ...1425,1431-1434 
  mcp-tool.ts      |   90.46 |     87.5 |   96.55 |   90.46 | ...11-612,662-663 
  memoryTool.ts    |   74.68 |     80.7 |   90.47 |   74.68 | ...41-350,463-547 
  ...iable-tool.ts |     100 |    84.61 |     100 |     100 | 102,109           
  read-file.ts     |   94.47 |    88.63 |      80 |   94.47 | ...74,80-83,86-87 
  repoMap.ts       |   59.42 |      100 |   33.33 |   59.42 | ...,47-61,109-112 
  ripGrep.ts       |   96.24 |    90.76 |     100 |   96.24 | ...73,276,354-355 
  ...-transport.ts |    6.34 |      100 |       0 |    6.34 | 47-145            
  shell.ts         |   85.31 |    78.12 |   85.71 |   85.31 | ...66-470,664-665 
  skill.ts         |   94.08 |    88.88 |   84.61 |   94.08 | ...16,255-258,262 
  task-create.ts   |   59.03 |      100 |   33.33 |   59.03 | ...,36-59,105-108 
  task-get.ts      |      50 |      100 |   33.33 |      50 | ...29,32-57,88-91 
  task-list.ts     |   47.82 |      100 |   33.33 |   47.82 | ...,40-72,113-116 
  task-output.ts   |    59.7 |      100 |   33.33 |    59.7 | ...30,33-50,87-90 
  task-ready.ts    |   39.44 |      100 |   33.33 |   39.44 | ...,35-93,132-135 
  task-stop.ts     |      50 |      100 |   33.33 |      50 | ...30,33-61,96-99 
  task-update.ts   |   86.56 |      100 |      75 |   86.56 | 33-38,156-167     
  tool-error.ts    |     100 |      100 |     100 |     100 |                   
  tool-names.ts    |     100 |      100 |     100 |     100 |                   
  tool-registry.ts |   62.56 |    65.38 |   57.57 |   62.56 | ...43-552,559-575 
  tools.ts         |   83.11 |    89.58 |   77.77 |   83.11 | ...35-436,452-458 
  web-fetch.ts     |   85.41 |    58.33 |   91.66 |   85.41 | ...58-259,261-262 
  write-file.ts    |   79.24 |    79.36 |   69.23 |   79.24 | ...46-449,461-496 
 ...ols/web-search |   79.93 |    74.13 |   78.94 |   79.93 |                   
  base-provider.ts |    72.5 |    57.14 |     100 |    72.5 | 44-48,63-66,75-76 
  index.ts         |   82.94 |    80.43 |   85.71 |   82.94 | ...80-188,196-200 
  types.ts         |       0 |        0 |       0 |       0 | 1                 
  utils.ts         |      60 |       50 |      50 |      60 | 35-42             
 ...arch/providers |   77.41 |    68.42 |   88.88 |   77.41 |                   
  ...e-provider.ts |   17.64 |      100 |       0 |   17.64 | 16-33             
  ...e-provider.ts |   83.33 |    55.55 |     100 |   83.33 | 57-58,61-62,76-80 
  ...y-provider.ts |   90.56 |       80 |     100 |   90.56 | 66-70             
 src/utils         |   84.48 |    87.09 |   88.56 |   84.48 |                   
  LruCache.ts      |       0 |        0 |       0 |       0 | 1-41              
  ...ssageQueue.ts |     100 |      100 |     100 |     100 |                   
  ...cFileWrite.ts |   76.08 |    44.44 |     100 |   76.08 | 61-70,72          
  ...essEmitter.ts |   10.86 |      100 |       0 |   10.86 | ...,95-99,114-190 
  browser.ts       |    7.69 |      100 |       0 |    7.69 | 17-56             
  ...igResolver.ts |     100 |      100 |     100 |     100 |                   
  cronDisplay.ts   |   42.85 |    23.07 |     100 |   42.85 | 26-31,33-45,47-54 
  cronParser.ts    |   89.74 |    85.71 |     100 |   89.74 | ...,63-64,183-186 
  debugLogger.ts   |   96.12 |    93.75 |   93.75 |   96.12 | 164-168           
  editHelper.ts    |   92.67 |    82.14 |     100 |   92.67 | ...52-454,463-464 
  editor.ts        |   96.98 |    93.87 |     100 |   96.98 | ...93-194,196-197 
  ...arResolver.ts |   94.28 |    88.88 |     100 |   94.28 | 28-29,125-126     
  ...entContext.ts |     100 |       95 |     100 |     100 | 83                
  errorParsing.ts  |   96.92 |       95 |     100 |   96.92 | 36-37             
  ...rReporting.ts |   88.46 |       90 |     100 |   88.46 | 69-74             
  errors.ts        |    68.7 |    77.27 |   53.33 |    68.7 | ...86-202,206-212 
  fetch.ts         |   71.97 |    72.22 |   71.42 |   71.97 | ...38,144,157,182 
  fileUtils.ts     |   87.96 |     81.4 |   94.73 |   87.96 | ...85-791,805-811 
  formatters.ts    |   54.54 |       50 |     100 |   54.54 | 12-16             
  ...eUtilities.ts |   89.21 |    86.66 |     100 |   89.21 | 16-17,49-55,65-66 
  ...rStructure.ts |   94.36 |    94.28 |     100 |   94.36 | ...17-120,330-335 
  getPty.ts        |    12.5 |      100 |       0 |    12.5 | 21-34             
  ...noreParser.ts |    92.3 |    89.36 |     100 |    92.3 | ...15-116,186-187 
  gitUtils.ts      |   36.66 |    76.92 |      50 |   36.66 | ...4,88-89,97-148 
  iconvHelper.ts   |     100 |      100 |     100 |     100 |                   
  ...rePatterns.ts |     100 |      100 |     100 |     100 |                   
  ...ionManager.ts |     100 |       90 |     100 |     100 | 26                
  jsonl-utils.ts   |    8.87 |      100 |       0 |    8.87 | ...51-184,190-196 
  ...-detection.ts |     100 |      100 |     100 |     100 |                   
  ...yDiscovery.ts |   82.01 |    73.21 |     100 |   82.01 | ...74-377,398-399 
  ...tProcessor.ts |   93.63 |       90 |     100 |   93.63 | ...96-302,384-385 
  ...Inspectors.ts |   61.53 |      100 |      50 |   61.53 | 18-23             
  ...kerChecker.ts |   84.04 |    78.94 |     100 |   84.04 | 68-69,79-84,92-98 
  openaiLogger.ts  |   86.27 |    82.14 |     100 |   86.27 | ...05-107,130-135 
  partUtils.ts     |     100 |      100 |     100 |     100 |                   
  pathReader.ts    |     100 |      100 |     100 |     100 |                   
  paths.ts         |   95.69 |    94.52 |     100 |   95.69 | ...,71-72,104-105 
  ...ectSummary.ts |    3.75 |      100 |       0 |    3.75 | 27-119            
  ...tIdContext.ts |     100 |      100 |     100 |     100 |                   
  ...rDetection.ts |   58.57 |       76 |     100 |   58.57 | ...4,88-89,95-100 
  ...noreParser.ts |   85.45 |    81.48 |     100 |   85.45 | ...59,65-66,72-73 
  rateLimit.ts     |      90 |    84.37 |     100 |      90 | 68,79-81          
  readManyFiles.ts |   85.95 |    85.71 |     100 |   85.95 | ...80-182,198-209 
  retry.ts         |   67.91 |    73.68 |     100 |   67.91 | ...82,200,207-208 
  ripgrepUtils.ts  |   46.53 |    83.33 |   66.66 |   46.53 | ...32-233,245-322 
  ...tchOptions.ts |   55.88 |       50 |      75 |   55.88 | ...29-130,151-152 
  safeJsonParse.ts |   74.07 |    83.33 |     100 |   74.07 | 40-46             
  ...nStringify.ts |     100 |      100 |     100 |     100 |                   
  ...aConverter.ts |   90.78 |    87.87 |     100 |   90.78 | ...41-42,93,95-96 
  ...aValidator.ts |     100 |    82.85 |     100 |     100 | 15-39,93-94,125   
  ...r-launcher.ts |   76.52 |     87.5 |   66.66 |   76.52 | ...33,135,153-191 
  shell-utils.ts   |   84.23 |    90.84 |     100 |   84.23 | ...1035,1042-1046 
  ...lAstParser.ts |   92.34 |    86.47 |    92.3 |   92.34 | ...1139-1141,1151 
  ...nlyChecker.ts |   95.75 |    92.39 |     100 |   95.75 | ...00-301,313-314 
  streamStall.ts   |   97.43 |    92.85 |     100 |   97.43 | 75                
  ...tGenerator.ts |     100 |     90.9 |     100 |     100 | 129               
  symlink.ts       |   77.77 |       50 |     100 |   77.77 | 44,54-59          
  ...emEncoding.ts |   96.36 |    91.17 |     100 |   96.36 | 59-60,124-125     
  ...Serializer.ts |   99.07 |    91.22 |     100 |   99.07 | 90,156-158        
  testUtils.ts     |   53.33 |      100 |   33.33 |   53.33 | ...53,59-64,70-72 
  textUtils.ts     |      60 |      100 |   66.66 |      60 | 36-55             
  thoughtUtils.ts  |     100 |    92.85 |     100 |     100 | 71                
  ...-converter.ts |   94.59 |    85.71 |     100 |   94.59 | 35-36             
  tool-utils.ts    |    93.6 |     91.3 |     100 |    93.6 | ...58-159,162-163 
  truncation.ts    |     100 |     90.9 |     100 |     100 | 52,71             
  ...aceContext.ts |   96.22 |       92 |   93.33 |   96.22 | ...15-116,133,160 
  yaml-parser.ts   |      92 |    83.67 |     100 |      92 | 49-53,65-69       
 ...ils/filesearch |   96.17 |     91.4 |     100 |   96.17 |                   
  crawlCache.ts    |     100 |      100 |     100 |     100 |                   
  crawler.ts       |   96.22 |     92.3 |     100 |   96.22 | 66-67             
  fileSearch.ts    |   93.22 |    87.14 |     100 |   93.22 | ...30-231,233-234 
  ignore.ts        |     100 |      100 |     100 |     100 |                   
  result-cache.ts  |     100 |     92.3 |     100 |     100 | 46                
 ...uest-tokenizer |   56.63 |    74.52 |   74.19 |   56.63 |                   
  ...eTokenizer.ts |   41.86 |    76.47 |   69.23 |   41.86 | ...70-443,453-507 
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...tTokenizer.ts |   68.39 |    69.49 |    90.9 |   68.39 | ...24-325,327-328 
  ...ageFormats.ts |      76 |      100 |   33.33 |      76 | 45-48,55-56       
  textTokenizer.ts |     100 |      100 |     100 |     100 |                   
  types.ts         |       0 |        0 |       0 |       0 | 1                 
-------------------|---------|----------|---------|---------|-------------------

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant