Skip to content

Harden secure-store fallback encryption (Fixes #1986) - #2178

Merged
acoliver merged 2 commits into
mainfrom
issue1986
Jun 25, 2026
Merged

Harden secure-store fallback encryption (Fixes #1986)#2178
acoliver merged 2 commits into
mainfrom
issue1986

Conversation

@acoliver

Copy link
Copy Markdown
Collaborator

TLDR

Hardened SecureStore fallback encryption by adding a shared high-entropy machine secret and writing new fallback envelopes as v:2 when that secret is available. Legacy v:1 fallback files remain readable, and SecureStore refuses to silently downgrade an existing v:2 fallback file to v:1 when the machine secret is unavailable.

Dive Deeper

This PR adds a machine-secret root of trust for SecureStore file fallback encryption. The new provider prefers OS keyring storage and falls back to a restrictive file at ~/.llxprt/machine_secret with atomic writes, 0700 parent directories, 0600 file permissions, source-scoped caching, and concurrent first-call deduplication.

The encrypted fallback envelope logic is now version-aware:

  • v:1 keeps the existing derivation exactly for backward compatibility.
  • v:2 mixes the machine secret into the KDF input while preserving AES-256-GCM and scrypt parameters.
  • New writes use v:2 when the machine secret resolves.
  • If the secret cannot resolve, new/legacy v:1 behavior remains available for availability.
  • Existing v:2 files are protected from silent weaker rewrites when the machine secret is unavailable.

The change also adds focused coverage for envelope validation, machine-secret persistence/cache/permissions, v:1 compatibility, v:2 read/write behavior, wrong or missing machine secrets, and downgrade prevention.

Two agents test files were adjusted only to satisfy full-repo lint rules that were exposed while running the prescribed verification; their behavior is unchanged.

Reviewer Test Plan

Recommended validation:

  • Run the storage tests and inspect the new v:2 fallback coverage.
  • Create a SecureStore with keyring unavailable and a deterministic machine secret, set a key, and confirm the .enc envelope has v:2.
  • Read a v:1 test envelope to confirm legacy compatibility.
  • Try reading v:2 with a different or unavailable machine secret and confirm SecureStoreError code CORRUPT.
  • Try overwriting an existing v:2 file with the machine secret unavailable and confirm it is rejected without replacing the original file.

Local verification performed:

  • npm run format: passed
  • npm run lint: passed
  • npm run typecheck: passed
  • npm run build: passed
  • node scripts/start.js --profile-load ollamakimi "write me a haiku and nothing else": passed
  • npm run test --workspace @vybestack/llxprt-code-storage: passed, 247 passed / 3 skipped
  • npm run test --workspace @vybestack/llxprt-code-agents -- src/api/tests/capabilityGaps.integration.spec.ts src/api/tests/policyControl.behavior.test.ts: passed, 24 passed
  • npm run test --workspaces --if-present -- --maxWorkers=1: attempted; tools/storage/auth/settings/telemetry/ide-integration/policy/mcp suites completed green, then the local shell received SIGTERM during the core workspace without an assertion failure. CI should provide the authoritative full-suite result.

Testing Matrix

🍏 🪟 🐧
npm run
npx
Docker
Podman - -
Seatbelt - -

Linked issues / bugs

Fixes #1986

@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Summary by CodeRabbit

  • New Features

    • Added machine-backed secret support for secure storage, with automatic fallback to a local secret file when needed.
    • Introduced encryption envelope handling for both legacy and newer fallback formats (versioned), choosing the newest format when the machine secret is available.
  • Bug Fixes

    • Ensured concurrent first-time secret requests converge on the same persisted value.
    • Added safer “fail closed” behavior and permission repair for supported systems.
    • Prevented accidental downgrade of existing encrypted fallback data.
  • Tests

    • Expanded coverage for envelope validation and secure-store fallback read/write and downgrade-prevention behavior.

Walkthrough

This PR adds a machine-secret-backed SecureStore fallback path, shared envelope/KDF helpers, a machine-secret path helper, and validation/integration tests. It also updates two Agent API tests with a masked-key helper and stricter rule-view existence checks.

Changes

Agent API test guards

Layer / File(s) Summary
Masked-key and rule-view guards
packages/agents/src/api/__tests__/capabilityGaps.integration.spec.ts, packages/agents/src/api/__tests__/policyControl.behavior.test.ts
A shared helper checks masked tool keys, and seeded rule lookups now throw when either view is missing before the source and args-pattern assertions run.

SecureStore machine-secret fallback

Layer / File(s) Summary
Shared path and envelope contracts
packages/storage/src/config/storage.ts, packages/storage/src/config/storage.test.ts, packages/storage/src/secure-store/envelope.ts, packages/storage/src/secure-store/envelope.test.ts
Storage.getMachineSecretPath() returns the home-directory .llxprt/machine_secret path, and envelope.ts adds versioned envelope types, shared scrypt parameters, KDF derivation helpers, and strict validation with tests.
Machine-secret provider
packages/storage/src/secure-store/machine-secret.ts, packages/storage/src/secure-store/machine-secret.test.ts
getMachineSecret caches by durable source, reads from the keyring or file, generates and persists 32-byte secrets when needed, and repairs or rejects Unix file permissions; tests cover persistence, concurrency, cache scoping, and failure paths.
SecureStore fallback versioning
packages/storage/src/secure-store/secure-store.ts
SecureStore now accepts machine-secret options, uses shared envelope helpers, selects v1 or v2 fallback envelopes based on machine-secret availability, blocks downgrades from an existing v2 file, and decrypts by envelope version.
Fallback and integration tests
packages/storage/src/secure-store/secure-store-integration.test.ts, packages/storage/src/secure-store/secure-store.fallback-v2.test.ts, packages/storage/src/secure-store/secure-store.fallback2.test.ts
Integration and fallback tests cover the default machine-secret path, v2 envelope creation and round-tripping, mismatch and missing-secret failures, overwrite downgrade prevention, legacy v1 compatibility, unknown-version errors, and null loader cases.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related PRs

  • vybestack/llxprt-code#1402: Touches the same SecureStore fallback and keyring-vs-fallback behavior that this PR extends with machine-secret-backed v2 envelopes.
  • vybestack/llxprt-code#2156: Related to the Agent API test changes in capabilityGaps.integration.spec.ts and policyControl.behavior.test.ts.

Poem

I whiskered through the fallback fog,
with secrets tucked in a tiny log.
v1 and v2 now hop in line,
and machine-secret paths align.
Thump-thump! 🐇

🚥 Pre-merge checks | ✅ 3 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The PR includes unrelated edits to two agents test files that were only for lint compliance, which is outside the secure-store hardening scope. Move those test-only lint fixes into a separate PR or revert them if they are not required for #1986.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main secure-store hardening change.
Description check ✅ Passed The PR description follows the template with TLDR, Dive Deeper, Reviewer Test Plan, Testing Matrix, and Linked issues sections filled in.
Linked Issues check ✅ Passed The changes add a machine-secret root of trust, v2 envelopes, and downgrade protection, matching #1986's hardening goal.

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

📋 Issue Planner

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

View plan used: #1986

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

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

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

github-actions Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

LLxprt PR Review – PR #2178

Issue Alignment

Issue #1986 is fully addressed. The PR replaces the non-secret KDF input (serviceName + sha256(hostname + username)) with a machine-secret root of trust for the SecureStore file fallback.

  • machine-secret.ts (+400 lines): Resolves a 32-byte crypto.randomBytes(32) secret via in-memory cache → OS keyring → file fallback → generate+persist. Atomic writes, 0700 parent dirs, 0600 file permissions, permission repair on existing files, source-scoped cache isolation, and concurrent first-call deduplication via shared in-flight promise.
  • envelope.ts (+132 lines): Centralizes envelope versioning. v:1 = serviceName-machineId (backward compatible). v:2 = machineSecretHex|serviceName|machineId (machine secret is dominant entropy). Validates scrypt params on read.
  • secure-store.ts (+104/-78): Uses v:2 when machine secret is available; falls back to v:1 otherwise. Refuses to silently overwrite an existing v:2 file with v:1 — this is the key hardening behavior described in the PR.
  • storage.ts (+4): Adds Storage.getMachineSecretPath()~/.llxprt/machine_secret.

The v:2 KDF input (machineSecretHex|serviceName|machineId) makes confidentiality depend on the high-entropy secret rather than solely on filesystem permissions, directly satisfying issue #1986.

Side Effects

  • New file on disk: ~/.llxprt/machine_secret (0600 permissions, created atomically with temp-file rename)
  • New OS keyring entry: service=llxprt-code-machine-secret, account=default (32-byte base64 secret)
  • Existing v:1 fallback files remain readable (backward compatible)
  • A v:2-capable store falling back to v:1 (secret unavailable) will throw rather than silently downgrade an existing v:2 file

Code Quality

Strengths:

  • Atomic file writes with renameWithRetry (handles Windows EPERM races)
  • Permission repair (ensureSecurePermissions, ensureSecureDirectory) before accepting pre-existing files — rejects insecure files rather than silently using them
  • Cache keyed by durable source identity (file path + keyring loader identity) — two SecureStore instances with different paths never share cache entries
  • Concurrent first-call deduplication: all concurrent callers for the same source share a single in-flight generation promise and converge on the durably persisted winner
  • readExistingEnvelopeVersion is a clean, focused helper for the downgrade check
  • v:1/v:2 ciphertext structure is byte-identical (same saltLen=16, iv=12, authTag=16 layout), so the decryption path handles both transparently

Minor observations (not blocking):

  • isValidEnvelope now validates scrypt N/r/p params for v:1 too (previously it only checked v === 1, alg, kdf, data). This is a stricter check — correct, but a behavioral change for tampered v:1 envelopes.
  • secure-store.fallback2.test.ts injects machineSecretLoader: async () => null to opt into v:1 behavior; the real default (tested in secure-store-integration.test.ts) resolves v:2.

Tests and Coverage

Coverage impact: Increase

  • machine-secret.test.ts (558 lines): Tests generation, keyring preference, file fallback, cache hit (no re-read), cache scoping by path/loader identity, permission repair (0o644→0o600, 0o777→0o700), invalid file degradation (null, not rotation), graceful null on persistence failure, concurrent deduplication (16 parallel calls, all return same secret), resetMachineSecretCache forces re-read.
  • envelope.test.ts (187 lines): Tests isValidEnvelope acceptance/rejection for v:1, v:2, unknown versions, bad cipher/KDF/params/saltLen/data type.
  • secure-store.fallback-v2.test.ts (482 lines): Tests v:2 round-trip, cross-instance read with shared secret, CORRUPT on secret mismatch, CORRUPT on unavailable secret during read, v:1 write when secret unavailable, v:2→v:1 downgrade prevention (throws, file unchanged, original value still recoverable), v:2 overwrite with unreadable existing file (re-throws, no overwrite), new file v:1 when secret unavailable, existing v:1 overwrite allowed, legacy v:1 readable by v:2-capable store, unknown version throws CORRUPT, cross-service key isolation.
  • secure-store-integration.test.ts (+46 lines): Tests the real default getMachineSecret path end-to-end — verifies v:2 envelope is written and round-trips without injected loader.
  • storage.test.ts (+5 lines): Tests getMachineSecretPath() value.

Tests are behavioral, not mock theater. Keyring/filesystem are injected; the actual provider logic is exercised. No tests flagged as inadequate.

Verdict

Ready. The PR fully addresses issue #1986 with high-quality, well-tested implementation. The machine secret is a proper root of trust, v:2/v:1 envelope versioning is correct, backward compatibility with v:1 is preserved, and the downgrade prevention is implemented correctly with appropriate test coverage. No blockers identified.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 5

Caution

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

⚠️ Outside diff range comments (2)
packages/storage/src/secure-store/secure-store.ts (2)

768-821: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

The v:2 downgrade guard is still bypassable under concurrent writers.

The version probe happens before the temp file is renamed into place. Another process can create or upgrade finalPath to v:2 in that window, and this v:1 write will still replace it on fs.rename(). That breaks the “never silently downgrade an existing v:2 file” guarantee for concurrent set() calls. You need a per-key lock or another atomic replace strategy that revalidates at commit time.

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

In `@packages/storage/src/secure-store/secure-store.ts` around lines 768 - 821,
The v:2 downgrade check in secure-store.ts is still racy because
readExistingEnvelopeVersion() runs before the final rename, so a concurrent
set() can create or upgrade the target to v:2 and still get overwritten by a v:1
write. Fix this in set() by adding a per-key lock or another atomic commit flow
around getFallbackFilePath(), readExistingEnvelopeVersion(), and
renameWithRetry() so the version is revalidated immediately before replace. Keep
the existing SecureStoreError guard, but move it into the commit path so v:1
never overwrites a v:2 envelope under concurrent writers.

903-923: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Guard non-object JSON before reading v.

JSON.parse('null') succeeds, and env.v then throws a raw TypeError here instead of the expected SecureStoreError. Malformed fallback files should stay on the controlled corruption path.

Suggested fix
     try {
       envelope = JSON.parse(content);
     } catch {
       throw new SecureStoreError(
         'Fallback file is corrupt or uses an unrecognized format',
         'CORRUPT',
         'Re-save the key or re-authenticate',
       );
     }

+    if (typeof envelope !== 'object' || envelope === null) {
+      throw new SecureStoreError(
+        'Fallback file envelope is malformed',
+        'CORRUPT',
+        'Re-save the key or re-authenticate',
+      );
+    }
+
     const env = envelope as Record<string, unknown>;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/storage/src/secure-store/secure-store.ts` around lines 903 - 923,
Guard the parsed fallback content in secure-store.ts before accessing env.v in
the envelope validation block. In the JSON.parse/content handling inside the
try/catch near the envelope and env checks, verify the parsed value is a
non-null object (not null/array/primitive) and throw the existing
SecureStoreError corruption path if it is not. This keeps malformed fallback
files from causing a raw TypeError and ensures the SecureStoreError flow remains
controlled.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/storage/src/secure-store/machine-secret.test.ts`:
- Around line 245-261: The failure-path test for getMachineSecret is flaky
because it relies on chmod-based directory permissions, which behave
inconsistently across platforms and privileged CI environments. Update the test
to use the same blocker-file approach as the existing blocker-based case in
machine-secret.test.ts, so the write/persistence path fails due to a filesystem
conflict rather than permission semantics. Keep the test focused on the
getMachineSecret flow and keyringLoader throw path, but make the setup
deterministic by reusing the blocker pattern instead of chmod(tempDir, 0o500).

In `@packages/storage/src/secure-store/machine-secret.ts`:
- Around line 257-267: The secure secret handling only fixes the file mode in
ensureSecurePermissions, but the containing directory can still be writable or
overly permissive. Update the machine-secret flow to also verify and repair the
parent directory of the secret before reading or accepting it, by checking its
permissions and hardening it to a private mode if needed. Use the existing
ensureSecurePermissions helper and the directory setup path around the
machine_secret creation/read logic to ensure both the file and its parent
directory are protected.
- Around line 146-160: The machine secret flow in machine-secret.ts is treating
invalid or unreadable durable data as if it were missing, which causes an
unnecessary secret rotation. Update the read path around loadKeyring,
readFromKeyring, and readFromFile so callers can distinguish “not found” from
“present but unusable” instead of collapsing both to null. Then only call
generatePersistAndReread when both durable sources are truly absent, and
propagate invalid/permission-repair failures instead of generating a new secret.
- Around line 93-103: The cache key in sourceKeyOf() is too coarse because it
only distinguishes injected versus default loaders, so different injected
keyring backends can collide and reuse the same secret. Update sourceKeyOf() to
include a stable identifier for the injected durable source in addition to
filePath, and make the key unique per injected backend while preserving
DEFAULT_SOURCE_KEY for the default machine-secret path. Ensure the change is
localized around sourceKeyOf() and any caller-provided keyringLoader metadata
used to distinguish sources.

In `@packages/storage/src/secure-store/secure-store.ts`:
- Around line 841-845: The secure store read path in readEnvelopeContent() is
treating every fs.readFile failure as “no existing envelope”; update the catch
around fs.readFile(filePath, 'utf8') to return null only for ENOENT and rethrow
or propagate all other errors so writeFallbackFile() does not overwrite an
existing v:2 file on EACCES, EPERM, or transient I/O failures.

---

Outside diff comments:
In `@packages/storage/src/secure-store/secure-store.ts`:
- Around line 768-821: The v:2 downgrade check in secure-store.ts is still racy
because readExistingEnvelopeVersion() runs before the final rename, so a
concurrent set() can create or upgrade the target to v:2 and still get
overwritten by a v:1 write. Fix this in set() by adding a per-key lock or
another atomic commit flow around getFallbackFilePath(),
readExistingEnvelopeVersion(), and renameWithRetry() so the version is
revalidated immediately before replace. Keep the existing SecureStoreError
guard, but move it into the commit path so v:1 never overwrites a v:2 envelope
under concurrent writers.
- Around line 903-923: Guard the parsed fallback content in secure-store.ts
before accessing env.v in the envelope validation block. In the
JSON.parse/content handling inside the try/catch near the envelope and env
checks, verify the parsed value is a non-null object (not null/array/primitive)
and throw the existing SecureStoreError corruption path if it is not. This keeps
malformed fallback files from causing a raw TypeError and ensures the
SecureStoreError flow remains controlled.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: ef0c0d0b-ef14-438f-8258-0bb25b3adf5f

📥 Commits

Reviewing files that changed from the base of the PR and between a6ec607 and 5e708e4.

📒 Files selected for processing (12)
  • packages/agents/src/api/__tests__/capabilityGaps.integration.spec.ts
  • packages/agents/src/api/__tests__/policyControl.behavior.test.ts
  • packages/storage/src/config/storage.test.ts
  • packages/storage/src/config/storage.ts
  • packages/storage/src/secure-store/envelope.test.ts
  • packages/storage/src/secure-store/envelope.ts
  • packages/storage/src/secure-store/machine-secret.test.ts
  • packages/storage/src/secure-store/machine-secret.ts
  • packages/storage/src/secure-store/secure-store-integration.test.ts
  • packages/storage/src/secure-store/secure-store.fallback-v2.test.ts
  • packages/storage/src/secure-store/secure-store.fallback2.test.ts
  • packages/storage/src/secure-store/secure-store.ts
📜 Review details
⏰ Context from checks skipped due to timeout. (6)
  • GitHub Check: E2E Test (Linux) - sandbox:none
  • GitHub Check: E2E Test (Linux) - sandbox:docker
  • GitHub Check: E2E Test (macOS)
  • GitHub Check: Lint (Javascript)
  • GitHub Check: CodeQL
  • GitHub Check: Run LLxprt review
🧰 Additional context used
🧠 Learnings (8)
📚 Learning: 2026-02-06T15:52:42.315Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1305
File: scripts/generate-keybindings-doc.ts:1-5
Timestamp: 2026-02-06T15:52:42.315Z
Learning: In reviews of vybestack/llxprt-code, do not suggest changing existing copyright headers from 'Google LLC' to 'Vybestack LLC' for files that originated from upstream. Preserve upstream copyrights in files that came from upstream, and only apply 'Vybestack LLC' copyright on newly created, original LLxprt files. If a file is clearly LLxprt-original, it may carry the Vybestack header; if it is upstream-originated, keep the original sponsor header.

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

  • packages/storage/src/secure-store/envelope.test.ts
  • packages/storage/src/secure-store/secure-store.fallback2.test.ts
  • packages/agents/src/api/__tests__/policyControl.behavior.test.ts
  • packages/storage/src/secure-store/machine-secret.test.ts
  • packages/storage/src/secure-store/envelope.ts
  • packages/agents/src/api/__tests__/capabilityGaps.integration.spec.ts
  • packages/storage/src/config/storage.ts
  • packages/storage/src/config/storage.test.ts
  • packages/storage/src/secure-store/secure-store.fallback-v2.test.ts
  • packages/storage/src/secure-store/secure-store-integration.test.ts
  • packages/storage/src/secure-store/machine-secret.ts
  • packages/storage/src/secure-store/secure-store.ts
📚 Learning: 2026-06-19T17:16:56.523Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 2108
File: packages/agents/src/api/agentImpl.ts:1047-1079
Timestamp: 2026-06-19T17:16:56.523Z
Learning: When the fake-provider test seam is active in vybestack/llxprt-code, `process.env.LLXPRT_FAKE_RESPONSES` is set to a fixture file path ending in a `.jsonl` (not to the string `'1'` or any other boolean-like value). In code, detect the seam by checking `process.env.LLXPRT_FAKE_RESPONSES !== undefined` (and/or that it is a non-empty string), rather than using `process.env.LLXPRT_FAKE_RESPONSES === '1'`. Update any callers of the env var accordingly (see `packages/providers/src/composition/providerManagerInstance.ts` and harness usages).

Applied to files:

  • packages/storage/src/secure-store/envelope.test.ts
  • packages/storage/src/secure-store/secure-store.fallback2.test.ts
  • packages/agents/src/api/__tests__/policyControl.behavior.test.ts
  • packages/storage/src/secure-store/machine-secret.test.ts
  • packages/storage/src/secure-store/envelope.ts
  • packages/agents/src/api/__tests__/capabilityGaps.integration.spec.ts
  • packages/storage/src/config/storage.ts
  • packages/storage/src/config/storage.test.ts
  • packages/storage/src/secure-store/secure-store.fallback-v2.test.ts
  • packages/storage/src/secure-store/secure-store-integration.test.ts
  • packages/storage/src/secure-store/machine-secret.ts
  • packages/storage/src/secure-store/secure-store.ts
📚 Learning: 2026-03-26T00:49:43.150Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1778
File: packages/cli/src/auth/__tests__/auth-flow-orchestrator.spec.ts:309-324
Timestamp: 2026-03-26T00:49:43.150Z
Learning: In this repository’s Jest (or Jest-like) test files, it is acceptable to use `expect(promiseReturningFunction).resolves.not.toThrow()` when the function returns `Promise<void>`. Do not flag this as an incorrect or suboptimal matcher; for `Promise<void>` it is functionally equivalent to using `resolves.toBeUndefined()` to assert successful resolution.

Applied to files:

  • packages/agents/src/api/__tests__/policyControl.behavior.test.ts
  • packages/agents/src/api/__tests__/capabilityGaps.integration.spec.ts
📚 Learning: 2026-06-19T17:16:55.805Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 2108
File: packages/agents/src/api/__tests__/hooks.spec.ts:86-119
Timestamp: 2026-06-19T17:16:55.805Z
Learning: In `vybestack/llxprt-code`’s agents package under `packages/agents/src/api/`, the chat-turn flow triggers hooks by directly calling `hookSystem.fireBeforeModelEvent` / `hookSystem.fireAfterModelEvent`. It does not emit bus-mediated `HOOK_EXECUTION_REQUEST` / `HOOK_EXECUTION_RESPONSE` messages. Therefore, `agent.hooks.onHookExecution` (which only observes bus-mediated hook messages) will not surface chat-turn hook executions. During code review, don’t expect chat-turn hooks to appear via `onHookExecution`; if you need them observable, that requires a separate production change to add bus publishing for chat-turn hook executions.

Applied to files:

  • packages/agents/src/api/__tests__/policyControl.behavior.test.ts
  • packages/agents/src/api/__tests__/capabilityGaps.integration.spec.ts
📚 Learning: 2026-06-23T21:59:35.738Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 2108
File: packages/agents/src/api/__tests__/cli-turn-parity.spec.ts:132-146
Timestamp: 2026-06-23T21:59:35.738Z
Learning: In `packages/agents/src/api/__tests__/`, some plan-phase snapshot spec files may be intentionally hash-frozen (their sha256 hashes are recorded in `project-plans/issue1594remediate/.completed/<phase>-frozen-hashes.txt` and enforced by a guard test). During code review, do not recommend edits to these frozen snapshot files; if you see boundary/correctness concerns, route the issue to the authoritative enforcement test `boundary.adequacy.test.ts` instead.

Applied to files:

  • packages/agents/src/api/__tests__/policyControl.behavior.test.ts
  • packages/agents/src/api/__tests__/capabilityGaps.integration.spec.ts
🪛 ast-grep (0.44.0)
packages/storage/src/secure-store/machine-secret.test.ts

[warning] 103-103: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.readFile(tempFilePath, 'utf8')
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

(detect-non-literal-fs-filename-typescript)


[warning] 147-147: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.writeFile(tempFilePath, fileSecret.toString('base64'))
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

(detect-non-literal-fs-filename-typescript)


[warning] 165-165: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.writeFile(tempFilePath, fileSecret.toString('base64'))
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

(detect-non-literal-fs-filename-typescript)


[warning] 232-232: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.writeFile(blockerFile, 'x')
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

(detect-non-literal-fs-filename-typescript)


[warning] 273-273: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.readFile(tempFilePath, 'utf8')
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

(detect-non-literal-fs-filename-typescript)


[warning] 366-366: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.readFile(tempFilePath, 'utf8')
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

(detect-non-literal-fs-filename-typescript)


[warning] 408-408: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.readFile(pathA, 'utf8')
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

(detect-non-literal-fs-filename-typescript)


[warning] 409-409: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.readFile(pathB, 'utf8')
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

(detect-non-literal-fs-filename-typescript)


[warning] 465-467: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.writeFile(tempFilePath, preExisting.toString('base64'), {
mode: 0o644,
})
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

(detect-non-literal-fs-filename-typescript)

packages/storage/src/secure-store/secure-store.fallback-v2.test.ts

[warning] 78-78: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.readFile(file, 'utf8')
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

(detect-non-literal-fs-filename-typescript)


[warning] 197-197: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.readFile(file, 'utf8')
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

(detect-non-literal-fs-filename-typescript)


[warning] 234-234: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.readFile(filePath, 'utf8')
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

(detect-non-literal-fs-filename-typescript)


[warning] 262-262: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.readFile(filePath, 'utf8')
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

(detect-non-literal-fs-filename-typescript)


[warning] 289-289: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.readFile(filePath, 'utf8')
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

(detect-non-literal-fs-filename-typescript)


[warning] 306-306: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.readFile(filePath, 'utf8')
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

(detect-non-literal-fs-filename-typescript)


[warning] 312-312: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.readFile(filePath, 'utf8')
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

(detect-non-literal-fs-filename-typescript)


[warning] 347-347: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.readFile(file, 'utf8')
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

(detect-non-literal-fs-filename-typescript)


[warning] 375-375: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.writeFile(path.join(tempDir, 'bad-version.enc'), badEnvelope)
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

(detect-non-literal-fs-filename-typescript)

packages/storage/src/secure-store/secure-store-integration.test.ts

[warning] 644-644: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.readFile(filePath, 'utf8')
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

(detect-non-literal-fs-filename-typescript)

packages/storage/src/secure-store/machine-secret.ts

[warning] 227-227: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.readFile(filePath, 'utf8')
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

(detect-non-literal-fs-filename-typescript)

packages/storage/src/secure-store/secure-store.ts

[warning] 842-842: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.readFile(filePath, 'utf8')
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

(detect-non-literal-fs-filename-typescript)

🔇 Additional comments (5)
packages/agents/src/api/__tests__/capabilityGaps.integration.spec.ts (1)

37-43: LGTM!

Also applies to: 178-178

packages/agents/src/api/__tests__/policyControl.behavior.test.ts (1)

155-166: LGTM!

packages/storage/src/secure-store/secure-store-integration.test.ts (1)

30-30: LGTM!

Also applies to: 612-653

packages/storage/src/secure-store/secure-store.fallback-v2.test.ts (1)

1-437: LGTM!

packages/storage/src/secure-store/secure-store.fallback2.test.ts (1)

110-110: LGTM!

Also applies to: 437-437

Comment thread packages/storage/src/secure-store/machine-secret.test.ts Outdated
Comment thread packages/storage/src/secure-store/machine-secret.ts Outdated
Comment thread packages/storage/src/secure-store/machine-secret.ts Outdated
Comment thread packages/storage/src/secure-store/machine-secret.ts
Comment thread packages/storage/src/secure-store/secure-store.ts Outdated
@github-actions

github-actions Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Summary

Package Lines Statements Functions Branches
CLI 55.99% 55.99% 57.93% 81.92%
Core 76.92% 76.92% 74.27% 83.5%
CLI Package - Full Text Report
-------------------|---------|----------|---------|---------|-------------------
File               | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-------------------|---------|----------|---------|---------|-------------------
All files          |   55.99 |    81.92 |   57.93 |   55.99 |                   
 src               |   70.04 |    65.71 |   89.09 |   70.04 |                   
  cli.tsx          |   56.97 |    59.74 |   78.57 |   56.97 | ...1286,1294-1313 
  ...st-helpers.ts |     100 |       60 |     100 |     100 | 23-34             
  ...ractiveCli.ts |   90.37 |     84.9 |   86.66 |   90.37 | ...04-209,282-284 
  ...liCommands.ts |   97.18 |    63.63 |     100 |   97.18 | 39-40             
  ...CliSupport.ts |   80.04 |    65.04 |      95 |   80.04 | ...76-478,500-501 
  ...ActiveAuth.ts |      60 |    68.42 |     100 |      60 | ...91-106,110-119 
 src/auth          |   98.07 |    81.25 |     100 |   98.07 |                   
  ...gs-adapter.ts |   98.07 |    81.25 |     100 |   98.07 | 76                
 src/commands      |   78.35 |      100 |   44.44 |   78.35 |                   
  extensions.tsx   |   55.88 |      100 |       0 |   55.88 | 25-38,42          
  hooks.ts         |   61.53 |      100 |       0 |   61.53 | 14-17,20          
  mcp.ts           |   94.11 |      100 |      50 |   94.11 | 26                
  skills.tsx       |     100 |      100 |     100 |     100 |                   
  utils.ts         |     100 |      100 |     100 |     100 |                   
 ...nds/extensions |    74.1 |    92.93 |   67.18 |    74.1 |                   
  config.ts        |   94.61 |    91.83 |     100 |   94.61 | ...66-167,196-201 
  disable.ts       |     100 |      100 |     100 |     100 |                   
  enable.ts        |     100 |      100 |     100 |     100 |                   
  install.ts       |   80.48 |    76.92 |    87.5 |   80.48 | ...63,199,202-209 
  link.ts          |   64.81 |    83.33 |      25 |   64.81 | 31,54-65,67-72    
  list.ts          |      90 |      100 |   33.33 |      90 | 35-37             
  new.ts           |     100 |      100 |     100 |     100 |                   
  settings.ts      |   72.13 |      100 |      70 |   72.13 | 32-80,218-222,225 
  uninstall.ts     |   78.43 |      100 |   66.66 |   78.43 | 54-59,62-66       
  update.ts        |   10.19 |      100 |       0 |   10.19 | ...71-190,192-197 
  utils.ts         |   13.33 |      100 |       0 |   13.33 | 29-60             
  validate.ts      |   89.36 |     87.5 |      75 |   89.36 | 50-53,60,112-116  
 .../hooks/scripts |       0 |        0 |       0 |       0 |                   
  on-start.js      |       0 |        0 |       0 |       0 | 1-8               
 ...les/mcp-server |       0 |        0 |       0 |       0 |                   
  example.js       |       0 |        0 |       0 |       0 | 1-60              
 ...commands/hooks |    7.59 |      100 |       0 |    7.59 |                   
  migrate.ts       |    7.59 |      100 |       0 |    7.59 | ...90-200,202-204 
 src/commands/mcp  |   96.95 |    86.15 |   94.44 |   96.95 |                   
  add.ts           |   99.56 |    93.33 |     100 |   99.56 | 142               
  list.ts          |   90.51 |    82.14 |      80 |   90.51 | ...13-115,148-150 
  remove.ts        |     100 |    71.42 |     100 |     100 | 21-25             
 ...ommands/skills |   60.98 |     92.3 |   31.25 |   60.98 |                   
  disable.ts       |      54 |      100 |   33.33 |      54 | 40-52,54-63       
  enable.ts        |   72.22 |      100 |   33.33 |   72.22 | 33-37,39-43       
  install.ts       |   42.69 |      100 |      25 |   42.69 | ...71-100,102-109 
  list.ts          |   84.93 |       80 |   33.33 |   84.93 | ...9,92-96,98-100 
  uninstall.ts     |   57.89 |      100 |   33.33 |   57.89 | 47-64,66-71       
 src/config        |   86.45 |    84.98 |   86.94 |   86.45 |                   
  ...deResolver.ts |   94.54 |    95.45 |     100 |   94.54 | 50-52             
  auth.ts          |   84.61 |    82.35 |     100 |   84.61 | 18-19,22-23,53-54 
  cliArgParser.ts  |   92.85 |    89.36 |     100 |   92.85 | ...24,285,287-290 
  config.ts        |     100 |      100 |     100 |     100 |                   
  configBuilder.ts |   95.41 |    95.52 |   66.66 |   95.41 | ...18-219,260-261 
  ...mentLoader.ts |    82.9 |    53.84 |     100 |    82.9 | ...29-131,139-142 
  extension.ts     |   75.07 |    88.23 |   78.04 |   75.07 | ...12-913,916-917 
  ...iveContext.ts |   93.75 |    91.66 |     100 |   93.75 | 79,81,87-92,232   
  ...iateConfig.ts |   96.39 |    97.05 |     100 |   96.39 | 53,150-152        
  keyBindings.ts   |     100 |      100 |     100 |     100 |                   
  ...rverConfig.ts |   83.33 |    94.44 |     100 |   83.33 | 23-39             
  paths.ts         |     100 |      100 |     100 |     100 |                   
  policy.ts        |   80.76 |      100 |      50 |   80.76 | 47-51             
  ...figRuntime.ts |   88.65 |    84.21 |     100 |   88.65 | ...22-429,440-443 
  ...eBootstrap.ts |   91.35 |     87.2 |   97.22 |   91.35 | ...07-809,818-819 
  ...Resolution.ts |   43.51 |    72.41 |    62.5 |   43.51 | ...72-291,303-311 
  ...pplication.ts |   85.03 |       65 |     100 |   85.03 | ...44,146-152,176 
  ...elResolver.ts |   90.38 |    73.68 |     100 |   90.38 | 40,42-43,70,79    
  sandboxConfig.ts |   69.81 |    51.48 |   88.46 |   69.81 | ...80-581,593-594 
  ...oxProfiles.ts |    8.53 |      100 |       0 |    8.53 | 47-48,51-129      
  settingPaths.ts  |     100 |      100 |     100 |     100 |                   
  ...validation.ts |   86.95 |    80.62 |     100 |   86.95 | ...02,404,406,408 
  settings.ts      |   82.92 |    86.27 |   65.21 |   82.92 | ...40-441,496-497 
  ...ingsLegacy.ts |    70.9 |    81.81 |     100 |    70.9 | 48-52,56-67       
  ...ingsLoader.ts |   94.11 |    81.39 |     100 |   94.11 | ...78,108-109,137 
  settingsMerge.ts |   99.51 |    95.65 |     100 |   99.51 | 128-129           
  ...Migrations.ts |   95.67 |    91.66 |     100 |   95.67 | 22-24,48-49,55-56 
  ...ingsSchema.ts |     100 |      100 |     100 |     100 |                   
  ...Governance.ts |   95.83 |    90.62 |     100 |   95.83 | 54,126-129        
  ...tedFolders.ts |   95.58 |       96 |     100 |   95.58 | 93,120-126        
  welcomeConfig.ts |   22.41 |      100 |       0 |   22.41 | ...71,74-79,82-83 
  yargsOptions.ts  |   98.73 |    96.77 |    87.5 |   98.73 | 144,153-156       
 ...fig/extensions |   76.18 |    84.44 |   87.61 |   76.18 |                   
  consent.ts       |   88.03 |    85.71 |     100 |   88.03 | ...77-378,381-382 
  ...ionConsent.ts |   87.38 |    76.66 |     100 |   87.38 | ...,64-67,113-116 
  ...Enablement.ts |    93.9 |       96 |     100 |    93.9 | ...06-212,275-277 
  ...sionLoader.ts |   93.33 |    89.36 |     100 |   93.33 | ...86-187,195-199 
  ...onSettings.ts |     100 |      100 |     100 |     100 |                   
  github.ts        |   62.19 |    81.73 |   70.83 |   62.19 | ...41-642,652-655 
  hookSchema.ts    |     100 |      100 |     100 |     100 |                   
  ...ntegration.ts |   55.31 |    84.78 |      50 |   55.31 | ...61,402,426-427 
  ...ingsPrompt.ts |      73 |    94.73 |      80 |      73 | 92-121            
  ...ngsStorage.ts |   84.77 |    75.92 |     100 |   84.77 | ...90-291,309-312 
  update.ts        |   69.52 |    52.94 |   85.71 |   69.52 | ...73-201,218-226 
  ...ableSchema.ts |     100 |      100 |     100 |     100 |                   
  variables.ts     |   95.55 |       90 |     100 |   95.55 | 33-34             
 ...ettings-schema |   99.78 |       60 |     100 |   99.78 |                   
  schema-core.ts   |     100 |      100 |     100 |     100 |                   
  ...extensions.ts |     100 |      100 |     100 |     100 |                   
  ...a-security.ts |   99.44 |       50 |     100 |   99.44 | 16-17             
  schema-tail.ts   |   99.52 |       50 |     100 |   99.52 | 13-14             
  schema-ui.ts     |     100 |      100 |     100 |     100 |                   
  schema.ts        |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/constants     |     100 |      100 |     100 |     100 |                   
  historyLimits.ts |     100 |      100 |     100 |     100 |                   
 src/extensions    |   66.86 |    61.81 |      75 |   66.86 |                   
  ...utoUpdater.ts |   66.86 |    61.81 |      75 |   66.86 | ...56-457,466,468 
 src/generated     |     100 |      100 |     100 |     100 |                   
  git-commit.ts    |     100 |      100 |     100 |     100 |                   
 ...egration-tests |   71.54 |    83.33 |   85.71 |   71.54 |                   
  ...st-helpers.ts |       0 |        0 |       0 |       0 | 1-79              
  test-utils.ts    |   91.93 |     86.2 |    92.3 |   91.93 | ...45,263-264,274 
 src/patches       |       0 |        0 |       0 |       0 |                   
  is-in-ci.ts      |       0 |        0 |       0 |       0 | 1-17              
 ...viders/logging |   89.31 |    90.24 |   69.23 |   89.31 |                   
  ...rvice-impl.ts |   44.44 |        0 |       0 |   44.44 | 21-22,25-30,36-37 
  git-stats.ts     |   96.46 |     92.5 |     100 |   96.46 | 154-155,195-196   
 src/runtime       |   97.65 |       92 |     100 |   97.65 |                   
  ...imeAdapter.ts |   97.65 |       92 |     100 |   97.65 | ...18-219,308-309 
 src/services      |   86.13 |    86.34 |   95.45 |   86.13 |                   
  ...mandLoader.ts |   79.75 |    73.33 |      80 |   79.75 | ...10-124,168-186 
  ...andService.ts |     100 |      100 |     100 |     100 |                   
  ...mandLoader.ts |   91.77 |    86.53 |     100 |   91.77 | ...10-215,300-307 
  ...omptLoader.ts |    67.5 |    68.96 |     100 |    67.5 | ...75,181-187,202 
  ...tArgParser.ts |   96.49 |    94.91 |     100 |   96.49 | ...,89-90,140-141 
  performResume.ts |   89.11 |    89.18 |     100 |   89.11 | ...61-264,270-271 
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 ...mpt-processors |      98 |     93.1 |     100 |      98 |                   
  ...tProcessor.ts |     100 |      100 |     100 |     100 |                   
  ...lProcessor.ts |   97.88 |    92.72 |     100 |   97.88 | 80-81,265-266     
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...o-continuation |   86.56 |    84.09 |   94.73 |   86.56 |                   
  ...ionService.ts |   86.56 |    84.09 |   94.73 |   86.56 | ...07,574,600-601 
 src/test-utils    |   76.07 |     90.9 |   26.78 |   76.07 |                   
  async.ts         |       0 |        0 |       0 |       0 | 1-34              
  ...eExtension.ts |     100 |      100 |     100 |     100 |                   
  ...omMatchers.ts |    14.7 |      100 |       0 |    14.7 | 13-45             
  ...andContext.ts |     100 |      100 |     100 |     100 |                   
  render.tsx       |   94.84 |    96.66 |      25 |   94.84 | ...51-156,259-260 
  ...e-testing.tsx |       0 |        0 |       0 |       0 | 1-56              
  ...iderConfig.ts |       0 |        0 |       0 |       0 | 1-19              
 src/ui            |   37.77 |    93.44 |   30.48 |   37.77 |                   
  App.tsx          |   37.25 |      100 |       0 |   37.25 | 64-91,97-104      
  AppContainer.tsx |     100 |      100 |     100 |     100 |                   
  ...erRuntime.tsx |   14.28 |      100 |   16.66 |   14.28 | 66-399            
  ...tionNudge.tsx |       8 |      100 |       0 |       8 | 29-104            
  colors.ts        |   37.14 |      100 |   20.33 |   37.14 | ...03-304,306-307 
  constants.ts     |     100 |      100 |     100 |     100 |                   
  debug.ts         |     100 |      100 |     100 |     100 |                   
  ...derOptions.ts |     100 |      100 |     100 |     100 |                   
  keyMatchers.ts   |   88.63 |       84 |     100 |   88.63 | 18,20-21,28-29    
  ...ntsEnabled.ts |     100 |      100 |     100 |     100 |                   
  ...submission.ts |     100 |      100 |     100 |     100 |                   
  ...tic-colors.ts |   78.94 |      100 |      60 |   78.94 | 15-16,24-25       
  textConstants.ts |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/ui/commands   |   71.08 |    76.72 |   76.95 |   71.08 |                   
  aboutCommand.ts  |   82.84 |    51.51 |   91.66 |   82.84 | ...92-193,195-196 
  authCommand.ts   |   49.52 |    77.63 |   61.53 |   49.52 | ...51-654,665-707 
  ...urlCommand.ts |      30 |      100 |       0 |      30 | 20-40             
  bugCommand.ts    |   71.23 |    30.76 |     100 |   71.23 | ...99-110,145-153 
  chatCommand.ts   |   69.72 |    74.62 |   66.66 |   69.72 | ...50-551,599-610 
  clearCommand.ts  |   88.88 |    88.88 |     100 |   88.88 | 96-103            
  ...essCommand.ts |    97.7 |    89.28 |     100 |    97.7 | 41,63-64          
  ...nueCommand.ts |     100 |      100 |     100 |     100 |                   
  copyCommand.ts   |     100 |      100 |     100 |     100 |                   
  debugCommands.ts |   13.29 |      100 |       0 |   13.29 | ...49,456,463,470 
  ...st-helpers.ts |   89.62 |     91.3 |      50 |   89.62 | ...93,95-96,98-99 
  ...icsCommand.ts |   66.28 |    32.83 |   84.61 |   66.28 | ...99-402,417-422 
  ...ticsTokens.ts |   90.96 |    87.17 |     100 |   90.96 | ...,67-72,107-108 
  ...ryCommand.tsx |    89.5 |    84.84 |     100 |    89.5 | ...29-137,204-212 
  docsCommand.ts   |     100 |      100 |     100 |     100 |                   
  ...extCommand.ts |   96.22 |    89.65 |     100 |   96.22 | 216-221           
  editorCommand.ts |     100 |      100 |     100 |     100 |                   
  ...onsCommand.ts |   41.27 |    88.09 |    62.5 |   41.27 | ...24-381,391-539 
  ...ionSection.ts |   83.33 |    93.33 |     100 |   83.33 | 28-34             
  helpCommand.ts   |     100 |      100 |     100 |     100 |                   
  hooksCommand.ts  |   89.62 |    87.27 |     100 |   89.62 | ...54,344-345,459 
  ideCommand.ts    |   69.87 |    73.52 |   69.23 |   69.87 | ...36-237,240-255 
  initCommand.ts   |   80.26 |    71.42 |   66.66 |   80.26 | 36-40,42-89       
  keyCommand.ts    |   89.87 |    80.76 |     100 |   89.87 | ...92,415-416,515 
  ...ileCommand.ts |    10.9 |      100 |       0 |    10.9 | 22-46,53-141      
  ...ingCommand.ts |   10.27 |      100 |       0 |   10.27 | ...19-572,589-601 
  logoutCommand.ts |   15.87 |      100 |       0 |   15.87 | 21-84             
  lspCommand.ts    |    90.9 |    87.17 |     100 |    90.9 | ...18-123,147-149 
  mcpAuth.ts       |   90.59 |    83.33 |   66.66 |   90.59 | 35-44,89-90       
  mcpCommand.ts    |   96.22 |    85.71 |     100 |   96.22 | 93-98             
  mcpDisplay.ts    |   83.25 |     80.8 |   94.11 |   83.25 | ...89-490,517-518 
  memoryCommand.ts |   87.45 |    75.47 |     100 |   87.45 | ...46,234-248,297 
  modelCommand.ts  |   98.92 |    93.02 |     100 |   98.92 | 120               
  mouseCommand.ts  |     100 |      100 |     100 |     100 |                   
  ...onsCommand.ts |    93.9 |    88.88 |     100 |    93.9 | 58-62             
  ...iesCommand.ts |   97.05 |    80.55 |     100 |   97.05 | 27,40-41          
  ...acyCommand.ts |   61.53 |      100 |       0 |   61.53 | 22-26             
  ...ileCommand.ts |   56.52 |    46.42 |   55.55 |   56.52 | ...35-476,497-513 
  profileLoad.ts   |   51.74 |       60 |    87.5 |   51.74 | ...47,174,185-189 
  ...adBalancer.ts |   81.36 |    84.61 |     100 |   81.36 | ...20-321,347-352 
  ...ileSchemas.ts |   67.11 |    81.81 |     100 |   67.11 | ...18-230,262-267 
  ...derCommand.ts |   56.96 |    31.57 |   88.88 |   56.96 | ...89-290,299-304 
  quitCommand.ts   |   36.66 |      100 |       0 |   36.66 | 17-36             
  ...oreCommand.ts |   90.16 |    82.85 |     100 |   90.16 | ...69-174,207-212 
  setCommand.ts    |   86.32 |    84.28 |     100 |   86.32 | ...91-200,217-222 
  ...mandSchema.ts |   71.57 |    81.81 |   84.61 |   71.57 | ...05,232-240,295 
  ...ngsCommand.ts |     100 |      100 |     100 |     100 |                   
  setupCommand.ts  |     100 |      100 |     100 |     100 |                   
  ...hubCommand.ts |   90.47 |    82.85 |     100 |   90.47 | ...13-216,223-227 
  skillsCommand.ts |   82.78 |       75 |     100 |   82.78 | ...91-292,305-306 
  statsCommand.ts  |   57.25 |    86.66 |   58.33 |   57.25 | ...04-216,234-235 
  statsQuota.ts    |   80.16 |     67.1 |   86.66 |   80.16 | ...05-406,439-443 
  ...entCommand.ts |   76.72 |    69.73 |   81.81 |   76.72 | ...09-615,626-632 
  tasksCommand.ts  |   78.53 |    78.78 |     100 |   78.53 | ...78-186,247-254 
  ...tupCommand.ts |     100 |      100 |     100 |     100 |                   
  themeCommand.ts  |     100 |      100 |     100 |     100 |                   
  todoCommand.ts   |   82.24 |    72.28 |     100 |   82.24 | ...48-460,468-472 
  ...Formatters.ts |   48.93 |    71.42 |   33.33 |   48.93 | ...5,70-86,92-113 
  ...Operations.ts |   85.75 |    77.77 |   95.23 |   85.75 | ...63-364,402-416 
  ...matCommand.ts |   26.66 |      100 |       0 |   26.66 | 33-92             
  ...keyCommand.ts |   98.88 |     92.3 |     100 |   98.88 | 34                
  ...ileCommand.ts |    99.1 |    94.11 |     100 |    99.1 | 36                
  toolsCommand.ts  |   86.56 |    76.47 |     100 |   86.56 | ...59,293,324-325 
  types.ts         |     100 |      100 |     100 |     100 |                   
  ...ileCommand.ts |   27.77 |        0 |       0 |   27.77 | 11-23             
  vimCommand.ts    |   44.44 |      100 |       0 |   44.44 | 15-25             
 ...ommands/schema |   96.06 |    92.54 |   94.11 |   96.06 |                   
  index.ts         |   95.84 |    91.58 |     100 |   95.84 | ...07-211,222-223 
  schemaHelpers.ts |   97.02 |    96.22 |     100 |   97.02 | 67-68,115-117     
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 src/ui/components |   11.62 |    39.04 |     7.5 |   11.62 |                   
  AboutBox.tsx     |   12.19 |      100 |       0 |   12.19 | ...,76-98,102-130 
  AnsiOutput.tsx   |    8.33 |      100 |       0 |    8.33 | 25-90             
  AppHeader.tsx    |   21.87 |      100 |       0 |   21.87 | 26-56             
  AsciiArt.ts      |     100 |      100 |     100 |     100 |                   
  AuthDialog.tsx   |    4.36 |      100 |       0 |    4.36 | ...38-263,266-347 
  ...nProgress.tsx |       0 |        0 |       0 |       0 | 1-63              
  ...Indicator.tsx |   15.15 |      100 |       0 |   15.15 | 17-47             
  ...firmation.tsx |   15.38 |      100 |       0 |   15.38 | 59-134,143-208    
  ...tsDisplay.tsx |   10.37 |      100 |       0 |   10.37 | ...70-110,114-168 
  CliSpinner.tsx   |       0 |        0 |       0 |       0 | 1-22              
  Composer.tsx     |    7.14 |      100 |       0 |    7.14 | 16-29,42-97       
  ...entPrompt.tsx |   18.75 |      100 |       0 |   18.75 | 21-51             
  ...ryDisplay.tsx |   21.05 |      100 |       0 |   21.05 | 17-35             
  ...ryDisplay.tsx |    4.65 |      100 |       0 |    4.65 | 29-107,110-174    
  ...geDisplay.tsx |       0 |        0 |       0 |       0 | 1-37              
  ...gProfiler.tsx |   16.86 |      100 |       0 |   16.86 | ...73-118,122-224 
  ...esDisplay.tsx |   10.52 |      100 |       0 |   10.52 | 24-82             
  ...ogManager.tsx |    5.54 |      100 |       0 |    5.54 | 71-782,786-810    
  ...ngsDialog.tsx |   12.56 |      100 |       0 |   12.56 | ...48-172,176-247 
  ...rBoundary.tsx |   10.16 |        0 |       0 |   10.16 | ...19-164,182-195 
  ...ustDialog.tsx |   16.34 |      100 |       0 |   16.34 | ...2,70-81,84-143 
  Footer.tsx       |   11.06 |        0 |       0 |   11.06 | ...24-693,698-715 
  ...ngSpinner.tsx |    40.9 |      100 |       0 |    40.9 | 31-47             
  Header.tsx       |    17.5 |      100 |       0 |    17.5 | 22-62             
  Help.tsx         |    6.84 |      100 |       0 |    6.84 | ...87-190,194-206 
  ...emDisplay.tsx |   12.01 |      100 |       0 |   12.01 | 55-239,242-280    
  ...usDisplay.tsx |       0 |        0 |       0 |       0 | 1-47              
  InputPrompt.tsx  |   53.38 |     42.1 |   67.34 |   53.38 | ...1639-1644,1662 
  ...tsDisplay.tsx |    4.36 |      100 |       0 |    4.36 | ...32-226,229-292 
  ...utManager.tsx |       0 |        0 |       0 |       0 | 1-99              
  ...ileDialog.tsx |    8.33 |      100 |       0 |    8.33 | ...8,72-81,85-152 
  ...Indicator.tsx |   13.84 |      100 |       0 |   13.84 | 20-24,34-96       
  ...ingDialog.tsx |    4.92 |      100 |       0 |    4.92 | ...65-382,386-435 
  ...geDisplay.tsx |       0 |        0 |       0 |       0 | 1-41              
  ModelDialog.tsx  |     3.6 |      100 |       0 |     3.6 | ...66-739,743-829 
  ...tsDisplay.tsx |    3.82 |      100 |       0 |    3.82 | 32-205,208-259    
  ...fications.tsx |   17.32 |      100 |       0 |   17.32 | ...11-142,145-180 
  ...odeDialog.tsx |     7.4 |      100 |       0 |     7.4 | 32-141            
  ...ustDialog.tsx |    5.53 |      100 |       0 |    5.53 | ...36-273,278-313 
  PrepareLabel.tsx |   13.33 |      100 |       0 |   13.33 | 20-48             
  ...ailDialog.tsx |   11.36 |      100 |       0 |   11.36 | ...93-499,503-576 
  ...ineEditor.tsx |    4.15 |      100 |       0 |    4.15 | ...68-554,557-632 
  ...istDialog.tsx |     4.6 |      100 |       0 |     4.6 | ...88-525,528-614 
  ...derDialog.tsx |    2.63 |      100 |       0 |    2.63 | 60-408,411-426    
  ...Indicator.tsx |       0 |        0 |       0 |       0 | 1-21              
  ...eKeyInput.tsx |       0 |        0 |       0 |       0 | 1-149             
  ...serDialog.tsx |    9.56 |      100 |       0 |    9.56 | ...52-603,611-670 
  ...ryDisplay.tsx |      50 |      100 |       0 |      50 | 15-17             
  ...ngsDialog.tsx |    1.03 |      100 |       0 |    1.03 | ...1738,1743-2800 
  ...putPrompt.tsx |   14.28 |      100 |       0 |   14.28 | 19-58             
  ...Indicator.tsx |   44.44 |      100 |       0 |   44.44 | 12-17             
  ...MoreLines.tsx |   30.43 |      100 |       0 |   30.43 | 18-38             
  StatsDisplay.tsx |    8.98 |      100 |       0 |    8.98 | ...40-445,449-500 
  ...usDisplay.tsx |       0 |        0 |       0 |       0 | 1-59              
  StickyHeader.tsx |    7.14 |      100 |       0 |    7.14 | 20-78             
  ...nsDisplay.tsx |    5.83 |      100 |       0 |    5.83 | 39-91,105-181     
  Table.tsx        |    7.54 |      100 |       0 |    7.54 | 27-89             
  ThemeDialog.tsx  |    3.96 |      100 |       0 |    3.96 | 51-441,444-500    
  ...dGradient.tsx |      25 |      100 |       0 |      25 | 27-46             
  Tips.tsx         |      16 |      100 |       0 |      16 | 17-45             
  TodoPanel.tsx    |     5.9 |      100 |       0 |     5.9 | ...87-244,247-296 
  ...tsDisplay.tsx |   10.05 |      100 |       0 |   10.05 | ...88-227,230-259 
  ToolsDialog.tsx  |   10.63 |      100 |       0 |   10.63 | ...5,41-47,50-123 
  ...ification.tsx |   36.36 |      100 |       0 |   36.36 | 15-22             
  ...ionDialog.tsx |    6.08 |      100 |       0 |    6.08 | 18-104,110-161    
  todo-utils.ts    |       0 |        0 |       0 |       0 | 1-7               
 ...leCreateWizard |   18.43 |       50 |       0 |   18.43 |                   
  ...aramsStep.tsx |   11.34 |      100 |       0 |   11.34 | ...34-247,259-343 
  ...ationStep.tsx |    7.12 |      100 |       0 |    7.12 | ...08-544,556-624 
  ...onfigStep.tsx |   12.35 |      100 |       0 |   12.35 | 19-25,36-117      
  ...electStep.tsx |    9.73 |      100 |       0 |    9.73 | ...13-280,296-341 
  ...ationMenu.tsx |       0 |        0 |       0 |       0 | 1-102             
  ...eSaveStep.tsx |    7.45 |      100 |       0 |    7.45 | ...76-305,317-396 
  ...ssSummary.tsx |   12.12 |      100 |       0 |   12.12 | 23-88             
  ...electStep.tsx |   16.92 |      100 |       0 |   16.92 | 28-97             
  TextInput.tsx    |    6.56 |      100 |       0 |    6.56 | ...01-111,119-202 
  constants.ts     |     100 |      100 |     100 |     100 |                   
  index.tsx        |   14.51 |      100 |       0 |   14.51 | ...94-223,232-316 
  types.ts         |     100 |      100 |     100 |     100 |                   
  utils.ts         |    5.15 |      100 |       0 |    5.15 | ...53-356,361-378 
  validation.ts    |   11.23 |      100 |       0 |   11.23 | ...97-104,107-111 
 ...gentManagement |    4.22 |      100 |       0 |    4.22 |                   
  ...entWizard.tsx |    2.91 |      100 |       0 |    2.91 | 30-232,237-312    
  ...ionWizard.tsx |    1.44 |      100 |       0 |    1.44 | 30-592,595-676    
  ...eteDialog.tsx |    5.88 |      100 |       0 |    5.88 | 14-94,104-147     
  ...tEditForm.tsx |    1.77 |      100 |       0 |    1.77 | 30-619,622-640    
  ...tListMenu.tsx |    2.94 |      100 |       0 |    2.94 | 17-266,269-350    
  ...tMainMenu.tsx |   16.66 |      100 |       0 |   16.66 | 22-62             
  ...gerDialog.tsx |    2.39 |      100 |       0 |    2.39 | 29-601,604-680    
  ...tShowView.tsx |    4.76 |      100 |       0 |    4.76 | 25-183,186-243    
  index.ts         |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...comeOnboarding |   14.36 |        0 |       0 |   14.36 |                   
  ...ethodStep.tsx |   22.47 |      100 |       0 |   22.47 | 44-129            
  ...ationStep.tsx |    7.35 |      100 |       0 |    7.35 | ...1,59-95,98-177 
  ...etionStep.tsx |    9.84 |      100 |       0 |    9.84 | ...,89-99,103-179 
  ...electStep.tsx |   12.12 |      100 |       0 |   12.12 | ...3,67-75,79-143 
  ...electStep.tsx |   34.48 |      100 |       0 |   34.48 | 51-120            
  SkipExitStep.tsx |    12.5 |      100 |       0 |    12.5 | 18-59             
  ...omeDialog.tsx |   11.76 |      100 |       0 |   11.76 | 51-118,121-166    
  WelcomeStep.tsx  |    10.2 |      100 |       0 |    10.2 | 23-74             
  index.ts         |       0 |        0 |       0 |       0 | 1-13              
 ...nents/messages |   18.01 |    88.63 |   12.67 |   18.01 |                   
  ...onMessage.tsx |   12.28 |      100 |       0 |   12.28 | 24-86             
  DiffRenderer.tsx |    3.02 |      100 |       0 |    3.02 | ...10-441,444-462 
  ErrorMessage.tsx |   22.22 |      100 |       0 |   22.22 | 16-31             
  ...niMessage.tsx |   14.51 |      100 |       0 |   14.51 | 28-95             
  ...geContent.tsx |   20.83 |      100 |       0 |   20.83 | 26-46             
  InfoMessage.tsx  |   19.23 |      100 |       0 |   19.23 | 19-41             
  ...rlMessage.tsx |   11.36 |      100 |       0 |   11.36 | 18-65             
  ...geMessage.tsx |     100 |      100 |     100 |     100 |                   
  ...ckDisplay.tsx |      20 |      100 |       0 |      20 | 43-64             
  ...onMessage.tsx |    3.18 |      100 |       0 |    3.18 | 40-524,537-616    
  ...upMessage.tsx |    6.77 |      100 |       0 |    6.77 | ...03-300,304-379 
  ToolMessage.tsx  |    4.33 |      100 |       0 |    4.33 | 40-342,358-428    
  ...ltDisplay.tsx |   91.53 |    85.71 |     100 |   91.53 | 39-53,222-224     
  ToolShared.tsx   |   64.61 |       90 |   33.33 |   64.61 | 78-99,102-105     
  UserMessage.tsx  |     100 |      100 |     100 |     100 |                   
  ...llMessage.tsx |   36.36 |      100 |       0 |   36.36 | 17-25             
  ...ngMessage.tsx |   26.31 |      100 |       0 |   26.31 | 17-32             
 ...ponents/shared |   41.49 |    64.39 |   40.85 |   41.49 |                   
  ...ctionList.tsx |    4.31 |      100 |       0 |    4.31 | 36-123,128-206    
  MaxSizedBox.tsx  |   49.89 |     58.1 |      75 |   49.89 | ...63-666,670-673 
  ...tonSelect.tsx |   12.76 |      100 |       0 |   12.76 | 66-113            
  ...lableList.tsx |    5.15 |      100 |       0 |    5.15 | 40-267            
  ...ist.hooks.tsx |    3.84 |      100 |       0 |    3.84 | ...68-793,796-833 
  ...lizedList.tsx |   11.11 |      100 |       0 |   11.11 | 28-108            
  ...List.types.ts |     100 |      100 |     100 |     100 |                   
  ...operations.ts |   75.54 |    48.14 |     100 |   75.54 | ...32-233,256-265 
  ...er-reducer.ts |   28.25 |    51.11 |   33.33 |   28.25 | ...30,632,644,687 
  buffer-types.ts  |     100 |      100 |     100 |     100 |                   
  text-buffer.ts   |   71.75 |    89.18 |   27.86 |   71.75 | ...33-635,654-660 
  ...formations.ts |   56.04 |     75.6 |    87.5 |   56.04 | ...74-181,205-251 
  ...n-handlers.ts |   33.99 |    61.53 |   23.25 |   33.99 | ...47-755,758-762 
  ...st-helpers.ts |       0 |        0 |       0 |       0 | 1-33              
  ...er-actions.ts |   93.84 |     87.5 |     100 |   93.84 | 91-93,100         
  visual-layout.ts |    90.2 |    71.73 |     100 |    90.2 | ...48-350,372-373 
  ...navigation.ts |   53.01 |    60.93 |   73.68 |   53.01 | ...39-360,383-405 
 ...mponents/views |    8.89 |      100 |       0 |    8.89 |                   
  ChatList.tsx     |    14.7 |      100 |       0 |    14.7 | 18-52             
  ...sionsList.tsx |    7.59 |      100 |       0 |    7.59 | 19-103            
  HooksList.tsx    |    10.1 |      100 |       0 |    10.1 | ...15-126,129-144 
  SkillsList.tsx   |    5.79 |      100 |       0 |    5.79 | 18-103            
 src/ui/constants  |   55.78 |     90.9 |      50 |   55.78 |                   
  ...ollections.ts |     100 |      100 |     100 |     100 |                   
  tips.ts          |       0 |        0 |       0 |       0 | 1-164             
 src/ui/containers |       0 |        0 |       0 |       0 |                   
  ...ontroller.tsx |       0 |        0 |       0 |       0 | 1-362             
  UIStateShell.tsx |       0 |        0 |       0 |       0 | 1-15              
 ...ainer/builders |   98.38 |      100 |   83.33 |   98.38 |                   
  ...dUIActions.ts |     100 |      100 |     100 |     100 |                   
  buildUIState.ts  |     100 |      100 |     100 |     100 |                   
  ...onsBuilder.ts |   66.66 |      100 |       0 |   66.66 | 21-22             
  ...ateBuilder.ts |   66.66 |      100 |       0 |   66.66 | 21-22             
 ...ontainer/hooks |   55.17 |     87.1 |   56.52 |   55.17 |                   
  ...pBootstrap.ts |   94.71 |    58.33 |     100 |   94.71 | ...20-223,227-229 
  useAppDialogs.ts |   41.37 |      100 |   42.85 |   41.37 | ...63,182-398,418 
  ...ntHandlers.ts |     100 |      100 |     100 |     100 |                   
  useAppInput.ts   |    5.55 |      100 |       0 |    5.55 | 100-521,524-528   
  useAppLayout.ts  |    7.92 |      100 |       0 |    7.92 | 92-299,302-305    
  ...reenAction.ts |   13.63 |      100 |       0 |   13.63 | 23-42             
  ...nSelection.ts |      20 |      100 |       0 |      20 | 27-48             
  ...hestration.ts |     100 |      100 |     100 |     100 |                   
  ...references.ts |      10 |      100 |       0 |      10 | 51-104            
  ...itHandling.ts |   89.79 |      100 |     100 |   89.79 | 131-139,143       
  ...textBridge.ts |   33.33 |      100 |       0 |   33.33 | 23-30             
  ...tartHotkey.ts |   26.66 |      100 |       0 |   26.66 | 23-33             
  ...omptSubmit.ts |     100 |      100 |     100 |     100 |                   
  ...utHandling.ts |   98.37 |     91.3 |     100 |   98.37 | 53,167            
  ...yBootstrap.ts |      30 |      100 |       0 |      30 | 28-34             
  ...eybindings.ts |   86.28 |    78.18 |     100 |   86.28 | ...06-208,252-253 
  ...easurement.ts |   15.38 |      100 |       0 |   15.38 | 45-95             
  ...reshAction.ts |   79.16 |     37.5 |     100 |   79.16 | 51,82-85,87-96    
  ...untimeSync.ts |     100 |      100 |     100 |     100 |                   
  ...elTracking.ts |   26.22 |      100 |      50 |   26.22 | 20-24,60-113      
  ...laceholder.ts |      15 |      100 |       0 |      15 | 13-18,21-34       
  ...rorTimeout.ts |   17.64 |      100 |       0 |   17.64 | 24-39             
  ...astructure.ts |   73.91 |      100 |      20 |   73.91 | 53,57,61,75-83    
  ...ebugLogger.ts |   17.24 |      100 |       0 |   17.24 | 23-51             
  ...ialization.ts |   70.45 |    84.61 |   66.66 |   70.45 | ...,72-94,127-128 
  ...sAutoReset.ts |     100 |       90 |     100 |     100 | 44                
  ...andActions.ts |     100 |      100 |     100 |     100 |                   
  ...eshManager.ts |     100 |      100 |     100 |     100 |                   
  ...uationFlow.ts |    7.93 |      100 |       0 |    7.93 | 54-150            
  ...csTracking.ts |    95.8 |    80.64 |     100 |    95.8 | ...32-133,184-185 
  ...uthBridges.ts |   17.94 |      100 |   33.33 |   17.94 | ...13-138,142-146 
 src/ui/contexts   |   56.12 |    79.18 |   53.33 |   56.12 |                   
  ...chContext.tsx |   88.23 |    66.66 |     100 |   88.23 | 27-28             
  FocusContext.tsx |       0 |        0 |       0 |       0 | 1-11              
  ...ssContext.tsx |   83.75 |     86.7 |    87.5 |   83.75 | ...17-520,573-574 
  MouseContext.tsx |   78.82 |       75 |      80 |   78.82 | ...00-101,111-117 
  ...erContext.tsx |   94.44 |    63.63 |     100 |   94.44 | 127-130           
  ...owContext.tsx |   21.42 |      100 |   33.33 |   21.42 | 34,40-88          
  ...meContext.tsx |   52.34 |       40 |   57.14 |   52.34 | ...95-196,201-202 
  ...lProvider.tsx |   92.05 |    73.84 |     100 |   92.05 | ...85-486,498-499 
  ...onContext.tsx |     4.4 |      100 |       0 |     4.4 | ...40-395,400-407 
  ...teContext.tsx |       0 |        0 |       0 |       0 | 1-57              
  ...gsContext.tsx |      50 |      100 |       0 |      50 | 15-20             
  ...ngContext.tsx |   42.85 |      100 |       0 |   42.85 | 15-22             
  TodoContext.tsx  |   54.54 |      100 |       0 |   54.54 | 28-31,33-36,39-40 
  TodoProvider.tsx |    3.37 |      100 |       0 |    3.37 | 27-167,170-200    
  ...llContext.tsx |     100 |      100 |       0 |     100 |                   
  ...lProvider.tsx |    6.75 |      100 |       0 |    6.75 | 24-118            
  ...nsContext.tsx |      25 |      100 |       0 |      25 | 203-214,217-222   
  ...teContext.tsx |      50 |       50 |      50 |      50 | 251-260,265-266   
  ...deContext.tsx |   11.11 |      100 |       0 |   11.11 | 30-82,85-90       
 src/ui/editors    |   98.18 |     87.5 |     100 |   98.18 |                   
  ...ngsManager.ts |   98.18 |     87.5 |     100 |   98.18 | 59                
 src/ui/hooks      |   68.42 |    85.73 |   72.52 |   68.42 |                   
  ...st-helpers.ts |    95.9 |    90.47 |   56.66 |    95.9 | 67,79-80,98-99    
  ...dProcessor.ts |   87.95 |    87.09 |   88.88 |   87.95 | ...78-180,241-253 
  ...sorHelpers.ts |    78.8 |    78.57 |   88.88 |    78.8 | ...21-822,850-856 
  ...etionUtils.ts |   53.36 |    88.23 |   64.28 |   53.36 | 57-207,335        
  index.ts         |       0 |        0 |       0 |       0 | 1-9               
  keyToAnsi.ts     |    42.5 |      100 |       0 |    42.5 | 27-37,47-61       
  ...etionUtils.ts |     100 |    66.66 |     100 |     100 | 49                
  ...dProcessor.ts |   96.29 |       80 |     100 |   96.29 | ...74-275,407-411 
  ...ndHandlers.ts |    17.6 |    27.27 |   22.22 |    17.6 | ...44-645,650-659 
  ...dPathUtils.ts |    95.7 |    90.52 |     100 |    95.7 | ...25-227,271-272 
  ...dProcessor.ts |     100 |      100 |     100 |     100 |                   
  ...sorSupport.ts |   68.72 |    70.83 |   66.66 |   68.72 | ...82-285,303-310 
  ...tionEffect.ts |   90.76 |    86.56 |   92.85 |   90.76 | ...04-405,418-419 
  ...etionTypes.ts |       0 |        0 |       0 |       0 | 1                 
  toolMapping.ts   |   90.76 |    88.88 |   93.33 |   90.76 | ...95-207,226-228 
  ...nateBuffer.ts |      50 |      100 |       0 |      50 | 16-18             
  ...dScrollbar.ts |   97.82 |      100 |     100 |   97.82 | 153-155           
  ...st-helpers.ts |     100 |      100 |     100 |     100 |                   
  ...Completion.ts |   93.03 |    88.51 |     100 |   93.03 | ...02-603,606-607 
  ...uthCommand.ts |   96.42 |    66.66 |     100 |   96.42 | 21                
  ...tIndicator.ts |     100 |     92.3 |     100 |     100 | 57                
  useBanner.ts     |     100 |    83.33 |     100 |     100 | 22,48             
  ...chedScroll.ts |   16.66 |      100 |       0 |   16.66 | 14-32             
  ...ketedPaste.ts |      20 |      100 |       0 |      20 | 20-38             
  ...ompletion.tsx |   97.24 |    82.75 |    90.9 |   97.24 | ...04-206,209-210 
  useCompletion.ts |    92.4 |     87.5 |     100 |    92.4 | 68-69,93-94,98-99 
  ...leMessages.ts |   96.15 |       90 |     100 |   96.15 | 56-57,63          
  ...ntHandlers.ts |   31.25 |      100 |     100 |   31.25 | 43-70,74-82       
  ...fileDialog.ts |   16.12 |      100 |       0 |   16.12 | 17-47             
  ...orSettings.ts |   11.86 |      100 |       0 |   11.86 | 31-87             
  ...AutoUpdate.ts |    8.33 |      100 |       0 |    8.33 | 18-64             
  ...ionUpdates.ts |   75.17 |    80.64 |   77.77 |   75.17 | ...60-261,289-303 
  ...erDetector.ts |     100 |      100 |     100 |     100 |                   
  useFocus.ts      |     100 |      100 |     100 |     100 |                   
  ...olderTrust.ts |   87.09 |     91.3 |     100 |   87.09 | 50-63,135-136     
  ...BranchName.ts |     100 |    89.47 |     100 |     100 | 60,63             
  ...oryManager.ts |   96.61 |    93.18 |     100 |   96.61 | ...70-171,214-215 
  ...splayState.ts |     100 |      100 |     100 |     100 |                   
  ...stListener.ts |   12.12 |      100 |       0 |   12.12 | 17-50             
  ...ivityTimer.ts |   76.19 |    66.66 |     100 |   76.19 | 30-35             
  ...putHistory.ts |    92.5 |    85.71 |     100 |    92.5 | 62-63,71,93-95    
  ...storyStore.ts |     100 |    94.11 |     100 |     100 | 67                
  useKeypress.ts   |   88.88 |       75 |     100 |   88.88 | 28-29             
  ...rdProtocol.ts |       0 |        0 |       0 |       0 | 1-26              
  ...fileDialog.ts |     5.3 |      100 |       0 |     5.3 | 26-72,75-148      
  ...gIndicator.ts |     100 |      100 |     100 |     100 |                   
  useLogger.ts     |   93.75 |      100 |     100 |   93.75 | 27                
  useMcpStatus.ts  |   90.69 |    66.66 |     100 |   90.69 | 19,33-35          
  ...oryMonitor.ts |     100 |      100 |     100 |     100 |                   
  ...ssageQueue.ts |     100 |      100 |     100 |     100 |                   
  useMouse.ts      |   77.77 |    66.66 |     100 |   77.77 | 31-34             
  useMouseClick.ts |     100 |      100 |     100 |     100 |                   
  ...eSelection.ts |     2.2 |      100 |       0 |     2.2 | 36-367,370-416    
  ...hestration.ts |     100 |      100 |     100 |     100 |                   
  ...oviderInfo.ts |       0 |        0 |       0 |       0 | 1-86              
  ...odifyTrust.ts |    9.09 |      100 |       0 |    9.09 | 43-134            
  ...raseCycler.ts |   79.72 |    73.33 |     100 |   79.72 | ...69,75-76,92-94 
  ...cySettings.ts |   86.72 |    83.33 |     100 |   86.72 | ...,95-99,127-138 
  ...Management.ts |    1.53 |      100 |       0 |    1.53 | 22-568,571-663    
  ...Completion.ts |   43.02 |    55.55 |      50 |   43.02 | ...84-297,328-337 
  ...iderDialog.ts |    5.66 |      100 |       0 |    5.66 | 45-83,86-158      
  ...lScheduler.ts |   75.46 |    83.33 |   73.52 |   75.46 | ...41-657,808,815 
  ...oryCommand.ts |       0 |        0 |       0 |       0 | 1-7               
  useResponsive.ts |     100 |      100 |     100 |     100 |                   
  ...ompletion.tsx |   69.56 |      100 |     100 |   69.56 | 45-47,51-66,78-81 
  useRewind.ts     |     100 |      100 |     100 |     100 |                   
  ...ectionList.ts |   89.78 |    88.88 |     100 |   89.78 | ...19-425,445-449 
  useSession.ts    |       0 |        0 |       0 |       0 | 1-23              
  ...ionBrowser.ts |     100 |      100 |     100 |     100 |                   
  ...serHelpers.ts |   95.79 |    85.21 |   97.36 |   95.79 | ...39-641,764-765 
  ...erKeypress.ts |   89.87 |    97.29 |   94.11 |   89.87 | 101-108,130-145   
  ...ngsCommand.ts |   18.75 |      100 |       0 |   18.75 | 10-25             
  ...ellHistory.ts |   90.75 |       80 |     100 |   90.75 | ...83,131-132,142 
  ...Completion.ts |   97.04 |    81.25 |     100 |   97.04 | 71-73,101-102     
  ...oryCommand.ts |       0 |        0 |       0 |       0 | 1-63              
  ...cessorCore.ts |   73.91 |       60 |     100 |   73.91 | ...18,154,174-201 
  ...ompletion.tsx |   96.73 |    81.39 |     100 |   96.73 | ...,92-93,335-343 
  ...leCallback.ts |     100 |      100 |     100 |     100 |                   
  ...tateAndRef.ts |   59.09 |      100 |     100 |   59.09 | 23-31             
  ...oryRefresh.ts |     100 |      100 |     100 |     100 |                   
  ...rminalSize.ts |   10.34 |      100 |       0 |   10.34 | 15-44,49-85       
  ...emeCommand.ts |    4.29 |      100 |       0 |    4.29 | 25-122,125-199    
  useTimer.ts      |    87.5 |    85.71 |     100 |    87.5 | 44-45,50-52       
  ...ntinuation.ts |   91.28 |    89.74 |     100 |   91.28 | ...25-126,153-163 
  ...ePreserver.ts |   57.14 |      100 |      80 |   57.14 | 58-76             
  ...oolsDialog.ts |    3.44 |      100 |       0 |    3.44 | 23-106,109-193    
  ...Onboarding.ts |    1.92 |      100 |       0 |    1.92 | 77-402,405-486    
  ...eMigration.ts |   11.66 |      100 |       0 |   11.66 | 15-74             
  vim.ts           |   85.73 |    87.17 |    90.9 |   85.73 | ...07-716,832-834 
 ...s/geminiStream |    88.1 |     80.7 |   89.09 |    88.1 |                   
  ...ersistence.ts |   98.29 |    95.12 |     100 |   98.29 | 162-164           
  ...tProcessor.ts |   77.85 |    69.56 |      80 |   77.85 | ...48-159,162-164 
  index.ts         |     100 |      100 |     100 |     100 |                   
  queryPreparer.ts |   65.26 |    46.66 |     100 |   65.26 | ...29-130,133-146 
  ...Dispatcher.ts |   90.14 |    85.45 |   91.66 |   90.14 | ...19,321-325,410 
  streamUtils.ts   |   98.98 |    94.87 |     100 |   98.98 | 349-351           
  thoughtState.ts  |   93.33 |    61.53 |     100 |   93.33 | 71-72,77-78       
  ...ionHandler.ts |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
  ...genticLoop.ts |   97.43 |     87.5 |      60 |   97.43 | 177-178,239,346   
  ...miniStream.ts |   99.33 |    88.23 |   85.71 |   99.33 | 87                
  ...mLifecycle.ts |   84.18 |    58.62 |      80 |   84.18 | ...30-231,260-265 
  ...hestration.ts |    98.8 |    91.66 |   88.88 |    98.8 | 110-111,268       
  ...ntHandlers.ts |    73.5 |    89.28 |     100 |    73.5 | ...30-436,445-454 
  ...treamState.ts |   79.76 |    52.17 |     100 |   79.76 | ...79,200,237-238 
  ...ubmitQuery.ts |      86 |    66.66 |   81.81 |      86 | ...30-432,434-436 
 src/ui/layouts    |   83.46 |    55.17 |   82.75 |   83.46 |                   
  ...AppLayout.tsx |   80.98 |    71.42 |   83.33 |   80.98 | ...88-202,318-356 
  ...utHelpers.tsx |    84.6 |    52.94 |    82.6 |    84.6 | ...02-803,824-852 
 ...noninteractive |      75 |      100 |    6.66 |      75 |                   
  ...eractiveUi.ts |      75 |      100 |    6.66 |      75 | 17-19,23-24,27-28 
 src/ui/privacy    |   19.41 |        0 |       0 |   19.41 |                   
  ...acyNotice.tsx |       0 |        0 |       0 |       0 | 1-139             
  ...acyNotice.tsx |       0 |        0 |       0 |       0 | 1-59              
  ...acyNotice.tsx |   12.19 |      100 |       0 |   12.19 | 16-62             
  ...acyNotice.tsx |   35.42 |      100 |       0 |   35.42 | 77-172,180-235    
  ...acyNotice.tsx |   19.35 |      100 |       0 |   19.35 | 21-52,55-57       
 src/ui/reducers   |    79.5 |    91.66 |      50 |    79.5 |                   
  appReducer.ts    |     100 |      100 |     100 |     100 |                   
  ...ionReducer.ts |       0 |        0 |       0 |       0 | 1-52              
 src/ui/state      |   52.63 |    30.76 |      50 |   52.63 |                   
  extensions.ts    |   52.63 |    30.76 |      50 |   52.63 | ...28,130,134-149 
 src/ui/themes     |      99 |    86.63 |   97.77 |      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   |   99.38 |    98.63 |     100 |   99.38 | 326-327           
  default-light.ts |     100 |      100 |     100 |     100 |                   
  default.ts       |     100 |      100 |     100 |     100 |                   
  dracula.ts       |     100 |      100 |     100 |     100 |                   
  github-dark.ts   |     100 |      100 |     100 |     100 |                   
  github-light.ts  |     100 |      100 |     100 |     100 |                   
  googlecode.ts    |     100 |      100 |     100 |     100 |                   
  green-screen.ts  |     100 |      100 |     100 |     100 |                   
  no-color.ts      |     100 |      100 |     100 |     100 |                   
  ...c-resolver.ts |     100 |      100 |     100 |     100 |                   
  ...tic-tokens.ts |     100 |      100 |     100 |     100 |                   
  ...-of-purple.ts |     100 |      100 |     100 |     100 |                   
  theme-compat.ts  |     100 |       50 |     100 |     100 | 79                
  theme-manager.ts |   88.55 |    82.81 |     100 |   88.55 | ...03-312,317-318 
  theme.ts         |   99.09 |     81.3 |   94.11 |   99.09 | 282-283,702-703   
  xcode.ts         |     100 |      100 |     100 |     100 |                   
 src/ui/types      |       0 |        0 |       0 |       0 |                   
  ...ngMetadata.ts |       0 |        0 |       0 |       0 |                   
 src/ui/utils      |   55.71 |    86.36 |   67.89 |   55.71 |                   
  ...Colorizer.tsx |    5.64 |      100 |       0 |    5.64 | ...27-168,180-249 
  ...olePatcher.ts |   72.09 |      100 |   83.33 |   72.09 | 51-62             
  ...nRenderer.tsx |   27.87 |    63.26 |      45 |   27.87 | ...09,411,415-416 
  ...wnDisplay.tsx |    3.05 |      100 |       0 |    3.05 | ...89-814,825-829 
  ...eRenderer.tsx |   10.46 |      100 |       0 |   10.46 | ...28-379,386-419 
  ...tGenerator.ts |    76.4 |    53.84 |      60 |    76.4 | ...63,69-72,84-85 
  ...ketedPaste.ts |      60 |      100 |       0 |      60 | 13-14,17-18       
  clipboard.ts     |   97.29 |    84.61 |     100 |   97.29 | 40                
  ...boardUtils.ts |   63.09 |    76.74 |   83.33 |   63.09 | ...52-264,334-336 
  commandUtils.ts  |   93.11 |    95.34 |   95.83 |   93.11 | ...40-244,325-333 
  computeStats.ts  |     100 |      100 |     100 |     100 |                   
  displayUtils.ts  |     100 |      100 |     100 |     100 |                   
  formatters.ts    |   90.47 |    95.23 |     100 |   90.47 | 57-60             
  fuzzyFilter.ts   |     100 |    96.55 |     100 |     100 | 84                
  highlight.ts     |   77.51 |    97.29 |      60 |   77.51 | 144-170,174-179   
  ...xportUtils.ts |   98.03 |    91.66 |     100 |   98.03 | 111-112           
  ...storyItems.ts |   99.04 |    94.44 |     100 |   99.04 | 72                
  input.ts         |   84.28 |    94.44 |   66.66 |   84.28 | 73-80,106-113     
  isNarrowWidth.ts |      50 |      100 |       0 |      50 | 13-14             
  ...nUtilities.ts |   66.66 |    85.71 |     100 |   66.66 | 75-94,103-104     
  mouse.ts         |   83.05 |    72.41 |     100 |   83.05 | ...94,201,214-215 
  ...mConstants.ts |     100 |      100 |     100 |     100 |                   
  ...opDetector.ts |       0 |        0 |       0 |       0 | 1-210             
  responsive.ts    |   73.39 |    76.66 |   83.33 |   73.39 | ...00-108,111-125 
  rewindFileOps.ts |   91.84 |    66.66 |     100 |   91.84 | ...15-218,262-266 
  ...putHandler.ts |   89.89 |    89.91 |     100 |   89.89 | ...80-289,356-357 
  ...ityManager.ts |   94.33 |    85.71 |   93.18 |   94.33 | ...58-459,497,507 
  ...alContract.ts |     100 |      100 |     100 |     100 |                   
  terminalLinks.ts |     100 |      100 |     100 |     100 |                   
  ...colCleanup.ts |   95.45 |       75 |     100 |   95.45 | 39                
  ...lSequences.ts |     100 |      100 |     100 |     100 |                   
  terminalSetup.ts |    3.64 |      100 |       0 |    3.64 | 42-397            
  textUtils.ts     |   95.27 |    92.15 |   88.88 |   95.27 | 20-25             
  ...Formatters.ts |       0 |        0 |       0 |       0 | 1-50              
  ...icsTracker.ts |     100 |    94.44 |     100 |     100 | 38                
  ui-sizing.ts     |      16 |      100 |       0 |      16 | 11-23,26-36       
  updateCheck.ts   |     100 |    94.11 |     100 |     100 | 34,45             
 src/utils         |   61.39 |    88.68 |    74.9 |   61.39 |                   
  ...ionContext.ts |   76.92 |       75 |     100 |   76.92 | 38-41,63-66,81-84 
  ...Formatting.ts |     100 |      100 |     100 |     100 |                   
  bootstrap.ts     |     100 |      100 |     100 |     100 |                   
  checks.ts        |   33.33 |      100 |       0 |   33.33 | 23-28             
  cleanup.ts       |   67.74 |       80 |      60 |   67.74 | ...66-68,71,85-94 
  commands.ts      |   51.78 |    71.42 |     100 |   51.78 | 25-26,57-85       
  commentJson.ts   |    92.3 |     92.5 |     100 |    92.3 | 94-102            
  ...ScopeUtils.ts |   27.58 |      100 |       0 |   27.58 | 24-41,58-86       
  ...icSettings.ts |   92.53 |    91.66 |     100 |   92.53 | 55-56,61-64,67-70 
  ...arResolver.ts |   96.66 |    96.42 |     100 |   96.66 | 115-116           
  errors.ts        |   94.87 |       88 |     100 |   94.87 | 54-55,96-97       
  events.ts        |     100 |      100 |     100 |     100 |                   
  ...lativeTime.ts |     100 |      100 |     100 |     100 |                   
  gitUtils.ts      |   93.54 |       85 |     100 |   93.54 | 63-64,79-82       
  ...AutoUpdate.ts |   69.45 |    78.57 |      80 |   69.45 | ...67-268,282-347 
  ...lationInfo.ts |   99.49 |     98.3 |     100 |   99.49 | 61                
  math.ts          |   66.66 |      100 |       0 |   66.66 | 15                
  ...stentState.ts |   95.31 |    84.21 |     100 |   95.31 | 42,63-64          
  readStdin.ts     |   81.03 |    91.66 |   83.33 |   81.03 | 32-39,51-53       
  relaunch.ts      |     100 |      100 |     100 |     100 |                   
  resolvePath.ts   |   66.66 |       25 |     100 |   66.66 | 12-13,16,18-19    
  ...containers.ts |    4.69 |      100 |       0 |    4.69 | ...35-655,659-685 
  ...entrypoint.ts |    9.87 |      100 |       0 |    9.87 | 19-48,51-100      
  sandbox-env.ts   |   74.65 |    77.14 |   66.66 |   74.65 | ...52-153,161-162 
  sandbox-exec.ts  |     4.6 |      100 |       0 |     4.6 | 51-392            
  sandbox-image.ts |    3.96 |      100 |       0 |    3.96 | 12-128            
  ...box-podman.ts |   74.59 |    94.73 |   77.77 |   74.59 | ...49-259,325-398 
  ...x-seatbelt.ts |     8.2 |      100 |       0 |     8.2 | 34-310            
  sandbox-ssh.ts   |   78.84 |    81.13 |     100 |   78.84 | ...06-307,371-375 
  sandbox.ts       |   13.23 |      100 |       0 |   13.23 | 47-111            
  ...st-helpers.ts |     100 |      100 |     100 |     100 |                   
  ...ionCleanup.ts |   86.64 |       84 |     100 |   86.64 | ...48-249,332-333 
  sessionUtils.ts  |     8.1 |      100 |       0 |     8.1 | 51-118,125-139    
  settingsUtils.ts |   85.67 |    91.34 |   94.28 |   85.67 | ...61-489,528-529 
  ...ttingSaver.ts |    1.92 |      100 |       0 |    1.92 | 11-32,40-85       
  skillSettings.ts |   86.13 |       88 |     100 |   86.13 | 99-107,134-138    
  skillUtils.ts    |   64.51 |    63.33 |   83.33 |   64.51 | ...98-199,206-227 
  spawnWrapper.ts  |     100 |      100 |     100 |     100 |                   
  ...upWarnings.ts |     100 |      100 |     100 |     100 |                   
  stdinSafety.ts   |   91.39 |    86.48 |     100 |   91.39 | ...66-167,170,245 
  terminalTheme.ts |     100 |      100 |     100 |     100 |                   
  ...entEmitter.ts |     100 |      100 |     100 |     100 |                   
  ...upWarnings.ts |     100 |      100 |     100 |     100 |                   
  version.ts       |     100 |      100 |     100 |     100 |                   
  windowTitle.ts   |     100 |      100 |     100 |     100 |                   
 src/utils/privacy |   62.91 |    77.35 |      80 |   62.91 |                   
  ...taRedactor.ts |   78.06 |    78.09 |   82.75 |   78.06 | ...86-588,594-615 
  ...acyManager.ts |       0 |        0 |       0 |       0 | 1-176             
 ...ed-integration |    9.73 |     92.3 |    9.23 |    9.73 |                   
  ...temService.ts |     100 |      100 |     100 |     100 |                   
  ...tent-utils.ts |    6.38 |      100 |       0 |    6.38 | ...9,62-75,78-124 
  zed-helpers.ts   |   20.76 |      100 |      25 |   20.76 | ...79-128,131-148 
  ...h-resolver.ts |     4.7 |      100 |       0 |     4.7 | ...70-502,505-529 
  ...vider-auth.ts |    3.53 |      100 |       0 |    3.53 | ...17-224,227-287 
  ...ol-handler.ts |     5.1 |      100 |       0 |     5.1 | ...85-305,308-361 
  ...ntegration.ts |   11.88 |       80 |       8 |   11.88 | ...43-646,649-655 
-------------------|---------|----------|---------|---------|-------------------
Core Package - Full Text Report
-------------------|---------|----------|---------|---------|-------------------
File               | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-------------------|---------|----------|---------|---------|-------------------
All files          |   76.92 |     83.5 |   74.27 |   76.92 |                   
 src               |     100 |      100 |     100 |     100 |                   
  ...-factories.ts |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
 src/__mocks__/fs  |       0 |        0 |       0 |       0 |                   
  promises.ts      |       0 |        0 |       0 |       0 | 1-48              
 src/adapters      |     100 |      100 |     100 |     100 |                   
  ...eamAdapter.ts |     100 |      100 |     100 |     100 |                   
 src/code_assist   |   69.18 |    80.63 |   78.12 |   69.18 |                   
  codeAssist.ts    |   11.76 |      100 |       0 |   11.76 | 16-62,65-73,81-94 
  converter.ts     |   95.54 |    93.02 |     100 |   95.54 | 186-190,219-220   
  ...al-storage.ts |   95.86 |    79.48 |     100 |   95.86 | 27-28,86,110,139  
  oauth2.ts        |    64.9 |       78 |   81.81 |    64.9 | ...88-789,794-795 
  server.ts        |   48.16 |    72.72 |      50 |   48.16 | ...10-251,254-257 
  setup.ts         |   86.09 |    73.07 |     100 |   86.09 | ...57-159,183-189 
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/commands      |     100 |      100 |     100 |     100 |                   
  extensions.ts    |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/config        |   71.44 |    79.64 |   60.17 |   71.44 |                   
  ...tLifecycle.ts |   95.36 |    94.59 |     100 |   95.36 | ...55-156,220-222 
  ...skServices.ts |    9.19 |      100 |       0 |    9.19 | ...5,62-80,89-129 
  config.ts        |   59.84 |    72.83 |   57.14 |   59.84 | ...35-744,769-776 
  configBase.ts    |   68.81 |    72.09 |   72.72 |   68.81 | ...48-255,257-261 
  ...igBaseCore.ts |   70.13 |    94.28 |    45.2 |   70.13 | ...52-753,755-756 
  ...onstructor.ts |   97.14 |    90.14 |     100 |   97.14 | ...16-517,520-521 
  ...estHarness.ts |   93.15 |    95.45 |   83.33 |   93.15 | 229-239,245-248   
  configTypes.ts   |      58 |      100 |      50 |      58 | 196-236           
  constants.ts     |     100 |      100 |     100 |     100 |                   
  endpoints.ts     |     100 |      100 |     100 |     100 |                   
  ...ngsHelpers.ts |   62.16 |       40 |     100 |   62.16 | ...31,35-36,42-43 
  index.ts         |       0 |        0 |       0 |       0 | 1-41              
  ...ntegration.ts |   63.22 |    75.47 |   73.68 |   63.22 | ...12,429,438,447 
  models.ts        |     100 |      100 |     100 |     100 |                   
  ...rSingleton.ts |   76.22 |    70.37 |   56.25 |   76.22 | ...94,397-400,408 
  ...entManager.ts |   50.76 |    68.91 |   65.21 |   50.76 | ...52-653,679-703 
  ...ingsParser.ts |   41.37 |    33.33 |     100 |   41.37 | 31-48             
  ...tryFactory.ts |   84.57 |    76.92 |   69.23 |   84.57 | ...56,471,488-504 
  types.ts         |       0 |        0 |       0 |       0 |                   
 ...nfirmation-bus |   83.33 |       50 |      50 |   83.33 |                   
  index.ts         |       0 |        0 |       0 |       0 | 1-2               
  message-bus.ts   |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/core          |   81.12 |    77.84 |   83.33 |   81.12 |                   
  ...ssionTypes.ts |   68.42 |      100 |      20 |   68.42 | ...05-107,112-113 
  ...ntContract.ts |     100 |      100 |     100 |     100 |                   
  ...tGenerator.ts |     100 |    96.15 |     100 |     100 | 94                
  ...okTriggers.ts |    47.7 |     61.9 |   66.66 |    47.7 | ...59,261,307-312 
  geminiRequest.ts |      60 |      100 |       0 |      60 | 18-19             
  ...nAIWrapper.ts |   77.77 |      100 |   66.66 |   77.77 | 58-61,64-67       
  ...okTriggers.ts |   96.12 |    84.37 |     100 |   96.12 | ...32,171,218,260 
  logger.ts        |   79.12 |    80.19 |   94.44 |   79.12 | ...34-448,491-500 
  prompts.ts       |   82.85 |     58.9 |    91.3 |   82.85 | ...55,558,619-620 
  subagentTypes.ts |      90 |    68.42 |    87.5 |      90 | ...72-273,288-289 
  tokenLimits.ts   |     100 |      100 |     100 |     100 |                   
  ...erContract.ts |     100 |      100 |     100 |     100 |                   
  turn.ts          |     100 |      100 |     100 |     100 |                   
 ...re/compression |   33.55 |       50 |   16.66 |   33.55 |                   
  ...nDirective.ts |    6.25 |      100 |       0 |    6.25 | 22-62             
  types.ts         |   41.02 |       50 |      20 |   41.02 | ...43-377,388-389 
 src/debug         |   61.53 |        0 |       0 |   61.53 |                   
  ...ionManager.ts |     100 |      100 |     100 |     100 |                   
  DebugLogger.ts   |     100 |      100 |     100 |     100 |                   
  FileOutput.ts    |     100 |      100 |     100 |     100 |                   
  ...ionManager.ts |       0 |        0 |       0 |       0 | 1-6               
  ...FileOutput.ts |       0 |        0 |       0 |       0 | 1-6               
  index.ts         |     100 |      100 |     100 |     100 |                   
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 src/filters       |   98.57 |    96.29 |     100 |   98.57 |                   
  EmojiFilter.ts   |   98.57 |    96.29 |     100 |   98.57 | ...55-156,352-353 
 src/hooks         |    83.1 |    85.15 |   80.72 |    83.1 |                   
  errors.ts        |     100 |      100 |     100 |     100 |                   
  ...Aggregator.ts |    90.4 |    81.33 |    87.5 |    90.4 | ...50,369,371,373 
  ...sContracts.ts |       0 |        0 |       0 |       0 | 1                 
  ...entHandler.ts |   91.42 |     87.3 |   93.75 |   91.42 | ...53,785-791,836 
  hookPlanner.ts   |   98.79 |    93.33 |     100 |   98.79 | 103               
  hookRegistry.ts  |   97.19 |    88.31 |     100 |   97.19 | ...97,399,401,403 
  hookRunner.ts    |   84.88 |    87.14 |   86.95 |   84.88 | ...37-439,502-505 
  hookSystem.ts    |    64.2 |    88.88 |      65 |    64.2 | ...49-351,364-366 
  ...Translator.ts |   93.96 |    68.08 |     100 |   93.96 | ...06-307,318,367 
  ...Validators.ts |    92.4 |    89.83 |     100 |    92.4 | 57-59,78-80       
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...ssion-hook.ts |   88.88 |    33.33 |     100 |   88.88 | 24,30             
  trustedHooks.ts  |   20.77 |      100 |       0 |   20.77 | ...6,82-90,96-109 
  types.ts         |    53.2 |     87.5 |      52 |    53.2 | ...36-437,448-449 
 ...oks/test-utils |       0 |        0 |       0 |       0 |                   
  ...igWithHook.ts |       0 |        0 |       0 |       0 | 1-137             
 src/interfaces    |       0 |        0 |       0 |       0 |                   
  index.ts         |       0 |        0 |       0 |       0 |                   
  ....interface.ts |       0 |        0 |       0 |       0 |                   
 src/models        |    83.7 |    92.41 |    87.5 |    83.7 |                   
  hydration.ts     |    4.76 |      100 |       0 |    4.76 | 65-129,151-231    
  index.ts         |     100 |      100 |     100 |     100 |                   
  profiles.ts      |     100 |      100 |     100 |     100 |                   
  ...ntegration.ts |   95.34 |    89.74 |     100 |   95.34 | ...36-137,200-201 
  registry.ts      |    91.4 |    88.88 |      92 |    91.4 | ...72-273,392-403 
  schema.ts        |     100 |      100 |     100 |     100 |                   
  transformer.ts   |     100 |      100 |     100 |     100 |                   
 src/parsers       |   80.75 |    80.71 |   92.85 |   80.75 |                   
  ...CallParser.ts |   84.59 |     80.4 |    92.3 |   84.59 | ...09-810,813-814 
  ...rg-parsing.ts |   83.37 |    85.71 |   90.47 |   83.37 | ...23-425,501-502 
  ...ll-helpers.ts |   73.94 |     79.5 |   92.85 |   73.94 | ...07-508,514-535 
  ...rser-utils.ts |      76 |    73.33 |     100 |      76 | ...09-110,114-119 
 src/policy        |    72.9 |    76.19 |   88.46 |    72.9 |                   
  config.ts        |   68.06 |    77.19 |   86.36 |   68.06 | ...25,381,458-459 
  index.ts         |     100 |      100 |     100 |     100 |                   
  policy-engine.ts |     100 |      100 |     100 |     100 |                   
  ...cy-helpers.ts |   88.88 |    66.66 |     100 |   88.88 | 31-39             
  ...-stringify.ts |     100 |      100 |     100 |     100 |                   
  toml-loader.ts   |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
  utils.ts         |     100 |      100 |     100 |     100 |                   
 src/prompt-config |   82.63 |    87.55 |   82.35 |   82.63 |                   
  ...lateEngine.ts |    94.7 |    89.24 |     100 |    94.7 | ...32-435,446-449 
  index.ts         |       0 |      100 |     100 |       0 | 5-41              
  prompt-cache.ts  |    99.1 |    97.43 |     100 |    99.1 | 236-237           
  ...-installer.ts |   83.82 |    81.87 |    92.3 |   83.82 | ...24-831,863-866 
  prompt-loader.ts |   90.93 |    92.56 |   89.65 |   90.93 | ...15-532,542-543 
  ...t-resolver.ts |   50.38 |       84 |      50 |   50.38 | ...22-423,428-527 
  ...pt-service.ts |   85.28 |    83.18 |   80.95 |   85.28 | ...27,544-551,582 
  ...delegation.ts |   93.54 |     90.9 |     100 |   93.54 | 34-35             
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...onfig/defaults |   56.45 |    46.03 |   85.41 |   56.45 |                   
  core-defaults.ts |      48 |     41.5 |   78.57 |      48 | ...55,365,371-379 
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...est-loader.ts |   81.81 |       80 |     100 |   81.81 | ...02-108,116-120 
  ...t-warnings.ts |    92.3 |    33.33 |     100 |    92.3 | 18-19             
  ...r-defaults.ts |   52.51 |    35.29 |   84.61 |   52.51 | ...24,334,340-345 
  ...e-defaults.ts |     100 |      100 |     100 |     100 |                   
  tool-defaults.ts |   56.05 |     42.3 |   84.61 |   56.05 | ...82-283,295-300 
 ...nfig/installer |   92.11 |    87.63 |   97.61 |   92.11 |                   
  ...resolution.ts |   96.63 |    92.45 |     100 |   96.63 | ...70-271,317-318 
  ...tory-utils.ts |   95.42 |    90.38 |     100 |   95.42 | ...14-117,154,175 
  file-writer.ts   |   78.78 |    73.68 |     100 |   78.78 | 31-32,51-52,69-78 
  ...operations.ts |   97.46 |    94.44 |     100 |   97.46 | 48-49             
  ...-expansion.ts |   82.67 |    81.81 |      90 |   82.67 | ...,70-71,165-172 
 ...onfig/resolver |   36.86 |    60.86 |   51.85 |   36.86 |                   
  ...ry-scanner.ts |    4.04 |      100 |       0 |    4.04 | ...98-159,163-207 
  fs-adapter.ts    |   39.06 |    66.66 |      50 |   39.06 | ...37,42-47,51-88 
  name-utils.ts    |   71.69 |       60 |   78.57 |   71.69 | ...03-204,208-218 
 src/prompts       |      30 |      100 |      25 |      30 |                   
  mcp-prompts.ts   |   28.57 |      100 |       0 |   28.57 | 11-15             
  ...t-registry.ts |   30.23 |      100 |   28.57 |   30.23 | ...43,49-56,69-74 
 src/recording     |    90.2 |    86.27 |   98.09 |    90.2 |                   
  ...ntegration.ts |    83.9 |       75 |     100 |    83.9 | ...31-132,143-144 
  ReplayEngine.ts  |   95.78 |    91.08 |     100 |   95.78 | ...37-342,502-509 
  ...nDiscovery.ts |   91.62 |    87.87 |     100 |   91.62 | ...44-345,360-361 
  ...ockManager.ts |   86.24 |    83.33 |     100 |   86.24 | ...18,233,260-261 
  ...ingService.ts |   82.97 |    92.45 |   95.65 |   82.97 | ...57,390-391,395 
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...st-helpers.ts |   91.12 |       90 |   92.85 |   91.12 | 190-200,227-230   
  resumeSession.ts |   93.19 |    89.65 |     100 |   93.19 | ...10-215,246-247 
  ...eanupUtils.ts |      90 |    69.23 |     100 |      90 | ...40-241,267,280 
  ...Management.ts |   88.23 |    85.71 |     100 |   88.23 | 94,108-112        
  types.ts         |       0 |        0 |       0 |       0 |                   
 src/resources     |   95.23 |     92.3 |     100 |   95.23 |                   
  ...e-registry.ts |   95.23 |     92.3 |     100 |   95.23 | 34-35             
 src/runtime       |   74.86 |    84.95 |   75.86 |   74.86 |                   
  ...imeContext.ts |     100 |      100 |     100 |     100 |                   
  ...timeLoader.ts |   85.18 |    72.41 |   83.33 |   85.18 | ...31,235,261-264 
  ...ntimeState.ts |   95.66 |    90.78 |     100 |   95.66 | ...03-504,544-545 
  ...ionContext.ts |   83.54 |    93.33 |   71.42 |   83.54 | ...55-156,167-174 
  ...imeContext.ts |   73.85 |    97.61 |   60.71 |   73.85 | ...69-274,276-283 
  index.ts         |       0 |        0 |       0 |       0 | 1-19              
  ...imeContext.ts |      70 |       90 |     100 |      70 | 88-108            
  ...meAdapters.ts |     4.8 |      100 |       0 |     4.8 | ...84-118,124-170 
  ...ateFactory.ts |   90.32 |    71.42 |     100 |   90.32 | ...79,102,112,125 
  ...imeAdapter.ts |   80.55 |    86.66 |   88.88 |   80.55 | 52-59,67-68,71-76 
 ...time/contracts |       0 |        0 |       0 |       0 |                   
  ...lureReason.ts |       0 |        0 |       0 |       0 | 1                 
  ...kContracts.ts |       0 |        0 |       0 |       0 | 1                 
  ...ningOutput.ts |       0 |        0 |       0 |       0 | 1                 
  ...torFactory.ts |       0 |        0 |       0 |       0 | 1                 
  RuntimeModel.ts  |       0 |        0 |       0 |       0 | 1                 
  ...meProvider.ts |       0 |        0 |       0 |       0 | 1                 
  ...oviderChat.ts |       0 |        0 |       0 |       0 | 1                 
  ...derManager.ts |       0 |        0 |       0 |       0 | 1                 
  ...eTokenizer.ts |       0 |        0 |       0 |       0 | 1                 
  ...zerFactory.ts |       0 |        0 |       0 |       0 | 1                 
  ...tryContext.ts |       0 |        0 |       0 |       0 | 1                 
  index.ts         |       0 |        0 |       0 |       0 | 1                 
 ...runtime/errors |   94.87 |    85.71 |   66.66 |   94.87 |                   
  ...viderError.ts |     100 |      100 |     100 |     100 |                   
  index.ts         |       0 |        0 |       0 |       0 | 1-14              
 src/safety        |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  pathValidator.ts |     100 |      100 |     100 |     100 |                   
 src/scheduler     |       0 |        0 |       0 |       0 |                   
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 src/services      |   84.67 |    86.25 |   88.31 |   84.67 |                   
  ...ardService.ts |   94.23 |    93.75 |     100 |   94.23 | 70,74-75          
  ...utoTrigger.ts |   97.33 |    95.83 |     100 |   97.33 | 127-128           
  ...askManager.ts |   95.81 |    93.93 |     100 |   95.81 | 151-157,365-366   
  ...derService.ts |   98.98 |    97.05 |     100 |   98.98 | 173               
  ...y-analyzer.ts |   83.51 |    79.85 |   87.09 |   83.51 | ...13-641,647-648 
  ...extManager.ts |     100 |    96.29 |     100 |     100 | 63                
  ...nitization.ts |    98.7 |    96.87 |     100 |    98.7 | 172-173           
  ...eryService.ts |     100 |      100 |     100 |     100 |                   
  ...temService.ts |     100 |      100 |     100 |     100 |                   
  ...ts-service.ts |      50 |      100 |       0 |      50 | 41-42,48-49       
  gitService.ts    |    86.6 |    86.95 |      80 |    86.6 | ...34-137,141-145 
  index.ts         |       0 |        0 |       0 |       0 | 1-23              
  ...ionService.ts |   96.43 |    95.08 |     100 |   96.43 | ...27-428,438-439 
  ...pExecution.ts |   88.42 |    78.57 |   83.33 |   88.42 | 65-66,92-100      
  ...lCpHelpers.ts |   87.83 |    87.75 |     100 |   87.83 | ...91,194,253-259 
  ...ionService.ts |   71.55 |    85.71 |    62.5 |   71.55 | ...80-303,362-375 
  ...utionTypes.ts |       0 |        0 |       0 |       0 | 1                 
  ...lExitGuard.ts |     100 |      100 |     100 |     100 |                   
  ...utputUtils.ts |   95.65 |    95.23 |     100 |   95.65 | 34-35             
  ...rocessKill.ts |   88.57 |    88.88 |     100 |   88.57 | 38-41             
  ...yExecution.ts |   96.15 |    93.33 |     100 |   96.15 | 110-111,132-134   
  ...PtyHelpers.ts |   87.03 |    76.19 |    87.5 |   87.03 | ...20,151-152,208 
  ...yLifecycle.ts |   86.77 |    78.68 |   88.88 |   86.77 | ...92,297,354-356 
  shellPtyState.ts |       0 |        0 |       0 |       0 | 1                 
  ...xt-tracker.ts |   94.87 |    88.88 |   85.71 |   94.87 | 54-55             
  ...er-service.ts |       0 |        0 |       0 |       0 | 1-161             
  ...er-service.ts |   68.47 |    48.48 |      80 |   68.47 | ...85-289,311-314 
 ...rvices/history |   82.58 |    84.98 |    87.5 |   82.58 |                   
  ...Converters.ts |   83.29 |    81.96 |   81.81 |   83.29 | ...51-452,558-581 
  HistoryEvents.ts |       0 |        0 |       0 |       0 |                   
  ...oryService.ts |    85.3 |     88.6 |   86.79 |    85.3 | ...03-704,783-784 
  IContent.ts      |    89.7 |       76 |     100 |    89.7 | ...40,250-251,262 
  ...calToolIds.ts |   96.87 |    93.33 |     100 |   96.87 | 36-37             
  ...ebugLogger.ts |   62.41 |       68 |   85.71 |   62.41 | ...33-145,158-162 
  ...Validation.ts |     100 |      100 |     100 |     100 |                   
  ...CloneUtils.ts |   73.07 |    88.46 |   83.33 |   73.07 | ...98-101,106-118 
  ...textWindow.ts |   91.42 |    55.55 |     100 |   91.42 | 59,61-62          
  ...ryCuration.ts |     100 |      100 |     100 |     100 |                   
  ...EventTypes.ts |       0 |        0 |       0 |       0 |                   
  ...erPipeline.ts |     100 |      100 |     100 |     100 |                   
  historyQuery.ts  |   63.63 |       50 |     100 |   63.63 | 27-30             
  ...Estimation.ts |   44.68 |    82.14 |      50 |   44.68 | ...87-196,202-251 
  ...zerAdapter.ts |     100 |     87.5 |     100 |     100 | 73                
  ...malization.ts |    91.7 |    87.12 |     100 |    91.7 | ...26-431,477-485 
  ...oolPairing.ts |   98.59 |     87.5 |     100 |   98.59 | 103               
 src/skills        |   73.86 |       80 |   77.14 |   73.86 |                   
  skillLoader.ts   |   59.42 |    78.94 |   76.92 |   59.42 | ...16-351,363-373 
  skillManager.ts  |   89.68 |    80.88 |   77.27 |   89.68 | ...94-395,401-402 
 src/storage       |   98.69 |    96.87 |     100 |   98.69 |                   
  ...FileWriter.ts |     100 |      100 |     100 |     100 |                   
  ...nceService.ts |   98.65 |    96.87 |     100 |   98.65 | 291-292           
  ...ey-storage.ts |     100 |      100 |     100 |     100 |                   
  secure-store.ts  |     100 |      100 |     100 |     100 |                   
  sessionTypes.ts  |     100 |      100 |     100 |     100 |                   
 src/telemetry     |   15.45 |        0 |       0 |   15.45 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  ...-exporters.ts |       0 |        0 |       0 |       0 | 1-6               
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...t.circular.ts |       0 |        0 |       0 |       0 | 1-17              
  ...t.circular.ts |       0 |        0 |       0 |       0 | 1-110             
  loggers.ts       |     100 |      100 |     100 |     100 |                   
  metrics.ts       |     100 |      100 |     100 |     100 |                   
  sdk.ts           |     100 |      100 |     100 |     100 |                   
  ...l-decision.ts |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
  uiTelemetry.ts   |     100 |      100 |     100 |     100 |                   
 src/test-utils    |      50 |    60.65 |   18.58 |      50 |                   
  config.ts        |   65.38 |      100 |   13.04 |   65.38 | ...,91-96,155-193 
  index.ts         |       0 |        0 |       0 |       0 | 1-9               
  mock-tool.ts     |       0 |        0 |       0 |       0 | 1-158             
  ...aceContext.ts |       0 |        0 |       0 |       0 | 1-32              
  ...allOptions.ts |   81.62 |    51.61 |   54.54 |   81.62 | ...83,196,225-228 
  runtime.ts       |   47.03 |    33.33 |    8.82 |   47.03 | ...17-279,287-350 
  tools.ts         |   43.02 |      100 |   31.57 |   43.02 | ...99-211,214-221 
 src/todo          |   12.86 |      100 |       0 |   12.86 |                   
  todoFormatter.ts |   12.86 |      100 |       0 |   12.86 | ...03,206-219,222 
 src/tools         |   79.33 |    83.33 |   91.66 |   79.33 |                   
  ...ey-storage.ts |   79.33 |    83.33 |   91.66 |   79.33 | ...05-310,319-324 
 ...tools-adapters |   44.15 |    65.64 |    34.7 |   44.15 |                   
  ...iceAdapter.ts |   61.22 |    83.33 |    62.5 |   61.22 | ...52,55-60,65-68 
  ...iceAdapter.ts |   27.58 |      100 |      40 |   27.58 | 21-26,29-37,40-45 
  ...iceAdapter.ts |   22.58 |      100 |      40 |   22.58 | 18-25,28-43,46-47 
  ...iceAdapter.ts |      30 |      100 |       0 |      30 | 16-18,21-22,25-33 
  ...BusAdapter.ts |   10.86 |      100 |      25 |   10.86 | ...16-129,132-138 
  ...iceAdapter.ts |      60 |        0 |       0 |      60 | ...27,36-37,40-41 
  ...iceAdapter.ts |   53.84 |      100 |      40 |   53.84 | 17-18,21-22,26-27 
  ...ostAdapter.ts |   19.33 |      100 |    8.69 |   19.33 | ...25-241,244-246 
  ...iceAdapter.ts |   15.58 |        0 |       0 |   15.58 | ...9,82-84,87-102 
  ...iceAdapter.ts |   52.94 |      100 |       0 |   52.94 | ...18,21-22,25-26 
  ...iceAdapter.ts |    50.9 |    60.97 |   65.51 |    50.9 | ...21-864,869-872 
  ...iceAdapter.ts |   68.18 |       50 |      50 |   68.18 | 32-36,39-40       
  ...ostAdapter.ts |    29.9 |      100 |   13.04 |    29.9 | ...48-154,157-158 
  ...ageAdapter.ts |   46.15 |      100 |       0 |   46.15 | ...33,36-37,40-41 
  ...ostAdapter.ts |   67.74 |      100 |   54.54 |   67.74 | ...57,60-61,64-65 
  ...iceAdapter.ts |      50 |      100 |   66.66 |      50 | 19-23             
  ...iceHelpers.ts |   63.79 |     61.7 |      75 |   63.79 | ...79-280,284-285 
  index.ts         |     100 |      100 |     100 |     100 |                   
 src/utils         |   81.77 |    86.65 |   83.33 |   81.77 |                   
  LruCache.ts      |    82.6 |      100 |   71.42 |    82.6 | 29-30,33-34       
  ...grep-utils.ts |   98.03 |     87.5 |     100 |   98.03 | 137-138           
  asyncIterator.ts |   73.07 |    84.61 |   66.66 |   73.07 | ...71,75-86,93-94 
  bfsFileSearch.ts |   93.61 |    92.85 |     100 |   93.61 | 36-44             
  browser.ts       |    8.69 |      100 |       0 |    8.69 | 17-53             
  channel.ts       |     100 |      100 |     100 |     100 |                   
  ...pointUtils.ts |      95 |    91.66 |     100 |      95 | 142-149           
  debugLogger.ts   |     100 |      100 |     100 |     100 |                   
  delay.ts         |     100 |      100 |     100 |     100 |                   
  editor.ts        |   96.46 |    90.38 |    90.9 |   96.46 | ...25-226,228-229 
  ...entContext.ts |     100 |      100 |     100 |     100 |                   
  errorParsing.ts  |   92.12 |     87.5 |   95.65 |   92.12 | ...87,218,302-303 
  ...rReporting.ts |   82.35 |       75 |     100 |   82.35 | ...41-143,151-156 
  errors.ts        |   74.67 |    95.12 |      50 |   74.67 | ...27-128,189-213 
  events.ts        |   65.74 |      100 |    62.5 |   65.74 | ...01-306,312-315 
  exitCodes.ts     |     100 |      100 |     100 |     100 |                   
  ...sionLoader.ts |   80.98 |    63.88 |   92.85 |   80.98 | ...70-171,224-232 
  fetch.ts         |   24.32 |      100 |       0 |   24.32 | 23-28,32-86,89-90 
  fileDiffUtils.ts |   94.87 |     90.9 |     100 |   94.87 | 25-26             
  fileUtils.ts     |   93.83 |    90.06 |   95.23 |   93.83 | ...85,454,488-494 
  formatters.ts    |   18.18 |      100 |       0 |   18.18 | 8-16              
  ...eUtilities.ts |   91.28 |       90 |   93.75 |   91.28 | ...98-302,350-360 
  ...rStructure.ts |   95.63 |     94.8 |     100 |   95.63 | ...18-219,379-384 
  getPty.ts        |    12.5 |      100 |       0 |    12.5 | 38-53             
  ...noreParser.ts |   89.53 |       90 |   85.71 |   89.53 | ...30-231,236-250 
  ...ineChanges.ts |       0 |        0 |       0 |       0 | 1-348             
  gitUtils.ts      |   42.55 |    71.42 |      50 |   42.55 | 32-33,40-44,53-80 
  googleErrors.ts  |   77.01 |    73.21 |     100 |   77.01 | ...08,346-347,364 
  ...uotaErrors.ts |   94.94 |    87.25 |     100 |   94.94 | ...76-277,315-316 
  ide-trust.ts     |      60 |      100 |       0 |      60 | 14-15             
  ...rePatterns.ts |     100 |    96.55 |     100 |     100 | 257               
  ...ionManager.ts |     100 |    88.88 |     100 |     100 | 24                
  ...edit-fixer.ts |       0 |        0 |       0 |       0 | 1-156             
  ...yDiscovery.ts |   83.84 |    79.71 |   82.35 |   83.84 | ...42-743,757-768 
  ...tProcessor.ts |   97.19 |    91.86 |   94.44 |   97.19 | ...11-312,406-407 
  ...Inspectors.ts |       0 |        0 |       0 |       0 | 1-23              
  output-format.ts |   36.36 |      100 |       0 |   36.36 | ...53-154,164-185 
  package.ts       |     100 |      100 |     100 |     100 |                   
  ...erCoercion.ts |   80.89 |       80 |     100 |   80.89 | ...47-348,351-352 
  partUtils.ts     |   96.87 |    94.87 |     100 |   96.87 | 101-102           
  pathReader.ts    |   22.58 |      100 |       0 |   22.58 | ...22,28-29,41-60 
  paths.ts         |      85 |    85.54 |   83.33 |      85 | ...84-285,300-310 
  ...rDetection.ts |   52.05 |    78.94 |   83.33 |   52.05 | ...03-104,114-115 
  ...archTarget.ts |   89.58 |    69.23 |     100 |   89.58 | 45-47,65-66       
  retry.ts         |    83.7 |    86.85 |   92.59 |    83.7 | ...68-971,976-977 
  ...thResolver.ts |     100 |      100 |     100 |     100 |                   
  ...nStringify.ts |     100 |      100 |     100 |     100 |                   
  sanitization.ts  |     100 |      100 |     100 |     100 |                   
  ...aValidator.ts |   91.22 |    76.36 |     100 |   91.22 | ...51-352,368-379 
  ...r-launcher.ts |   90.29 |    81.81 |     100 |   90.29 | ...92,210,212-213 
  session.ts       |     100 |      100 |     100 |     100 |                   
  shell-parser.ts  |   24.51 |    47.82 |   36.84 |   24.51 | ...70-512,524-526 
  shell-utils.ts   |   84.86 |    89.65 |   96.15 |   84.86 | ...36-642,806-814 
  ...Completion.ts |   94.21 |    92.15 |     100 |   94.21 | 71-77             
  stdio.ts         |   83.83 |    56.52 |     100 |   83.83 | ...25-129,138-142 
  ...dleTimeout.ts |   97.26 |    92.85 |     100 |   97.26 | 43-44             
  summarizer.ts    |      98 |       90 |     100 |      98 | 92                
  ...emEncoding.ts |   94.96 |    88.88 |     100 |   94.96 | ...10,142-143,197 
  terminal.ts      |   34.09 |      100 |       0 |   34.09 | ...55,58-59,62-66 
  ...Serializer.ts |    98.2 |    92.75 |     100 |    98.2 | ...,98-99,181-183 
  testUtils.ts     |      50 |      100 |   33.33 |      50 | ...47,53-58,64-66 
  textUtils.ts     |    12.5 |      100 |       0 |    12.5 | 15-34             
  thoughtUtils.ts  |     100 |      100 |     100 |     100 |                   
  tool-utils.ts    |   68.64 |    77.77 |      80 |   68.64 | ...34-135,156-180 
  ...putLimiter.ts |   95.14 |    81.63 |     100 |   95.14 | ...5-66,78-79,113 
  unicodeUtils.ts  |     100 |      100 |     100 |     100 |                   
  ...untManager.ts |   88.52 |    86.48 |     100 |   88.52 | ...,83-88,104-106 
  version.ts       |     100 |      100 |     100 |     100 |                   
  ...aceContext.ts |   96.85 |    95.23 |    92.3 |   96.85 | 95-96,110-111     
 ...ils/filesearch |   88.54 |    90.44 |   93.75 |   88.54 |                   
  crawlCache.ts    |     100 |      100 |     100 |     100 |                   
  crawler.ts       |   83.15 |     82.6 |      60 |   83.15 | ...99-101,113-118 
  fileSearch.ts    |   83.73 |    87.35 |     100 |   83.73 | ...00-301,323-324 
  ignore.ts        |     100 |      100 |     100 |     100 |                   
  result-cache.ts  |     100 |      100 |     100 |     100 |                   
-------------------|---------|----------|---------|---------|-------------------

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

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

⚠️ Outside diff range comments (2)
packages/storage/src/secure-store/machine-secret.ts (1)

204-227: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Do not cache a secret that was not confirmed durable.

Lines 217 and 227 return the freshly generated secret when the post-persist reread is missing or unusable. That can cache and use a root secret that is not actually recoverable from the durable source, producing v2 fallback files that may not decrypt after restart or after another writer wins.

Proposed fix
       // Re-read the keyring winner in case a concurrent writer persisted a
       // different secret first.
       const winner = await readFromKeyring(keyring);
-      return winner.status === 'found' ? winner.secret : secret;
+      return winner.status === 'found' ? winner.secret : null;
     }
   }
 
@@
   }
   // Re-read the file winner.
   const winner = await readFromFile(filePath);
-  return winner.status === 'found' ? winner.secret : secret;
+  return winner.status === 'found' ? winner.secret : null;
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/storage/src/secure-store/machine-secret.ts` around lines 204 - 227,
The generatePersistAndReread flow in machine-secret.ts should not return the
freshly generated secret unless it has been confirmed durable by rereading it
from the keyring or file. Update the logic in generatePersistAndReread,
persistToKeyring, and persistToFile call handling so that a post-persist reread
returning missing or unusable yields null (or retries/propagates failure)
instead of caching the local secret; only return the reread winner.secret when
readFromKeyring/readFromFile reports found.
packages/storage/src/secure-store/secure-store.ts (1)

773-777: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Close the remaining v2→v1 downgrade gaps.

The downgrade guard checks only the sanitized final path, but get() can still read a legacy path for the same key. A degraded write can therefore shadow an existing legacy v2 file with a new v1 file. Also, readExistingEnvelopeVersion() returns null for parsed-but-malformed { v: 2, ... }, allowing a v1 overwrite even though the file declares a v2 envelope.

Proposed fix
     if (!useV2) {
       const finalPathForCheck = this.getFallbackFilePath(key);
-      const existingVersion =
-        await this.readExistingEnvelopeVersion(finalPathForCheck);
-      if (existingVersion === 2) {
+      const legacyPathForCheck = this.getLegacyFallbackFilePath(key);
+      const pathsToCheck = [finalPathForCheck];
+      if (legacyPathForCheck !== finalPathForCheck) {
+        pathsToCheck.push(legacyPathForCheck);
+      }
+      const existingVersions = await Promise.all(
+        pathsToCheck.map((candidatePath) =>
+          this.readExistingEnvelopeVersion(candidatePath),
+        ),
+      );
+      if (existingVersions.includes(2)) {
         throw new SecureStoreError(
           'Refusing to overwrite v:2 fallback file with a weaker v:1 envelope while the machine secret is unavailable',
           'UNAVAILABLE',
@@
-    if (!isValidEnvelope(parsed)) {
-      return null;
-    }
-    return parsed.v;
+    const version = (parsed as { v?: unknown }).v;
+    return typeof version === 'number' && ENVELOPE_VERSIONS.has(version)
+      ? version
+      : null;
   }

Also applies to: 856-859

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

In `@packages/storage/src/secure-store/secure-store.ts` around lines 773 - 777,
The downgrade protection in secure-store still has gaps because get() can
resolve a legacy path and readExistingEnvelopeVersion() treats malformed v2
envelopes as null. Update the write path in SecureStore’s guarded fallback flow
so it checks both the sanitized fallback path and the legacy path used by get()
before allowing a v1 write, and make readExistingEnvelopeVersion() preserve a
detected v2 envelope even when parsing is malformed instead of returning null.
Keep the fix centered around get(), getFallbackFilePath(), and
readExistingEnvelopeVersion() so v2 files cannot be shadowed by a degraded v1
write.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@packages/storage/src/secure-store/machine-secret.ts`:
- Around line 204-227: The generatePersistAndReread flow in machine-secret.ts
should not return the freshly generated secret unless it has been confirmed
durable by rereading it from the keyring or file. Update the logic in
generatePersistAndReread, persistToKeyring, and persistToFile call handling so
that a post-persist reread returning missing or unusable yields null (or
retries/propagates failure) instead of caching the local secret; only return the
reread winner.secret when readFromKeyring/readFromFile reports found.

In `@packages/storage/src/secure-store/secure-store.ts`:
- Around line 773-777: The downgrade protection in secure-store still has gaps
because get() can resolve a legacy path and readExistingEnvelopeVersion() treats
malformed v2 envelopes as null. Update the write path in SecureStore’s guarded
fallback flow so it checks both the sanitized fallback path and the legacy path
used by get() before allowing a v1 write, and make readExistingEnvelopeVersion()
preserve a detected v2 envelope even when parsing is malformed instead of
returning null. Keep the fix centered around get(), getFallbackFilePath(), and
readExistingEnvelopeVersion() so v2 files cannot be shadowed by a degraded v1
write.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 959ff5cd-6a66-4497-95dd-b0b6a4945e41

📥 Commits

Reviewing files that changed from the base of the PR and between 5e708e4 and 06a814a.

📒 Files selected for processing (4)
  • packages/storage/src/secure-store/machine-secret.test.ts
  • packages/storage/src/secure-store/machine-secret.ts
  • packages/storage/src/secure-store/secure-store.fallback-v2.test.ts
  • packages/storage/src/secure-store/secure-store.ts
📜 Review details
⏰ Context from checks skipped due to timeout. (5)
  • GitHub Check: E2E Test (Linux) - sandbox:docker
  • GitHub Check: E2E Test (Linux) - sandbox:none
  • GitHub Check: Lint (Javascript)
  • GitHub Check: CodeQL
  • GitHub Check: Run LLxprt review
🧰 Additional context used
🧠 Learnings (5)
📚 Learning: 2026-02-06T15:52:42.315Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1305
File: scripts/generate-keybindings-doc.ts:1-5
Timestamp: 2026-02-06T15:52:42.315Z
Learning: In reviews of vybestack/llxprt-code, do not suggest changing existing copyright headers from 'Google LLC' to 'Vybestack LLC' for files that originated from upstream. Preserve upstream copyrights in files that came from upstream, and only apply 'Vybestack LLC' copyright on newly created, original LLxprt files. If a file is clearly LLxprt-original, it may carry the Vybestack header; if it is upstream-originated, keep the original sponsor header.

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

  • packages/storage/src/secure-store/machine-secret.test.ts
  • packages/storage/src/secure-store/secure-store.fallback-v2.test.ts
  • packages/storage/src/secure-store/secure-store.ts
  • packages/storage/src/secure-store/machine-secret.ts
📚 Learning: 2026-06-19T17:16:56.523Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 2108
File: packages/agents/src/api/agentImpl.ts:1047-1079
Timestamp: 2026-06-19T17:16:56.523Z
Learning: When the fake-provider test seam is active in vybestack/llxprt-code, `process.env.LLXPRT_FAKE_RESPONSES` is set to a fixture file path ending in a `.jsonl` (not to the string `'1'` or any other boolean-like value). In code, detect the seam by checking `process.env.LLXPRT_FAKE_RESPONSES !== undefined` (and/or that it is a non-empty string), rather than using `process.env.LLXPRT_FAKE_RESPONSES === '1'`. Update any callers of the env var accordingly (see `packages/providers/src/composition/providerManagerInstance.ts` and harness usages).

Applied to files:

  • packages/storage/src/secure-store/machine-secret.test.ts
  • packages/storage/src/secure-store/secure-store.fallback-v2.test.ts
  • packages/storage/src/secure-store/secure-store.ts
  • packages/storage/src/secure-store/machine-secret.ts
🪛 ast-grep (0.44.0)
packages/storage/src/secure-store/machine-secret.test.ts

[warning] 246-246: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.writeFile(blockerFile, 'x')
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

(detect-non-literal-fs-filename-typescript)


[warning] 523-525: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.writeFile(tempFilePath, preExisting.toString('base64'), {
mode: 0o600,
})
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

(detect-non-literal-fs-filename-typescript)


[warning] 544-544: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.writeFile(tempFilePath, 'not-a-valid-32-byte-secret')
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

(detect-non-literal-fs-filename-typescript)


[warning] 554-554: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.readFile(tempFilePath, 'utf8')
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

(detect-non-literal-fs-filename-typescript)

packages/storage/src/secure-store/secure-store.fallback-v2.test.ts

[warning] 289-289: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.readFile(filePath, 'utf8')
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

(detect-non-literal-fs-filename-typescript)


[warning] 319-319: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.readFile(filePath, 'utf8')
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

(detect-non-literal-fs-filename-typescript)

packages/storage/src/secure-store/machine-secret.ts

[warning] 261-261: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.readFile(filePath, 'utf8')
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

(detect-non-literal-fs-filename-typescript)

🔇 Additional comments (4)
packages/storage/src/secure-store/machine-secret.ts (1)

72-75: LGTM!

Also applies to: 91-128, 165-194, 240-281, 313-330, 347-381

packages/storage/src/secure-store/machine-secret.test.ts (1)

245-257: LGTM!

Also applies to: 439-472, 518-557

packages/storage/src/secure-store/secure-store.ts (1)

92-93: LGTM!

Also applies to: 252-287, 842-849, 862-973

packages/storage/src/secure-store/secure-store.fallback-v2.test.ts (1)

16-16: LGTM!

Also applies to: 278-322

@acoliver

Copy link
Copy Markdown
Collaborator Author

🤖 Automated review — please read this attribution note first.
This comment was generated and posted by the LLxprt Code agent running automated tooling, including the open-code-review (ocr) CLI and a static analysis pass. It is NOT a personal review or opinion by @acoliver. Because the bot posts through the authenticated account, it will appear under that name — please treat the contents below as machine-generated analysis (LLxprt Code + OCR), not as a human statement. I am surfacing it here so the findings are tracked on the PR.


Summary verdict: the fix is genuine ✅

PR #2178 genuinely resolves the root cause of #1986. The original v:1 KDF input (serviceName + '-' + sha256(hostname + username)) was derived entirely from non-secret host metadata, so fallback .enc confidentiality depended solely on filesystem permissions. The new v:2 envelope prepends a 32-byte high-entropy secret (crypto.randomBytes(32)) into the scrypt KDF input, persisted in the OS keyring (preferred) or a 0o600 file. Verified independently:

  • deriveV2KdfInput()machineSecret.toString('hex') + '|' + serviceName + '|' + machineId() — the secret is the dominant entropy source. ✅
  • The secret is generated with crypto.randomBytes(32) and decodeSecret() rejects anything that isn't exactly 32 bytes, so the default production path can never produce an empty/short secret. ✅
  • New writes prefer v:2 (useV2 = machineSecret !== null); v:1 is retained only for backwards-compatible reads and explicit graceful degradation. ✅
  • An anti-downgrade guard refuses to overwrite an existing v:2 file with a weaker v:1 envelope. ✅
  • isValidEnvelope() now also validates the scrypt parameters (N/r/p/saltLen), preventing a tamper/downgrade via envelope field edits. ✅
  • v:2 decryption fails closed (CORRUPT) when the machine secret is unavailable or differs. ✅

"Hide vs. fix" cheat check ✅ (no rule overrides / suppression)

Specifically scanned for ways the problem could be hidden rather than fixed:

  • No eslint-disable, @ts-ignore, @ts-expect-error, @ts-nocheck, noqa, .skip(, .only(, xit, it.todo, or : any anywhere in the diff.
  • No ESLint/tsconfig/biome config or rule-severity changes in this branch (no guardrails weakened).
  • The only as unknown as is one line in envelope.test.ts that deliberately feeds an invalid data field to verify isValidEnvelope rejects it — a legitimate validation test, not suppression.
  • Legacy tests pinning v:1 (via machineSecretLoader: async () => null) are genuine backward-compatibility coverage; the default v:2 path is independently exercised by secure-store-integration.test.ts.
  • The 3 pre-existing .skips in secure-store.fallback.test.ts are not introduced by this branch.
  • All 179 storage tests + the 24 touched agents tests pass.

Conclusion: this is a real fix, not LLM cheating / suppression.

Important findings to consider (not blockers for #1986, but worth tracking)

These are from OCR (15 comments total) plus my own static analysis. They do not reopen #1986; they are hardening/robustness items for this module or follow-ups.

Security / "silent defeat" paths (defense-in-depth)

  1. deriveV2KdfInput() does not validate that machineSecret is non-empty / 32-byte (envelope.ts:97). An empty Buffer would yield a KDF input of '|svc|machineId' — reverting to the exact weakness v:2 was meant to eliminate. Note: the default provider path cannot produce this today (decodeSecret enforces 32 bytes), so this is a contract/defense-in-depth gap, not a live exploit — but a length guard would make the invariant explicit and fail loud.
  2. chmod failure on the machine_secret file is silently swallowed (machine-secret.ts:372, .catch(() => {})). If chmod fails after the atomic rename, the file can retain insecure permissions while persistToFile still returns true. For a file that is the security boundary of the new root-of-trust, a permission failure should fail persistence (return false) or be logged, not hidden.

Correctness / availability

  1. Re-read-after-persist contract violation (machine-secret.ts:214 and :225). If persistToKeyring/persistToFile succeeds but the re-read returns non-found, the code returns the in-memory secret. This contradicts the documented "no caller returns a generated secret unless durably persisted" contract: data encrypted with the transient secret could become unrecoverable on the next process start if a different secret is generated. Recommend returning null (graceful degradation) when the re-read fails.
  2. Cache poisoning on rejection (machine-secret.ts:150). If resolveAndPersist throws, await promise rejects and the cache entry is left as { secret: null, inFlight: <rejected> }, so all future calls permanently re-throw until resetMachineSecretCache() is called. A try/catch that cache.delete(key)s on rejection would allow retry.

TOCTOU

  1. Anti-downgrade guard has a TOCTOU window (secure-store.ts:773). The version is read at line ~776 but the file is replaced via renameWithRetry only at ~821. A concurrent v:2 writer in that window could be silently overwritten by the v:1 rename — the exact downgrade the guard exists to prevent. Low probability in practice (needs concurrent writers + secret unavailable), but a file lock (flock/O_EXCL) or a re-check immediately before rename would close it.

Test-quality gaps (valid, lower priority)

  1. No explicit test that v:1 vs v:2 KDF inputs differ for the same service (envelope.test.ts).
  2. Cross-service isolation test (secure-store.fallback-v2.test.ts:471) overwrites storeA's file with storeB's (same key/dir), so it doesn't actually prove bidirectional service isolation.
  3. No v:2-specific ciphertext-tamper test (GCM integrity). (A v:1 tamper test exists in the integration suite; a v:2 variant would be additive.)
  4. The default-path integration test (secure-store-integration.test.ts:628) asserts v:2 unconditionally, which could be non-deterministic on a machine with a locked keyring, and it does not clean up a real keyring entry it may create.

Maintainability (minor)

  1. Hardcoded offsets 28/44 in the decrypt path (secure-store.ts:936) don't track SALT_LEN like the adjacent lines do; derive them from named IV_LEN/AUTH_TAG_LEN constants.

Related (out of scope for this PR, but the same vulnerability class exists elsewhere)

While verifying "are there others", I found three live, sibling implementations that still derive an AES-256-GCM key from non-secret data with a hard-coded password — the same weakness #1986 describes, but not routed through SecureStore (so they do not benefit from this fix). These store OAuth tokens and tool keys:

  • packages/mcp/src/auth/token-storage/file-token-storage.ts:25crypto.scryptSync('llxprt-cli-oauth', hostname-username, 32)
  • packages/mcp/src/auth/file-token-store.ts:91crypto.scryptSync('llxprt-cli-oauth', hostname:username:serviceName, 32)
  • packages/core/src/tools/tool-key-storage.ts:135crypto.scryptSync('llxprt-cli-tool-keys', hostname-username, 32)

(provider-key-storage.ts and KeyringTokenStore correctly delegate to SecureStore and are already covered.) These are out of scope for this PR but are strong candidates for a follow-up hardening issue using the same machine-secret root-of-trust.


Generated by LLxprt Code (codeanalyzer subagent + open-code-review ocr, 15 automated comments) and an independent static-analysis pass. Tests were included in the review scope. Posted programmatically — not a manual review by @acoliver.

@acoliver
acoliver merged commit d71c47e into main Jun 25, 2026
22 checks passed
Stanley00 pushed a commit to stanley-fork/llxprt-code that referenced this pull request Jun 26, 2026
…et KDF (Fixes vybestack#2187)

Follow-up to PR vybestack#2178 (vybestack#1986). PR vybestack#2178 hardened SecureStore's fallback
encryption with a machine-secret root of trust and a versioned AES-256-GCM
envelope (v:1 legacy host/user KDF, v:2 machine-secret KDF), but three sibling
encrypted file stores bypassed SecureStore and still derived keys from
hard-coded constants plus non-secret host/user metadata.

This migrates the live and reachable siblings onto the same root of trust via a
new shared codec, preserves backward-compatible reads of existing files, and
makes rotation/downgrade failures fail closed.

Phase 1 - shared codec (packages/storage):
- Add secure-store/envelope-codec.ts exposing encryptEnvelopeString,
  decryptEnvelopeString, and readEnvelopeVersion. It is a thin wrapper over the
  existing envelope.ts primitives (scrypt + AES-256-GCM, layout
  [salt][iv][authTag][ciphertext]) and introduces no new crypto parameters.
  Centralizes v:1/v:2 selection, the anti-downgrade guard, and fail-closed
  decrypt (EnvelopeCodecError).
- Export the codec from the barrel and add a deep sub-path export
  (./storage/envelope-codec.js) so core and mcp can import it without crossing
  the import-boundary guard.

Phase 2 - ToolKeyStorage live .key fallback (packages/core):
- Route saveToFile/getFromFile through the codec: new writes are v:2 envelopes
  when the machine secret is available; legacy iv:authTag:ciphertext files
  still decrypt; a v:2 file with a missing/rotated secret fails closed instead
  of being misread as "no key configured"; unrecognized content fails closed.

Phase 3 - FileTokenStorage MCP fallback (packages/mcp):
- Route loadTokens/saveTokens through the codec with the same v:2/legacy/
  anti-downgrade/fail-closed semantics, mapping codec errors to the existing
  "Token file corrupted" behavior.

Phase 4 - deprecate the dead store:
- Mark FileTokenStore (file-token-store.ts) @deprecated; it has no production
  instantiation and is retained only for public-API/backward-compatible reads.

Tests:
- New behavioral tests (real temp-dir files, injected machine-secret loaders)
  prove v:2 writes use the secret root of trust, legacy data stays readable,
  and downgrade/rotation failures fail closed across all touched stores.
- Update the three vitest storageExportToSource alias maps for the new
  sub-path export.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Harden secure-store fallback encryption: KDF input derived from non-secret host metadata

1 participant