Skip to content

Harden sibling encrypted file stores with machine-secret KDF (Fixes #2187) - #2188

Merged
acoliver merged 10 commits into
mainfrom
issue2187
Jun 26, 2026
Merged

Harden sibling encrypted file stores with machine-secret KDF (Fixes #2187)#2188
acoliver merged 10 commits into
mainfrom
issue2187

Conversation

@acoliver

Copy link
Copy Markdown
Collaborator

Summary

Fixes #2187. Follow-up to PR #2178 (#1986).

PR #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-metadata KDF, v:2 = machine-secret-backed KDF). However, three sibling encrypted file stores bypassed SecureStore entirely and still derived AES-256-GCM keys from hard-coded constants plus non-secret host/user metadata — i.e. confidentiality depended on filesystem permissions and predictable metadata rather than a high-entropy secret.

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

What changed

Phase 1 — Shared envelope codec (packages/storage)

  • New secure-store/envelope-codec.ts exposing encryptEnvelopeString, decryptEnvelopeString, and readEnvelopeVersion.
  • It is a thin wrapper over the existing envelope.ts primitives (deriveV1KdfInput, deriveV2KdfInput, isValidEnvelope, scryptAsync, SCRYPT_PARAMS, SALT_LEN) — no new crypto parameters. Same on-disk layout [salt][iv][authTag][ciphertext], scrypt + AES-256-GCM.
  • Centralizes the three behaviors already proven inside SecureStore: v:1/v:2 version selection, the anti-downgrade guard (never overwrite an existing v:2 with a weaker v:1 when the machine secret is unavailable), and fail-closed decrypt (EnvelopeCodecError).
  • Exported from the barrel plus 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) — prioritized

This is the only path live in production today (used whenever the OS keyring is unavailable), so it is addressed first.

  • saveToFile/getFromFile now route through the codec. New writes are v:2 envelopes when the machine secret is available.
  • Existing legacy iv:authTag:ciphertext .key files still decrypt (positively recognized via a strict hex-colon matcher).
  • A v:2 file whose machine secret is missing/rotated now fails closed (throws) instead of being silently misread as "no key configured". Unrecognized/garbage content also fails closed.

Phase 3 — FileTokenStorage MCP fallback (packages/mcp)

  • loadTokens/saveTokens route through the codec with the same v:2 / legacy-read / anti-downgrade / fail-closed semantics, mapping codec failures to the existing Token file corrupted behavior.

Phase 4 — Deprecate the dead store

  • FileTokenStore (file-token-store.ts) is marked @deprecated. It has no production instantiation and is retained only for public-API compatibility and backward-compatible reads, directing consumers to HybridTokenStorage / FileTokenStorage.

Tests

  • New behavioral tests use real temp-dir files and injected machine-secret loaders (no mock theater) proving, across every touched store:
    1. new writes use the secret root of trust (valid v:2 envelope, not the legacy hex:hex:hex string),
    2. legacy data remains readable,
    3. downgrade/rotation failures fail closed (missing-secret v:2 reads throw; anti-downgrade refuses a v:1 overwrite of an existing v:2).
  • Updated the three vitest.config.ts storageExportToSource alias maps for the new sub-path export.

Verification

  • npm run format, npm run typecheck, npm run lint, npm run lint:eslint-guard, npm run build — all green.
  • New/changed test suites: storage codec, mcp file-token-storage, core tool-key-storage — all green.
  • Smoke test (node scripts/start.js --profile-load ollamakimi) — green.

Note on pre-existing flakes

A handful of packages/core/src/utils/filesearch/ tests (crawler.test.ts, fileSearch.directory.test.ts) are flaky under worker co-location due to a module-global cache shared between two test files. This is pre-existing and unrelated to this change — it reproduces identically on a pristine origin/main worktree with none of these changes applied, and main CI is green. Not touched here.

…et KDF (Fixes #2187)

Follow-up to PR #2178 (#1986). PR #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.
@github-actions github-actions Bot added the maintainer:e2e:ok Trusted contributor; maintainer-approved E2E run label Jun 26, 2026
@github-actions

github-actions Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

No description provided.

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@acoliver, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 10 minutes and 33 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: f960e496-2149-40c8-98d7-c0ae962ff74f

📥 Commits

Reviewing files that changed from the base of the PR and between 937c045 and 73576b5.

📒 Files selected for processing (1)
  • package.json

Walkthrough

Adds a shared versioned envelope codec, updates machine-secret handling, and switches ToolKeyStorage and FileTokenStorage to envelope-based writes while preserving legacy hex-colon reads and tightening permissions.

Changes

Envelope-backed storage hardening

Layer / File(s) Summary
Shared codec surface
packages/storage/src/secure-store/envelope-codec.ts, packages/storage/src/index.ts, packages/storage/package.json, packages/cli/vitest.config.ts, packages/providers/vitest.config.ts, packages/settings/vitest.config.ts
Adds the shared envelope codec module, re-exports its public surface, and wires package and Vitest resolution for the new storage subpath.
Machine secret read-only path
packages/storage/src/secure-store/machine-secret.ts, packages/storage/src/secure-store/machine-secret.test.ts
Adds a read-only machine-secret option, updates cache resolution for non-generating reads, and covers null-return behavior without persistence.
ToolKeyStorage migration
packages/core/src/tools/tool-key-storage.ts, packages/core/src/tools/tool-key-storage.test.ts
Updates ToolKeyStorage to accept machine-secret options, write envelope files, and read v:2 envelopes or legacy hex-colon files with fail-closed corruption handling.
FileTokenStorage migration
packages/mcp/src/auth/file-token-store.ts, packages/mcp/src/auth/token-storage/file-token-storage.ts
Updates FileTokenStorage construction and docs, and switches token reads and writes to versioned envelopes while retaining legacy decrypt compatibility.
FileTokenStorage tests
packages/mcp/src/auth/token-storage/file-token-storage.behavior.test.ts, packages/mcp/src/auth/token-storage/file-token-storage.test.ts
Reworks token-storage behavior tests to assert v2 envelopes, legacy hex-colon reads, anti-downgrade behavior, permission tightening, and CRUD operations.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • vybestack/llxprt-code#2178: Introduces the shared envelope-based storage flow that this PR applies to sibling token and key storage paths.
  • vybestack/llxprt-code#1316: Touches packages/core/src/tools/tool-key-storage.ts, which is updated here to use the envelope codec.
  • vybestack/llxprt-code#736: Relates to FileTokenStorage read-path handling around missing files and stored credentials.

Suggested labels

maintainer:e2e:ok

Poem

A rabbit found a glowing key,
Wrapped safe in v2 secrecy.
Old hex paths still know the way,
But stricter paws now guard the tray.
Hop hop — the envelopes softly hum,
And little secrets stay more snug. 🐇

🚥 Pre-merge checks | ✅ 3 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The a2a-server tsconfig lib tweak is unrelated to the sibling encrypted file store hardening work. Remove the a2a-server tsconfig change unless it is required by a documented dependency for this PR.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: hardening sibling encrypted file stores with a machine-secret-backed KDF.
Description check ✅ Passed The description is substantive and covers summary, changes, tests, and linked issue context, though it omits some template sections.
Linked Issues check ✅ Passed The PR addresses #2187 by adding a shared envelope codec, migrating the live and reachable stores, preserving legacy reads, and deprecating dead code.
📋 Issue Planner

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

View plan used: #2187

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

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

@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: 4

🤖 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/core/src/tools/tool-key-storage.ts`:
- Line 234: The key write path in tool-key-storage’s save logic only sets mode
on creation, so existing .key files may keep broader permissions after being
overwritten. Update the write flow around the fs.writeFile call in the key
persistence method to explicitly apply a restrictive chmod on filePath after
writing, ensuring migrated or updated keys remain private.
- Around line 219-233: In the tool-key storage write path, the existing envelope
version check is too permissive because tool-key-storage.ts treats a null result
from readEnvelopeVersion(existing) as if no prior file existed. Update the logic
around the existingVersion handling in this flow so malformed or tampered
envelopes fail closed instead of being overwritten; only pass a version into
encryptEnvelopeString when the parsed version is valid, and otherwise reject the
write or surface an error rather than downgrading an existing file.

In `@packages/mcp/src/auth/token-storage/file-token-storage.ts`:
- Around line 132-145: The legacy decrypt path in `FileTokenStorage` still lets
raw crypto errors escape from `this.decrypt(data)` for malformed
`iv:authTag:ciphertext` input. Update the catch in the legacy plaintext load
flow to normalize every exception from `this.decrypt(data)` to `Token file
corrupted`, and keep the existing behavior for the current encrypted format
separate if needed. Add a regression test around `FileTokenStorage` for
malformed legacy content (for example invalid IV or auth tag lengths) to verify
it now fails closed with `Token file corrupted`.

In `@packages/storage/src/secure-store/envelope-codec.ts`:
- Around line 121-133: The default loader path in
defaultMachineSecretLoader()/resolveLoader currently uses getMachineSecret() for
both encrypt and decrypt, which can generate a new machine secret during v:2
reads. Split the behavior so decryptEnvelopeString() only loads an existing
secret and fails closed when missing or rotated, while generate-on-miss remains
limited to write/encrypt paths; update the loader selection in resolveLoader to
use the non-generating path for decrypt and preserve the existing write
behavior.
🪄 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: f60593e5-9867-4ffb-9a60-3cfae6bdad65

📥 Commits

Reviewing files that changed from the base of the PR and between d71c47e and 3abc2c2.

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

Applied to files:

  • packages/mcp/src/auth/file-token-store.ts
  • packages/storage/src/index.ts
  • packages/settings/vitest.config.ts
  • packages/cli/vitest.config.ts
  • packages/providers/vitest.config.ts
  • packages/mcp/src/auth/token-storage/file-token-storage.behavior.test.ts
  • packages/storage/src/secure-store/envelope-codec.test.ts
  • packages/mcp/src/auth/token-storage/file-token-storage.ts
  • packages/storage/src/secure-store/envelope-codec.ts
  • packages/core/src/tools/tool-key-storage.test.ts
  • packages/core/src/tools/tool-key-storage.ts
  • packages/mcp/src/auth/token-storage/file-token-storage.test.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/mcp/src/auth/file-token-store.ts
  • packages/storage/src/index.ts
  • packages/settings/vitest.config.ts
  • packages/cli/vitest.config.ts
  • packages/providers/vitest.config.ts
  • packages/mcp/src/auth/token-storage/file-token-storage.behavior.test.ts
  • packages/storage/src/secure-store/envelope-codec.test.ts
  • packages/mcp/src/auth/token-storage/file-token-storage.ts
  • packages/storage/src/secure-store/envelope-codec.ts
  • packages/core/src/tools/tool-key-storage.test.ts
  • packages/core/src/tools/tool-key-storage.ts
  • packages/mcp/src/auth/token-storage/file-token-storage.test.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/mcp/src/auth/file-token-store.ts
  • packages/storage/src/index.ts
  • packages/settings/vitest.config.ts
  • packages/cli/vitest.config.ts
  • packages/providers/vitest.config.ts
  • packages/mcp/src/auth/token-storage/file-token-storage.behavior.test.ts
  • packages/storage/src/secure-store/envelope-codec.test.ts
  • packages/mcp/src/auth/token-storage/file-token-storage.ts
  • packages/storage/src/secure-store/envelope-codec.ts
  • packages/core/src/tools/tool-key-storage.test.ts
  • packages/core/src/tools/tool-key-storage.ts
  • packages/mcp/src/auth/token-storage/file-token-storage.test.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/mcp/src/auth/file-token-store.ts
  • packages/storage/src/index.ts
  • packages/settings/vitest.config.ts
  • packages/cli/vitest.config.ts
  • packages/providers/vitest.config.ts
  • packages/mcp/src/auth/token-storage/file-token-storage.behavior.test.ts
  • packages/storage/src/secure-store/envelope-codec.test.ts
  • packages/mcp/src/auth/token-storage/file-token-storage.ts
  • packages/storage/src/secure-store/envelope-codec.ts
  • packages/core/src/tools/tool-key-storage.test.ts
  • packages/core/src/tools/tool-key-storage.ts
  • packages/mcp/src/auth/token-storage/file-token-storage.test.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/mcp/src/auth/file-token-store.ts
  • packages/storage/src/index.ts
  • packages/mcp/src/auth/token-storage/file-token-storage.behavior.test.ts
  • packages/storage/src/secure-store/envelope-codec.test.ts
  • packages/mcp/src/auth/token-storage/file-token-storage.ts
  • packages/storage/src/secure-store/envelope-codec.ts
  • packages/core/src/tools/tool-key-storage.test.ts
  • packages/core/src/tools/tool-key-storage.ts
  • packages/mcp/src/auth/token-storage/file-token-storage.test.ts
📚 Learning: 2026-02-16T16:11:07.481Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1434
File: packages/core/src/tools/delete_line_range.ts:204-254
Timestamp: 2026-02-16T16:11:07.481Z
Learning: Identify duplicated LSP diagnostics collection logic across packages/core/src/tools/*.ts. In reviews, flag the common block (checkFile, filter by includeSeverities, limit by maxDiagnosticsPerFile, format with <diagnostics> tags) that is replicated in six files (ast-edit.ts, delete_line_range.ts, insert_at_line.ts, edit.ts, write-file.ts, apply-patch.ts). Recommend extracting into a shared helper (e.g., collectLspDiagnosticsBlock) and ensure it handles Promise.race timeout and uses the correct severities label instead of a hardcoded "LSP errors". This guideline applies to all files in that directory and similar tools unless explicitly excluded.

Applied to files:

  • packages/core/src/tools/tool-key-storage.test.ts
  • packages/core/src/tools/tool-key-storage.ts
📚 Learning: 2026-06-24T07:45:19.981Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 2146
File: packages/core/src/tools-adapters/CoreSubagentServiceAdapter.ts:299-300
Timestamp: 2026-06-24T07:45:19.981Z
Learning: In this repo, follow the "unnecessary-condition" lint policy: if a value is already typed as non-optional (e.g., `SubagentManager.loadSubagent(...)` returns `SubagentConfig`, not `SubagentConfig | undefined`), do not add defensive conditional guards like `loaded ? ... : undefined` before passing the value into helpers (e.g., `toToolsSubagentConfig(loaded)`). Passing the non-optional value directly is the correct pattern; adding such branches is considered dead code and should be avoided so the lint passes.

Applied to files:

  • packages/core/src/tools/tool-key-storage.test.ts
  • packages/core/src/tools/tool-key-storage.ts
🪛 ast-grep (0.44.0)
packages/mcp/src/auth/token-storage/file-token-storage.behavior.test.ts

[warning] 102-102: 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(tokenFilePath, 'utf-8')
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

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


[warning] 205-205: 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(tokenFilePath, legacyContent, { mode: 0o600 })
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

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


[warning] 224-224: 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(tokenFilePath, 'utf-8')
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

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


[warning] 241-241: 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(tokenFilePath, 'utf-8')
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

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

packages/mcp/src/auth/token-storage/file-token-storage.ts

[warning] 101-101: 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(this.tokenFilePath, 'utf-8')
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

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


[warning] 167-167: 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(this.tokenFilePath, 'utf-8')
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

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

packages/core/src/tools/tool-key-storage.test.ts

[warning] 359-359: 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, 'utf-8')
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

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


[warning] 465-465: 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(filePath, legacyContent, { mode: 0o600 })
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

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


[warning] 486-488: 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(filePath, 'this-is-not-a-valid-key-file', {
mode: 0o600,
})
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

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


[warning] 515-515: 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(filePath, bogusLegacy, { mode: 0o600 })
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

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


[warning] 537-537: 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, 'utf-8')
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

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


[warning] 552-552: 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, 'utf-8')
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

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

packages/core/src/tools/tool-key-storage.ts

[warning] 220-220: 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, 'utf-8')
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

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


[warning] 233-233: 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(filePath, envelopeJson, { mode: 0o600 })
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

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


[warning] 253-253: 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, 'utf-8')
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

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

🔇 Additional comments (2)
packages/core/src/tools/tool-key-storage.ts (1)

32-37: LGTM!

Also applies to: 96-110, 132-149, 160-171, 237-293

packages/core/src/tools/tool-key-storage.test.ts (1)

17-25: LGTM!

Also applies to: 35-35, 82-116, 351-367, 406-561

Comment thread packages/core/src/tools/tool-key-storage.ts
Comment thread packages/core/src/tools/tool-key-storage.ts
Comment thread packages/mcp/src/auth/token-storage/file-token-storage.ts
Comment thread packages/storage/src/secure-store/envelope-codec.ts
@github-actions

github-actions Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Summary

Package Lines Statements Functions Branches
CLI 56.54% 56.54% 58.47% 82.16%
Core 76.89% 76.89% 74.28% 83.49%
CLI Package - Full Text Report
-------------------|---------|----------|---------|---------|-------------------
File               | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-------------------|---------|----------|---------|---------|-------------------
All files          |   56.54 |    82.16 |   58.47 |   56.54 |                   
 src               |    73.2 |    66.39 |   87.77 |    73.2 |                   
  cli.tsx          |   59.34 |    76.19 |   71.42 |   59.34 | ...28,655,663-682 
  cliBootstrap.tsx |   68.22 |    55.55 |   89.65 |   68.22 | ...18,821-825,830 
  ...nBootstrap.ts |   71.58 |    63.63 |   83.33 |   71.58 | ...49-259,264-265 
  ...st-helpers.ts |     100 |       60 |     100 |     100 | 23-34             
  ...ractiveCli.ts |    90.4 |     84.9 |   86.66 |    90.4 | ...03-208,281-283 
  ...liCommands.ts |   97.22 |       70 |     100 |   97.22 | 40-41             
  ...CliSupport.ts |   80.26 |    64.42 |      95 |   80.26 | ...79-481,503-504 
  ...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 |   73.98 |    92.93 |   67.18 |   73.98 |                   
  config.ts        |   93.93 |    91.83 |     100 |   93.93 | ...72-173,204-209 
  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.06 |      100 |       0 |   10.06 | ...73-192,194-199 
  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.18 |      100 |       0 |    7.18 |                   
  migrate.ts       |    7.18 |      100 |       0 |    7.18 | ...00-210,212-214 
 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        |   87.88 |    85.61 |   88.54 |   87.88 |                   
  ...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  |   93.36 |    91.11 |     100 |   93.36 | ...22-223,286-289 
  config.ts        |     100 |      100 |     100 |     100 |                   
  configBuilder.ts |   95.53 |    95.52 |   66.66 |   95.53 | ...19-220,261-262 
  ...mentLoader.ts |    82.9 |    53.84 |     100 |    82.9 | ...29-131,139-142 
  extension.ts     |   74.85 |    88.38 |   79.06 |   74.85 | ...28-929,932-933 
  ...iveContext.ts |   93.75 |    91.66 |     100 |   93.75 | 79,81,87-92,232   
  ...iateConfig.ts |   96.46 |    96.96 |     100 |   96.46 | 54,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 | 45-49             
  ...figRuntime.ts |   89.73 |    88.46 |     100 |   89.73 | ...47-454,465-468 
  ...eBootstrap.ts |   91.79 |    87.42 |     100 |   91.79 | ...04-806,815-816 
  ...Resolution.ts |   78.66 |    76.74 |     100 |   78.66 | ...87-290,303-311 
  ...pplication.ts |   92.12 |       80 |     100 |   92.12 | ...,92-93,109,176 
  ...elResolver.ts |    93.1 |    81.25 |     100 |    93.1 | 41,43-44,80       
  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.99 |    80.62 |     100 |   86.99 | ...02,404,406,408 
  settings.ts      |   82.97 |    85.84 |   69.23 |   82.97 | ...66-467,514-515 
  ...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.16 |    91.17 |     100 |   95.16 | 47-48,129-132     
  ...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.28 |     84.5 |   87.38 |   76.28 |                   
  consent.ts       |   88.03 |    85.71 |     100 |   88.03 | ...76-377,380-381 
  ...ionConsent.ts |   87.38 |    76.66 |     100 |   87.38 | ...,64-67,113-116 
  ...Enablement.ts |   94.02 |       96 |     100 |   94.02 | ...15-221,284-286 
  ...sionLoader.ts |   91.92 |    88.46 |     100 |   91.92 | ...20-221,229-233 
  ...onSettings.ts |     100 |      100 |     100 |     100 |                   
  github.ts        |   61.73 |    81.73 |      68 |   61.73 | ...49-650,660-663 
  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 |   85.57 |    77.19 |     100 |   85.57 | ...05-306,324-327 
  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 
 ...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      |   85.69 |       85 |   94.87 |   85.69 |                   
  ...mandLoader.ts |   79.75 |    73.33 |      80 |   79.75 | ...10-124,168-186 
  ...andService.ts |     100 |      100 |     100 |     100 |                   
  ...mandLoader.ts |   91.91 |    86.27 |     100 |   91.91 | ...11-216,303-310 
  ...omptLoader.ts |    67.5 |    68.96 |     100 |    67.5 | ...75,181-187,202 
  ...tArgParser.ts |     100 |    94.28 |     100 |     100 | 42,72             
  performResume.ts |   89.11 |    89.18 |     100 |   89.11 | ...59-262,268-269 
  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 | 78-79,263-264     
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...o-continuation |   86.84 |    84.09 |   94.73 |   86.84 |                   
  ...ionService.ts |   86.84 |    84.09 |   94.73 |   86.84 | ...16,583,609-610 
 src/test-utils    |    76.6 |    81.96 |   37.87 |    76.6 |                   
  assertions.ts    |   76.47 |       50 |     100 |   76.47 | ...40,49-50,59-60 
  async.ts         |       0 |        0 |       0 |       0 | 1-34              
  ...eExtension.ts |     100 |      100 |     100 |     100 |                   
  ...omMatchers.ts |   22.22 |      100 |       0 |   22.22 | 19-49             
  inkFrame.ts      |      65 |    66.66 |   66.66 |      65 | 31-32,40-44       
  ...andContext.ts |     100 |      100 |     100 |     100 |                   
  regex.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            |   38.21 |    93.65 |   32.14 |   38.21 |                   
  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 |                   
  ...lobalState.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.27 |     76.7 |   77.16 |   71.27 |                   
  aboutCommand.ts  |   82.84 |    51.51 |   91.66 |   82.84 | ...92-193,195-196 
  authCommand.ts   |   50.36 |     78.2 |    62.5 |   50.36 | ...69-672,683-725 
  ...urlCommand.ts |      30 |      100 |       0 |      30 | 20-40             
  bugCommand.ts    |   71.23 |    30.76 |     100 |   71.23 | ...99-110,145-153 
  chatCommand.ts   |   69.89 |    74.62 |   66.66 |   69.89 | ...42-543,591-602 
  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.81 |      100 |       0 |   13.81 | ...52,459,466,473 
  ...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 | ...27-135,202-210 
  docsCommand.ts   |     100 |      100 |     100 |     100 |                   
  ...extCommand.ts |   96.22 |    89.65 |     100 |   96.22 | 220-225           
  editorCommand.ts |     100 |      100 |     100 |     100 |                   
  ...onsCommand.ts |   41.27 |    88.09 |    62.5 |   41.27 | ...23-380,390-538 
  ...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.76 |    71.42 |   66.66 |   80.76 | 37-41,43-90       
  keyCommand.ts    |   90.05 |    80.76 |     100 |   90.05 | ...97,420-421,520 
  ...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    |    93.8 |    85.36 |     100 |    93.8 | 43,95-100         
  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   |   52.08 |       60 |    87.5 |   52.08 | ...45,172,183-187 
  ...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 |   60.49 |    33.33 |     100 |   60.49 | ...94-295,304-309 
  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  |   79.89 |    77.41 |     100 |   79.89 | ...75-183,244-251 
  ...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.93 |    77.77 |   95.23 |   85.93 | ...71-372,410-424 
  ...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.66 |    76.47 |     100 |   86.66 | ...62,295,326-327 
  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.59 |   94.11 |   96.06 |                   
  index.ts         |   95.84 |    91.66 |     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 |   12.17 |    39.07 |    7.69 |   12.17 |                   
  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.71 |      100 |       0 |    4.71 | ...39-264,267-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     |     8.1 |      100 |       0 |     8.1 | 17-32,45-100      
  ...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-222 
  ...esDisplay.tsx |   10.52 |      100 |       0 |   10.52 | 24-82             
  ...ogManager.tsx |    5.66 |      100 |       0 |    5.66 | 71-803,807-831    
  ...ngsDialog.tsx |   12.56 |      100 |       0 |   12.56 | ...48-172,176-247 
  ...rBoundary.tsx |   10.07 |        0 |       0 |   10.07 | ...26-171,189-204 
  ...ustDialog.tsx |   16.34 |      100 |       0 |   16.34 | ...2,70-81,84-143 
  Footer.tsx       |   11.64 |        0 |       0 |   11.64 | ...92-696,700-769 
  ...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 | 53-237,240-278    
  ...usDisplay.tsx |       0 |        0 |       0 |       0 | 1-47              
  InputPrompt.tsx  |     100 |       75 |     100 |     100 | 45                
  ...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 |   14.92 |      100 |       0 |   14.92 | 21-25,35-97       
  ...ingDialog.tsx |    6.68 |      100 |       0 |    6.68 | ...66-383,387-436 
  ...geDisplay.tsx |       0 |        0 |       0 |       0 | 1-41              
  ModelDialog.tsx  |    3.82 |      100 |       0 |    3.82 | ...79-752,756-842 
  ...tsDisplay.tsx |    3.82 |      100 |       0 |    3.82 | 32-205,208-259    
  ...fications.tsx |   17.32 |      100 |       0 |   17.32 | ...09-140,143-178 
  ...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.34 |      100 |       0 |    4.34 | ...66-552,555-630 
  ...istDialog.tsx |     4.5 |      100 |       0 |     4.5 | ...93-530,533-619 
  ...derDialog.tsx |    2.58 |      100 |       0 |    2.58 | 58-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 |    9.75 |      100 |       0 |    9.75 | 29-105            
  ...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        |    6.77 |      100 |       0 |    6.77 | 31-36,39-99       
  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    
  ...romptHooks.ts |   87.61 |    65.51 |     100 |   87.61 | ...39-343,359-366 
  ...eyHandlers.ts |   24.33 |    33.33 |      50 |   24.33 | ...75-577,581-606 
  ...mptRender.tsx |   53.05 |     31.7 |   72.72 |   53.05 | ...02,314-322,343 
  ...PromptText.ts |   31.08 |    55.55 |   28.57 |   31.08 | ...25-175,179-199 
  ...romptTypes.ts |     100 |      100 |     100 |     100 |                   
  ...logActions.ts |    2.59 |      100 |       0 |    2.59 | ...92-562,565-602 
  ...logDisplay.ts |    4.28 |      100 |       0 |    4.28 | 25-120,125-184    
  ...logHelpers.ts |    7.64 |      100 |       0 |    7.64 | ...76-194,201-214 
  ...ialogHooks.ts |     2.8 |      100 |       0 |     2.8 | ...98-599,632-807 
  ...ogKeypress.ts |    1.69 |      100 |       0 |    1.69 | 34-386,481-678    
  ...ialogTypes.ts |       0 |        0 |       0 |       0 | 1                 
  ...alogViews.tsx |    4.13 |      100 |       0 |    4.13 | 31-133,167-378    
  todo-utils.ts    |       0 |        0 |       0 |       0 | 1-7               
 ...leCreateWizard |   18.54 |       50 |       0 |   18.54 |                   
  ...aramsStep.tsx |   13.42 |      100 |       0 |   13.42 | ...33-246,258-342 
  ...ationStep.tsx |    7.23 |      100 |       0 |    7.23 | ...35-571,583-651 
  ...onfigStep.tsx |   13.33 |      100 |       0 |   13.33 | 20-26,37-117      
  ...electStep.tsx |    9.73 |      100 |       0 |    9.73 | ...12-279,295-340 
  ...ationMenu.tsx |       0 |        0 |       0 |       0 | 1-102             
  ...eSaveStep.tsx |    7.73 |      100 |       0 |    7.73 | ...75-304,316-394 
  ...ssSummary.tsx |   12.12 |      100 |       0 |   12.12 | 23-88             
  ...electStep.tsx |   18.18 |      100 |       0 |   18.18 | 29-96             
  TextInput.tsx    |    6.56 |      100 |       0 |    6.56 | ...99-109,117-200 
  constants.ts     |     100 |      100 |     100 |     100 |                   
  index.tsx        |   14.17 |      100 |       0 |   14.17 | ...97-226,235-319 
  types.ts         |     100 |      100 |     100 |     100 |                   
  utils.ts         |    5.05 |      100 |       0 |    5.05 | ...58-360,365-382 
  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-146     
  ...tEditForm.tsx |    1.77 |      100 |       0 |    1.77 | 30-619,622-640    
  ...tListMenu.tsx |    2.94 |      100 |       0 |    2.94 | 15-264,267-348    
  ...tMainMenu.tsx |   16.66 |      100 |       0 |   16.66 | 22-62             
  ...gerDialog.tsx |    2.39 |      100 |       0 |    2.39 | 29-600,603-679    
  ...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.85 |       90 |   15.06 |   18.85 |                   
  ...onMessage.tsx |   12.28 |      100 |       0 |   12.28 | 24-86             
  DiffRenderer.tsx |    3.59 |      100 |       0 |    3.59 | ...81-412,415-433 
  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  |   17.24 |      100 |       0 |   17.24 | 19-44             
  ...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.04 |      100 |       0 |    3.04 | 38-554,559-638    
  ...upMessage.tsx |    7.42 |      100 |       0 |    7.42 | ...75-273,277-352 
  ToolMessage.tsx  |    4.37 |      100 |       0 |    4.37 | 38-342,358-428    
  ...ltDisplay.tsx |   92.03 |    88.23 |     100 |   92.03 | 55-69,238-240     
  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 |    23.8 |      100 |       0 |    23.8 | 17-34             
 ...ponents/shared |   40.93 |     63.4 |   40.34 |   40.93 |                   
  ...ctionList.tsx |    4.31 |      100 |       0 |    4.31 | 36-123,128-206    
  MaxSizedBox.tsx  |    50.2 |    57.33 |   76.47 |    50.2 | ...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.81 |      100 |       0 |    3.81 | ...70-795,798-835 
  ...lizedList.tsx |   11.49 |      100 |       0 |   11.49 | 28-112            
  ...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 |   42.85 |    71.42 |      80 |   42.85 | ...32-139,163-209 
  ...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 |    72.34 |     100 |    90.2 | ...48-350,372-373 
  ...navigation.ts |   53.38 |    61.53 |   73.68 |   53.38 | ...45-366,389-411 
 ...mponents/views |    9.79 |      100 |       0 |    9.79 |                   
  ChatList.tsx     |   20.58 |      100 |       0 |   20.58 | 24-55             
  ...sionsList.tsx |     7.5 |      100 |       0 |     7.5 | 19-103            
  HooksList.tsx    |   10.67 |      100 |       0 |   10.67 | ...18-129,132-147 
  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-361             
  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 | 20-21             
  ...ateBuilder.ts |   66.66 |      100 |       0 |   66.66 | 20-21             
 ...ontainer/hooks |   55.22 |     87.1 |   56.52 |   55.22 |                   
  ...pBootstrap.ts |   94.71 |    58.33 |     100 |   94.71 | ...20-223,227-229 
  useAppDialogs.ts |   41.37 |      100 |   42.85 |   41.37 | ...63,182-397,417 
  ...ntHandlers.ts |     100 |      100 |     100 |     100 |                   
  useAppInput.ts   |     5.8 |      100 |       0 |     5.8 | 101-517,520-524   
  useAppLayout.ts  |    7.92 |      100 |       0 |    7.92 | 92-299,302-305    
  ...reenAction.ts |   13.63 |      100 |       0 |   13.63 | 23-41             
  ...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 | 130-138,142       
  ...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,166            
  ...yBootstrap.ts |      30 |      100 |       0 |      30 | 28-34             
  ...eybindings.ts |   86.28 |    78.18 |     100 |   86.28 | ...04-206,250-251 
  ...easurement.ts |   15.38 |      100 |       0 |   15.38 | 45-95             
  ...reshAction.ts |   79.16 |     37.5 |     100 |   79.16 | 51,81-84,86-95    
  ...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.28 |       80 |   54.34 |   56.28 |                   
  ...chContext.tsx |   88.23 |    66.66 |     100 |   88.23 | 27-28             
  FocusContext.tsx |       0 |        0 |       0 |       0 | 1-11              
  ...ssContext.tsx |   83.41 |    87.89 |    87.5 |   83.41 | ...22-523,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 |    91.8 |    74.62 |     100 |    91.8 | ...94-495,507-508 
  ...onContext.tsx |     4.4 |      100 |       0 |     4.4 | ...38-393,398-405 
  ...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.35 |      100 |       0 |    3.35 | 27-166,169-199    
  ...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.37 |     85.9 |   72.16 |   68.37 |                   
  ...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.84 |    78.57 |   88.88 |   78.84 | ...22-823,851-857 
  ...etionUtils.ts |   53.36 |    88.23 |   64.28 |   53.36 | 57-207,335        
  index.ts         |       0 |        0 |       0 |       0 | 1-9               
  keyToAnsi.ts     |    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 | ...71-272,404-408 
  ...ndHandlers.ts |   17.54 |    27.27 |   22.22 |   17.54 | ...45-646,651-660 
  ...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 | ...81-284,302-309 
  ...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 |   92.52 |    89.65 |     100 |   92.52 | ...02-603,606-607 
  ...uthCommand.ts |   96.42 |    66.66 |     100 |   96.42 | 21                
  ...tIndicator.ts |     100 |     92.3 |     100 |     100 | 57                
  useBanner.ts     |     100 |    83.33 |     100 |     100 | 22,48             
  ...chedScroll.ts |   16.66 |      100 |       0 |   16.66 | 14-32             
  ...ketedPaste.ts |      20 |      100 |       0 |      20 | 20-38             
  ...ompletion.tsx |   97.24 |    82.75 |    90.9 |   97.24 | ...04-206,209-210 
  useCompletion.ts |    92.4 |     87.5 |     100 |    92.4 | 68-69,93-94,98-99 
  ...leMessages.ts |   96.15 |       90 |     100 |   96.15 | 56-57,63          
  ...ntHandlers.ts |   31.25 |      100 |     100 |   31.25 | 43-70,74-82       
  ...fileDialog.ts |   16.12 |      100 |       0 |   16.12 | 17-47             
  ...orSettings.ts |   11.86 |      100 |       0 |   11.86 | 31-87             
  ...AutoUpdate.ts |    8.33 |      100 |       0 |    8.33 | 18-64             
  ...ionUpdates.ts |   75.17 |    80.64 |   77.77 |   75.17 | ...60-261,289-303 
  ...erDetector.ts |     100 |      100 |     100 |     100 |                   
  useFocus.ts      |     100 |      100 |     100 |     100 |                   
  ...olderTrust.ts |   87.09 |     91.3 |     100 |   87.09 | 50-63,135-136     
  ...st-helpers.ts |     100 |      100 |     100 |     100 |                   
  ...BranchName.ts |     100 |    89.47 |     100 |     100 | 58,61             
  ...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 | 51-378,381-427    
  ...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.68 |    83.33 |   73.52 |   75.68 | ...25,641-657,814 
  ...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 |     89.1 |     100 |   89.78 | ...17-423,443-447 
  useSession.ts    |       0 |        0 |       0 |       0 | 1-23              
  ...ionBrowser.ts |     100 |      100 |     100 |     100 |                   
  ...serHelpers.ts |   95.79 |    85.21 |   97.36 |   95.79 | ...37-639,762-763 
  ...erKeypress.ts |   89.87 |    97.26 |   94.11 |   89.87 | 101-108,130-145   
  ...ngsCommand.ts |   18.75 |      100 |       0 |   18.75 | 10-25             
  ...hallowMemo.ts |      10 |      100 |       0 |      10 | 9-22,35-47        
  ...ellHistory.ts |   92.17 |    78.78 |     100 |   92.17 | ...81,129-130,140 
  ...Completion.ts |   97.07 |    81.25 |     100 |   97.07 | 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.8 |    90.9 |   85.73 | ...07-716,832-834 
 ...s/geminiStream |   88.12 |    80.89 |   89.09 |   88.12 |                   
  ...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.28 |    87.03 |   91.66 |   90.28 | ...22,324-328,413 
  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 | 85                
  ...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 | ...28-434,443-452 
  ...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.47 |    56.89 |   83.33 |   83.47 |                   
  ...AppLayout.tsx |   80.98 |    71.42 |   83.33 |   80.98 | ...86-200,316-354 
  ...utHelpers.tsx |   86.29 |     54.9 |   95.23 |   86.29 | ...87-788,809-837 
  ...ainContent.ts |   23.52 |      100 |       0 |   23.52 | 16-22,25-28,31-34 
 ...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.04 |    85.65 |   97.61 |   99.04 |                   
  ansi-light.ts    |     100 |      100 |     100 |     100 |                   
  ansi.ts          |     100 |      100 |     100 |     100 |                   
  atom-one-dark.ts |     100 |      100 |     100 |     100 |                   
  ayu-light.ts     |     100 |      100 |     100 |     100 |                   
  ayu.ts           |     100 |      100 |     100 |     100 |                   
  color-utils.ts   |     100 |      100 |     100 |     100 |                   
  default-light.ts |     100 |      100 |     100 |     100 |                   
  default.ts       |     100 |      100 |     100 |     100 |                   
  dracula.ts       |     100 |      100 |     100 |     100 |                   
  github-dark.ts   |     100 |      100 |     100 |     100 |                   
  github-light.ts  |     100 |      100 |     100 |     100 |                   
  googlecode.ts    |     100 |      100 |     100 |     100 |                   
  green-screen.ts  |     100 |      100 |     100 |     100 |                   
  no-color.ts      |     100 |      100 |     100 |     100 |                   
  ...c-resolver.ts |     100 |      100 |     100 |     100 |                   
  ...tic-tokens.ts |     100 |      100 |     100 |     100 |                   
  ...-of-purple.ts |     100 |      100 |     100 |     100 |                   
  theme-compat.ts  |     100 |       50 |     100 |     100 | 79                
  theme-manager.ts |   88.55 |    82.81 |     100 |   88.55 | ...03-312,317-318 
  theme.ts         |   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      |   61.43 |    88.18 |   72.83 |   61.43 |                   
  ...Colorizer.tsx |    5.64 |      100 |       0 |    5.64 | ...27-168,180-249 
  ...olePatcher.ts |   72.09 |      100 |   83.33 |   72.09 | 50-61             
  ...nRenderer.tsx |   96.88 |    87.87 |     100 |   96.88 | ...69-271,275-277 
  ...wnDisplay.tsx |       5 |      100 |       0 |       5 | ...90-717,728-732 
  ...eRenderer.tsx |   11.17 |      100 |       0 |   11.17 | ...34-387,394-427 
  ...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 |   62.28 |    76.74 |   83.33 |   62.28 | ...52-266,336-338 
  commandUtils.ts  |   93.02 |    94.44 |   96.15 |   93.02 | ...31-235,316-324 
  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.69 |    97.29 |      60 |   77.69 | 146-172,176-181   
  ...xportUtils.ts |   98.47 |    92.85 |     100 |   98.47 | 139-140           
  ...storyItems.ts |   99.08 |    94.59 |     100 |   99.08 | 79                
  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 |   92.34 |    71.79 |     100 |   92.34 | ...48-251,291-295 
  ...putHandler.ts |   94.44 |    91.12 |     100 |   94.44 | ...15-316,386-387 
  ...ityManager.ts |    94.9 |    85.71 |    90.9 |    94.9 | ...28,352,380,391 
  ...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 |   10.72 |      100 |    7.14 |   10.72 | 80-419            
  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.76 |    88.94 |    74.9 |   61.76 |                   
  ...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 
  coalesce.ts      |     100 |      100 |     100 |     100 |                   
  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 |   88.07 |     87.5 |     100 |   88.07 | ...70,82-85,88-91 
  ...arResolver.ts |   96.72 |    96.42 |     100 |   96.72 | 118-119           
  errors.ts        |   94.87 |       88 |     100 |   94.87 | 53-54,95-96       
  events.ts        |     100 |      100 |     100 |     100 |                   
  ...lativeTime.ts |     100 |      100 |     100 |     100 |                   
  gitUtils.ts      |   93.54 |       85 |     100 |   93.54 | 61-62,77-80       
  ...AutoUpdate.ts |   69.48 |    80.76 |   77.77 |   69.48 | ...68-269,283-348 
  ...lationInfo.ts |   99.49 |     98.3 |     100 |   99.49 | 58                
  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 |   88.34 |    83.11 |     100 |   88.34 | ...47-248,331-332 
  sessionUtils.ts  |    8.86 |      100 |       0 |    8.86 | 52-122,129-143    
  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    |   71.33 |    70.96 |   83.33 |   71.33 | ...88-189,203-224 
  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 |                   
  typeGuards.ts    |   65.38 |      100 |      75 |   65.38 | 26-34             
  ...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 |   66.15 |       70 |   76.19 |   66.15 |                   
  ...taRedactor.ts |   81.91 |    71.42 |      80 |   81.91 | ...08-610,616-637 
  ...acyManager.ts |       0 |        0 |       0 |       0 | 1-176             
 ...ed-integration |    9.72 |     92.3 |    9.23 |    9.72 |                   
  ...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.69 |      100 |       0 |    4.69 | ...70-505,508-532 
  ...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.89 |    83.49 |   74.28 |   76.89 |                   
 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.35 |     100 |   98.57 |                   
  EmojiFilter.ts   |   98.57 |    96.35 |     100 |   98.57 | ...55-156,352-353 
 src/hooks         |    83.1 |    85.37 |   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 |    88.18 |   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 |    45.74 |   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 |    79.31 |     100 |   81.81 | ...02-108,116-120 
  ...t-warnings.ts |    92.3 |    33.33 |     100 |    92.3 | 18-19             
  ...r-defaults.ts |   52.51 |    35.29 |   84.61 |   52.51 | ...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.23 |   98.09 |    90.2 |                   
  ...ntegration.ts |    83.9 |       75 |     100 |    83.9 | ...31-132,143-144 
  ReplayEngine.ts  |   95.78 |       91 |     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.83 |   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.54 |     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         |   75.17 |    81.15 |      92 |   75.17 |                   
  ...ey-storage.ts |   75.17 |    81.15 |      92 |   75.17 | ...59-464,473-478 
 ...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.

Remediates CodeRabbit findings on the #2187 hardening:

- envelope-codec: a v:2 decrypt must never generate a new machine secret on a
  miss. Thread a generateIfMissing flag through the default loader so encrypt
  may mint/persist a root of trust but decrypt fails closed (CORRUPT) when the
  secret is gone, rather than minting a fresh secret that cannot decrypt the
  existing envelope.

- machine-secret: add generateIfMissing (default true) to MachineSecretOptions.
  When false, getMachineSecret only loads an existing secret (keyring -> file)
  and returns null without generating/persisting. A read-only miss is not
  negatively cached, so it cannot poison a later generating write for the same
  source.

- tool-key-storage / file-token-storage: writeFile's mode only applies on
  creation, so overwriting a pre-existing file left looser permissions intact.
  Explicitly chmod 0o600 after every write on POSIX (no-op on Windows) so a
  credential file is never left group/world-readable.

- file-token-storage: normalize every legacy hex-colon decrypt failure to a
  single 'Token file corrupted' error so raw crypto error details never leak.

Tests:
- machine-secret: read-only (generateIfMissing:false) loads existing keyring/
  file secrets, returns null without persisting on a miss, and a read miss does
  not poison a later generating call.
- file-token-storage / tool-key-storage: overwriting a loose-mode file tightens
  it back to 0o600; a malformed legacy token file fails closed as corrupted.

@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/mcp/src/auth/token-storage/file-token-storage.ts (1)

160-186: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Tighten existing permissions before writing the new token envelope.

Line 180 writes fresh token data while a pre-existing loose-mode file remains readable until Lines 184-185 complete; a crash or local read race can leave the new envelope exposed under the old permissions.

Proposed hardening
     // Detect an existing envelope version for anti-downgrade protection.
     // Non-envelope (legacy) files and missing files yield null.
     let existingVersion: number | null = null;
+    let fileExists = false;
     try {
       const existing = await fs.readFile(this.tokenFilePath, 'utf-8');
+      fileExists = true;
       existingVersion = readEnvelopeVersion(existing);
     } catch (error: unknown) {
       const err = error as NodeJS.ErrnoException;
       if (err.code !== 'ENOENT') {
         throw error;
@@
     const encrypted = await encryptEnvelopeString(json, this.serviceName, {
       ...this.codecOptions,
       existingEnvelopeVersion: existingVersion,
     });
 
+    if (fileExists && process.platform !== 'win32') {
+      await fs.chmod(this.tokenFilePath, 0o600);
+    }
     await fs.writeFile(this.tokenFilePath, encrypted, { mode: 0o600 });
     // writeFile's `mode` only applies on creation; overwriting a pre-existing
🤖 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/mcp/src/auth/token-storage/file-token-storage.ts` around lines 160 -
186, The token write path in file-token-storage’s write flow leaves a
pre-existing file under its old permissions until after fs.writeFile completes,
so tighten permissions before the new envelope is written. In the code around
existingVersion/encryptEnvelopeString/writeFile, change the update sequence so
any existing tokenFilePath is chmod’d to 0o600 before writing the new encrypted
envelope, while still keeping the post-write chmod on POSIX as a safeguard.
packages/core/src/tools/tool-key-storage.ts (1)

230-238: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Tighten existing permissions before writing the new key.

The current order writes the new secret while a pre-existing loose-mode file is still group/world-readable until Line 238 runs; a crash or local read race before chmod leaves the fresh key exposed.

Proposed hardening
     let existingVersion: number | null = null;
+    let fileExists = false;
     try {
       const existing = await fs.readFile(filePath, 'utf-8');
+      fileExists = true;
       existingVersion = readEnvelopeVersion(existing);
     } catch (error) {
       const err = error as NodeJS.ErrnoException;
       if (err.code !== 'ENOENT') {
         throw error;
       }
     }
 
     const envelopeJson = await encryptEnvelopeString(key, KEYCHAIN_SERVICE, {
       ...this.codecOptions,
       existingEnvelopeVersion: existingVersion,
     });
+    if (fileExists) {
+      await this.chmodIfPosix(filePath);
+    }
     await fs.writeFile(filePath, envelopeJson, { mode: 0o600 });
     // writeFile's `mode` only applies when the file is created; overwriting a
     // pre-existing file with looser permissions leaves them unchanged. Tighten
🤖 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/core/src/tools/tool-key-storage.ts` around lines 230 - 238, The key
file is being overwritten in `tool-key-storage.ts` while any existing loose
permissions remain in place until after the write completes. Update the write
flow in the key storage path that uses `encryptEnvelopeString`, `fs.writeFile`,
and `chmodIfPosix` so the destination file is tightened before the new secret is
written, then persist the envelope and re-apply the restrictive mode after
writing if needed. Use the existing `chmodIfPosix` helper to ensure a
pre-existing file is never left group/world-readable during the overwrite.
🤖 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/core/src/tools/tool-key-storage.ts`:
- Around line 230-238: The key file is being overwritten in
`tool-key-storage.ts` while any existing loose permissions remain in place until
after the write completes. Update the write flow in the key storage path that
uses `encryptEnvelopeString`, `fs.writeFile`, and `chmodIfPosix` so the
destination file is tightened before the new secret is written, then persist the
envelope and re-apply the restrictive mode after writing if needed. Use the
existing `chmodIfPosix` helper to ensure a pre-existing file is never left
group/world-readable during the overwrite.

In `@packages/mcp/src/auth/token-storage/file-token-storage.ts`:
- Around line 160-186: The token write path in file-token-storage’s write flow
leaves a pre-existing file under its old permissions until after fs.writeFile
completes, so tighten permissions before the new envelope is written. In the
code around existingVersion/encryptEnvelopeString/writeFile, change the update
sequence so any existing tokenFilePath is chmod’d to 0o600 before writing the
new encrypted envelope, while still keeping the post-write chmod on POSIX as a
safeguard.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: f66ac69a-7448-44e4-80aa-9a2712ff9e9e

📥 Commits

Reviewing files that changed from the base of the PR and between 3abc2c2 and f0d4d7d.

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

Applied to files:

  • packages/storage/src/secure-store/machine-secret.test.ts
  • packages/mcp/src/auth/token-storage/file-token-storage.behavior.test.ts
  • packages/storage/src/secure-store/machine-secret.ts
  • packages/core/src/tools/tool-key-storage.test.ts
  • packages/storage/src/secure-store/envelope-codec.ts
  • packages/core/src/tools/tool-key-storage.ts
  • packages/mcp/src/auth/token-storage/file-token-storage.test.ts
  • packages/mcp/src/auth/token-storage/file-token-storage.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/mcp/src/auth/token-storage/file-token-storage.behavior.test.ts
  • packages/storage/src/secure-store/machine-secret.ts
  • packages/core/src/tools/tool-key-storage.test.ts
  • packages/storage/src/secure-store/envelope-codec.ts
  • packages/core/src/tools/tool-key-storage.ts
  • packages/mcp/src/auth/token-storage/file-token-storage.test.ts
  • packages/mcp/src/auth/token-storage/file-token-storage.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/mcp/src/auth/token-storage/file-token-storage.behavior.test.ts
  • packages/storage/src/secure-store/machine-secret.ts
  • packages/core/src/tools/tool-key-storage.test.ts
  • packages/storage/src/secure-store/envelope-codec.ts
  • packages/core/src/tools/tool-key-storage.ts
  • packages/mcp/src/auth/token-storage/file-token-storage.test.ts
  • packages/mcp/src/auth/token-storage/file-token-storage.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/mcp/src/auth/token-storage/file-token-storage.behavior.test.ts
  • packages/storage/src/secure-store/machine-secret.ts
  • packages/core/src/tools/tool-key-storage.test.ts
  • packages/storage/src/secure-store/envelope-codec.ts
  • packages/core/src/tools/tool-key-storage.ts
  • packages/mcp/src/auth/token-storage/file-token-storage.test.ts
  • packages/mcp/src/auth/token-storage/file-token-storage.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/mcp/src/auth/token-storage/file-token-storage.behavior.test.ts
  • packages/storage/src/secure-store/machine-secret.ts
  • packages/core/src/tools/tool-key-storage.test.ts
  • packages/storage/src/secure-store/envelope-codec.ts
  • packages/core/src/tools/tool-key-storage.ts
  • packages/mcp/src/auth/token-storage/file-token-storage.test.ts
  • packages/mcp/src/auth/token-storage/file-token-storage.ts
📚 Learning: 2026-02-16T16:11:07.481Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1434
File: packages/core/src/tools/delete_line_range.ts:204-254
Timestamp: 2026-02-16T16:11:07.481Z
Learning: Identify duplicated LSP diagnostics collection logic across packages/core/src/tools/*.ts. In reviews, flag the common block (checkFile, filter by includeSeverities, limit by maxDiagnosticsPerFile, format with <diagnostics> tags) that is replicated in six files (ast-edit.ts, delete_line_range.ts, insert_at_line.ts, edit.ts, write-file.ts, apply-patch.ts). Recommend extracting into a shared helper (e.g., collectLspDiagnosticsBlock) and ensure it handles Promise.race timeout and uses the correct severities label instead of a hardcoded "LSP errors". This guideline applies to all files in that directory and similar tools unless explicitly excluded.

Applied to files:

  • packages/core/src/tools/tool-key-storage.test.ts
  • packages/core/src/tools/tool-key-storage.ts
📚 Learning: 2026-06-24T07:45:19.981Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 2146
File: packages/core/src/tools-adapters/CoreSubagentServiceAdapter.ts:299-300
Timestamp: 2026-06-24T07:45:19.981Z
Learning: In this repo, follow the "unnecessary-condition" lint policy: if a value is already typed as non-optional (e.g., `SubagentManager.loadSubagent(...)` returns `SubagentConfig`, not `SubagentConfig | undefined`), do not add defensive conditional guards like `loaded ? ... : undefined` before passing the value into helpers (e.g., `toToolsSubagentConfig(loaded)`). Passing the non-optional value directly is the correct pattern; adding such branches is considered dead code and should be avoided so the lint passes.

Applied to files:

  • packages/core/src/tools/tool-key-storage.test.ts
  • packages/core/src/tools/tool-key-storage.ts
🪛 ast-grep (0.44.0)
packages/storage/src/secure-store/machine-secret.test.ts

[warning] 601-601: 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] 628-630: 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, existing.toString('base64'), {
mode: 0o600,
})
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

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

packages/mcp/src/auth/token-storage/file-token-storage.behavior.test.ts

[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.writeFile(tokenFilePath, malformedLegacy, { mode: 0o600 })
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

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

packages/core/src/tools/tool-key-storage.test.ts

[warning] 381-381: 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(filePath, 'placeholder', { mode: 0o644 })
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

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

🔇 Additional comments (9)
packages/core/src/tools/tool-key-storage.ts (2)

215-233: Existing malformed key files are still treated as overwrite-safe.

readEnvelopeVersion(existing) === null still collapses malformed/unsupported envelopes with legacy or missing files, so this is the same unresolved anti-downgrade/fail-closed concern from the previous review.


105-110: LGTM!

Also applies to: 127-192, 247-311

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

90-103: LGTM!

Also applies to: 128-152, 166-211, 226-301

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

60-68: LGTM!

Also applies to: 149-187, 224-229

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

559-672: LGTM!

packages/core/src/tools/tool-key-storage.test.ts (1)

370-395: LGTM!

packages/mcp/src/auth/token-storage/file-token-storage.ts (1)

29-58: LGTM!

Also applies to: 61-151, 189-264

packages/mcp/src/auth/token-storage/file-token-storage.test.ts (1)

30-88: LGTM!

packages/mcp/src/auth/token-storage/file-token-storage.behavior.test.ts (1)

259-310: LGTM!

acoliver added 2 commits June 26, 2026 04:05
Follow-up review pass on the #2187 hardening. No behavior-changing crypto
changes; tightens completeness of the fail-closed contract, hardens the
permission-tightening path, makes legacy detection stricter, removes a small
duplication, and strengthens test assertions.

Source:
- envelope-codec: complete the fail-closed contract on a v:2 decrypt. Wrap the
  machine-secret loader() call so a rejected loader is normalized to
  EnvelopeCodecError(CORRUPT) instead of leaking a raw exception, and move
  scryptAsync inside the decrypt try so a KDF failure also fails closed. Extract
  a shared parseEnvelope() helper so decryptEnvelopeString and
  readEnvelopeVersion can never drift in how they recognize a valid envelope.
- tool-key-storage / file-token-storage: if the post-write chmod 0o600 fails,
  unlink the just-written file and throw a descriptive error so a secret is
  never left on disk with over-permissive modes (distinct from a write failure).
- tool-key-storage: tighten legacy hex-colon detection to the exact legacy
  shape (32-hex IV, 32-hex auth tag, non-empty hex ciphertext) via a single
  anchored pattern, so short/garbage `a:b:c` content fails closed as
  unrecognized rather than being routed to a decrypt attempt.
- file-token-storage: lazily derive the legacy KDF key only when a legacy file
  is actually read (writes and envelope reads no longer pay the scrypt cost),
  and document the anti-downgrade read as best-effort defense-in-depth (TOCTOU).

Tests:
- envelope-codec: assert the structured CORRUPT code rather than brittle message
  text; add a rejecting-loader fail-closed test and a readEnvelopeVersion('')
  null edge case.
- tool-key-storage: assert a generic rejection instead of Node's raw crypto
  message; document the frozen legacy KDF spec; add length-validation regression
  tests; drop redundant mkdir calls covered by beforeEach.
- machine-secret: add a read-only (generateIfMissing:false) corrupt-file test
  proving it fails closed (null) and leaves the file untouched.
- file-token-storage: decrypt written envelopes to assert merge-on-update and
  removal-on-delete; rename the misleading anti-downgrade behavior test and
  tighten a server-list assertion to exact membership.
The previous open-code-review pass introduced two changes to
decryptEnvelopeString that contradicted the canonical
SecureStore.readFallbackFileAtPath contract this codec is documented to
mirror, and broke the file-token-storage behavior test that encodes the
intended design:

- A try/catch around the v:2 machine-secret loader relabeled ANY loader
  rejection as EnvelopeCodecError('CORRUPT'). A loader rejection signals a
  transient infrastructure fault (e.g. a temporarily broken keyring), not an
  unreadable envelope, so the original error must propagate unchanged. Only a
  loader that resolves to null (secret genuinely unavailable) fails closed as
  CORRUPT.
- Moving scryptAsync inside the decrypt try block would likewise mask an
  unexpected KDF fault (e.g. resource exhaustion) as data corruption.

Both are reverted so the codec matches readFallbackFileAtPath exactly: the
loader call and KDF derivation stay outside the try, and only a genuine
authentication/decrypt failure fails closed as CORRUPT. The corresponding
unit test now asserts the correct behavior (an unexpected loader rejection
propagates unchanged and is not an EnvelopeCodecError), mirroring the mcp
file-token-storage behavior test.

@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: 2

Caution

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

⚠️ Outside diff range comments (1)
packages/mcp/src/auth/token-storage/file-token-storage.ts (1)

204-223: 🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

Avoid overwriting the live token file before permission tightening succeeds.

Line 204 replaces the target in place before Line 210 proves the mode can be tightened. If the existing file is still 0644, the new credentials stay readable under that mode until chmod runs, and a chmod failure then deletes the only copy at Lines 216-223. Write to a temp file created with 0o600, tighten/verify that path, then rename atomically over the target so this hardening path doesn't introduce credential loss.

🤖 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/mcp/src/auth/token-storage/file-token-storage.ts` around lines 204 -
223, The file write flow in FileTokenStorage is still overwriting the live token
file before permission tightening is confirmed. Update the write path in the
token persistence logic around the fs.writeFile/fs.chmod sequence so credentials
are first written to a temporary file created with 0o600, then chmod/verify
succeeds on that temp file, and only then atomically rename it over the final
tokenFilePath; keep the existing error handling and cleanup behavior tied to the
file write method in FileTokenStorage.
🤖 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/core/src/tools/tool-key-storage.ts`:
- Around line 322-327: The legacy format check in isLegacyHexColonFormat is too
strict because it rejects valid old records with an empty ciphertext after the
second colon. Update the regex or equivalent validation in tool-key-storage.ts
so it still requires the two 32-hex segments and the two separators, but allows
the ciphertext portion to be empty; keep the function name
isLegacyHexColonFormat as the place to adjust backward-compatible parsing.

In `@packages/storage/src/secure-store/envelope-codec.ts`:
- Around line 333-334: readEnvelopeVersion currently depends on full
parseEnvelope validation, so tampered v:2 envelopes can be treated as null and
later downgraded. Update readEnvelopeVersion in envelope-codec.ts to detect and
preserve the envelope version marker independently of KDF/crypto metadata
validation, returning 2 whenever the v:2 marker is present even if parseEnvelope
fails. Keep parseEnvelope for full decoding, but make existingEnvelopeVersion
derive from the version marker so the anti-downgrade guard still triggers.

---

Outside diff comments:
In `@packages/mcp/src/auth/token-storage/file-token-storage.ts`:
- Around line 204-223: The file write flow in FileTokenStorage is still
overwriting the live token file before permission tightening is confirmed.
Update the write path in the token persistence logic around the
fs.writeFile/fs.chmod sequence so credentials are first written to a temporary
file created with 0o600, then chmod/verify succeeds on that temp file, and only
then atomically rename it over the final tokenFilePath; keep the existing error
handling and cleanup behavior tied to the file write method in FileTokenStorage.
🪄 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: 6921f413-52e3-4831-a5a0-61757fc482fe

📥 Commits

Reviewing files that changed from the base of the PR and between f0d4d7d and 0dcd647.

📒 Files selected for processing (8)
  • packages/core/src/tools/tool-key-storage.test.ts
  • packages/core/src/tools/tool-key-storage.ts
  • packages/mcp/src/auth/token-storage/file-token-storage.behavior.test.ts
  • packages/mcp/src/auth/token-storage/file-token-storage.test.ts
  • packages/mcp/src/auth/token-storage/file-token-storage.ts
  • packages/storage/src/secure-store/envelope-codec.test.ts
  • packages/storage/src/secure-store/envelope-codec.ts
  • packages/storage/src/secure-store/machine-secret.test.ts
📜 Review details
🧰 Additional context used
🧠 Learnings (7)
📚 Learning: 2026-02-06T15:52:42.315Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1305
File: scripts/generate-keybindings-doc.ts:1-5
Timestamp: 2026-02-06T15:52:42.315Z
Learning: In reviews of vybestack/llxprt-code, do not suggest changing existing copyright headers from 'Google LLC' to 'Vybestack LLC' for files that originated from upstream. Preserve upstream copyrights in files that came from upstream, and only apply 'Vybestack LLC' copyright on newly created, original LLxprt files. If a file is clearly LLxprt-original, it may carry the Vybestack header; if it is upstream-originated, keep the original sponsor header.

Applied to files:

  • packages/storage/src/secure-store/machine-secret.test.ts
  • packages/mcp/src/auth/token-storage/file-token-storage.behavior.test.ts
  • packages/core/src/tools/tool-key-storage.test.ts
  • packages/core/src/tools/tool-key-storage.ts
  • packages/storage/src/secure-store/envelope-codec.test.ts
  • packages/mcp/src/auth/token-storage/file-token-storage.ts
  • packages/storage/src/secure-store/envelope-codec.ts
  • packages/mcp/src/auth/token-storage/file-token-storage.test.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/mcp/src/auth/token-storage/file-token-storage.behavior.test.ts
  • packages/core/src/tools/tool-key-storage.test.ts
  • packages/core/src/tools/tool-key-storage.ts
  • packages/storage/src/secure-store/envelope-codec.test.ts
  • packages/mcp/src/auth/token-storage/file-token-storage.ts
  • packages/storage/src/secure-store/envelope-codec.ts
  • packages/mcp/src/auth/token-storage/file-token-storage.test.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/mcp/src/auth/token-storage/file-token-storage.behavior.test.ts
  • packages/core/src/tools/tool-key-storage.test.ts
  • packages/core/src/tools/tool-key-storage.ts
  • packages/storage/src/secure-store/envelope-codec.test.ts
  • packages/mcp/src/auth/token-storage/file-token-storage.ts
  • packages/storage/src/secure-store/envelope-codec.ts
  • packages/mcp/src/auth/token-storage/file-token-storage.test.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/mcp/src/auth/token-storage/file-token-storage.behavior.test.ts
  • packages/core/src/tools/tool-key-storage.test.ts
  • packages/core/src/tools/tool-key-storage.ts
  • packages/storage/src/secure-store/envelope-codec.test.ts
  • packages/mcp/src/auth/token-storage/file-token-storage.ts
  • packages/storage/src/secure-store/envelope-codec.ts
  • packages/mcp/src/auth/token-storage/file-token-storage.test.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/mcp/src/auth/token-storage/file-token-storage.behavior.test.ts
  • packages/core/src/tools/tool-key-storage.test.ts
  • packages/core/src/tools/tool-key-storage.ts
  • packages/storage/src/secure-store/envelope-codec.test.ts
  • packages/mcp/src/auth/token-storage/file-token-storage.ts
  • packages/storage/src/secure-store/envelope-codec.ts
  • packages/mcp/src/auth/token-storage/file-token-storage.test.ts
📚 Learning: 2026-02-16T16:11:07.481Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1434
File: packages/core/src/tools/delete_line_range.ts:204-254
Timestamp: 2026-02-16T16:11:07.481Z
Learning: Identify duplicated LSP diagnostics collection logic across packages/core/src/tools/*.ts. In reviews, flag the common block (checkFile, filter by includeSeverities, limit by maxDiagnosticsPerFile, format with <diagnostics> tags) that is replicated in six files (ast-edit.ts, delete_line_range.ts, insert_at_line.ts, edit.ts, write-file.ts, apply-patch.ts). Recommend extracting into a shared helper (e.g., collectLspDiagnosticsBlock) and ensure it handles Promise.race timeout and uses the correct severities label instead of a hardcoded "LSP errors". This guideline applies to all files in that directory and similar tools unless explicitly excluded.

Applied to files:

  • packages/core/src/tools/tool-key-storage.test.ts
  • packages/core/src/tools/tool-key-storage.ts
📚 Learning: 2026-06-24T07:45:19.981Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 2146
File: packages/core/src/tools-adapters/CoreSubagentServiceAdapter.ts:299-300
Timestamp: 2026-06-24T07:45:19.981Z
Learning: In this repo, follow the "unnecessary-condition" lint policy: if a value is already typed as non-optional (e.g., `SubagentManager.loadSubagent(...)` returns `SubagentConfig`, not `SubagentConfig | undefined`), do not add defensive conditional guards like `loaded ? ... : undefined` before passing the value into helpers (e.g., `toToolsSubagentConfig(loaded)`). Passing the non-optional value directly is the correct pattern; adding such branches is considered dead code and should be avoided so the lint passes.

Applied to files:

  • packages/core/src/tools/tool-key-storage.test.ts
  • packages/core/src/tools/tool-key-storage.ts
🪛 ast-grep (0.44.0)
packages/storage/src/secure-store/machine-secret.test.ts

[warning] 649-651: 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', {
mode: 0o600,
})
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

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


[warning] 661-661: 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/core/src/tools/tool-key-storage.test.ts

[warning] 586-586: 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(filePath, 'aa:bb:cc', { mode: 0o600 })
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

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


[warning] 610-612: 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(filePath, ${shortIv}:${authTag}:2222, {
mode: 0o600,
})
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

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

🔇 Additional comments (7)
packages/storage/src/secure-store/envelope-codec.ts (1)

155-176: LGTM!

Also applies to: 254-323

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

255-263: LGTM!

Also applies to: 279-306, 357-362

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

643-664: LGTM!

packages/core/src/tools/tool-key-storage.ts (1)

238-252: LGTM!

Also applies to: 261-311

packages/core/src/tools/tool-key-storage.test.ts (1)

102-136: LGTM!

Also applies to: 569-622

packages/mcp/src/auth/token-storage/file-token-storage.behavior.test.ts (1)

218-218: LGTM!

Also applies to: 230-234, 324-328

packages/mcp/src/auth/token-storage/file-token-storage.test.ts (1)

21-49: LGTM!

Also applies to: 245-256, 322-328

Comment thread packages/core/src/tools/tool-key-storage.ts Outdated
Comment thread packages/storage/src/secure-store/envelope-codec.ts
@acoliver

Copy link
Copy Markdown
Collaborator Author

Valid — fixed in the follow-up commit. The legacy encrypt() path was iv:authTag: + cipher.update(text)+final(), and since AES-256-GCM is a stream cipher the ciphertext length equals the plaintext length. A legacy file that stored an empty key therefore serializes as iv:authTag: with an empty third part, which the + quantifier wrongly rejected as "unrecognized". Changed the quantifier to * so the exact 32-hex IV / 32-hex auth-tag length checks are preserved (short/garbage a:b:c content is still rejected) while an empty-ciphertext legacy file round-trips. Added a regression test ("reads a legacy empty-key .key file whose ciphertext is empty (iv:authTag:)") proving it decrypts to ''.

acoliver added 2 commits June 26, 2026 05:57
…ward-compat read

CodeRabbit review on PR #2188 flagged that isLegacyHexColonFormat required a
non-empty hex ciphertext (`+` quantifier). Because the legacy AES-256-GCM
encrypt path is a stream cipher (ciphertext length == plaintext length), a
legacy file that stored an empty key serializes as `iv:authTag:` with an empty
third part. The stricter pattern rejected those genuine legacy files as
'unrecognized format' instead of reading them back compatibly.

Relax the ciphertext quantifier to `*` while keeping the exact 32-hex IV and
32-hex auth-tag length checks, so short/garbage `a:b:c` content is still not
misclassified as legacy. Add a regression test proving an empty-key legacy file
round-trips to ''.

The companion CodeRabbit suggestion to make readEnvelopeVersion tolerate
tampered crypto metadata was declined (with rationale on the PR): it rests on an
incorrect threat model, would diverge from the canonical
SecureStore.readExistingEnvelopeVersion it mirrors, and would prevent re-saving
over a genuinely corrupt file.
…rdening

Second open-code-review pass on the #2187 hardening. Completes the
fail-closed/permission contracts and strengthens test coverage; no
behavior-changing crypto.

Source:
- file-token-storage: restructure loadTokens to classify content as
  versioned-envelope, exact legacy hex-colon shape, or neither. Add a private
  isLegacyHexColonFormat guard (mirroring ToolKeyStorage) so short/garbage
  a:b:c content fails closed as "Token file corrupted" instead of being passed
  into the crypto API with an invalid-length IV.
- file-token-storage: preserve the structured EnvelopeCodecError as `cause` on
  the "Token file corrupted" error so callers/debuggers can still distinguish
  UNAVAILABLE vs CORRUPT and recover the remediation hint.
- file-token-storage / tool-key-storage: if the post-write chmod 0o600 fails
  AND the cleanup unlink also fails, no longer throw a message that falsely
  claims the file was removed. Track the unlink outcome and throw a branched,
  accurate message; tool-key-storage additionally logs the path and unlink
  error via debugLogger.warn so an operator can manually remove the
  over-permissive secret.
- tool-key-storage: saveKeyfilesMap now calls chmodIfPosix after writeFile.
  writeFile's `mode` only applies on creation, so overwriting a pre-existing
  keyfiles.json left its prior (possibly group/world-readable) permissions
  intact; tighten explicitly on POSIX, mirroring saveToFile.
- a2a-server tsconfig: add ES2022.Error to `lib`. a2a-server type-checks mcp
  source directly, and the new Error(..., { cause }) overload requires the
  ES2022.Error lib (already present in mcp and 9 sibling packages).

Tests:
- file-token-storage: add an expired-token read test proving the storage layer
  returns expired credentials without filtering; decrypt the written envelope
  to assert the persisted credential map on create; add chmod-failure path
  tests for both the unlink-succeeds and unlink-also-fails branches; document
  the legacy-KDF helper's frozen magic strings against the production
  getLegacyEncryptionKey.
- envelope-codec: add a v:1 cross-service isolation test (decrypt under a
  different serviceName fails CORRUPT); add a readEnvelopeVersion v:1 test; add
  an anti-downgrade happy-path test (existing v:2 + available secret overwrites
  as v:2).
- machine-secret: add a read-only (generateIfMissing:false) test proving a
  rejecting keyring loader with no existing file fails closed (null) and writes
  no file.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (1)
packages/core/src/tools/tool-key-storage.ts (1)

383-392: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Clean up keyfiles.json when chmod hardening fails.

Line 392 throws on chmod failure but leaves the just-written keyfiles.json in place with its previous broad permissions. Mirror saveToFile here so plaintext keyfile paths are not left group/world-readable after a failed hardening step.

Proposed hardening
     await fs.writeFile(this.keyfilesJsonPath, JSON.stringify(map, null, 2), {
       mode: 0o600,
     });
@@
-    await this.chmodIfPosix(this.keyfilesJsonPath);
+    try {
+      await this.chmodIfPosix(this.keyfilesJsonPath);
+    } catch (chmodError) {
+      let unlinkFailed = false;
+      try {
+        await fs.unlink(this.keyfilesJsonPath);
+      } catch {
+        unlinkFailed = true;
+      }
+      const detail =
+        chmodError instanceof Error ? chmodError.message : String(chmodError);
+      throw new Error(
+        unlinkFailed
+          ? `keyfiles.json was written but permissions could not be tightened to 0o600, and the over-permissive file could not be removed: ${detail}`
+          : `keyfiles.json was written but permissions could not be tightened to 0o600; the file was removed: ${detail}`,
+      );
+    }
🤖 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/core/src/tools/tool-key-storage.ts` around lines 383 - 392, The
chmod hardening in saveKeyfilesMap can fail after keyfiles.json has already been
written, leaving the plaintext path map on disk with its existing permissions.
Update saveKeyfilesMap to mirror saveToFile by catching chmodIfPosix failures,
removing the newly written keyfilesJsonPath on error, and rethrowing so the
failure is not silently ignored.
🤖 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/mcp/src/auth/token-storage/file-token-storage.test.ts`:
- Around line 300-350: These chmod failure cases in the file-token-storage tests
are POSIX-only and should not run on Windows because the production path in
setCredentials skips chmod when process.platform is win32. Guard or skip the two
affected tests so they only execute on non-Windows platforms, keeping the
expectations around chmod, unlink cleanup, and the “permissions could not be
restricted” / “could not be removed” errors tied to the same setCredentials
flow.

---

Outside diff comments:
In `@packages/core/src/tools/tool-key-storage.ts`:
- Around line 383-392: The chmod hardening in saveKeyfilesMap can fail after
keyfiles.json has already been written, leaving the plaintext path map on disk
with its existing permissions. Update saveKeyfilesMap to mirror saveToFile by
catching chmodIfPosix failures, removing the newly written keyfilesJsonPath on
error, and rethrowing so the failure is not silently ignored.
🪄 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: fb0418e5-6363-4f54-87d1-b093fae13c1e

📥 Commits

Reviewing files that changed from the base of the PR and between 27cf502 and 937c045.

📒 Files selected for processing (6)
  • packages/a2a-server/tsconfig.json
  • packages/core/src/tools/tool-key-storage.ts
  • packages/mcp/src/auth/token-storage/file-token-storage.test.ts
  • packages/mcp/src/auth/token-storage/file-token-storage.ts
  • packages/storage/src/secure-store/envelope-codec.test.ts
  • packages/storage/src/secure-store/machine-secret.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout. (2)
  • GitHub Check: E2E Test (Linux) - sandbox:none
  • GitHub Check: E2E Test (Linux) - sandbox:docker
⚠️ CI failures not shown inline (4)

GitHub Actions: LLxprt Code CI / 7_Lint (Javascript).txt: Harden sibling encrypted file stores with machine-secret KDF (Fixes #2187)

Conclusion: failure

View job details

##[group]Run npm run format
 �[36;1mnpm run format�[0m
 �[36;1m# Check for changes, excluding project-plans directory�[0m
 �[36;1mgit diff --exit-code -- . ':!project-plans/'�[0m
 shell: /usr/bin/bash --noprofile --norc -e -o pipefail {0}
 env:
   ACTIONLINT_VERSION: 1.7.7
   SHELLCHECK_VERSION: 0.11.0
   YAMLLINT_VERSION: 1.35.1
 ##[endgroup]
 > `@vybestack/llxprt-code`@0.10.0 format
 > prettier --experimental-cli --write .
 .llxprt/LLXPRT.md
 warning: in the working copy of 'packages/vscode-ide-companion/NOTICES.txt', CRLF will be replaced by LF the next time Git touches it
 diff --git a/.llxprt/LLXPRT.md b/.llxprt/LLXPRT.md
 index 2760baf67..f1271dd7b 100644
 --- a/.llxprt/LLXPRT.md
 +++ b/.llxprt/LLXPRT.md
 @@ -2,5 +2,5 @@
  - CRITICAL: NEVER delete, remove, or modify the .llxprt/ directory or any of its contents (LLXPRT.md, settings.json, skills/, commands/). This directory contains project memories, settings, and skills that are version-controlled. Do not run rm, git clean, git checkout, or any other command that would remove these files. If git status shows .llxprt files as modified, leave them alone — they are supposed to be there. "Clean workspace" means only: checkout main and pull from origin. It does NOT mean deleting files.
  - Before checking in code changes from the main project directory, run: npm run test, npm run lint, npm run typecheck, npm run format, npm run build, and node scripts/start.js --profile-load ollamakimi "write me a haiku and nothing else"; fix any errors, ensure code is formatted before pushing/creating PRs, and always use gh for PRs/issues/comments (never webfetch).
 -- When user requests to address GitHub issue `#NUM`: 1) Checkout main and pull latest from origin (do NOT delete any files or run git clean — just git checkout main && git pull), 2) Create branch "issueNUM", 3) Use gh to pull issue and comments, 4) Research issue in codebase using description/comments as starting point, 5) Create test-first plan following dev-docs/RULE...

GitHub Actions: LLxprt Code CI / Lint (GitHub Actions): Harden sibling encrypted file stores with machine-secret KDF (Fixes #2187)

Conclusion: failure

View job details

##[group]Run actionlint \
 �[36;1mactionlint \�[0m
 �[36;1m  -color \�[0m
 �[36;1m  -format "{{range \$err := .}}::error file={{\$err.Filepath}},line={{\$err.Line}},col={{\$err.Column}}::{{\$err.Filepath}}@{{\$err.Line}} {{\$err.Message}}%0A\`\`\`%0A{{replace \$err.Snippet \"\\\\n\" \"%0A\"}}%0A\`\`\`\\n{{end}}" \�[0m

GitHub Actions: LLxprt Code CI / Lint (Javascript): Harden sibling encrypted file stores with machine-secret KDF (Fixes #2187)

Conclusion: failure

View job details

##[group]Run npm run format
 �[36;1mnpm run format�[0m
 �[36;1m# Check for changes, excluding project-plans directory�[0m
 �[36;1mgit diff --exit-code -- . ':!project-plans/'�[0m
 shell: /usr/bin/bash --noprofile --norc -e -o pipefail {0}
 env:
   ACTIONLINT_VERSION: 1.7.7
   SHELLCHECK_VERSION: 0.11.0
   YAMLLINT_VERSION: 1.35.1
 ##[endgroup]
 > `@vybestack/llxprt-code`@0.10.0 format
 > prettier --experimental-cli --write .
 .llxprt/LLXPRT.md
 warning: in the working copy of 'packages/vscode-ide-companion/NOTICES.txt', CRLF will be replaced by LF the next time Git touches it
 diff --git a/.llxprt/LLXPRT.md b/.llxprt/LLXPRT.md
 index 2760baf67..f1271dd7b 100644
 --- a/.llxprt/LLXPRT.md
 +++ b/.llxprt/LLXPRT.md
 @@ -2,5 +2,5 @@
  - CRITICAL: NEVER delete, remove, or modify the .llxprt/ directory or any of its contents (LLXPRT.md, settings.json, skills/, commands/). This directory contains project memories, settings, and skills that are version-controlled. Do not run rm, git clean, git checkout, or any other command that would remove these files. If git status shows .llxprt files as modified, leave them alone — they are supposed to be there. "Clean workspace" means only: checkout main and pull from origin. It does NOT mean deleting files.
  - Before checking in code changes from the main project directory, run: npm run test, npm run lint, npm run typecheck, npm run format, npm run build, and node scripts/start.js --profile-load ollamakimi "write me a haiku and nothing else"; fix any errors, ensure code is formatted before pushing/creating PRs, and always use gh for PRs/issues/comments (never webfetch).
 -- When user requests to address GitHub issue `#NUM`: 1) Checkout main and pull latest from origin (do NOT delete any files or run git clean — just git checkout main && git pull), 2) Create branch "issueNUM", 3) Use gh to pull issue and comments, 4) Research issue in codebase using description/comments as starting point, 5) Create test-first plan following dev-docs/RULE...

GitHub Actions: LLxprt Code CI / 6_Lint (GitHub Actions).txt: Harden sibling encrypted file stores with machine-secret KDF (Fixes #2187)

Conclusion: failure

View job details

##[group]Run actionlint \
 �[36;1mactionlint \�[0m
 �[36;1m  -color \�[0m
 �[36;1m  -format "{{range \$err := .}}::error file={{\$err.Filepath}},line={{\$err.Line}},col={{\$err.Column}}::{{\$err.Filepath}}@{{\$err.Line}} {{\$err.Message}}%0A\`\`\`%0A{{replace \$err.Snippet \"\\\\n\" \"%0A\"}}%0A\`\`\`\\n{{end}}" \�[0m
🧰 Additional context used
🧠 Learnings (8)
📚 Learning: 2026-06-11T05:52:47.561Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1991
File: packages/ide-integration/tsconfig.json:6-6
Timestamp: 2026-06-11T05:52:47.561Z
Learning: In the vybestack/llxprt-code monorepo, preserve the repo-wide TypeScript tsconfig convention that each workspace package’s `compilerOptions.lib` intentionally includes both `"DOM"` and `"DOM.Iterable"`. This is required for DOM-typed globals like `fetch`/`Response` used by packages (e.g., `ide-client.ts`). During code review, avoid suggesting removal of these DOM libs from any package tsconfig; if a package’s tsconfig is missing them, add them rather than removing them.

Applied to files:

  • packages/a2a-server/tsconfig.json
📚 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/envelope-codec.test.ts
  • packages/mcp/src/auth/token-storage/file-token-storage.ts
  • packages/core/src/tools/tool-key-storage.ts
  • packages/mcp/src/auth/token-storage/file-token-storage.test.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/envelope-codec.test.ts
  • packages/mcp/src/auth/token-storage/file-token-storage.ts
  • packages/core/src/tools/tool-key-storage.ts
  • packages/mcp/src/auth/token-storage/file-token-storage.test.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/envelope-codec.test.ts
  • packages/mcp/src/auth/token-storage/file-token-storage.ts
  • packages/core/src/tools/tool-key-storage.ts
  • packages/mcp/src/auth/token-storage/file-token-storage.test.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/envelope-codec.test.ts
  • packages/mcp/src/auth/token-storage/file-token-storage.ts
  • packages/core/src/tools/tool-key-storage.ts
  • packages/mcp/src/auth/token-storage/file-token-storage.test.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/envelope-codec.test.ts
  • packages/mcp/src/auth/token-storage/file-token-storage.ts
  • packages/core/src/tools/tool-key-storage.ts
  • packages/mcp/src/auth/token-storage/file-token-storage.test.ts
📚 Learning: 2026-02-16T16:11:07.481Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1434
File: packages/core/src/tools/delete_line_range.ts:204-254
Timestamp: 2026-02-16T16:11:07.481Z
Learning: Identify duplicated LSP diagnostics collection logic across packages/core/src/tools/*.ts. In reviews, flag the common block (checkFile, filter by includeSeverities, limit by maxDiagnosticsPerFile, format with <diagnostics> tags) that is replicated in six files (ast-edit.ts, delete_line_range.ts, insert_at_line.ts, edit.ts, write-file.ts, apply-patch.ts). Recommend extracting into a shared helper (e.g., collectLspDiagnosticsBlock) and ensure it handles Promise.race timeout and uses the correct severities label instead of a hardcoded "LSP errors". This guideline applies to all files in that directory and similar tools unless explicitly excluded.

Applied to files:

  • packages/core/src/tools/tool-key-storage.ts
📚 Learning: 2026-06-24T07:45:19.981Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 2146
File: packages/core/src/tools-adapters/CoreSubagentServiceAdapter.ts:299-300
Timestamp: 2026-06-24T07:45:19.981Z
Learning: In this repo, follow the "unnecessary-condition" lint policy: if a value is already typed as non-optional (e.g., `SubagentManager.loadSubagent(...)` returns `SubagentConfig`, not `SubagentConfig | undefined`), do not add defensive conditional guards like `loaded ? ... : undefined` before passing the value into helpers (e.g., `toToolsSubagentConfig(loaded)`). Passing the non-optional value directly is the correct pattern; adding such branches is considered dead code and should be avoided so the lint passes.

Applied to files:

  • packages/core/src/tools/tool-key-storage.ts
🪛 ast-grep (0.44.0)
packages/storage/src/secure-store/machine-secret.test.ts

[warning] 621-621: 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)

🔇 Additional comments (7)
packages/a2a-server/tsconfig.json (1)

5-5: LGTM!

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

607-625: LGTM!

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

233-261: LGTM!

Also applies to: 362-405

packages/core/src/tools/tool-key-storage.ts (1)

132-348: LGTM!

packages/mcp/src/auth/token-storage/file-token-storage.ts (2)

82-178: LGTM!

Also applies to: 197-254


156-159: 🎯 Functional Correctness

No tsconfig change needed for Error.cause packages/mcp/tsconfig.json already includes ES2022.Error, so new Error(message, { cause }) is supported.

packages/mcp/src/auth/token-storage/file-token-storage.test.ts (1)

81-89: LGTM!

Also applies to: 162-185, 226-231

Comment thread packages/mcp/src/auth/token-storage/file-token-storage.test.ts Outdated
acoliver added 4 commits June 26, 2026 12:52
The root format script used 'prettier --experimental-cli --write .', but the
experimental CLI does not auto-load .prettierignore the way the stable CLI
does. As a result 'npm run format' reformatted ignored files (e.g.
.llxprt/LLXPRT.md, which is listed in .prettierignore), and CI's formatter
check ('npm run format' followed by 'git diff --exit-code') failed on any
code-bearing PR even though the offending file was never touched by the branch.

Adding an explicit '--ignore-path .prettierignore' restores the intended
behavior: the experimental CLI now skips ignored paths, matching the sibling
'format:check' script (plain 'prettier --check .') which already honors the
ignore file. Verified that the full-repo format run no longer modifies any
ignored files and that the CI formatter check is clean.
The two chmod-failure tests in file-token-storage.test.ts mock fs.chmod to
reject and expect setCredentials to reject. Production only tightens
permissions on POSIX platforms (chmod is skipped when
process.platform === 'win32'), so on Windows the promise would resolve and
these tests would fail.

Guard both with it.skipIf(process.platform === 'win32'), matching the existing
convention in tool-key-storage.test.ts and elsewhere in the repo.
@acoliver
acoliver merged commit 1edcfc9 into main Jun 26, 2026
9 of 19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Harden sibling encrypted file stores using non-secret KDF inputs

1 participant