Skip to content

fix(oauth): preserve Linux auth fallback paths (Fixes #1895)#1897

Merged
acoliver merged 5 commits intomainfrom
issue1895
Apr 10, 2026
Merged

fix(oauth): preserve Linux auth fallback paths (Fixes #1895)#1897
acoliver merged 5 commits intomainfrom
issue1895

Conversation

@acoliver
Copy link
Copy Markdown
Collaborator

@acoliver acoliver commented Apr 9, 2026

Fixes #1895

Summary

  • persist the encrypted SecureStore fallback when keyring writes succeed and fallback is allowed so Linux OAuth sessions remain readable when the keyring later returns nothing
  • reuse the canonical Codex device callback URI in the CLI device flow to avoid the token exchange redirect mismatch
  • add targeted coverage for the Linux fallback behavior and canonical device callback URI wiring

Verification

  • npx vitest run src/storage/secure-store.spec.ts src/storage/secure-store.test.ts
  • npx vitest run src/auth/codex-oauth-provider.spec.ts src/auth/tests/codex-oauth-provider.test.ts src/auth/tests/codex-oauth-provider.fallback.spec.ts
  • npm run typecheck
  • npm run format
  • npm run build
  • npm run lint (fails on pre-existing repository issues unrelated to this diff: generated/prompt .d.ts parsing and import/no-internal-modules errors on files unchanged from main)
  • node scripts/start.js --profile-load synthetic "write me a haiku and nothing else" (build is up to date; run exits 0 but reports an OpenAI API error in this environment)

@github-actions github-actions bot added the maintainer:e2e:ok Trusted contributor; maintainer-approved E2E run label Apr 9, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 9, 2026

Summary by CodeRabbit

  • Bug Fixes

    • Use the canonical device authentication callback URI.
    • Improved secure-storage fallback so data remains available when native keyring is unreliable; refined fallback write and error-handling semantics.
    • OAuth token requests no longer emit a synthetic default profile id when no profile is loaded.
  • Refactor

    • Made OAuth/device-flow configuration accessible for shared configuration use.
  • Tests

    • Added/updated tests for device-auth callback, secure-store fallback policies, and OAuth profile handling.

Walkthrough

Replaced a hardcoded Codex device-auth callback URI with CODEX_CONFIG.deviceAuthCallbackUri and exported CODEX_CONFIG; added a test asserting the canonical callback. Modified SecureStore.set() to track keyring write outcome and change fallback write/error-handling, with extensive tests for Linux/keyring fallback scenarios.

Changes

Cohort / File(s) Summary
Device Auth / Config Export
packages/cli/src/auth/codex-oauth-provider.ts, packages/core/src/auth/codex-device-flow.ts, packages/cli/src/auth/codex-oauth-provider.spec.ts
Replaced hardcoded device-auth redirect URI with CODEX_CONFIG.deviceAuthCallbackUri, exported CODEX_CONFIG, and added a test ensuring the canonical callback URI is used (Issue #1895).
SecureStore Logic & Tests
packages/core/src/storage/secure-store.ts, packages/core/src/storage/secure-store.spec.ts
Added tracking of keyring write success/error in SecureStore.set(); gated fallback writes on policy/platform/keyring result; made backup fallback writes non-fatal when keyring succeeded; added comprehensive tests covering Linux/unreliable keyring behavior and fallbackPolicy semantics.
Auth Precedence Adjustments
packages/core/src/auth/precedence.ts, packages/core/src/auth/precedence.test.ts
Changed resolveProfileId to return `string

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant SecureStore
    participant Keyring as Keyring Adapter
    participant Fallback as Fallback File

    Client->>SecureStore: set(key, value, {fallbackPolicy})
    SecureStore->>Keyring: setPassword(key, encryptedValue)
    alt Keyring succeeds
        Keyring-->>SecureStore: success
        alt fallbackPolicy == 'deny' and platform != linux
            SecureStore-->>Client: return success (no fallback)
        else
            SecureStore->>Fallback: try writeFallbackFile(...) (backup)
            alt write succeeds
                Fallback-->>SecureStore: written
                SecureStore-->>Client: return success
            else write fails
                SecureStore-->>SecureStore: debug log error
                SecureStore-->>Client: return success
            end
        end
    else Keyring fails
        Keyring-->>SecureStore: error
        alt fallbackPolicy == 'allow' or platform == linux
            SecureStore->>Fallback: writeFallbackFile(...) (await)
            Fallback-->>SecureStore: written
            SecureStore-->>Client: return success (via fallback)
        else fallbackPolicy == 'deny'
            SecureStore-->>Client: throw SecureStoreError (UNAVAILABLE or classified)
        end
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐇 I sniffed the configs, nudged a path aright,

Replaced the hardcoded with a canonical light.
When keyrings wobble on Linux nights,
I tucked secrets into fallback bytes.
Hooray — small hops, secure delights!

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: fixing Linux OAuth fallback paths by ensuring encrypted SecureStore fallback persists when keyring writes succeed and fallback is allowed, addressing issue #1895.
Description check ✅ Passed The description covers the summary of changes, touches on verification steps, but lacks detailed TLDR section, comprehensive Dive Deeper context, structured Reviewer Test Plan, and Testing Matrix as specified in the template.
Linked Issues check ✅ Passed The PR directly addresses issue #1895 by fixing Linux OAuth failures through SecureStore fallback persistence, canonical device callback URI reuse, and adding comprehensive test coverage for both scenarios outlined in the linked issue.
Out of Scope Changes check ✅ Passed All changes are scoped to fixing issue #1895: SecureStore fallback behavior on Linux, canonical Codex device callback URI wiring, profile ID handling to avoid synthetic defaults, and comprehensive test coverage—no unrelated changes detected.

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

📋 Issue Planner

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

View plan used: #1895

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

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

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 9, 2026

LLxprt PR Review – PR #1897

Issue Alignment

The PR correctly addresses Issue #1895 with two targeted fixes:

  1. Linux keyring fallback reliability (secure-store.ts): On Linux with fallbackPolicy='allow', the encrypted fallback file is now written in addition to a successful keyring write. This ensures that if the keyring later returns null on read, the fallback file can still recover the OAuth session token. This is the core "broken on Linux" scenario described in the issue.

  2. Canonical device callback URI (codex-oauth-provider.ts + codex-device-flow.ts): CLI device flow now imports and uses CODEX_CONFIG.deviceAuthCallbackUri (https://auth.openai.com/deviceauth/callback) instead of the old hardcoded incorrect value (https://auth.openai.com/api/accounts/deviceauth/callback). This eliminates the token exchange redirect mismatch that caused the 400 error on headless Linux.

  3. resolveProfileId null behavior (precedence.ts): Changed from silently defaulting to 'default' to returning null, which better distinguishes "no profile loaded" from an implicit default. The profileScopeId alias (profileId ?? 'no-profile') keeps cache-key construction safe.

Side Effects

  • secure-store.ts: Logic flow is well-guarded; errors in fallback writes after keyring success are caught and logged as best-effort — no exception propagates. Behavior is gated on process.platform === 'linux', so non-Linux platforms are unaffected.
  • precedence.ts: The profileId: undefined in OAuthTokenRequestMetadata is a semantically meaningful change. Callers of resolveProviderAuth() that serialize or log profileId will now receive undefined instead of 'default'. This appears intentional per the updated doc comment, but could affect downstream telemetry or cache diagnostics.
  • CODEX_CONFIG export: Exported from codex-device-flow.ts — low risk; provides a single source of truth.

Code Quality

Overall sound. Key observations:

  • Error handling in set() is improved: classified errors from keyring write failures are now preserved when fallbackPolicy === 'deny', rather than always throwing a generic UNAVAILABLE error.
  • Conditional logic for shouldWriteFallback is correct: Linux always gets the dual write; non-Linux only writes fallback when keyring fails.
  • Minor: resolveProfileId signature changed to string | null but the inline comment and JSDoc on the function still describe only the null return — slightly stale but not harmful.

Tests and Coverage

Coverage impact: Increase

  • secure-store.spec.ts (new, 372 lines): 9 focused tests covering the Linux fallback scenario, platform gating, error classification, and keyring-vs-fallback precedence. Tests are behavioral and use real filesystem mocks — not mock theater.
  • codex-oauth-provider.spec.ts (added 71 lines): Single behavioral test verifying the canonical URI is passed to completeDeviceAuth rather than the old incorrect hardcoded value.
  • precedence.test.ts (1 line): Updated expectation from 'default'undefined to match the new null-returning behavior.

Flag: The test "should persist fallback file even when keyring write succeeds on Linux" only asserts fileExists, not content integrity (doesn't fs.readFile and compare). If the fallback write corrupts data silently, this test wouldn't catch it. Recommend reading back and comparing as a defensive check.

Verdict

Ready — The PR cleanly fixes both root causes of Issue #1895 with targeted, well-tested changes. The fallback dual-write on Linux, canonical URI wiring, and resolveProfileId null semantics are all correct. One minor recommendation: strengthen the fallback file persistence test to verify content (not just existence) on Linux. Otherwise, no blocking issues.

@acoliver
Copy link
Copy Markdown
Collaborator Author

acoliver commented Apr 9, 2026

Updated the PR description to explicitly include Fixes #1895 so the automated review can evaluate the linked issue context.

@acoliver
Copy link
Copy Markdown
Collaborator Author

acoliver commented Apr 9, 2026

Addressed the formatter failure by updating packages/core/src/storage/secure-store.spec.ts to the exact layout expected by the CI Prettier check, then pushed commit 66a7a33.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

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/storage/secure-store.ts (1)

425-449: ⚠️ Potential issue | 🟠 Major

This changes fallbackPolicy: 'allow' from fallback-permitted to always-write-a-disk-copy.

packages/core/src/storage/provider-key-storage.ts:71-75 uses fallbackPolicy: 'allow' in production, so this branch now writes a fallback file on every successful provider-credential save, not just the Linux recovery case from issue #1895. That's a material storage-model change for healthy keyring installs. Please gate the extra backup write behind a narrower opt-in or Linux-specific path instead of the existing broad allow policy.

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

In `@packages/core/src/storage/secure-store.ts` around lines 425 - 449, The
current logic writes a fallback file whenever fallbackPolicy === 'allow',
causing every successful keyring write to also create a disk backup; change the
condition around writeFallbackFile so it only writes the fallback when either
the keyring write failed (keyringWriteSucceeded === false) or when running on
Linux for reliability (process.platform === 'linux'), or behind a new explicit
opt-in flag (e.g., writeFallbackOnSuccess) if you prefer configuration; update
the branch in the set flow that calls writeFallbackFile (referencing
fallbackPolicy, keyringWriteSucceeded, and writeFallbackFile) to check these
narrower conditions so production use of fallbackPolicy: 'allow' no longer
forces an extra backup write.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/core/src/storage/secure-store.spec.ts`:
- Around line 1-233: The new test file "secure-store.spec.ts" (the "SecureStore
- Linux Keyring Fallback Reliability" suite) is failing Prettier; run the
project formatter (npm run format or the repo's Prettier config) on that spec to
apply the style fixes, ensure the formatted output for the tests (describe
blocks, it cases, imports, and async callbacks around SecureStore,
SecureStoreError, KeyringAdapter usage) is committed, and push the updated
formatted file so CI no longer reports Prettier rewrites.

In `@packages/core/src/storage/secure-store.ts`:
- Around line 442-449: The set() flow currently treats writeFallbackFile
failures as fatal even after keyringWriteSucceeded is true; change it so that
when keyringWriteSucceeded is true and fallbackPolicy === 'allow' you attempt
writeFallbackFile(key, value) but catch and log any errors (use
this.logger.error/debug with fallbackDir and key) and do not rethrow, making the
fallback best-effort; only treat a fallback write as required (and propagate
errors) when the keyring path did not persist the secret (i.e.,
keyringWriteSucceeded is false), preserving the existing behavior for the
non-keyring code paths.

---

Outside diff comments:
In `@packages/core/src/storage/secure-store.ts`:
- Around line 425-449: The current logic writes a fallback file whenever
fallbackPolicy === 'allow', causing every successful keyring write to also
create a disk backup; change the condition around writeFallbackFile so it only
writes the fallback when either the keyring write failed (keyringWriteSucceeded
=== false) or when running on Linux for reliability (process.platform ===
'linux'), or behind a new explicit opt-in flag (e.g., writeFallbackOnSuccess) if
you prefer configuration; update the branch in the set flow that calls
writeFallbackFile (referencing fallbackPolicy, keyringWriteSucceeded, and
writeFallbackFile) to check these narrower conditions so production use of
fallbackPolicy: 'allow' no longer forces an extra backup write.
🪄 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

Run ID: fa73840f-9527-45c9-883c-0453beba7186

📥 Commits

Reviewing files that changed from the base of the PR and between 5422c41 and d57c84d.

📒 Files selected for processing (5)
  • packages/cli/src/auth/codex-oauth-provider.spec.ts
  • packages/cli/src/auth/codex-oauth-provider.ts
  • packages/core/src/auth/codex-device-flow.ts
  • packages/core/src/storage/secure-store.spec.ts
  • packages/core/src/storage/secure-store.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 270000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Run LLxprt review
  • GitHub Check: E2E Test (Linux) - sandbox:none
  • GitHub Check: E2E Test (macOS)
  • GitHub Check: E2E Test (Linux) - sandbox:docker
🧰 Additional context used
🧠 Learnings (34)
📓 Common learnings
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1778
File: packages/cli/src/auth/token-access-coordinator.ts:640-647
Timestamp: 2026-03-26T03:34:18.861Z
Learning: In `packages/cli/src/auth/token-access-coordinator.ts` (vybestack/llxprt-code PR `#1778`, decomposed from `oauth-manager.ts`), the locked disk-check path in `performDiskCheck()` calls `performDiskCheckUnderLock()` without a surrounding try-catch and does not call `scheduleProactiveRenewal()` on the result. This is pre-existing behavior faithfully extracted from the original `oauth-manager.ts` line ~1308 on main. The proactive renewal call on the unlocked fallback (line ~653) is a targeted addition specific to that bypass path. The locked path feeds into the standard refresh cycle which handles renewal scheduling. Do not flag the missing error guard or missing renewal scheduling on the locked disk-check path as a decomposition regression in future reviews — adding them would be scope expansion beyond the refactoring goal.
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 0
File: :0-0
Timestamp: 2026-03-29T16:31:31.631Z
Learning: In vybestack/llxprt-code issue `#1783` (OAuth bucket failover behavioral test spec), the formal scenario catalog was expanded from 39 to ~58 scenarios with four new categories: UE-01–UE-08 (User Entry Points/Lifecycle Triggers), SA-01–SA-04 (Subagent Isolation, tied to PR `#1720/`#1718/#1719), EC-01–EC-04 (Error & Edge Cases), and RO-01–RO-03 (Multi-bucket RetryOrchestrator Integration). Critical zero-coverage gaps are: SB-10 (auth flow mid-turn timeout), UE lifecycle triggers (useGeminiStream.ts turn boundary), SA subagent isolation regressions, and RO multi-bucket retry paths. Two mock-theater test files should be rewritten with MemoryTokenStore: `oauth-manager.failover-wiring.spec.ts` and `oauth-manager.getToken-bucket-peek.spec.ts`. Cross-process simulation uses shared SecureStore/lockDir (two KeyringTokenStore instances), not child_process.fork.
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1874
File: packages/core/src/providers/__tests__/RetryOrchestrator.onAuthError.test.ts:79-404
Timestamp: 2026-04-03T05:57:51.304Z
Learning: In vybestack/llxprt-code, `RetryOrchestrator.onAuthError` tests (packages/core/src/providers/__tests__/RetryOrchestrator.onAuthError.test.ts, PR `#1874`) are intentionally scoped to the default/single-bucket path covering issue1861's core fix. Multi-bucket / non-default session-bucket regression coverage belongs at the OAuthManager/TokenAccessCoordinator layer (forceRefreshToken.test.ts), not in RetryOrchestrator tests. Do not flag the absence of multi-bucket bucket-context tests in RetryOrchestrator.onAuthError.test.ts as a coverage gap.
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1778
File: packages/cli/src/auth/auth-flow-orchestrator.ts:431-437
Timestamp: 2026-03-26T02:12:39.396Z
Learning: In `packages/cli/src/auth/auth-flow-orchestrator.ts` (vybestack/llxprt-code PR `#1778`, decomposed from `oauth-manager.ts`), the early return in `authenticateMultipleBuckets` when `unauthenticatedBuckets.length === 0` intentionally skips re-enabling OAuth in-memory/settings and skips installing a bucket failover handler. This is pre-existing behavior faithfully extracted from the original `oauth-manager.ts` around line 2547 on main. Do not flag the missing success-side-effects (provider enablement, failover handler installation) on the all-valid fast path as a bug in decomposition or future PRs — adding these side-effects would be a behavioral change beyond the refactoring scope.
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1778
File: packages/cli/src/auth/qwen-oauth-provider.ts:234-242
Timestamp: 2026-03-26T00:30:20.796Z
Learning: In `packages/cli/src/auth/qwen-oauth-provider.ts` (vybestack/llxprt-code PR `#1778`, decomposed from `oauth-manager.ts`), the broad `catch` block in `openQwenBrowserIfInteractive` that silently swallows all errors from the dynamic import of `../runtime/runtimeSettings.js` (setting `noBrowser = false` as the default) is pre-existing behavior faithfully extracted from the original `oauth-manager.ts`. Do not flag the absence of debug logging or error discrimination in this catch block as a gap in decomposition or future PRs — adding error-type discrimination would be a behavioral change beyond the refactoring scope.
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1874
File: packages/cli/src/auth/__tests__/forceRefreshToken.test.ts:449-477
Timestamp: 2026-04-03T06:29:38.156Z
Learning: In `packages/cli/src/auth/token-access-coordinator.ts` (vybestack/llxprt-code PR `#1874`), `forceRefreshToken` uses a lock-first, single-read TOCTOU pattern: acquire refresh lock → read stored token once (under the lock) → compare stored token with failed access token → act. There is no pre-lock read. The test in `packages/cli/src/auth/__tests__/forceRefreshToken.test.ts` correctly simulates the "another process already refreshed" case by preloading an updated token in the store. Do not flag the absence of a second `getToken` call or suggest asserting `getToken` was called twice — the implementation intentionally reads only once under the lock.
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1778
File: packages/cli/src/auth/provider-usage-info.ts:228-233
Timestamp: 2026-03-26T00:30:00.337Z
Learning: In `packages/cli/src/auth/provider-usage-info.ts` (vybestack/llxprt-code PR `#1778`, decomposed from `oauth-manager.ts`), `getHigherPriorityAuth` calls `getSettingsService().get('authOnly')` globally (without a try/catch guard) alongside the passed `LoadedSettings`. This is pre-existing behavior faithfully extracted from the original `getHigherPriorityAuth` method at line 1836 of `oauth-manager.ts` on main. Do not flag the unconditional `getSettingsService()` call or the `authOnly` handling pattern as a new issue or scope expansion in decomposition or future PRs — rearchitecting the auth-priority dependency chain is explicitly out of scope.
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1785
File: packages/cli/src/config/__tests__/approvalModeParity.test.ts:351-393
Timestamp: 2026-03-27T01:00:29.058Z
Learning: In `packages/cli/src/config/__tests__/approvalModeParity.test.ts` (vybestack/llxprt-code PR `#1785`), the test suite is intentionally scoped to verifying that the extracted approval-mode resolution logic in `approvalModeResolver.ts` produces identical results to the original inline logic. Adding new combination scenarios (e.g., admin-disabled YOLO combined with an untrusted folder) is considered scope expansion beyond parity coverage. The ordering of admin checks before trust-fallback checks is preserved from the original code. Do not flag missing cross-branch combination tests in this file as a gap in refactoring PRs.
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1778
File: packages/cli/src/auth/BucketFailoverHandlerImpl.spec.ts:500-503
Timestamp: 2026-03-26T00:29:42.510Z
Learning: In `packages/cli/src/auth/BucketFailoverHandlerImpl.spec.ts` (vybestack/llxprt-code), the `if (provider)` guard pattern used after `oauthManager.getProvider(...)` to conditionally stub `provider.refreshToken` is pre-existing from the original test suite. Do not flag this as a silent-skip risk or suggest hardening (e.g., `expect(provider).toBeDefined()`) in decomposition or refactoring PRs — changing test structure is explicitly out of scope for those PRs.
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1778
File: packages/cli/src/auth/auth-status-service.ts:241-263
Timestamp: 2026-03-26T02:12:35.416Z
Learning: In `packages/cli/src/auth/auth-status-service.ts` (vybestack/llxprt-code PR `#1778`, decomposed from `oauth-manager.ts`), `logoutAll()` only iterates `tokenStore.listProviders()` and does not include providers whose auth state is managed exclusively via `provider.isAuthenticated()` (i.e., providers with no persisted token store entry). This is pre-existing behavior faithfully extracted from the original `oauth-manager.ts` `logoutAll()`. Do not flag this as a regression or gap in decomposition PRs — improving coverage to include registry-only providers is a follow-up enhancement, not a refactoring concern.
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 0
File: :0-0
Timestamp: 2026-02-16T19:05:47.580Z
Learning: Issue `#1442` resolution: Random Codex OAuth failures were caused by stale tokens from the old MultiProviderTokenStore after migration to KeyringTokenStore (commits 916605df, 8aeecbee). Old tokens failed CodexOAuthTokenSchema validation (missing account_id) causing random auth requests. Repeated logout/login manually cleaned up both storage locations. Codex provider lacks legacy cleanup methods that Gemini has (migrateFromLegacyTokens, clearLegacyTokens). Solution: add automatic legacy cleanup to Codex like Gemini.
📚 Learning: 2026-03-26T00:30:20.796Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1778
File: packages/cli/src/auth/qwen-oauth-provider.ts:234-242
Timestamp: 2026-03-26T00:30:20.796Z
Learning: In `packages/cli/src/auth/qwen-oauth-provider.ts` (vybestack/llxprt-code PR `#1778`, decomposed from `oauth-manager.ts`), the broad `catch` block in `openQwenBrowserIfInteractive` that silently swallows all errors from the dynamic import of `../runtime/runtimeSettings.js` (setting `noBrowser = false` as the default) is pre-existing behavior faithfully extracted from the original `oauth-manager.ts`. Do not flag the absence of debug logging or error discrimination in this catch block as a gap in decomposition or future PRs — adding error-type discrimination would be a behavioral change beyond the refactoring scope.

Applied to files:

  • packages/cli/src/auth/codex-oauth-provider.ts
  • packages/core/src/auth/codex-device-flow.ts
📚 Learning: 2026-02-16T19:05:47.580Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 0
File: :0-0
Timestamp: 2026-02-16T19:05:47.580Z
Learning: Issue `#1442` resolution: Random Codex OAuth failures were caused by stale tokens from the old MultiProviderTokenStore after migration to KeyringTokenStore (commits 916605df, 8aeecbee). Old tokens failed CodexOAuthTokenSchema validation (missing account_id) causing random auth requests. Repeated logout/login manually cleaned up both storage locations. Codex provider lacks legacy cleanup methods that Gemini has (migrateFromLegacyTokens, clearLegacyTokens). Solution: add automatic legacy cleanup to Codex like Gemini.

Applied to files:

  • packages/cli/src/auth/codex-oauth-provider.ts
📚 Learning: 2026-03-27T01:24:59.499Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1784
File: packages/cli/src/auth/codex-oauth-provider.ts:394-402
Timestamp: 2026-03-27T01:24:59.499Z
Learning: In `packages/cli/src/auth/**` (including `codex-oauth-provider.ts` and related OAuth bridge files), `-1` is an intentional sentinel value used by stub `addItem` callbacks where no real history ID is available (for example `p.setAddItem?.(() => -1)`). Reviewers should not flag this as a magic number, nor suggest replacing it with a named constant, since callers never consume the returned ID and the literal `-1` is an established convention in this codebase.

Applied to files:

  • packages/cli/src/auth/codex-oauth-provider.ts
  • packages/cli/src/auth/codex-oauth-provider.spec.ts
📚 Learning: 2026-03-26T00:30:00.337Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1778
File: packages/cli/src/auth/provider-usage-info.ts:228-233
Timestamp: 2026-03-26T00:30:00.337Z
Learning: In `packages/cli/src/auth/provider-usage-info.ts` (vybestack/llxprt-code PR `#1778`, decomposed from `oauth-manager.ts`), `getHigherPriorityAuth` calls `getSettingsService().get('authOnly')` globally (without a try/catch guard) alongside the passed `LoadedSettings`. This is pre-existing behavior faithfully extracted from the original `getHigherPriorityAuth` method at line 1836 of `oauth-manager.ts` on main. Do not flag the unconditional `getSettingsService()` call or the `authOnly` handling pattern as a new issue or scope expansion in decomposition or future PRs — rearchitecting the auth-priority dependency chain is explicitly out of scope.

Applied to files:

  • packages/cli/src/auth/codex-oauth-provider.ts
📚 Learning: 2026-03-26T02:12:39.396Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1778
File: packages/cli/src/auth/auth-flow-orchestrator.ts:431-437
Timestamp: 2026-03-26T02:12:39.396Z
Learning: In `packages/cli/src/auth/auth-flow-orchestrator.ts` (vybestack/llxprt-code PR `#1778`, decomposed from `oauth-manager.ts`), the early return in `authenticateMultipleBuckets` when `unauthenticatedBuckets.length === 0` intentionally skips re-enabling OAuth in-memory/settings and skips installing a bucket failover handler. This is pre-existing behavior faithfully extracted from the original `oauth-manager.ts` around line 2547 on main. Do not flag the missing success-side-effects (provider enablement, failover handler installation) on the all-valid fast path as a bug in decomposition or future PRs — adding these side-effects would be a behavioral change beyond the refactoring scope.

Applied to files:

  • packages/cli/src/auth/codex-oauth-provider.ts
  • packages/cli/src/auth/codex-oauth-provider.spec.ts
📚 Learning: 2026-03-26T02:12:35.416Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1778
File: packages/cli/src/auth/auth-status-service.ts:241-263
Timestamp: 2026-03-26T02:12:35.416Z
Learning: In `packages/cli/src/auth/auth-status-service.ts` (vybestack/llxprt-code PR `#1778`, decomposed from `oauth-manager.ts`), `logoutAll()` only iterates `tokenStore.listProviders()` and does not include providers whose auth state is managed exclusively via `provider.isAuthenticated()` (i.e., providers with no persisted token store entry). This is pre-existing behavior faithfully extracted from the original `oauth-manager.ts` `logoutAll()`. Do not flag this as a regression or gap in decomposition PRs — improving coverage to include registry-only providers is a follow-up enhancement, not a refactoring concern.

Applied to files:

  • packages/cli/src/auth/codex-oauth-provider.ts
  • packages/cli/src/auth/codex-oauth-provider.spec.ts
📚 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/cli/src/auth/codex-oauth-provider.ts
  • packages/core/src/auth/codex-device-flow.ts
  • packages/core/src/storage/secure-store.ts
  • packages/cli/src/auth/codex-oauth-provider.spec.ts
  • packages/core/src/storage/secure-store.spec.ts
📚 Learning: 2026-03-03T15:00:27.688Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1656
File: packages/cli/src/auth/gemini-oauth-provider.ts:349-361
Timestamp: 2026-03-03T15:00:27.688Z
Learning: Centralize token expiry handling in OAuthManager and keep OAuth provider implementations as read-only pass-throughs. In vybestack/llxprt-code, after the issue `#1652` refactor, providers (GeminiOAuthProvider, CodexOAuthProvider, AnthropicOAuthProvider, QwenOAuthProvider) should not perform expiry checks or refresh logic; OAuthManager.getToken() and OAuthManager.getOAuthToken() must validate expiry and refresh when needed before returning tokens. Provider refreshIfNeeded() should be deprecated no-ops. This pattern should apply to all OAuth provider implementations, not just the Gemini provider.

Applied to files:

  • packages/cli/src/auth/codex-oauth-provider.ts
📚 Learning: 2026-03-26T01:27:59.283Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1778
File: packages/cli/src/auth/auth-flow-orchestrator.ts:692-705
Timestamp: 2026-03-26T01:27:59.283Z
Learning: When reviewing code under packages/cli/src/auth (including decomposed modules related to auth-flow orchestration), do not treat missing explicit bucket strings as a production behavioral change if the production token store normalizes `bucket` with `bucket ?? DEFAULT_BUCKET` (where `DEFAULT_BUCKET` is the string "default"). In particular, passing `undefined` for `bucket` should be considered equivalent to passing "default", so calls like `getToken(provider, undefined)` are functionally identical to `getToken(provider, "default")` in production. This normalization is part of the existing production contract (e.g., KeyringTokenStore / prior oauth-manager behavior); InMemoryTokenStore/test helpers do not govern that production behavior.

Applied to files:

  • packages/cli/src/auth/codex-oauth-provider.ts
  • packages/cli/src/auth/codex-oauth-provider.spec.ts
📚 Learning: 2026-03-26T01:28:33.474Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1778
File: packages/cli/src/auth/provider-usage-info.ts:36-37
Timestamp: 2026-03-26T01:28:33.474Z
Learning: When doing token lookups via `tokenStore.getToken(provider, bucket)` in `packages/cli/src/auth`, treat `bucket ?? 'default'` as correct when the goal is to normalize missing buckets to the default bucket. The production `KeyringTokenStore` already normalizes `undefined` to `DEFAULT_BUCKET` (`"default"`), and this pattern was also used in the original `oauth-manager.ts`, so using `bucket ?? 'default'` here is faithful and should not be flagged as a contract/lookup violation nor used to recommend splitting `undefined` (lookup) vs `'default'` (display) behavior across this codebase.

Applied to files:

  • packages/cli/src/auth/codex-oauth-provider.ts
  • packages/cli/src/auth/codex-oauth-provider.spec.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/cli/src/auth/codex-oauth-provider.ts
  • packages/core/src/auth/codex-device-flow.ts
  • packages/core/src/storage/secure-store.ts
  • packages/cli/src/auth/codex-oauth-provider.spec.ts
  • packages/core/src/storage/secure-store.spec.ts
📚 Learning: 2026-03-25T00:25:22.892Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1741
File: packages/core/src/config/configConstructor.ts:77-203
Timestamp: 2026-03-25T00:25:22.892Z
Learning: In `packages/core/src/config/configConstructor.ts` (vybestack/llxprt-code PR `#1741`), `ConfigConstructorTarget` is an intentionally exported shadow interface that exists to break the circular dependency between `configConstructor.ts` and `config.ts` — `configConstructor.ts` cannot import `Config` directly without creating a cycle. The six `as unknown as Config` casts inside `applyConfigParams` are intentional and limited to operations that genuinely require the full concrete `Config` type: `initializeTelemetry`, `FileExclusions`, `createAgentRuntimeStateFromConfig`, and `logCliConfiguration`. Both `ConfigConstructorTarget` and `applyConfigParams` must remain exported so `config.ts` can import and use them. Do not flag this pattern as a maintenance smell or suggest moving these symbols to be non-exported or file-local in decomposition/refactoring PRs.

Applied to files:

  • packages/core/src/auth/codex-device-flow.ts
📚 Learning: 2026-03-24T23:55:40.614Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1741
File: packages/core/src/config/config.ts:52-82
Timestamp: 2026-03-24T23:55:40.614Z
Learning: In vybestack/llxprt-code, `TelemetryTarget` was never exported from `packages/core/src/config/config.ts` on main. It is always imported directly from `../telemetry/index.js` (or re-exported via `configTypes.ts`). Do not flag its absence from the backward-compat re-export block in `config.ts` as a missing export — no consumer imports it from any config path.

Applied to files:

  • packages/core/src/auth/codex-device-flow.ts
📚 Learning: 2026-03-26T00:29:57.154Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1778
File: packages/cli/src/auth/OAuthBucketManager.ts:36-47
Timestamp: 2026-03-26T00:29:57.154Z
Learning: In `packages/cli/src/auth/OAuthBucketManager.ts` (vybestack/llxprt-code), `getSessionBucketScopeKey(provider, metadata?)` must remain public — it is called externally by `packages/cli/src/auth/token-bucket-failover-helper.ts` (lines 66 and 73) to compute session/bucket scope keys. Do not suggest making it private in code reviews.

Applied to files:

  • packages/core/src/auth/codex-device-flow.ts
📚 Learning: 2026-03-27T01:25:02.388Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1784
File: packages/cli/src/auth/codex-oauth-provider.ts:394-402
Timestamp: 2026-03-27T01:25:02.388Z
Learning: In `packages/cli/src/auth/codex-oauth-provider.ts` and related files (vybestack/llxprt-code), `-1` is an established sentinel value for stub `addItem` callbacks where no real history ID is available (e.g., `p.setAddItem?.(() => -1)` in `useUpdateAndOAuthBridges.ts`). Callers never consume the returned ID. Do not suggest replacing this literal with a named constant — it is intentional codebase-wide convention.

Applied to files:

  • packages/core/src/auth/codex-device-flow.ts
📚 Learning: 2026-03-24T21:33:43.130Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1766
File: packages/cli/src/runtime/providerMutations.ts:258-265
Timestamp: 2026-03-24T21:33:43.130Z
Learning: In `packages/cli/src/runtime/providerMutations.ts` (vybestack/llxprt-code PR `#1766`, decomposed from the original `runtimeSettings.ts`), `updateActiveProviderApiKey` intentionally does NOT clear `auth-key` in `settingsService` during the update (non-null key) branch. The update branch sets the ephemeral `auth-key` to the new value instead; only the remove (null/empty key) branch clears all aliases in both `settingsService` and config ephemeral settings. This asymmetry is pre-existing behavior from the original `runtimeSettings.ts` (lines 2182-2187 on main). Do not flag this as a credential-leak or stale-alias bug in decomposition reviews.

Applied to files:

  • packages/core/src/storage/secure-store.ts
📚 Learning: 2026-03-24T21:35:42.622Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1766
File: packages/cli/src/runtime/settingsResolver.ts:96-103
Timestamp: 2026-03-24T21:35:42.622Z
Learning: In `packages/cli/src/runtime/settingsResolver.ts` (vybestack/llxprt-code PR `#1766`), the `--key` and `--keyfile` branches both call `updateActiveProviderApiKey`, which internally calls `config.setEphemeralSetting('auth-key-name', undefined)` at line 289 of `providerMutations.ts` (update branch) and line 265 (remove branch). Do not flag missing `auth-key-name` clearing at the `settingsResolver.ts` call sites — it is already handled inside the mutation function. Trace the full call chain into `updateActiveProviderApiKey` before raising such a comment.

Applied to files:

  • packages/core/src/storage/secure-store.ts
📚 Learning: 2026-03-26T03:34:18.861Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1778
File: packages/cli/src/auth/token-access-coordinator.ts:640-647
Timestamp: 2026-03-26T03:34:18.861Z
Learning: In `packages/cli/src/auth/token-access-coordinator.ts` (vybestack/llxprt-code PR `#1778`, decomposed from `oauth-manager.ts`), the locked disk-check path in `performDiskCheck()` calls `performDiskCheckUnderLock()` without a surrounding try-catch and does not call `scheduleProactiveRenewal()` on the result. This is pre-existing behavior faithfully extracted from the original `oauth-manager.ts` line ~1308 on main. The proactive renewal call on the unlocked fallback (line ~653) is a targeted addition specific to that bypass path. The locked path feeds into the standard refresh cycle which handles renewal scheduling. Do not flag the missing error guard or missing renewal scheduling on the locked disk-check path as a decomposition regression in future reviews — adding them would be scope expansion beyond the refactoring goal.

Applied to files:

  • packages/core/src/storage/secure-store.ts
  • packages/core/src/storage/secure-store.spec.ts
📚 Learning: 2026-03-26T01:28:01.197Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1778
File: packages/cli/src/auth/auth-flow-orchestrator.ts:692-705
Timestamp: 2026-03-26T01:28:01.197Z
Learning: In vybestack/llxprt-code, the production `KeyringTokenStore` (at `packages/core/src/auth/keyring-token-store.ts` line 94) normalizes an `undefined` bucket argument to `DEFAULT_BUCKET` (the string `"default"`) internally via `const resolvedBucket = bucket ?? DEFAULT_BUCKET`. As a result, `getToken(provider, undefined)` and `getToken(provider, "default")` are functionally identical in production. The original `oauth-manager.ts` also applied the same `bucket ?? "default"` normalization (line 2169). Do not flag the omission of explicit `"default"` bucket strings in `auth-flow-orchestrator.ts` or related decomposed modules as a behavioral divergence — passing `undefined` is equivalent and is a faithful extraction of pre-existing behavior. InMemoryTokenStore behavior in test helpers does not govern the production contract.

Applied to files:

  • packages/core/src/storage/secure-store.ts
  • packages/core/src/storage/secure-store.spec.ts
📚 Learning: 2026-03-26T00:29:42.510Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1778
File: packages/cli/src/auth/BucketFailoverHandlerImpl.spec.ts:500-503
Timestamp: 2026-03-26T00:29:42.510Z
Learning: In `packages/cli/src/auth/BucketFailoverHandlerImpl.spec.ts` (vybestack/llxprt-code), the `if (provider)` guard pattern used after `oauthManager.getProvider(...)` to conditionally stub `provider.refreshToken` is pre-existing from the original test suite. Do not flag this as a silent-skip risk or suggest hardening (e.g., `expect(provider).toBeDefined()`) in decomposition or refactoring PRs — changing test structure is explicitly out of scope for those PRs.

Applied to files:

  • packages/cli/src/auth/codex-oauth-provider.spec.ts
  • packages/core/src/storage/secure-store.spec.ts
📚 Learning: 2026-03-29T16:31:31.631Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 0
File: :0-0
Timestamp: 2026-03-29T16:31:31.631Z
Learning: In vybestack/llxprt-code issue `#1783` (OAuth bucket failover behavioral test spec), the formal scenario catalog was expanded from 39 to ~58 scenarios with four new categories: UE-01–UE-08 (User Entry Points/Lifecycle Triggers), SA-01–SA-04 (Subagent Isolation, tied to PR `#1720/`#1718/#1719), EC-01–EC-04 (Error & Edge Cases), and RO-01–RO-03 (Multi-bucket RetryOrchestrator Integration). Critical zero-coverage gaps are: SB-10 (auth flow mid-turn timeout), UE lifecycle triggers (useGeminiStream.ts turn boundary), SA subagent isolation regressions, and RO multi-bucket retry paths. Two mock-theater test files should be rewritten with MemoryTokenStore: `oauth-manager.failover-wiring.spec.ts` and `oauth-manager.getToken-bucket-peek.spec.ts`. Cross-process simulation uses shared SecureStore/lockDir (two KeyringTokenStore instances), not child_process.fork.

Applied to files:

  • packages/cli/src/auth/codex-oauth-provider.spec.ts
  • packages/core/src/storage/secure-store.spec.ts
📚 Learning: 2026-04-03T05:57:42.326Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1874
File: packages/core/src/auth/invalidateProviderCache.test.ts:107-163
Timestamp: 2026-04-03T05:57:42.326Z
Learning: In `packages/core/src/auth/invalidateProviderCache.test.ts` (vybestack/llxprt-code PR `#1874`), the profile-specific positive-match path for `invalidateProviderCache('anthropic', profileId)` is intentionally not directly tested because `resolveAuthentication` does not expose a `profileId` metadata parameter in its public API, making it impossible to construct a profile-keyed cache entry from outside. The wildcard invalidation test (`invalidateProviderCache('anthropic')` with no profileId) exercises the same matching predicate. Do not flag the missing profile-specific positive-match case as a test gap — adding it is a low-priority follow-up that requires internal API changes.

Applied to files:

  • packages/cli/src/auth/codex-oauth-provider.spec.ts
  • packages/core/src/storage/secure-store.spec.ts
📚 Learning: 2026-04-03T05:57:51.304Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1874
File: packages/core/src/providers/__tests__/RetryOrchestrator.onAuthError.test.ts:79-404
Timestamp: 2026-04-03T05:57:51.304Z
Learning: In vybestack/llxprt-code, `RetryOrchestrator.onAuthError` tests (packages/core/src/providers/__tests__/RetryOrchestrator.onAuthError.test.ts, PR `#1874`) are intentionally scoped to the default/single-bucket path covering issue1861's core fix. Multi-bucket / non-default session-bucket regression coverage belongs at the OAuthManager/TokenAccessCoordinator layer (forceRefreshToken.test.ts), not in RetryOrchestrator tests. Do not flag the absence of multi-bucket bucket-context tests in RetryOrchestrator.onAuthError.test.ts as a coverage gap.

Applied to files:

  • packages/cli/src/auth/codex-oauth-provider.spec.ts
  • packages/core/src/storage/secure-store.spec.ts
📚 Learning: 2026-03-19T23:27:49.587Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1736
File: packages/core/src/providers/openai/__tests__/OpenAIProvider.e2e.test.ts:199-203
Timestamp: 2026-03-19T23:27:49.587Z
Learning: In `packages/core/src/providers/openai/__tests__/OpenAIProvider.e2e.test.ts` (vybestack/llxprt-code), Scenarios 3, 7a, 7b, and 7c use `buildMessagesWithReasoning` (imported directly from `OpenAIRequestBuilder`) rather than calling `provider.generateChatCompletion`. This is intentional and pre-existing behavior: the original tests accessed the same helper via a hacky `buildMessagesWithReasoning.call(provider, ...)` private-method pattern. The PR's direct import is an improvement, not a regression. Do not flag these scenarios as insufficiently integrated — they are helper-level tests by design, and adding full provider-path coverage is out of scope for refactoring PRs.

Applied to files:

  • packages/cli/src/auth/codex-oauth-provider.spec.ts
📚 Learning: 2026-03-27T01:00:29.058Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1785
File: packages/cli/src/config/__tests__/approvalModeParity.test.ts:351-393
Timestamp: 2026-03-27T01:00:29.058Z
Learning: In `packages/cli/src/config/__tests__/approvalModeParity.test.ts` (vybestack/llxprt-code PR `#1785`), the test suite is intentionally scoped to verifying that the extracted approval-mode resolution logic in `approvalModeResolver.ts` produces identical results to the original inline logic. Adding new combination scenarios (e.g., admin-disabled YOLO combined with an untrusted folder) is considered scope expansion beyond parity coverage. The ordering of admin checks before trust-fallback checks is preserved from the original code. Do not flag missing cross-branch combination tests in this file as a gap in refactoring PRs.

Applied to files:

  • packages/cli/src/auth/codex-oauth-provider.spec.ts
  • packages/core/src/storage/secure-store.spec.ts
📚 Learning: 2026-03-20T01:26:21.401Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1736
File: packages/core/src/providers/openai/OpenAIClientFactory.test.ts:241-246
Timestamp: 2026-03-20T01:26:21.401Z
Learning: In `packages/core/src/providers/openai/OpenAIClientFactory.test.ts` (vybestack/llxprt-code PR `#1736`), the `instantiateClient` tests intentionally inspect the OpenAI SDK's internal `_options` field (e.g., `(client as unknown as Record<string, unknown>)._options`) to assert `defaultHeaders` and HTTP agent propagation. This is a deliberate pragmatic tradeoff over mocking the OpenAI constructor (which would require module-level `vi.mock`, constructor spy setup, and restore lifecycle). The `_options` field has been stable across many SDK versions, and the approach is considered acceptable. Do not flag `_options` inspection in this test file as relying on unstable internals.

Applied to files:

  • packages/cli/src/auth/codex-oauth-provider.spec.ts
📚 Learning: 2026-04-03T06:29:38.156Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1874
File: packages/cli/src/auth/__tests__/forceRefreshToken.test.ts:449-477
Timestamp: 2026-04-03T06:29:38.156Z
Learning: In `packages/cli/src/auth/token-access-coordinator.ts` (vybestack/llxprt-code PR `#1874`), `forceRefreshToken` uses a lock-first, single-read TOCTOU pattern: acquire refresh lock → read stored token once (under the lock) → compare stored token with failed access token → act. There is no pre-lock read. The test in `packages/cli/src/auth/__tests__/forceRefreshToken.test.ts` correctly simulates the "another process already refreshed" case by preloading an updated token in the store. Do not flag the absence of a second `getToken` call or suggest asserting `getToken` was called twice — the implementation intentionally reads only once under the lock.

Applied to files:

  • packages/cli/src/auth/codex-oauth-provider.spec.ts
  • packages/core/src/storage/secure-store.spec.ts
📚 Learning: 2026-03-31T02:14:05.575Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1854
File: packages/core/src/providers/openai/schemaConverter.issue1844.test.ts:14-20
Timestamp: 2026-03-31T02:14:05.575Z
Learning: In `packages/core/src/providers/openai/schemaConverter.issue1844.test.ts` and neighboring issue regression test files (e.g., `openai-vercel/schemaConverter.issue1844.test.ts`, `subagentRuntimeSetup.issue1844.test.ts`, `AnthropicResponseParser.issue1844.test.ts`), the pattern of using a `beforeAll` async dynamic import to load the module under test is intentional. This style is used consistently across all `*.issue1844.test.ts` regression test files for loading consistency. Do not suggest replacing dynamic imports with static imports in these files.

Applied to files:

  • packages/cli/src/auth/codex-oauth-provider.spec.ts
📚 Learning: 2026-03-27T00:46:43.700Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1785
File: packages/cli/src/config/__tests__/folderTrustOriginalSettingsParity.test.ts:347-383
Timestamp: 2026-03-27T00:46:43.700Z
Learning: In `packages/cli/src/config/__tests__/folderTrustOriginalSettingsParity.test.ts` (vybestack/llxprt-code PR `#1785`), the last test ("profile ephemeral folderTrust value does NOT change the trust check") intentionally omits a real profile load. Its sole purpose is to assert that `isWorkspaceTrusted` is called with the original settings object (not a profile-merged copy) in the untrusted-folder branch. The profile-merge path is covered by other parity test files. Do not suggest adding an inline profile or `LLXPRT_PROFILE` env var to this test — that would be scope expansion beyond its intended parity coverage.

Applied to files:

  • packages/core/src/storage/secure-store.spec.ts
📚 Learning: 2026-03-27T01:00:28.649Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1785
File: packages/cli/src/config/__tests__/toolGovernanceParity.test.ts:458-472
Timestamp: 2026-03-27T01:00:28.649Z
Learning: In `packages/cli/src/config/__tests__/toolGovernanceParity.test.ts` (vybestack/llxprt-code PR `#1785`), the "non-interactive DEFAULT with explicit --allowed-tools" and corresponding YOLO test cases intentionally use `read_file` (a tool already in `READ_ONLY_TOOL_NAMES`) as the explicit `--allowed-tools` value. The tests are scoped to verifying that existing allowlist behavior is preserved through the refactor, not to proving union/exclusion semantics with non-read-only tools. Do not flag the choice of `read_file` as insufficient for proving merging behavior in parity or refactoring PRs — improving assertion specificity is new test design work beyond the refactoring scope.

Applied to files:

  • packages/core/src/storage/secure-store.spec.ts
📚 Learning: 2026-03-27T02:12:12.434Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1785
File: packages/cli/src/config/__tests__/profileOverridePrecedenceParity.test.ts:212-306
Timestamp: 2026-03-27T02:12:12.434Z
Learning: In `packages/cli/src/config/__tests__/profileOverridePrecedenceParity.test.ts` (vybestack/llxprt-code PR `#1785`), `applyProfileSnapshot` is intentionally mocked in both `../../runtime/profileSnapshot.js` (the primary call-tracking mock, capturing calls into `profileSnapshotCalls`) and `../../runtime/runtimeSettings.js` (a fallback mock). This dual mocking is required because `config.ts` imports `applyProfileSnapshot` from both paths. Do not flag this as confusing duplication or suggest collapsing into a single mock in future reviews.

Applied to files:

  • packages/core/src/storage/secure-store.spec.ts
📚 Learning: 2026-03-29T20:44:28.357Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1841
File: packages/cli/src/auth/__tests__/behavioral/user-entry-points.behavioral.spec.ts:131-159
Timestamp: 2026-03-29T20:44:28.357Z
Learning: In `packages/cli/src/auth/__tests__/behavioral/user-entry-points.behavioral.spec.ts` (vybestack/llxprt-code PR `#1841`), UE-03 intentionally calls `handler.resetSession()` directly rather than triggering it through the actual turn-boundary entry point in `useGeminiStream.ts` (L73). This is an explicit scope boundary: `useGeminiStream.ts` is a React hook that requires a full UI render context; testing through it would require mounting React components and simulating user input, which is a different category of integration test. The behavioral spec verifies the handler-level contract (resetSession clears triedBuckets and enables fresh failover). Do not flag the direct `resetSession()` call in this test as missing turn-boundary wiring coverage.

Applied to files:

  • packages/core/src/storage/secure-store.spec.ts
📚 Learning: 2026-03-26T01:28:37.959Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1778
File: packages/cli/src/auth/provider-usage-info.ts:36-37
Timestamp: 2026-03-26T01:28:37.959Z
Learning: In `packages/cli/src/auth/provider-usage-info.ts` (vybestack/llxprt-code PR `#1778`, decomposed from `oauth-manager.ts`), the `bucket ?? 'default'` normalization before calling `tokenStore.getToken(provider, bucket)` is correct and functionally identical to passing `undefined`. The production `KeyringTokenStore` (packages/core/src/auth/keyring-token-store.ts, line 94) already normalizes `undefined` to `DEFAULT_BUCKET` (the string `"default"`) internally via `const resolvedBucket = bucket ?? DEFAULT_BUCKET`. The `InMemoryTokenStore` used in test helpers does not define the production contract. Do not flag `bucket ?? 'default'` lookups as a contract violation or suggest splitting into `undefined`-for-lookup vs `'default'`-for-display in this codebase — the original `oauth-manager.ts` used the same pattern (line 2169) and the behavior is faithfully preserved.

Applied to files:

  • packages/core/src/storage/secure-store.spec.ts
🪛 GitHub Actions: LLxprt Code CI
packages/core/src/storage/secure-store.spec.ts

[error] 133-133: Prettier failed during formatting step (npm run format / prettier --experimental-cli --write .). Prettier reported a diff indicating formatting changes were applied, and the job exited with code 1.

🔇 Additional comments (3)
packages/core/src/auth/codex-device-flow.ts (1)

18-20: Good centralization of Codex OAuth constants.

Exporting CODEX_CONFIG here gives CLI/core a single source of truth and directly prevents callback URI drift.

packages/cli/src/auth/codex-oauth-provider.ts (1)

11-12: Canonical callback wiring is correctly applied.

Nice fix: provider now consumes CODEX_CONFIG.deviceAuthCallbackUri instead of a literal, which addresses the redirect mismatch at the root cause.

Also applies to: 336-341

packages/cli/src/auth/codex-oauth-provider.spec.ts (1)

294-363: Targeted regression test is solid.

This test cleanly locks in the canonical device callback URI behavior and explicitly guards against reintroducing the old incorrect URI.

Comment thread packages/core/src/storage/secure-store.spec.ts
Comment thread packages/core/src/storage/secure-store.ts Outdated
@acoliver
Copy link
Copy Markdown
Collaborator Author

acoliver commented Apr 9, 2026

Addressed the formatter failure by updating packages/core/src/storage/secure-store.spec.ts to the layout expected by the CI Prettier check, then pushed commit 66a7a33.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/core/src/storage/secure-store.spec.ts`:
- Around line 116-121: The test currently calls store.set('denied-key',
'secret') twice; instead call it once, capture the thrown rejection (e.g., const
p = store.set('denied-key', 'secret')) and assert both the error class
(SecureStoreError) and the message ('Keyring is unavailable and fallback is
denied') from that single invocation so the failure path is verified without
re-executing store.set.
- Around line 43-60: The test's keyring-failure simulation is flaky due to
timer-based toggling; modify the mockKeyring used by SecureStore to expose a
controllable state (e.g., a boolean flag or a promise you can resolve) instead
of calling setTimeout and sleeping—have keyring.setPassword check that
flag/promise and behave as successful first call then fail deterministically
when you flip the flag (or resolve the promise) in the test before continuing;
update the test to flip the flag or resolve the promise instead of relying on
setTimeout + sleep so SecureStore.set('test-key', ...) and the subsequent
failure behavior are reproducible.
🪄 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

Run ID: 6b3ea789-3535-4f1a-ac12-9e8bc7a43eab

📥 Commits

Reviewing files that changed from the base of the PR and between d57c84d and 66a7a33.

📒 Files selected for processing (1)
  • packages/core/src/storage/secure-store.spec.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 270000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: E2E Test (Linux) - sandbox:none
  • GitHub Check: E2E Test (Linux) - sandbox:docker
  • GitHub Check: Lint (Javascript)
🧰 Additional context used
🧠 Learnings (19)
📓 Common learnings
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 0
File: :0-0
Timestamp: 2026-03-29T16:31:31.631Z
Learning: In vybestack/llxprt-code issue `#1783` (OAuth bucket failover behavioral test spec), the formal scenario catalog was expanded from 39 to ~58 scenarios with four new categories: UE-01–UE-08 (User Entry Points/Lifecycle Triggers), SA-01–SA-04 (Subagent Isolation, tied to PR `#1720/`#1718/#1719), EC-01–EC-04 (Error & Edge Cases), and RO-01–RO-03 (Multi-bucket RetryOrchestrator Integration). Critical zero-coverage gaps are: SB-10 (auth flow mid-turn timeout), UE lifecycle triggers (useGeminiStream.ts turn boundary), SA subagent isolation regressions, and RO multi-bucket retry paths. Two mock-theater test files should be rewritten with MemoryTokenStore: `oauth-manager.failover-wiring.spec.ts` and `oauth-manager.getToken-bucket-peek.spec.ts`. Cross-process simulation uses shared SecureStore/lockDir (two KeyringTokenStore instances), not child_process.fork.
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1778
File: packages/cli/src/auth/token-access-coordinator.ts:640-647
Timestamp: 2026-03-26T03:34:18.861Z
Learning: In `packages/cli/src/auth/token-access-coordinator.ts` (vybestack/llxprt-code PR `#1778`, decomposed from `oauth-manager.ts`), the locked disk-check path in `performDiskCheck()` calls `performDiskCheckUnderLock()` without a surrounding try-catch and does not call `scheduleProactiveRenewal()` on the result. This is pre-existing behavior faithfully extracted from the original `oauth-manager.ts` line ~1308 on main. The proactive renewal call on the unlocked fallback (line ~653) is a targeted addition specific to that bypass path. The locked path feeds into the standard refresh cycle which handles renewal scheduling. Do not flag the missing error guard or missing renewal scheduling on the locked disk-check path as a decomposition regression in future reviews — adding them would be scope expansion beyond the refactoring goal.
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1778
File: packages/cli/src/auth/auth-flow-orchestrator.ts:431-437
Timestamp: 2026-03-26T02:12:39.396Z
Learning: In `packages/cli/src/auth/auth-flow-orchestrator.ts` (vybestack/llxprt-code PR `#1778`, decomposed from `oauth-manager.ts`), the early return in `authenticateMultipleBuckets` when `unauthenticatedBuckets.length === 0` intentionally skips re-enabling OAuth in-memory/settings and skips installing a bucket failover handler. This is pre-existing behavior faithfully extracted from the original `oauth-manager.ts` around line 2547 on main. Do not flag the missing success-side-effects (provider enablement, failover handler installation) on the all-valid fast path as a bug in decomposition or future PRs — adding these side-effects would be a behavioral change beyond the refactoring scope.
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1874
File: packages/core/src/providers/__tests__/RetryOrchestrator.onAuthError.test.ts:79-404
Timestamp: 2026-04-03T05:57:51.304Z
Learning: In vybestack/llxprt-code, `RetryOrchestrator.onAuthError` tests (packages/core/src/providers/__tests__/RetryOrchestrator.onAuthError.test.ts, PR `#1874`) are intentionally scoped to the default/single-bucket path covering issue1861's core fix. Multi-bucket / non-default session-bucket regression coverage belongs at the OAuthManager/TokenAccessCoordinator layer (forceRefreshToken.test.ts), not in RetryOrchestrator tests. Do not flag the absence of multi-bucket bucket-context tests in RetryOrchestrator.onAuthError.test.ts as a coverage gap.
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1778
File: packages/cli/src/auth/qwen-oauth-provider.ts:234-242
Timestamp: 2026-03-26T00:30:20.796Z
Learning: In `packages/cli/src/auth/qwen-oauth-provider.ts` (vybestack/llxprt-code PR `#1778`, decomposed from `oauth-manager.ts`), the broad `catch` block in `openQwenBrowserIfInteractive` that silently swallows all errors from the dynamic import of `../runtime/runtimeSettings.js` (setting `noBrowser = false` as the default) is pre-existing behavior faithfully extracted from the original `oauth-manager.ts`. Do not flag the absence of debug logging or error discrimination in this catch block as a gap in decomposition or future PRs — adding error-type discrimination would be a behavioral change beyond the refactoring scope.
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1874
File: packages/cli/src/auth/__tests__/forceRefreshToken.test.ts:449-477
Timestamp: 2026-04-03T06:29:38.156Z
Learning: In `packages/cli/src/auth/token-access-coordinator.ts` (vybestack/llxprt-code PR `#1874`), `forceRefreshToken` uses a lock-first, single-read TOCTOU pattern: acquire refresh lock → read stored token once (under the lock) → compare stored token with failed access token → act. There is no pre-lock read. The test in `packages/cli/src/auth/__tests__/forceRefreshToken.test.ts` correctly simulates the "another process already refreshed" case by preloading an updated token in the store. Do not flag the absence of a second `getToken` call or suggest asserting `getToken` was called twice — the implementation intentionally reads only once under the lock.
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1778
File: packages/cli/src/auth/provider-usage-info.ts:36-37
Timestamp: 2026-03-26T01:28:37.959Z
Learning: In `packages/cli/src/auth/provider-usage-info.ts` (vybestack/llxprt-code PR `#1778`, decomposed from `oauth-manager.ts`), the `bucket ?? 'default'` normalization before calling `tokenStore.getToken(provider, bucket)` is correct and functionally identical to passing `undefined`. The production `KeyringTokenStore` (packages/core/src/auth/keyring-token-store.ts, line 94) already normalizes `undefined` to `DEFAULT_BUCKET` (the string `"default"`) internally via `const resolvedBucket = bucket ?? DEFAULT_BUCKET`. The `InMemoryTokenStore` used in test helpers does not define the production contract. Do not flag `bucket ?? 'default'` lookups as a contract violation or suggest splitting into `undefined`-for-lookup vs `'default'`-for-display in this codebase — the original `oauth-manager.ts` used the same pattern (line 2169) and the behavior is faithfully preserved.
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 0
File: :0-0
Timestamp: 2026-02-16T19:05:47.580Z
Learning: Issue `#1442` resolution: Random Codex OAuth failures were caused by stale tokens from the old MultiProviderTokenStore after migration to KeyringTokenStore (commits 916605df, 8aeecbee). Old tokens failed CodexOAuthTokenSchema validation (missing account_id) causing random auth requests. Repeated logout/login manually cleaned up both storage locations. Codex provider lacks legacy cleanup methods that Gemini has (migrateFromLegacyTokens, clearLegacyTokens). Solution: add automatic legacy cleanup to Codex like Gemini.
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1778
File: packages/cli/src/auth/token-access-coordinator.ts:442-449
Timestamp: 2026-03-26T00:30:25.258Z
Learning: In `packages/cli/src/auth/token-access-coordinator.ts` (vybestack/llxprt-code PR `#1778`, decomposed from `oauth-manager.ts`), `getToken()` calls `peekOtherProfileBuckets()` even when `explicitBucket` is `true`, and the associated profile-bucket count check can suppress auth when multiple profile buckets exist. This is pre-existing behavior faithfully extracted from the original `oauth-manager.ts` getOAuthToken method (lines 1136-1412 on main). The bucket resolution logic intentionally supports profile-scoped session buckets with failover. Do not flag this as a bug in decomposition or future PRs — rearchitecting the bucket resolution chain would be a behavioral change beyond refactoring scope.
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1778
File: packages/cli/src/auth/BucketFailoverHandlerImpl.spec.ts:500-503
Timestamp: 2026-03-26T00:29:42.510Z
Learning: In `packages/cli/src/auth/BucketFailoverHandlerImpl.spec.ts` (vybestack/llxprt-code), the `if (provider)` guard pattern used after `oauthManager.getProvider(...)` to conditionally stub `provider.refreshToken` is pre-existing from the original test suite. Do not flag this as a silent-skip risk or suggest hardening (e.g., `expect(provider).toBeDefined()`) in decomposition or refactoring PRs — changing test structure is explicitly out of scope for those PRs.
📚 Learning: 2026-03-27T01:00:29.058Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1785
File: packages/cli/src/config/__tests__/approvalModeParity.test.ts:351-393
Timestamp: 2026-03-27T01:00:29.058Z
Learning: In `packages/cli/src/config/__tests__/approvalModeParity.test.ts` (vybestack/llxprt-code PR `#1785`), the test suite is intentionally scoped to verifying that the extracted approval-mode resolution logic in `approvalModeResolver.ts` produces identical results to the original inline logic. Adding new combination scenarios (e.g., admin-disabled YOLO combined with an untrusted folder) is considered scope expansion beyond parity coverage. The ordering of admin checks before trust-fallback checks is preserved from the original code. Do not flag missing cross-branch combination tests in this file as a gap in refactoring PRs.

Applied to files:

  • packages/core/src/storage/secure-store.spec.ts
📚 Learning: 2026-03-27T00:46:43.700Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1785
File: packages/cli/src/config/__tests__/folderTrustOriginalSettingsParity.test.ts:347-383
Timestamp: 2026-03-27T00:46:43.700Z
Learning: In `packages/cli/src/config/__tests__/folderTrustOriginalSettingsParity.test.ts` (vybestack/llxprt-code PR `#1785`), the last test ("profile ephemeral folderTrust value does NOT change the trust check") intentionally omits a real profile load. Its sole purpose is to assert that `isWorkspaceTrusted` is called with the original settings object (not a profile-merged copy) in the untrusted-folder branch. The profile-merge path is covered by other parity test files. Do not suggest adding an inline profile or `LLXPRT_PROFILE` env var to this test — that would be scope expansion beyond its intended parity coverage.

Applied to files:

  • packages/core/src/storage/secure-store.spec.ts
📚 Learning: 2026-03-29T16:31:31.631Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 0
File: :0-0
Timestamp: 2026-03-29T16:31:31.631Z
Learning: In vybestack/llxprt-code issue `#1783` (OAuth bucket failover behavioral test spec), the formal scenario catalog was expanded from 39 to ~58 scenarios with four new categories: UE-01–UE-08 (User Entry Points/Lifecycle Triggers), SA-01–SA-04 (Subagent Isolation, tied to PR `#1720/`#1718/#1719), EC-01–EC-04 (Error & Edge Cases), and RO-01–RO-03 (Multi-bucket RetryOrchestrator Integration). Critical zero-coverage gaps are: SB-10 (auth flow mid-turn timeout), UE lifecycle triggers (useGeminiStream.ts turn boundary), SA subagent isolation regressions, and RO multi-bucket retry paths. Two mock-theater test files should be rewritten with MemoryTokenStore: `oauth-manager.failover-wiring.spec.ts` and `oauth-manager.getToken-bucket-peek.spec.ts`. Cross-process simulation uses shared SecureStore/lockDir (two KeyringTokenStore instances), not child_process.fork.

Applied to files:

  • packages/core/src/storage/secure-store.spec.ts
📚 Learning: 2026-04-03T05:57:42.326Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1874
File: packages/core/src/auth/invalidateProviderCache.test.ts:107-163
Timestamp: 2026-04-03T05:57:42.326Z
Learning: In `packages/core/src/auth/invalidateProviderCache.test.ts` (vybestack/llxprt-code PR `#1874`), the profile-specific positive-match path for `invalidateProviderCache('anthropic', profileId)` is intentionally not directly tested because `resolveAuthentication` does not expose a `profileId` metadata parameter in its public API, making it impossible to construct a profile-keyed cache entry from outside. The wildcard invalidation test (`invalidateProviderCache('anthropic')` with no profileId) exercises the same matching predicate. Do not flag the missing profile-specific positive-match case as a test gap — adding it is a low-priority follow-up that requires internal API changes.

Applied to files:

  • packages/core/src/storage/secure-store.spec.ts
📚 Learning: 2026-03-26T00:29:42.510Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1778
File: packages/cli/src/auth/BucketFailoverHandlerImpl.spec.ts:500-503
Timestamp: 2026-03-26T00:29:42.510Z
Learning: In `packages/cli/src/auth/BucketFailoverHandlerImpl.spec.ts` (vybestack/llxprt-code), the `if (provider)` guard pattern used after `oauthManager.getProvider(...)` to conditionally stub `provider.refreshToken` is pre-existing from the original test suite. Do not flag this as a silent-skip risk or suggest hardening (e.g., `expect(provider).toBeDefined()`) in decomposition or refactoring PRs — changing test structure is explicitly out of scope for those PRs.

Applied to files:

  • packages/core/src/storage/secure-store.spec.ts
📚 Learning: 2026-04-03T06:29:38.156Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1874
File: packages/cli/src/auth/__tests__/forceRefreshToken.test.ts:449-477
Timestamp: 2026-04-03T06:29:38.156Z
Learning: In `packages/cli/src/auth/token-access-coordinator.ts` (vybestack/llxprt-code PR `#1874`), `forceRefreshToken` uses a lock-first, single-read TOCTOU pattern: acquire refresh lock → read stored token once (under the lock) → compare stored token with failed access token → act. There is no pre-lock read. The test in `packages/cli/src/auth/__tests__/forceRefreshToken.test.ts` correctly simulates the "another process already refreshed" case by preloading an updated token in the store. Do not flag the absence of a second `getToken` call or suggest asserting `getToken` was called twice — the implementation intentionally reads only once under the lock.

Applied to files:

  • packages/core/src/storage/secure-store.spec.ts
📚 Learning: 2026-03-26T03:34:18.861Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1778
File: packages/cli/src/auth/token-access-coordinator.ts:640-647
Timestamp: 2026-03-26T03:34:18.861Z
Learning: In `packages/cli/src/auth/token-access-coordinator.ts` (vybestack/llxprt-code PR `#1778`, decomposed from `oauth-manager.ts`), the locked disk-check path in `performDiskCheck()` calls `performDiskCheckUnderLock()` without a surrounding try-catch and does not call `scheduleProactiveRenewal()` on the result. This is pre-existing behavior faithfully extracted from the original `oauth-manager.ts` line ~1308 on main. The proactive renewal call on the unlocked fallback (line ~653) is a targeted addition specific to that bypass path. The locked path feeds into the standard refresh cycle which handles renewal scheduling. Do not flag the missing error guard or missing renewal scheduling on the locked disk-check path as a decomposition regression in future reviews — adding them would be scope expansion beyond the refactoring goal.

Applied to files:

  • packages/core/src/storage/secure-store.spec.ts
📚 Learning: 2026-03-27T01:00:28.649Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1785
File: packages/cli/src/config/__tests__/toolGovernanceParity.test.ts:458-472
Timestamp: 2026-03-27T01:00:28.649Z
Learning: In `packages/cli/src/config/__tests__/toolGovernanceParity.test.ts` (vybestack/llxprt-code PR `#1785`), the "non-interactive DEFAULT with explicit --allowed-tools" and corresponding YOLO test cases intentionally use `read_file` (a tool already in `READ_ONLY_TOOL_NAMES`) as the explicit `--allowed-tools` value. The tests are scoped to verifying that existing allowlist behavior is preserved through the refactor, not to proving union/exclusion semantics with non-read-only tools. Do not flag the choice of `read_file` as insufficient for proving merging behavior in parity or refactoring PRs — improving assertion specificity is new test design work beyond the refactoring scope.

Applied to files:

  • packages/core/src/storage/secure-store.spec.ts
📚 Learning: 2026-03-29T20:44:28.357Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1841
File: packages/cli/src/auth/__tests__/behavioral/user-entry-points.behavioral.spec.ts:131-159
Timestamp: 2026-03-29T20:44:28.357Z
Learning: In `packages/cli/src/auth/__tests__/behavioral/user-entry-points.behavioral.spec.ts` (vybestack/llxprt-code PR `#1841`), UE-03 intentionally calls `handler.resetSession()` directly rather than triggering it through the actual turn-boundary entry point in `useGeminiStream.ts` (L73). This is an explicit scope boundary: `useGeminiStream.ts` is a React hook that requires a full UI render context; testing through it would require mounting React components and simulating user input, which is a different category of integration test. The behavioral spec verifies the handler-level contract (resetSession clears triedBuckets and enables fresh failover). Do not flag the direct `resetSession()` call in this test as missing turn-boundary wiring coverage.

Applied to files:

  • packages/core/src/storage/secure-store.spec.ts
📚 Learning: 2026-03-27T02:12:12.434Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1785
File: packages/cli/src/config/__tests__/profileOverridePrecedenceParity.test.ts:212-306
Timestamp: 2026-03-27T02:12:12.434Z
Learning: In `packages/cli/src/config/__tests__/profileOverridePrecedenceParity.test.ts` (vybestack/llxprt-code PR `#1785`), `applyProfileSnapshot` is intentionally mocked in both `../../runtime/profileSnapshot.js` (the primary call-tracking mock, capturing calls into `profileSnapshotCalls`) and `../../runtime/runtimeSettings.js` (a fallback mock). This dual mocking is required because `config.ts` imports `applyProfileSnapshot` from both paths. Do not flag this as confusing duplication or suggest collapsing into a single mock in future reviews.

Applied to files:

  • packages/core/src/storage/secure-store.spec.ts
📚 Learning: 2025-11-25T16:56:18.980Z
Learnt from: CR
Repo: vybestack/llxprt-code PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T16:56:18.980Z
Learning: Before reporting a task as finished, run `npm run format` from the repository root and ensure it succeeds (exit code 0)

Applied to files:

  • packages/core/src/storage/secure-store.spec.ts
📚 Learning: 2026-02-26T19:06:23.993Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1627
File: integration-tests/run_shell_command.test.ts:550-557
Timestamp: 2026-02-26T19:06:23.993Z
Learning: In `integration-tests/run_shell_command.test.ts`, the "rejects invalid shell expressions" test intentionally does not assert `toolRequest.success === false` for shell syntax errors because issue `#1625` tracks that `run_shell_command` currently reports `success: true` for commands that fail with non-zero exit codes (it only sets `result.error` on spawn failures, not non-zero exits). The test uses FakeProvider to script model responses but executes the real tool, so asserting `success === false` would fail until `#1625` is resolved. The test correctly verifies the tool was invoked with the invalid syntax and the model responded with FAIL.
<!--

Applied to files:

  • packages/core/src/storage/secure-store.spec.ts
📚 Learning: 2026-03-24T21:07:40.805Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1767
File: packages/cli/src/ui/components/shared/golden-snapshot.test.ts:64-65
Timestamp: 2026-03-24T21:07:40.805Z
Learning: In `packages/cli/src/ui/components/shared/golden-snapshot.test.ts` (vybestack/llxprt-code PR `#1767`), `parseAction` uses `actionStr.split(':')` to parse action corpus entries. The action corpus (`project-plans/issue1577/action-corpus.json`) has been confirmed to contain zero multi-colon action strings, so the current two-element destructuring is correct for all existing entries. Do not flag this as a truncation bug in future reviews — the corpus format is validated and the parsing matches it.

Applied to files:

  • packages/core/src/storage/secure-store.spec.ts
📚 Learning: 2026-04-03T05:57:51.304Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1874
File: packages/core/src/providers/__tests__/RetryOrchestrator.onAuthError.test.ts:79-404
Timestamp: 2026-04-03T05:57:51.304Z
Learning: In vybestack/llxprt-code, `RetryOrchestrator.onAuthError` tests (packages/core/src/providers/__tests__/RetryOrchestrator.onAuthError.test.ts, PR `#1874`) are intentionally scoped to the default/single-bucket path covering issue1861's core fix. Multi-bucket / non-default session-bucket regression coverage belongs at the OAuthManager/TokenAccessCoordinator layer (forceRefreshToken.test.ts), not in RetryOrchestrator tests. Do not flag the absence of multi-bucket bucket-context tests in RetryOrchestrator.onAuthError.test.ts as a coverage gap.

Applied to files:

  • packages/core/src/storage/secure-store.spec.ts
📚 Learning: 2026-03-26T01:28:01.197Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1778
File: packages/cli/src/auth/auth-flow-orchestrator.ts:692-705
Timestamp: 2026-03-26T01:28:01.197Z
Learning: In vybestack/llxprt-code, the production `KeyringTokenStore` (at `packages/core/src/auth/keyring-token-store.ts` line 94) normalizes an `undefined` bucket argument to `DEFAULT_BUCKET` (the string `"default"`) internally via `const resolvedBucket = bucket ?? DEFAULT_BUCKET`. As a result, `getToken(provider, undefined)` and `getToken(provider, "default")` are functionally identical in production. The original `oauth-manager.ts` also applied the same `bucket ?? "default"` normalization (line 2169). Do not flag the omission of explicit `"default"` bucket strings in `auth-flow-orchestrator.ts` or related decomposed modules as a behavioral divergence — passing `undefined` is equivalent and is a faithful extraction of pre-existing behavior. InMemoryTokenStore behavior in test helpers does not govern the production contract.

Applied to files:

  • packages/core/src/storage/secure-store.spec.ts
📚 Learning: 2026-03-26T01:28:37.959Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1778
File: packages/cli/src/auth/provider-usage-info.ts:36-37
Timestamp: 2026-03-26T01:28:37.959Z
Learning: In `packages/cli/src/auth/provider-usage-info.ts` (vybestack/llxprt-code PR `#1778`, decomposed from `oauth-manager.ts`), the `bucket ?? 'default'` normalization before calling `tokenStore.getToken(provider, bucket)` is correct and functionally identical to passing `undefined`. The production `KeyringTokenStore` (packages/core/src/auth/keyring-token-store.ts, line 94) already normalizes `undefined` to `DEFAULT_BUCKET` (the string `"default"`) internally via `const resolvedBucket = bucket ?? DEFAULT_BUCKET`. The `InMemoryTokenStore` used in test helpers does not define the production contract. Do not flag `bucket ?? 'default'` lookups as a contract violation or suggest splitting into `undefined`-for-lookup vs `'default'`-for-display in this codebase — the original `oauth-manager.ts` used the same pattern (line 2169) and the behavior is faithfully preserved.

Applied to files:

  • packages/core/src/storage/secure-store.spec.ts
📚 Learning: 2026-02-06T15:52:42.315Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1305
File: scripts/generate-keybindings-doc.ts:1-5
Timestamp: 2026-02-06T15:52:42.315Z
Learning: In reviews of vybestack/llxprt-code, do not suggest changing existing copyright headers from 'Google LLC' to 'Vybestack LLC' for files that originated from upstream. Preserve upstream copyrights in files that came from upstream, and only apply 'Vybestack LLC' copyright on newly created, original LLxprt files. If a file is clearly LLxprt-original, it may carry the Vybestack header; if it is upstream-originated, keep the original sponsor header.

Applied to files:

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

Applied to files:

  • packages/core/src/storage/secure-store.spec.ts
🔇 Additional comments (2)
packages/core/src/storage/secure-store.spec.ts (2)

132-155: Good precedence test for keyring-over-fallback reads.

This case clearly locks down the intended source-of-truth ordering and protects against regressions in mixed-storage states.


190-231: Nice policy-preservation coverage for allow vs deny.

These tests map directly to behavior contract boundaries and complement the Linux fallback regression cases well.

Comment thread packages/core/src/storage/secure-store.spec.ts Outdated
Comment thread packages/core/src/storage/secure-store.spec.ts Outdated
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 9, 2026

Code Coverage Summary

Package Lines Statements Functions Branches
CLI 58.38% 58.38% 66.85% 80.11%
Core 78.19% 78.19% 78.15% 81.51%
CLI Package - Full Text Report
-------------------|---------|----------|---------|---------|-------------------
File               | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-------------------|---------|----------|---------|---------|-------------------
All files          |   58.38 |    80.11 |   66.85 |   58.38 |                   
 src               |   56.56 |    57.47 |    62.5 |   56.56 |                   
  gemini.tsx       |    50.4 |    56.81 |   54.54 |    50.4 | ...1195,1203-1222 
  ...ractiveCli.ts |   61.01 |    55.88 |   55.55 |   61.01 | ...98-605,607-616 
  ...liCommands.ts |   97.22 |       60 |     100 |   97.22 | 39-40             
  ...ActiveAuth.ts |   59.42 |    70.58 |     100 |   59.42 | ...0,78-93,97-106 
 src/auth          |    80.8 |    88.39 |   88.43 |    80.8 |                   
  ...andlerImpl.ts |   85.83 |    87.38 |   91.66 |   85.83 | ...49,578,593-594 
  ...henticator.ts |     100 |    95.65 |   83.33 |     100 | 170               
  ...ketManager.ts |     100 |      100 |     100 |     100 |                   
  ...andlerImpl.ts |   25.49 |      100 |      50 |   25.49 | 53-92,98-102      
  ...h-provider.ts |   78.28 |    85.96 |      80 |   78.28 | ...36-451,463-486 
  ...chestrator.ts |   89.33 |    86.59 |     100 |   89.33 | ...96,650-665,671 
  ...us-service.ts |   90.84 |    88.73 |     100 |   90.84 | ...54-358,445-446 
  auth-utils.ts    |   77.35 |    83.33 |     100 |   77.35 | 23-30,84-85,89-90 
  ...h-provider.ts |   73.95 |    63.15 |    87.5 |   73.95 | ...68,474,484-526 
  ...h-provider.ts |   19.55 |      100 |   34.78 |   19.55 | ...53-484,502-521 
  ...l-oauth-ui.ts |   96.42 |      100 |     100 |   96.42 | 52,89             
  ...h-callback.ts |   82.94 |    75.67 |    90.9 |   82.94 | ...74-775,788-790 
  migration.ts     |       0 |        0 |       0 |       0 | 1-69              
  oauth-manager.ts |   95.58 |    97.91 |   97.29 |   95.58 | 403,469-478       
  ...vider-base.ts |     100 |    96.96 |     100 |     100 | 83                
  ...al-manager.ts |   86.68 |    96.25 |   93.75 |   86.68 | ...95-396,427-468 
  profile-utils.ts |   77.27 |    69.23 |     100 |   77.27 | ...6-87,95-96,108 
  ...r-registry.ts |   97.46 |     87.5 |     100 |   97.46 | 78-79             
  ...usage-info.ts |   99.45 |    97.22 |     100 |   99.45 | 237               
  ...h-provider.ts |   58.29 |    66.66 |   72.72 |   58.29 | ...98-336,344-385 
  ...oordinator.ts |   87.92 |    90.24 |     100 |   87.92 | ...99-903,918,934 
  ...ver-helper.ts |   89.53 |    88.88 |     100 |   89.53 | 82,96,128-133,141 
  ...e-resolver.ts |   96.07 |     90.9 |     100 |   96.07 | 42,73-74,80       
  ...esh-helper.ts |   91.51 |    86.48 |     100 |   91.51 | ...46,179,186,209 
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/auth/proxy    |   82.34 |    77.74 |   82.35 |   82.34 |                   
  ...oxy-server.ts |   84.53 |    74.58 |   96.66 |   84.53 | ...-960,1079-1084 
  ...re-factory.ts |     100 |      100 |     100 |     100 |                   
  ...on-manager.ts |   98.16 |    94.11 |     100 |   98.16 | 51-52             
  ...-scheduler.ts |    92.3 |    84.61 |     100 |    92.3 | 56-59             
  ...th-adapter.ts |   63.54 |    66.66 |    64.7 |   63.54 | ...44-245,256,260 
  ...oordinator.ts |   98.98 |    82.05 |     100 |   98.98 | 156               
  ...-lifecycle.ts |    59.5 |    66.66 |   33.33 |    59.5 | ...92,199,241-242 
 src/commands      |   78.35 |      100 |   44.44 |   78.35 |                   
  extensions.tsx   |   55.88 |      100 |       0 |   55.88 | 25-38,42          
  hooks.ts         |   61.53 |      100 |       0 |   61.53 | 14-17,20          
  mcp.ts           |   94.11 |      100 |      50 |   94.11 | 26                
  skills.tsx       |     100 |      100 |     100 |     100 |                   
  utils.ts         |     100 |      100 |     100 |     100 |                   
 ...nds/extensions |   74.01 |       92 |   67.34 |   74.01 |                   
  config.ts        |   93.36 |    88.88 |     100 |   93.36 | ...25-226,228-233 
  disable.ts       |     100 |      100 |     100 |     100 |                   
  enable.ts        |     100 |      100 |     100 |     100 |                   
  install.ts       |   77.61 |    71.42 |   66.66 |   77.61 | ...10,156,159-166 
  link.ts          |   64.15 |    83.33 |      25 |   64.15 | 30,53-64,66-71    
  list.ts          |      90 |      100 |   33.33 |      90 | 35-37             
  new.ts           |     100 |      100 |     100 |     100 |                   
  settings.ts      |   70.62 |      100 |   66.66 |   70.62 | 32-81,223-227,230 
  uninstall.ts     |   78.43 |      100 |   66.66 |   78.43 | 54-59,62-66       
  update.ts        |   11.42 |      100 |       0 |   11.42 | ...44-159,161-166 
  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 |    9.37 |      100 |       0 |    9.37 |                   
  migrate.ts       |    9.37 |      100 |       0 |    9.37 | ...60-170,172-174 
 src/commands/mcp  |   96.73 |    85.48 |    90.9 |   96.73 |                   
  add.ts           |   99.51 |    92.59 |     100 |   99.51 | 49                
  list.ts          |   90.43 |    82.14 |      80 |   90.43 | ...14-116,149-151 
  remove.ts        |     100 |    71.42 |     100 |     100 | 21-25             
 ...ommands/skills |   60.85 |     92.3 |   31.25 |   60.85 |                   
  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.72 |       80 |   33.33 |   84.72 | ...78,91-95,97-99 
  uninstall.ts     |   57.89 |      100 |   33.33 |   57.89 | 47-64,66-71       
 src/config        |   88.32 |    81.27 |    83.5 |   88.32 |                   
  ...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  |   90.57 |    86.95 |     100 |   90.57 | ...53-256,286-289 
  ...alSettings.ts |   86.66 |    88.23 |     100 |   86.66 | 40-41,44-47       
  config.ts        |     100 |      100 |     100 |     100 |                   
  configBuilder.ts |   96.28 |      100 |    87.5 |   96.28 | 109-115,235-236   
  ...mentLoader.ts |   83.78 |    60.86 |     100 |   83.78 | ...23-125,133-136 
  extension.ts     |   77.34 |    86.63 |   77.14 |   77.34 | ...1117,1120-1121 
  ...iveContext.ts |   93.66 |    91.42 |     100 |   93.66 | 79,81,87-92,232   
  ...iateConfig.ts |   94.93 |    96.66 |     100 |   94.93 | 76,84-86          
  keyBindings.ts   |     100 |      100 |     100 |     100 |                   
  ...rverConfig.ts |      86 |    94.44 |     100 |      86 | 23-36             
  paths.ts         |     100 |      100 |     100 |     100 |                   
  policy.ts        |   80.76 |      100 |      50 |   80.76 | 45-49             
  ...figRuntime.ts |   88.68 |       84 |     100 |   88.68 | ...21-428,439-442 
  ...eBootstrap.ts |   89.31 |    84.55 |      90 |   89.31 | ...72-774,783-784 
  ...Resolution.ts |   69.86 |     62.5 |   83.33 |   69.86 | ...29-230,266-285 
  ...pplication.ts |   91.17 |    76.19 |     100 |   91.17 | ...31,155,182,187 
  ...elResolver.ts |   92.59 |    83.33 |     100 |   92.59 | 40,42-43,79       
  sandboxConfig.ts |    66.9 |    48.35 |   89.47 |    66.9 | ...93-500,518-519 
  ...oxProfiles.ts |    8.53 |      100 |       0 |    8.53 | 47-48,51-129      
  settingPaths.ts  |     100 |      100 |     100 |     100 |                   
  ...validation.ts |   84.73 |    82.35 |     100 |   84.73 | ...60,263-267,270 
  settings.ts      |   79.73 |     71.3 |   74.19 |   79.73 | ...1155,1190-1191 
  ...ingsSchema.ts |    99.9 |     90.9 |     100 |    99.9 | 57-58             
  ...Governance.ts |   95.83 |    90.62 |     100 |   95.83 | 52,124-127        
  ...tedFolders.ts |    95.2 |    95.91 |     100 |    95.2 | 93,119-125        
  welcomeConfig.ts |   22.41 |      100 |       0 |   22.41 | ...71,74-79,82-83 
  yargsOptions.ts  |   98.65 |    94.44 |   85.71 |   98.65 | 116,125-128       
 ...fig/extensions |   73.18 |    83.77 |   90.78 |   73.18 |                   
  consent.ts       |    82.6 |    86.95 |   91.66 |    82.6 | ...70-371,374-375 
  ...Enablement.ts |   93.87 |    96.05 |     100 |   93.87 | ...98-204,265-267 
  ...onSettings.ts |     100 |      100 |     100 |     100 |                   
  github.ts        |   64.04 |       79 |     100 |   64.04 | ...62-565,570-571 
  hookSchema.ts    |     100 |      100 |     100 |     100 |                   
  ...ntegration.ts |    55.1 |    84.44 |      50 |    55.1 | ...61,402,426-427 
  ...ingsPrompt.ts |   72.72 |    94.44 |      80 |   72.72 | 92-121            
  ...ngsStorage.ts |   84.61 |    75.92 |     100 |   84.61 | ...86-287,305-308 
  update.ts        |   62.57 |    46.66 |   66.66 |   62.57 | ...23-151,168-176 
  ...ableSchema.ts |     100 |      100 |     100 |     100 |                   
  variables.ts     |   95.45 |       90 |     100 |   95.45 | 32-33             
 src/constants     |     100 |      100 |     100 |     100 |                   
  historyLimits.ts |     100 |      100 |     100 |     100 |                   
 src/extensions    |   65.75 |    57.89 |      75 |   65.75 |                   
  ...utoUpdater.ts |   65.75 |    57.89 |      75 |   65.75 | ...50-451,460,462 
 src/generated     |     100 |      100 |     100 |     100 |                   
  git-commit.ts    |     100 |      100 |     100 |     100 |                   
 ...egration-tests |   91.46 |    85.18 |     100 |   91.46 |                   
  test-utils.ts    |   91.46 |    85.18 |     100 |   91.46 | ...16,234-235,245 
 src/patches       |       0 |        0 |       0 |       0 |                   
  is-in-ci.ts      |       0 |        0 |       0 |       0 | 1-17              
 src/providers     |   83.41 |    73.57 |   77.35 |   83.41 |                   
  IFileSystem.ts   |   65.51 |      100 |   57.14 |   65.51 | 45-46,49-54,67-68 
  ...Precedence.ts |   94.59 |    86.66 |     100 |   94.59 | 40-41             
  index.ts         |       0 |        0 |       0 |       0 | 1-19              
  ...gistration.ts |   77.94 |    68.75 |   33.33 |   77.94 | ...97-101,107-108 
  ...derAliases.ts |   82.97 |    82.97 |     100 |   82.97 | ...37-243,248-249 
  ...onfigUtils.ts |   92.45 |       75 |     100 |   92.45 | 26-30             
  ...erInstance.ts |   84.13 |    69.86 |   83.33 |   84.13 | ...89-793,911-912 
  types.ts         |       0 |        0 |       0 |       0 | 1-8               
 ...viders/logging |   87.59 |    88.63 |   63.63 |   87.59 |                   
  ...rvice-impl.ts |   44.44 |        0 |       0 |   44.44 | 21-22,25-30,36-37 
  git-stats.ts     |   94.59 |    90.69 |     100 |   94.59 | ...48-149,180-181 
 src/runtime       |   79.61 |    78.72 |   88.37 |   79.61 |                   
  ...imeAdapter.ts |   97.65 |    92.15 |     100 |   97.65 | ...18-219,308-309 
  ...etFailover.ts |   97.05 |    91.66 |     100 |   97.05 | 31-32,215         
  messages.ts      |   63.07 |    66.66 |      75 |   63.07 | 51,74-102         
  ...pplication.ts |   88.51 |    82.11 |      80 |   88.51 | ...63-666,762-763 
  ...leSnapshot.ts |   47.28 |    50.87 |   53.84 |   47.28 | ...16-518,521-545 
  ...rMutations.ts |   83.43 |    85.71 |   86.66 |   83.43 | ...19-423,437-438 
  ...iderSwitch.ts |   85.76 |    80.68 |     100 |   85.76 | ...83-600,637,742 
  ...eAccessors.ts |   70.05 |    60.97 |     100 |   70.05 | ...09-510,518-519 
  ...extFactory.ts |   91.26 |    70.96 |     100 |   91.26 | ...10-313,400-407 
  ...eLifecycle.ts |   84.31 |     87.5 |     100 |   84.31 | ...11-120,154-158 
  ...meRegistry.ts |   90.67 |    91.22 |     100 |   90.67 | ...55-159,165-166 
  ...meSettings.ts |     100 |      100 |     100 |     100 |                   
  ...gsResolver.ts |   74.52 |    75.86 |      75 |   74.52 | ...47-158,174-182 
  ...sHardening.ts |   58.42 |       85 |    87.5 |   58.42 | ...77,90-91,97-98 
 src/services      |   82.38 |    80.82 |   86.36 |   82.38 |                   
  ...mandLoader.ts |   79.48 |    71.42 |      80 |   79.48 | ...06-120,160-177 
  ...ardService.ts |    91.3 |    33.33 |     100 |    91.3 | 35-36             
  ...andService.ts |     100 |      100 |     100 |     100 |                   
  ...mandLoader.ts |   89.47 |    88.88 |     100 |   89.47 | ...82-187,261-268 
  ...omptLoader.ts |   71.05 |    76.74 |   83.33 |   71.05 | ...41,208,260-261 
  performResume.ts |   86.13 |    79.31 |     100 |   86.13 | ...85-188,194-195 
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 ...mpt-processors |   97.57 |    94.11 |     100 |   97.57 |                   
  ...tProcessor.ts |     100 |      100 |     100 |     100 |                   
  ...lProcessor.ts |   97.38 |    93.61 |     100 |   97.38 | 77-78,203-204     
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...o-continuation |   85.62 |    82.14 |   94.11 |   85.62 |                   
  ...ionService.ts |   85.62 |    82.14 |   94.11 |   85.62 | ...94,553,579-580 
 src/settings      |   85.96 |     64.7 |     100 |   85.96 |                   
  ...alSettings.ts |   94.44 |       70 |     100 |   94.44 | 74-75             
  ...aramParser.ts |   71.42 |    57.14 |     100 |   71.42 | 21-22,24-25,30-31 
 src/test-utils    |    76.7 |     90.9 |   27.27 |    76.7 |                   
  async.ts         |       0 |        0 |       0 |       0 | 1-34              
  ...eExtension.ts |     100 |      100 |     100 |     100 |                   
  ...omMatchers.ts |   18.75 |      100 |       0 |   18.75 | 16-44             
  ...andContext.ts |     100 |      100 |     100 |     100 |                   
  render.tsx       |   94.84 |    96.66 |      25 |   94.84 | ...51-156,259-260 
  ...e-testing.tsx |       0 |        0 |       0 |       0 | 1-56              
  ...iderConfig.ts |       0 |        0 |       0 |       0 | 1-19              
 src/ui            |   37.93 |    93.44 |   30.48 |   37.93 |                   
  App.tsx          |   37.25 |      100 |       0 |   37.25 | 64-91,97-104      
  AppContainer.tsx |     100 |      100 |     100 |     100 |                   
  ...erRuntime.tsx |   14.43 |      100 |   16.66 |   14.43 | 66-395            
  ...tionNudge.tsx |       8 |      100 |       0 |       8 | 27-102            
  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 | 22,24-25,32-33    
  ...ntsEnabled.ts |     100 |      100 |     100 |     100 |                   
  ...submission.ts |     100 |      100 |     100 |     100 |                   
  ...tic-colors.ts |   78.94 |      100 |      60 |   78.94 | 15-16,24-25       
  textConstants.ts |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/ui/commands   |   67.48 |     74.7 |   71.98 |   67.48 |                   
  aboutCommand.ts  |   73.13 |    26.08 |     100 |   73.13 | ...13-114,134-137 
  authCommand.ts   |   50.56 |    77.33 |   58.33 |   50.56 | ...43-646,657-695 
  ...urlCommand.ts |      30 |      100 |       0 |      30 | 20-40             
  bugCommand.ts    |    62.5 |    23.07 |     100 |    62.5 | ...,71-98,123-132 
  chatCommand.ts   |   70.02 |    80.64 |   63.63 |   70.02 | ...27-528,576-587 
  clearCommand.ts  |   86.88 |    86.66 |     100 |   86.88 | 67-74             
  ...essCommand.ts |   99.09 |    91.66 |     100 |   99.09 | 96                
  ...nueCommand.ts |     100 |      100 |     100 |     100 |                   
  copyCommand.ts   |   98.33 |    94.44 |     100 |   98.33 | 39                
  debugCommands.ts |   13.29 |      100 |       0 |   13.29 | ...48,455,462,469 
  ...icsCommand.ts |   66.83 |    45.83 |      75 |   66.83 | ...53-357,468-473 
  ...ryCommand.tsx |   88.82 |     87.5 |     100 |   88.82 | ...,46-54,178-186 
  docsCommand.ts   |     100 |      100 |     100 |     100 |                   
  ...extCommand.ts |   93.18 |    77.77 |     100 |   93.18 | 108-113           
  editorCommand.ts |     100 |      100 |     100 |     100 |                   
  ...onsCommand.ts |   39.27 |    87.17 |   63.63 |   39.27 | ...94-324,334-482 
  ...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    |   66.97 |    68.96 |   55.55 |   66.97 | ...25-228,237-244 
  initCommand.ts   |   80.26 |    71.42 |   66.66 |   80.26 | 35-39,41-88       
  keyCommand.ts    |   89.84 |    79.74 |     100 |   89.84 | ...93,416-417,516 
  ...ileCommand.ts |   11.11 |      100 |       0 |   11.11 | 23-134            
  ...ingCommand.ts |   10.96 |      100 |       0 |   10.96 | ...59-528,545-556 
  logoutCommand.ts |   15.62 |      100 |       0 |   15.62 | 21-85             
  lspCommand.ts    |    90.9 |    87.17 |     100 |    90.9 | ...18-123,145-147 
  mcpCommand.ts    |   82.19 |    79.09 |   83.33 |   82.19 | ...91-492,510-511 
  memoryCommand.ts |   86.24 |    77.55 |     100 |   86.24 | ...73,235,261,268 
  modelCommand.ts  |   98.92 |    93.02 |     100 |   98.92 | 121               
  mouseCommand.ts  |     100 |      100 |     100 |     100 |                   
  ...onsCommand.ts |    93.9 |    88.88 |     100 |    93.9 | 58-62             
  ...iesCommand.ts |   97.08 |    80.55 |     100 |   97.08 | 27,40-41          
  ...acyCommand.ts |   61.53 |      100 |       0 |   61.53 | 22-26             
  ...ileCommand.ts |   52.84 |    58.24 |   61.53 |   52.84 | ...1047,1068-1084 
  ...derCommand.ts |   53.94 |    28.94 |      80 |   53.94 | ...63-267,275-280 
  quitCommand.ts   |   36.66 |      100 |       0 |   36.66 | 17-36             
  ...oreCommand.ts |   92.59 |     87.5 |     100 |   92.59 | ...,90-91,120-125 
  setCommand.ts    |   75.48 |    74.28 |   72.72 |   75.48 | ...41-546,588-601 
  ...ngsCommand.ts |     100 |      100 |     100 |     100 |                   
  setupCommand.ts  |     100 |      100 |     100 |     100 |                   
  ...hubCommand.ts |   91.38 |    82.85 |     100 |   91.38 | ...13-216,223-227 
  skillsCommand.ts |   82.37 |       76 |     100 |   82.37 | ...86-287,300-301 
  statsCommand.ts  |   70.67 |    65.71 |      75 |   70.67 | ...31-540,548-625 
  ...entCommand.ts |   76.77 |    70.27 |   81.81 |   76.77 | ...09-615,626-632 
  tasksCommand.ts  |   78.75 |    78.78 |     100 |   78.75 | ...78-186,247-254 
  ...tupCommand.ts |     100 |      100 |     100 |     100 |                   
  themeCommand.ts  |     100 |      100 |     100 |     100 |                   
  todoCommand.ts   |   65.52 |    69.53 |    92.3 |   65.52 | ...1256,1268-1275 
  ...matCommand.ts |   26.66 |      100 |       0 |   26.66 | 33-92             
  ...keyCommand.ts |    98.9 |     92.3 |     100 |    98.9 | 34                
  ...ileCommand.ts |   99.11 |    94.11 |     100 |   99.11 | 36                
  toolsCommand.ts  |   85.88 |    76.11 |     100 |   85.88 | ...87-296,309-310 
  types.ts         |     100 |      100 |     100 |     100 |                   
  ...ileCommand.ts |   27.77 |        0 |       0 |   27.77 | 11-23             
  vimCommand.ts    |   44.44 |      100 |       0 |   44.44 | 14-24             
 ...ommands/schema |   96.22 |    91.13 |    92.3 |   96.22 |                   
  index.ts         |   96.45 |    91.71 |     100 |   96.45 | ...08-412,423-424 
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 src/ui/components |   10.14 |    30.76 |    2.08 |   10.14 |                   
  AboutBox.tsx     |    4.46 |      100 |       0 |    4.46 | 26-147            
  AnsiOutput.tsx   |    8.33 |      100 |       0 |    8.33 | 25-90             
  AppHeader.tsx    |   22.58 |      100 |       0 |   22.58 | 26-54             
  AsciiArt.ts      |     100 |      100 |     100 |     100 |                   
  AuthDialog.tsx   |    6.29 |      100 |       0 |    6.29 | 22-189            
  ...nProgress.tsx |       0 |        0 |       0 |       0 | 1-62              
  ...Indicator.tsx |   15.15 |      100 |       0 |   15.15 | 17-47             
  ...firmation.tsx |    7.43 |      100 |       0 |    7.43 | 51-180            
  ...tsDisplay.tsx |    7.69 |      100 |       0 |    7.69 | 23-34,38-156      
  CliSpinner.tsx   |       0 |        0 |       0 |       0 | 1-22              
  Composer.tsx     |    8.62 |      100 |       0 |    8.62 | 24-81             
  ...entPrompt.tsx |   18.75 |      100 |       0 |   18.75 | 21-51             
  ...ryDisplay.tsx |   21.05 |      100 |       0 |   21.05 | 17-35             
  ...ryDisplay.tsx |    5.71 |      100 |       0 |    5.71 | 30-141            
  ...geDisplay.tsx |       0 |        0 |       0 |       0 | 1-37              
  ...gProfiler.tsx |   16.86 |      100 |       0 |   16.86 | ...73-118,122-224 
  ...esDisplay.tsx |   10.52 |      100 |       0 |   10.52 | 24-82             
  ...ogManager.tsx |    8.62 |      100 |       0 |    8.62 | 71-591            
  ...ngsDialog.tsx |    6.53 |      100 |       0 |    6.53 | 31-193            
  ...rBoundary.tsx |   10.16 |        0 |       0 |   10.16 | ...17-162,180-192 
  ...ustDialog.tsx |   16.66 |      100 |       0 |   16.66 | 32-124            
  Footer.tsx       |    9.25 |        0 |     100 |    9.25 | ...35-518,522-539 
  ...ngSpinner.tsx |    40.9 |      100 |       0 |    40.9 | 31-47             
  Header.tsx       |    17.5 |      100 |       0 |    17.5 | 22-62             
  Help.tsx         |    3.93 |      100 |       0 |    3.93 | 18-180            
  ...emDisplay.tsx |   18.54 |      100 |       0 |   18.54 | 54-203            
  ...usDisplay.tsx |       0 |        0 |       0 |       0 | 1-47              
  InputPrompt.tsx  |   42.65 |    33.33 |   66.66 |   42.65 | ...1178,1185-1196 
  ...tsDisplay.tsx |    4.41 |      100 |       0 |    4.41 | 26-37,41-249      
  ...utManager.tsx |       0 |        0 |       0 |       0 | 1-97              
  ...ileDialog.tsx |    6.89 |      100 |       0 |    6.89 | 20-119            
  ...Indicator.tsx |   14.28 |      100 |       0 |   14.28 | 25-89             
  ...ingDialog.tsx |    4.52 |      100 |       0 |    4.52 | ...9,84-90,93-354 
  ...geDisplay.tsx |       0 |        0 |       0 |       0 | 1-40              
  ModelDialog.tsx  |    1.79 |      100 |       0 |    1.79 | 53-76,79-629      
  ...tsDisplay.tsx |    4.84 |      100 |       0 |    4.84 | 28-220            
  ...fications.tsx |   15.65 |      100 |       0 |   15.65 | 36-151            
  ...odeDialog.tsx |    7.31 |      100 |       0 |    7.31 | 30-140            
  ...ustDialog.tsx |    6.21 |      100 |       0 |    6.21 | 30-237            
  PrepareLabel.tsx |   13.33 |      100 |       0 |   13.33 | 20-48             
  ...ailDialog.tsx |   11.58 |      100 |       0 |   11.58 | 57-68,71-343      
  ...ineEditor.tsx |    2.59 |      100 |       0 |    2.59 | 25-65,69-357      
  ...istDialog.tsx |    2.99 |      100 |       0 |    2.99 | 35-369            
  ...derDialog.tsx |    3.84 |      100 |       0 |    3.84 | 22-272            
  ...Indicator.tsx |       0 |        0 |       0 |       0 | 1-21              
  ...eKeyInput.tsx |       0 |        0 |       0 |       0 | 1-138             
  ...serDialog.tsx |    1.96 |      100 |       0 |    1.96 | 41-49,56-588      
  ...ryDisplay.tsx |      50 |      100 |       0 |      50 | 15-17             
  ...ngsDialog.tsx |    1.69 |      100 |       0 |    1.69 | ...2-161,164-1624 
  ...putPrompt.tsx |   16.21 |      100 |       0 |   16.21 | 19-53             
  ...Indicator.tsx |   44.44 |      100 |       0 |   44.44 | 12-17             
  ...MoreLines.tsx |      28 |      100 |       0 |      28 | 18-40             
  StatsDisplay.tsx |    4.82 |      100 |       0 |    4.82 | ...03-241,250-413 
  ...usDisplay.tsx |       0 |        0 |       0 |       0 | 1-59              
  StickyHeader.tsx |    7.14 |      100 |       0 |    7.14 | 20-78             
  ...nsDisplay.tsx |    7.76 |      100 |       0 |    7.76 | 49-164            
  Table.tsx        |    7.54 |      100 |       0 |    7.54 | 27-87             
  ThemeDialog.tsx  |    5.22 |      100 |       0 |    5.22 | 45-420            
  ...dGradient.tsx |      25 |      100 |       0 |      25 | 27-46             
  Tips.tsx         |      16 |      100 |       0 |      16 | 17-45             
  TodoPanel.tsx    |    5.55 |      100 |       0 |    5.55 | 26-74,77-245      
  ...tsDisplay.tsx |    7.42 |      100 |       0 |    7.42 | 30-53,56-228      
  ToolsDialog.tsx  |    7.86 |      100 |       0 |    7.86 | 23-119            
  ...ification.tsx |   36.36 |      100 |       0 |   36.36 | 15-22             
  ...ionDialog.tsx |    7.52 |      100 |       0 |    7.52 | 18-123            
  todo-utils.ts    |       0 |        0 |       0 |       0 | 1-7               
 ...leCreateWizard |   19.22 |       50 |       0 |   19.22 |                   
  ...aramsStep.tsx |    5.82 |      100 |       0 |    5.82 | 27-244            
  ...ationStep.tsx |    4.82 |      100 |       0 |    4.82 | 27-294            
  ...onfigStep.tsx |   11.23 |      100 |       0 |   11.23 | 25-119            
  ...electStep.tsx |    6.11 |      100 |       0 |    6.11 | 28-236            
  ...ationMenu.tsx |       0 |        0 |       0 |       0 | 1-101             
  ...eSaveStep.tsx |    6.28 |      100 |       0 |    6.28 | 33-257            
  ...ssSummary.tsx |   12.12 |      100 |       0 |   12.12 | 22-87             
  ...electStep.tsx |   16.92 |      100 |       0 |   16.92 | 27-94             
  TextInput.tsx    |     5.5 |      100 |       0 |     5.5 | 27-170            
  constants.ts     |     100 |      100 |     100 |     100 |                   
  index.tsx        |    6.27 |      100 |       0 |    6.27 | 28-296            
  types.ts         |     100 |      100 |     100 |     100 |                   
  utils.ts         |    5.22 |      100 |       0 |    5.22 | ...46-350,355-372 
  validation.ts    |   11.23 |      100 |       0 |   11.23 | ...97-104,107-111 
 ...gentManagement |    6.23 |      100 |       0 |    6.23 |                   
  ...entWizard.tsx |    4.06 |      100 |       0 |    4.06 | 33-239            
  ...ionWizard.tsx |    2.26 |      100 |       0 |    2.26 | 30-442            
  ...eteDialog.tsx |    6.59 |      100 |       0 |    6.59 | 21-127            
  ...tEditForm.tsx |    3.37 |      100 |       0 |    3.37 | 31-349            
  ...tListMenu.tsx |    3.97 |      100 |       0 |    3.97 | 25-236            
  ...tMainMenu.tsx |   16.66 |      100 |       0 |   16.66 | 21-61             
  ...gerDialog.tsx |    3.66 |      100 |       0 |    3.66 | 26-472            
  ...tShowView.tsx |    4.96 |      100 |       0 |    4.96 | 27-211            
  index.ts         |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...comeOnboarding |   13.04 |        0 |       0 |   13.04 |                   
  ...ethodStep.tsx |   22.47 |      100 |       0 |   22.47 | 43-128            
  ...ationStep.tsx |    5.42 |      100 |       0 |    5.42 | 28-183            
  ...etionStep.tsx |    5.08 |      100 |       0 |    5.08 | 22-165            
  ...electStep.tsx |    7.95 |      100 |       0 |    7.95 | 30-131            
  ...electStep.tsx |   34.48 |      100 |       0 |   34.48 | 50-119            
  SkipExitStep.tsx |    12.5 |      100 |       0 |    12.5 | 18-59             
  ...omeDialog.tsx |   12.38 |      100 |       0 |   12.38 | 37-146            
  WelcomeStep.tsx  |    10.2 |      100 |       0 |    10.2 | 23-74             
  index.ts         |       0 |        0 |       0 |       0 | 1-13              
 ...nents/messages |   20.14 |    88.09 |   13.33 |   20.14 |                   
  ...onMessage.tsx |   12.28 |      100 |       0 |   12.28 | 24-86             
  DiffRenderer.tsx |    3.33 |      100 |       0 |    3.33 | ...79-360,363-381 
  ErrorMessage.tsx |   22.22 |      100 |       0 |   22.22 | 16-31             
  ...niMessage.tsx |   14.51 |      100 |       0 |   14.51 | 28-95             
  ...geContent.tsx |   20.83 |      100 |       0 |   20.83 | 26-46             
  InfoMessage.tsx  |   19.23 |      100 |       0 |   19.23 | 19-41             
  ...rlMessage.tsx |   11.36 |      100 |       0 |   11.36 | 18-65             
  ...geMessage.tsx |     100 |      100 |     100 |     100 |                   
  ...ckDisplay.tsx |      20 |      100 |       0 |      20 | 43-64             
  ...onMessage.tsx |    4.01 |      100 |       0 |    4.01 | 46-464            
  ...upMessage.tsx |   10.55 |      100 |       0 |   10.55 | ...5,68-83,87-260 
  ToolMessage.tsx  |    8.38 |      100 |       0 |    8.38 | 46-219            
  ...ltDisplay.tsx |    87.5 |    84.61 |     100 |    87.5 | 58-60,116-132     
  ToolShared.tsx   |   64.61 |       90 |   33.33 |   64.61 | 78-99,102-105     
  UserMessage.tsx  |     100 |      100 |     100 |     100 |                   
  ...llMessage.tsx |   36.36 |      100 |       0 |   36.36 | 17-25             
  ...ngMessage.tsx |   26.31 |      100 |       0 |   26.31 | 17-32             
 ...ponents/shared |   41.59 |    61.12 |    43.1 |   41.59 |                   
  ...ctionList.tsx |    5.55 |      100 |       0 |    5.55 | 53-184            
  MaxSizedBox.tsx  |    48.7 |    56.16 |   88.88 |    48.7 | ...72-576,619-620 
  ...tonSelect.tsx |   12.76 |      100 |       0 |   12.76 | 66-113            
  ...lableList.tsx |    6.21 |      100 |       0 |    6.21 | 44-221            
  ...lizedList.tsx |    2.29 |      100 |       0 |    2.29 | 56-486            
  ...operations.ts |   75.67 |    48.14 |     100 |   75.67 | ...31-232,255-264 
  ...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   |   57.36 |    69.56 |    7.89 |   57.36 | ...15,561,566-570 
  ...formations.ts |   42.42 |    71.42 |      80 |   42.42 | ...27-134,158-204 
  ...n-handlers.ts |   33.99 |    61.53 |   23.25 |   33.99 | ...47-755,758-762 
  ...er-actions.ts |   93.84 |     87.5 |     100 |   93.84 | 91-93,100         
  visual-layout.ts |    90.2 |    71.73 |     100 |    90.2 | ...48-350,372-373 
  ...navigation.ts |   56.22 |     62.9 |   77.77 |   56.22 | ...21-333,359-381 
 ...mponents/views |    7.36 |      100 |       0 |    7.36 |                   
  ChatList.tsx     |    14.7 |      100 |       0 |    14.7 | 18-51             
  ...sionsList.tsx |    7.59 |      100 |       0 |    7.59 | 19-102            
  HooksList.tsx    |    5.06 |      100 |       0 |    5.06 | 17-106            
  SkillsList.tsx   |    6.06 |      100 |       0 |    6.06 | 18-99             
 src/ui/constants  |   56.16 |     92.3 |      50 |   56.16 |                   
  ...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-354             
  UIStateShell.tsx |       0 |        0 |       0 |       0 | 1-15              
 ...ainer/builders |   98.37 |      100 |   83.33 |   98.37 |                   
  ...dUIActions.ts |     100 |      100 |     100 |     100 |                   
  buildUIState.ts  |     100 |      100 |     100 |     100 |                   
  ...onsBuilder.ts |   66.66 |      100 |       0 |   66.66 | 21-22             
  ...ateBuilder.ts |   66.66 |      100 |       0 |   66.66 | 21-22             
 ...ontainer/hooks |   51.42 |    82.35 |   51.28 |   51.42 |                   
  ...pBootstrap.ts |   94.71 |    58.33 |     100 |   94.71 | ...20-223,227-229 
  useAppDialogs.ts |   40.97 |      100 |   42.85 |   40.97 | ...55-157,174-376 
  ...ntHandlers.ts |     100 |      100 |     100 |     100 |                   
  useAppInput.ts   |     5.6 |      100 |       0 |     5.6 | 99-516,519-523    
  useAppLayout.ts  |    8.14 |      100 |       0 |    8.14 | 89-290,293-296    
  ...reenAction.ts |   13.63 |      100 |       0 |   13.63 | 23-42             
  ...nSelection.ts |      20 |      100 |       0 |      20 | 27-48             
  ...hestration.ts |     100 |      100 |     100 |     100 |                   
  ...references.ts |      10 |      100 |       0 |      10 | 51-104            
  ...itHandling.ts |   89.79 |      100 |     100 |   89.79 | 131-139,143       
  ...textBridge.ts |   33.33 |      100 |       0 |   33.33 | 23-30             
  ...tartHotkey.ts |   26.66 |      100 |       0 |   26.66 | 23-33             
  ...omptSubmit.ts |    6.12 |      100 |       0 |    6.12 | 26-74             
  ...utHandling.ts |   90.32 |    86.66 |     100 |   90.32 | 59,106-113        
  ...yBootstrap.ts |      30 |      100 |       0 |      30 | 28-34             
  ...eybindings.ts |   85.36 |    70.83 |     100 |   85.36 | ...05-207,241-242 
  ...easurement.ts |   15.38 |      100 |       0 |   15.38 | 44-94             
  ...reshAction.ts |   79.16 |     37.5 |     100 |   79.16 | 51,81-84,86-95    
  ...untimeSync.ts |     100 |      100 |     100 |     100 |                   
  ...elTracking.ts |   28.57 |      100 |     100 |   28.57 | 37-83             
  ...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.93 |    84.61 |     100 |   70.93 | 68-92,124-125     
  ...sAutoReset.ts |   21.87 |      100 |       0 |   21.87 | 28-54             
  ...andActions.ts |     100 |      100 |     100 |     100 |                   
  ...eshManager.ts |     100 |      100 |     100 |     100 |                   
  ...uationFlow.ts |    7.93 |      100 |       0 |    7.93 | 54-150            
  ...csTracking.ts |   98.15 |    81.48 |     100 |   98.15 | 88,107-108        
  ...uthBridges.ts |   36.84 |      100 |     100 |   36.84 | 47-70,74-78       
 src/ui/contexts   |   54.21 |    76.75 |   46.55 |   54.21 |                   
  ...chContext.tsx |    64.7 |      100 |      50 |    64.7 | 24-29             
  FocusContext.tsx |       0 |        0 |       0 |       0 | 1-11              
  ...ssContext.tsx |   81.62 |    84.05 |     100 |   81.62 | ...78-679,734-735 
  MouseContext.tsx |   74.72 |       75 |      80 |   74.72 | ...00-101,112-125 
  ...erContext.tsx |       0 |        0 |       0 |       0 | 1-120             
  ...owContext.tsx |   21.42 |      100 |   33.33 |   21.42 | 33,39-87          
  ...meContext.tsx |   53.12 |    36.36 |   57.14 |   53.12 | ...86,194-195,200 
  ...lProvider.tsx |   90.61 |     70.9 |     100 |   90.61 | ...74-375,387-388 
  ...onContext.tsx |     6.7 |      100 |       0 |     6.7 | ...90-284,289-296 
  ...teContext.tsx |       0 |        0 |       0 |       0 | 1-61              
  ...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 |    5.55 |      100 |       0 |    5.55 | 24-126            
  ...llContext.tsx |     100 |      100 |       0 |     100 |                   
  ...lProvider.tsx |    6.75 |      100 |       0 |    6.75 | 28-122            
  ...nsContext.tsx |      25 |      100 |       0 |      25 | 202-213,216-221   
  ...teContext.tsx |      50 |       50 |      50 |      50 | 248-257,262-263   
  ...deContext.tsx |   11.11 |      100 |       0 |   11.11 | 29-81,84-89       
 src/ui/editors    |   98.18 |     87.5 |     100 |   98.18 |                   
  ...ngsManager.ts |   98.18 |     87.5 |     100 |   98.18 | 59                
 src/ui/hooks      |   62.64 |    83.87 |   73.68 |   62.64 |                   
  ...dProcessor.ts |   71.09 |     75.6 |      75 |   71.09 | ...72-694,716-722 
  index.ts         |       0 |        0 |       0 |       0 | 1-9               
  keyToAnsi.ts     |    3.92 |      100 |       0 |    3.92 | 19-77             
  ...dProcessor.ts |   94.81 |       75 |     100 |   94.81 | ...05-306,311-312 
  ...dProcessor.ts |   25.91 |       55 |      50 |   25.91 | ...28-429,434-975 
  toolMapping.ts   |    91.3 |    92.85 |     100 |    91.3 | 130,157-167       
  ...nateBuffer.ts |      50 |      100 |       0 |      50 | 16-18             
  ...dScrollbar.ts |   96.77 |      100 |     100 |   96.77 | 112-114           
  ...Completion.ts |   94.75 |       89 |     100 |   94.75 | ...19,342,389-390 
  ...uthCommand.ts |      16 |      100 |       0 |      16 | 13-36             
  ...tIndicator.ts |     100 |     92.3 |     100 |     100 | 57                
  useBanner.ts     |     100 |    81.81 |     100 |     100 | 22,45             
  ...chedScroll.ts |   16.66 |      100 |       0 |   16.66 | 14-32             
  ...ketedPaste.ts |      20 |      100 |       0 |      20 | 20-38             
  ...ompletion.tsx |   93.11 |    81.81 |      50 |   93.11 | ...34-235,239-246 
  useCompletion.ts |    92.4 |     87.5 |     100 |    92.4 | ...,95-96,100-101 
  ...leMessages.ts |   96.25 |    90.47 |     100 |   96.25 | 56-57,63          
  ...ntHandlers.ts |    32.6 |      100 |     100 |    32.6 | 43-68,72-80       
  ...fileDialog.ts |   16.12 |      100 |       0 |   16.12 | 17-47             
  ...orSettings.ts |   11.86 |      100 |       0 |   11.86 | 31-87             
  ...AutoUpdate.ts |    9.52 |      100 |       0 |    9.52 | 18-58             
  ...ionUpdates.ts |   67.31 |    76.92 |   66.66 |   67.31 | ...76-182,197-214 
  ...erDetector.ts |     100 |      100 |     100 |     100 |                   
  useFocus.ts      |     100 |      100 |     100 |     100 |                   
  ...olderTrust.ts |   86.27 |    94.11 |     100 |   86.27 | 95-108            
  ...BranchName.ts |     100 |    89.47 |     100 |     100 | 58,61             
  ...oryManager.ts |   96.37 |     92.1 |     100 |   96.37 | ...75-176,219-220 
  ...splayState.ts |     100 |      100 |     100 |     100 |                   
  ...stListener.ts |   12.12 |      100 |       0 |   12.12 | 17-50             
  ...ivityTimer.ts |   76.19 |    66.66 |     100 |   76.19 | 30-35             
  ...putHistory.ts |    92.5 |    85.71 |     100 |    92.5 | 62-63,71,93-95    
  ...storyStore.ts |     100 |    94.11 |     100 |     100 | 67                
  useKeypress.ts   |   22.22 |      100 |       0 |   22.22 | 24-39             
  ...rdProtocol.ts |       0 |        0 |       0 |       0 | 1-26              
  ...fileDialog.ts |    5.71 |      100 |       0 |    5.71 | 27-135            
  ...gIndicator.ts |     100 |      100 |     100 |     100 |                   
  useLogger.ts     |   93.75 |      100 |     100 |   93.75 | 26                
  useMcpStatus.ts  |   90.47 |    66.66 |     100 |   90.47 | 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 |    3.04 |      100 |       0 |    3.04 | 36-103,106-322    
  ...hestration.ts |      10 |      100 |       0 |      10 | 28-63             
  ...oviderInfo.ts |       0 |        0 |       0 |       0 | 1-80              
  ...odifyTrust.ts |    9.09 |      100 |       0 |    9.09 | 46-137            
  ...raseCycler.ts |   79.16 |    71.42 |     100 |   79.16 | ...69,72-73,89-91 
  ...cySettings.ts |   85.84 |    81.81 |     100 |   85.84 | ...,88-92,120-131 
  ...Management.ts |     2.4 |      100 |       0 |     2.4 | 21-62,74-438      
  ...Completion.ts |   29.56 |       40 |     100 |   29.56 | ...13-226,235-241 
  ...iderDialog.ts |    6.81 |      100 |       0 |    6.81 | 28-123            
  ...lScheduler.ts |   67.25 |    76.47 |      60 |   67.25 | ...60,467-489,494 
  ...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 |   87.29 |    88.04 |     100 |   87.29 | ...10-411,420-423 
  useSession.ts    |       0 |        0 |       0 |       0 | 1-23              
  ...ionBrowser.ts |   89.59 |    84.61 |    91.3 |   89.59 | ...68-669,726-727 
  ...ngsCommand.ts |   18.75 |      100 |       0 |   18.75 | 10-25             
  ...ellHistory.ts |   91.66 |    79.41 |     100 |   91.66 | ...69,117-118,128 
  ...Completion.ts |   96.29 |    79.31 |     100 |   96.29 | 90-92,119-120     
  ...oryCommand.ts |       0 |        0 |       0 |       0 | 1-62              
  ...ompletion.tsx |   82.12 |    85.02 |      75 |   82.12 | ...03-904,915-916 
  ...leCallback.ts |     100 |      100 |     100 |     100 |                   
  ...tateAndRef.ts |   59.09 |      100 |     100 |   59.09 | 23-31             
  ...oryRefresh.ts |     100 |      100 |     100 |     100 |                   
  ...rminalSize.ts |   11.42 |      100 |       0 |   11.42 | 13-55             
  ...emeCommand.ts |    6.03 |      100 |       0 |    6.03 | 26-151            
  useTimer.ts      |   88.09 |    85.71 |     100 |   88.09 | 44-45,51-53       
  ...ntinuation.ts |   91.16 |    91.89 |     100 |   91.16 | ...54-155,180-189 
  ...ePreserver.ts |   57.14 |      100 |      80 |   57.14 | 58-76             
  ...oolsDialog.ts |    4.67 |      100 |       0 |    4.67 | 24-145            
  ...Onboarding.ts |    2.47 |      100 |       0 |    2.47 | 78-407            
  ...eMigration.ts |   11.86 |      100 |       0 |   11.86 | 15-73             
  vim.ts           |    83.6 |     79.5 |     100 |    83.6 | ...39,743-751,760 
 ...s/geminiStream |    76.6 |    75.43 |   90.62 |    76.6 |                   
  ...ersistence.ts |   98.26 |    95.23 |     100 |   98.26 | 158-160           
  index.ts         |     100 |      100 |     100 |     100 |                   
  streamUtils.ts   |   98.98 |    95.34 |     100 |   98.98 | 361-363           
  ...ionHandler.ts |   71.36 |    88.88 |     100 |   71.36 | ...92-299,333-339 
  types.ts         |     100 |      100 |     100 |     100 |                   
  ...miniStream.ts |   77.32 |    65.16 |      40 |   77.32 | ...75,582,619-621 
  ...ntHandlers.ts |   62.31 |    51.13 |     100 |   62.31 | ...12-813,816-820 
 src/ui/layouts    |   60.33 |    29.41 |   33.33 |   60.33 |                   
  ...AppLayout.tsx |   60.33 |    29.41 |   33.33 |   60.33 | ...95-689,693-718 
 ...noninteractive |      75 |      100 |    6.66 |      75 |                   
  ...eractiveUi.ts |      75 |      100 |    6.66 |      75 | 17-19,23-24,27-28 
 src/ui/privacy    |   21.98 |        0 |       0 |   21.98 |                   
  ...acyNotice.tsx |       0 |        0 |       0 |       0 | 1-123             
  ...acyNotice.tsx |       0 |        0 |       0 |       0 | 1-59              
  ...acyNotice.tsx |   12.19 |      100 |       0 |   12.19 | 16-62             
  ...acyNotice.tsx |   41.33 |      100 |       0 |   41.33 | 78-91,99-193      
  ...acyNotice.tsx |      25 |      100 |       0 |      25 | 21-43,46-48       
 src/ui/reducers   |   78.44 |     90.9 |      50 |   78.44 |                   
  appReducer.ts    |     100 |      100 |     100 |     100 |                   
  ...ionReducer.ts |       0 |        0 |       0 |       0 | 1-52              
 src/ui/state      |   54.34 |    30.76 |     100 |   54.34 |                   
  extensions.ts    |   54.34 |    30.76 |     100 |   54.34 | ...28,130-142,144 
 src/ui/themes     |   99.04 |    84.41 |   96.96 |   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.79 |    82.81 |     100 |   88.79 | ...13-322,327-328 
  theme.ts         |    99.1 |    79.13 |    87.5 |    99.1 | 282-283,699-700   
  xcode.ts         |     100 |      100 |     100 |     100 |                   
 src/ui/types      |       0 |        0 |       0 |       0 |                   
  ...ngMetadata.ts |       0 |        0 |       0 |       0 |                   
 src/ui/utils      |   57.85 |     86.9 |   73.59 |   57.85 |                   
  ...Colorizer.tsx |    6.36 |      100 |       0 |    6.36 | ...17-129,141-233 
  ...olePatcher.ts |   68.88 |      100 |   83.33 |   68.88 | 51-64             
  ...nRenderer.tsx |   16.23 |      100 |      50 |   16.23 | 27-171            
  ...wnDisplay.tsx |    5.63 |      100 |       0 |    5.63 | ...00-425,436-440 
  ...eRenderer.tsx |   10.63 |      100 |       0 |   10.63 | ...32-247,260-395 
  ...tGenerator.ts |   72.72 |    61.53 |      60 |   72.72 | ...66,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 |    64.7 |     77.5 |     100 |    64.7 | ...31-242,312-313 
  commandUtils.ts  |   92.75 |    95.23 |   95.45 |   92.75 | ...08-212,298-306 
  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 | 75                
  highlight.ts     |   73.22 |    94.44 |      50 |   73.22 | 133-165,169-174   
  ...xportUtils.ts |     100 |      100 |     100 |     100 |                   
  ...storyItems.ts |   98.95 |    94.11 |     100 |   98.95 | 88                
  input.ts         |   64.51 |    85.71 |   33.33 |   64.51 | 18-25,51-58       
  isNarrowWidth.ts |      50 |      100 |       0 |      50 | 13-14             
  ...nUtilities.ts |   69.84 |    86.66 |     100 |   69.84 | 75-91,100-101     
  mouse.ts         |   83.69 |    71.42 |     100 |   83.69 | ...03,210,223-224 
  ...mConstants.ts |     100 |      100 |     100 |     100 |                   
  ...opDetector.ts |       0 |        0 |       0 |       0 | 1-210             
  responsive.ts    |    69.9 |    73.33 |      80 |    69.9 | ...95-103,106-121 
  rewindFileOps.ts |   88.02 |     64.7 |     100 |   88.02 | ...40-244,246-251 
  ...putHandler.ts |   84.24 |    86.53 |     100 |   84.24 | ...25-134,228-229 
  ...ityManager.ts |   94.11 |     83.6 |   88.88 |   94.11 | ...96,320,348,359 
  ...alContract.ts |     100 |      100 |     100 |     100 |                   
  terminalLinks.ts |     100 |      100 |     100 |     100 |                   
  ...colCleanup.ts |     100 |      100 |     100 |     100 |                   
  ...lSequences.ts |     100 |      100 |     100 |     100 |                   
  terminalSetup.ts |    4.16 |      100 |       0 |    4.16 | 42-361            
  textUtils.ts     |   95.41 |    92.59 |   88.88 |   95.41 | 20-25             
  ...Formatters.ts |       0 |        0 |       0 |       0 | 1-52              
  ...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 | 33,44             
 src/utils         |   62.66 |    87.67 |   84.48 |   62.66 |                   
  ...ionContext.ts |   76.92 |       75 |     100 |   76.92 | 38-41,63-66,81-84 
  bootstrap.ts     |    97.4 |    95.65 |     100 |    97.4 | 76-77             
  checks.ts        |   33.33 |      100 |       0 |   33.33 | 23-28             
  cleanup.ts       |   67.21 |       80 |      60 |   67.21 | ...69-71,74,88-97 
  commands.ts      |    50.9 |    63.63 |     100 |    50.9 | 25-26,45,57-84    
  commentJson.ts   |    92.3 |     92.5 |     100 |    92.3 | 94-102            
  ...ScopeUtils.ts |   27.58 |      100 |       0 |   27.58 | 23-40,57-85       
  ...icSettings.ts |   88.61 |    89.18 |     100 |   88.61 | ...41,44-47,65-68 
  ...arResolver.ts |   96.42 |       96 |     100 |   96.42 | 111-112           
  errors.ts        |   94.36 |       88 |     100 |   94.36 | 50-51,86-87       
  events.ts        |     100 |      100 |     100 |     100 |                   
  ...lativeTime.ts |     100 |      100 |     100 |     100 |                   
  gitUtils.ts      |   93.68 |    84.21 |     100 |   93.68 | 63-64,79-82       
  ...AutoUpdate.ts |   67.18 |    76.59 |   71.42 |   67.18 | ...13-214,261-326 
  ...lationInfo.ts |   99.38 |    97.87 |     100 |   99.38 | 98                
  math.ts          |   66.66 |      100 |       0 |   66.66 | 15                
  ...stentState.ts |   95.38 |       85 |     100 |   95.38 | 43,64-65          
  readStdin.ts     |   81.03 |    91.66 |   83.33 |   81.03 | 32-39,51-53       
  relaunch.ts      |     100 |      100 |     100 |     100 |                   
  resolvePath.ts   |   66.66 |       25 |     100 |   66.66 | 12-13,16,18-19    
  sandbox.ts       |   32.64 |    85.27 |   70.58 |   32.64 | ...1018,1035-2226 
  ...ionCleanup.ts |   85.82 |    83.56 |     100 |   85.82 | ...54-255,336-337 
  sessionUtils.ts  |    7.89 |      100 |       0 |    7.89 | 51-120,127-141    
  settingsUtils.ts |   84.14 |    90.52 |   93.33 |   84.14 | ...12-439,478-479 
  ...ttingSaver.ts |    1.92 |      100 |       0 |    1.92 | 7-28,36-81        
  skillSettings.ts |   86.13 |       88 |     100 |   86.13 | 99-107,134-138    
  skillUtils.ts    |   57.71 |    60.71 |      75 |   57.71 | ...85-186,193-214 
  spawnWrapper.ts  |     100 |      100 |     100 |     100 |                   
  ...upWarnings.ts |     100 |      100 |     100 |     100 |                   
  stdinSafety.ts   |   91.44 |    86.48 |     100 |   91.44 | ...66-167,171,246 
  terminalTheme.ts |     100 |      100 |     100 |     100 |                   
  ...entEmitter.ts |     100 |      100 |     100 |     100 |                   
  ...upWarnings.ts |     100 |      100 |     100 |     100 |                   
  version.ts       |     100 |      100 |     100 |     100 |                   
  windowTitle.ts   |     100 |      100 |     100 |     100 |                   
 src/utils/privacy |    46.3 |    68.57 |   52.63 |    46.3 |                   
  ...taRedactor.ts |   60.66 |    70.58 |   55.55 |   60.66 | ...77-479,485-506 
  ...acyManager.ts |       0 |        0 |       0 |       0 | 1-178             
 ...ed-integration |    8.29 |     92.3 |      20 |    8.29 |                   
  ...temService.ts |     100 |      100 |     100 |     100 |                   
  ...ntegration.ts |    6.27 |     87.5 |   11.11 |    6.27 | ...1538,1553-1623 
-------------------|---------|----------|---------|---------|-------------------
Core Package - Full Text Report
-------------------|---------|----------|---------|---------|-------------------
File               | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-------------------|---------|----------|---------|---------|-------------------
All files          |   78.19 |    81.51 |   78.15 |   78.19 |                   
 src               |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
 src/__mocks__/fs  |       0 |        0 |       0 |       0 |                   
  promises.ts      |       0 |        0 |       0 |       0 | 1-48              
 src/adapters      |     100 |      100 |     100 |     100 |                   
  ...eamAdapter.ts |     100 |      100 |     100 |     100 |                   
 src/agents        |   90.01 |    74.21 |     100 |   90.01 |                   
  executor.ts      |   89.34 |    73.33 |     100 |   89.34 | ...64-765,801-807 
  invocation.ts    |   96.55 |    76.47 |     100 |   96.55 | 61,65-66          
  types.ts         |     100 |      100 |     100 |     100 |                   
  utils.ts         |   78.94 |       80 |     100 |   78.94 | 32-35             
 src/auth          |   68.27 |    81.38 |   79.81 |   68.27 |                   
  ...evice-flow.ts |    7.21 |        0 |       0 |    7.21 | ...49-268,274-282 
  ...evice-flow.ts |   46.65 |    57.14 |   63.63 |   46.65 | ...96-485,495-581 
  ...oken-store.ts |   88.92 |       87 |     100 |   88.92 | ...84-387,408-414 
  oauth-errors.ts  |   94.15 |    83.33 |     100 |   94.15 | ...69,610,636-637 
  precedence.ts    |   78.02 |    80.15 |   94.73 |   78.02 | ...1075,1081-1084 
  ...evice-flow.ts |    8.33 |      100 |       0 |    8.33 | ...69-206,214-220 
  token-merge.ts   |     100 |      100 |     100 |     100 |                   
  ...nitization.ts |     100 |      100 |     100 |     100 |                   
  token-store.ts   |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/auth/proxy    |   90.37 |    84.95 |   86.27 |   90.37 |                   
  framing.ts       |    97.1 |    90.47 |     100 |    97.1 | 83-84             
  ...ey-storage.ts |   94.28 |       80 |     100 |   94.28 | 45-46             
  ...ket-client.ts |   86.51 |       88 |   78.26 |   86.51 | ...32-235,255-258 
  ...oken-store.ts |   93.02 |    77.77 |   84.61 |   93.02 | 104-108,112       
 src/code_assist   |   68.13 |    79.31 |   76.47 |   68.13 |                   
  codeAssist.ts    |   17.64 |       50 |   33.33 |   17.64 | 16-62,70-73,81-94 
  converter.ts     |   94.96 |    93.02 |     100 |   94.96 | ...88,202,219-220 
  ...al-storage.ts |   98.21 |       75 |     100 |   98.21 | 76,125            
  oauth2.ts        |   62.83 |    76.47 |   78.57 |   62.83 | ...07-708,713-714 
  server.ts        |   48.16 |    72.72 |      50 |   48.16 | ...08-249,252-255 
  setup.ts         |   82.92 |    73.91 |     100 |   82.92 | ...27-129,153-159 
  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.69 |    79.81 |   61.61 |   71.69 |                   
  config.ts        |   66.66 |       71 |    60.6 |   66.66 | ...67-776,803-807 
  configBase.ts    |    64.9 |    80.85 |   72.72 |    64.9 | ...18-231,244-265 
  ...igBaseCore.ts |   71.35 |    94.44 |   47.85 |   71.35 | ...82-683,685-686 
  ...onstructor.ts |   96.37 |    88.33 |     100 |   96.37 | ...08-409,412-413 
  configTypes.ts   |   60.37 |      100 |      50 |   60.37 | 187-227           
  constants.ts     |     100 |      100 |     100 |     100 |                   
  endpoints.ts     |     100 |      100 |     100 |     100 |                   
  ...ngsHelpers.ts |   67.56 |       50 |     100 |   67.56 | ...26,30-31,35-36 
  index.ts         |       0 |        0 |       0 |       0 | 1-38              
  ...ntegration.ts |   57.66 |    72.72 |   58.33 |   57.66 | ...31,348,357,366 
  models.ts        |     100 |      100 |     100 |     100 |                   
  ...ileManager.ts |    84.3 |    80.26 |     100 |    84.3 | ...09-413,415-419 
  ...rSingleton.ts |   75.43 |    80.95 |   41.66 |   75.43 | ...20,323-326,334 
  storage.ts       |   91.15 |    87.09 |    93.1 |   91.15 | ...,73,75,100-101 
  ...entManager.ts |   52.46 |     67.5 |   68.18 |   52.46 | ...76-677,695-719 
  ...tryFactory.ts |   84.45 |    78.26 |      50 |   84.45 | ...21-235,244-253 
  types.ts         |       0 |        0 |       0 |       0 |                   
 ...nfirmation-bus |   71.42 |     86.2 |      75 |   71.42 |                   
  index.ts         |       0 |        0 |       0 |       0 | 1-2               
  message-bus.ts   |   70.23 |    88.88 |   81.81 |   70.23 | ...08-242,251-259 
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/core          |   80.52 |    78.18 |   76.71 |   80.52 |                   
  ...ookManager.ts |     100 |      100 |     100 |     100 |                   
  ...ionFactory.ts |   94.55 |    89.74 |     100 |   94.55 | ...80-282,328-331 
  ...ionManager.ts |   66.18 |    62.22 |   56.25 |   66.18 | ...26-434,441-445 
  ...eProcessor.ts |   53.57 |    30.18 |   68.75 |   53.57 | ...75-528,543-554 
  ...extTracker.ts |   93.62 |    88.73 |     100 |   93.62 | ...74-177,217-221 
  ...eConverter.ts |   58.92 |    74.11 |   57.14 |   58.92 | ...75,538,549-560 
  ...chestrator.ts |   88.01 |       75 |      75 |   88.01 | ...77-882,922-928 
  ...mProcessor.ts |   74.57 |    76.29 |    62.5 |   74.57 | ...89,893,905-927 
  ...ionService.ts |   91.87 |    91.81 |     100 |   91.87 | ...99,359,384-406 
  TurnProcessor.ts |   77.08 |    64.36 |   70.37 |   77.08 | ...74-675,677-727 
  baseLlmClient.ts |   95.23 |    90.74 |     100 |   95.23 | ...85-286,367-368 
  ...ntegration.ts |   96.66 |    96.07 |     100 |   96.66 | ...37-138,218-219 
  client.ts        |   62.54 |    83.09 |      68 |   62.54 | ...40-658,710-726 
  clientHelpers.ts |   89.47 |     83.6 |     100 |   89.47 | ...,82-83,103-106 
  ...mUtilities.ts |   96.77 |    70.58 |     100 |   96.77 | ...15-116,172-173 
  ...Governance.ts |   98.01 |    97.14 |     100 |   98.01 | 101-102           
  ...ion-config.ts |     100 |      100 |     100 |     100 |                   
  ...tGenerator.ts |   97.22 |    90.47 |     100 |   97.22 | 100-101           
  ...okTriggers.ts |   77.19 |    65.85 |     100 |   77.19 | ...70-271,295-300 
  ...lScheduler.ts |   82.25 |    88.77 |   70.45 |   82.25 | ...15-719,733-734 
  geminiChat.ts    |   82.68 |    80.76 |   60.41 |   82.68 | ...61-462,493-494 
  ...iChatTypes.ts |   94.73 |      100 |      80 |   94.73 | 112-113           
  geminiRequest.ts |     100 |      100 |     100 |     100 |                   
  ...nAIWrapper.ts |   88.88 |      100 |   83.33 |   88.88 | 56-59             
  ...okTriggers.ts |   96.21 |    89.13 |     100 |   96.21 | ...13,157,209,256 
  logger.ts        |   80.96 |    81.81 |     100 |   80.96 | ...65-379,426-440 
  ...olExecutor.ts |   59.79 |       60 |      50 |   59.79 | ...31-136,148-177 
  prompts.ts       |   85.26 |    61.42 |    90.9 |   85.26 | ...52-455,465,487 
  subagent.ts      |   76.45 |     62.5 |   95.83 |   76.45 | ...21-826,831-833 
  ...tExecution.ts |   59.67 |    83.05 |   73.33 |   59.67 | ...94,498,500-503 
  ...chestrator.ts |   90.38 |    76.59 |   95.83 |   90.38 | ...61,664-665,670 
  ...ntimeSetup.ts |   84.95 |    78.21 |   57.89 |   84.95 | ...80-584,619-627 
  ...tScheduler.ts |       0 |        0 |       0 |       0 | 1                 
  ...Processing.ts |      88 |    84.94 |     100 |      88 | ...75,479-507,514 
  subagentTypes.ts |     100 |      100 |   83.33 |     100 |                   
  tokenLimits.ts   |   88.15 |    70.37 |     100 |   88.15 | ...79,81,83,87,97 
  ...Governance.ts |    94.2 |     90.9 |     100 |    94.2 | 34-35,51-52       
  turn.ts          |   92.69 |    80.48 |   81.81 |   92.69 | ...00-601,631-632 
  turnLogging.ts   |   75.29 |    66.66 |      80 |   75.29 | 35-58             
 ...re/compression |   84.37 |    84.91 |   88.17 |   84.37 |                   
  ...ionHandler.ts |   86.94 |    83.17 |   74.19 |   86.94 | ...24-825,833-834 
  ...tyStrategy.ts |   92.32 |    88.88 |   93.75 |   92.32 | ...34,893-894,931 
  ...utStrategy.ts |   88.51 |    76.92 |     100 |   88.51 | ...35-446,449-458 
  ...otStrategy.ts |   82.08 |    75.67 |     100 |   82.08 | ...76-287,290-299 
  ...onStrategy.ts |     100 |      100 |     100 |     100 |                   
  ...nBudgeting.ts |   36.06 |       70 |     100 |   36.06 | ...06-107,112-164 
  ...egyFactory.ts |   90.62 |    88.88 |     100 |   90.62 | 52-54             
  index.ts         |       0 |        0 |       0 |       0 | 1-17              
  types.ts         |   99.03 |    91.42 |     100 |   99.03 | 239               
  utils.ts         |   71.94 |    87.91 |      90 |   71.94 | ...98-399,416-417 
 src/debug         |   78.31 |    88.53 |    87.3 |   78.31 |                   
  ...ionManager.ts |   77.66 |    78.04 |      85 |   77.66 | ...33-234,251-255 
  DebugLogger.ts   |   90.78 |    90.47 |   88.46 |   90.78 | ...77,221-225,268 
  FileOutput.ts    |   88.13 |    94.11 |   86.66 |   88.13 | ...32-136,162-163 
  ...ionManager.ts |       0 |      100 |     100 |       0 | 18-64             
  ...FileOutput.ts |       0 |      100 |     100 |       0 | 17-39             
  index.ts         |     100 |      100 |     100 |     100 |                   
  types.ts         |       0 |        0 |       0 |       0 |                   
 src/filters       |   99.19 |    98.76 |     100 |   99.19 |                   
  EmojiFilter.ts   |   99.19 |    98.76 |     100 |   99.19 | 208-209           
 src/hooks         |   84.89 |    84.74 |   83.68 |   84.89 |                   
  errors.ts        |     100 |      100 |     100 |     100 |                   
  ...Aggregator.ts |    92.7 |    89.23 |    87.5 |    92.7 | ...31,350,352,354 
  ...sContracts.ts |       0 |        0 |       0 |       0 | 1                 
  ...entHandler.ts |   91.62 |    85.82 |   93.33 |   91.62 | ...20,756-762,807 
  hookPlanner.ts   |   98.79 |    93.33 |     100 |   98.79 | 103               
  hookRegistry.ts  |   98.25 |    86.56 |     100 |   98.25 | 341,343,345,347   
  hookRunner.ts    |    83.8 |    81.48 |     100 |    83.8 | ...08-310,319-320 
  hookSystem.ts    |   71.02 |    89.47 |      70 |   71.02 | ...49-351,364-366 
  ...Translator.ts |   94.65 |     65.9 |     100 |   94.65 | ...88-289,300,349 
  ...Validators.ts |    92.3 |    88.52 |     100 |    92.3 | 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         |    65.6 |    86.95 |   70.83 |    65.6 | ...58-379,426-427 
 ...oks/test-utils |       0 |        0 |       0 |       0 |                   
  ...igWithHook.ts |       0 |        0 |       0 |       0 | 1-139             
 src/ide           |   73.67 |    86.38 |   73.07 |   73.67 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  detect-ide.ts    |     100 |      100 |     100 |     100 |                   
  ide-client.ts    |   56.37 |    79.66 |   54.83 |   56.37 | ...21-529,557-565 
  ide-installer.ts |   90.55 |    85.18 |     100 |   90.55 | ...35,142-146,159 
  ideContext.ts    |   84.82 |      100 |     100 |   84.82 | 89-105            
  process-utils.ts |    89.2 |    83.05 |     100 |    89.2 | ...70-171,212-213 
 src/interfaces    |       0 |        0 |       0 |       0 |                   
  index.ts         |       0 |        0 |       0 |       0 |                   
  ....interface.ts |       0 |        0 |       0 |       0 |                   
 src/lsp           |   71.03 |    73.91 |      90 |   71.03 |                   
  ...ice-client.ts |   71.03 |    73.62 |   89.47 |   71.03 | ...06,448-468,479 
  types.ts         |       0 |        0 |       0 |       0 |                   
 src/mcp           |   79.82 |    78.71 |   72.41 |   79.82 |                   
  auth-provider.ts |       0 |        0 |       0 |       0 | 1                 
  ...oken-store.ts |    86.4 |    90.47 |   81.25 |    86.4 | ...39-340,343-344 
  ...h-provider.ts |    90.1 |      100 |      40 |    90.1 | ...97,101,105-106 
  ...h-provider.ts |   76.26 |     57.4 |     100 |   76.26 | ...39,968,975-977 
  ...en-storage.ts |    81.5 |    88.88 |   68.18 |    81.5 | ...97-198,203-204 
  oauth-utils.ts   |   72.44 |    85.36 |    92.3 |   72.44 | ...09-313,339-374 
  ...n-provider.ts |      88 |    94.73 |   33.33 |      88 | ...37,141,145-146 
  token-store.ts   |     100 |      100 |     100 |     100 |                   
 .../token-storage |   88.17 |    87.94 |   93.02 |   88.17 |                   
  ...en-storage.ts |     100 |      100 |     100 |     100 |                   
  ...en-storage.ts |   86.61 |    87.09 |   92.85 |   86.61 | ...64-172,180-181 
  ...en-storage.ts |     100 |      100 |     100 |     100 |                   
  ...en-storage.ts |   83.76 |    83.11 |   84.61 |   83.76 | ...57,259,311-312 
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/models        |   83.44 |    91.15 |    87.5 |   83.44 |                   
  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.31 |    85.36 |     100 |   95.31 | ...35-136,199-200 
  registry.ts      |   90.45 |    88.88 |      92 |   90.45 | ...69-270,389-402 
  schema.ts        |     100 |      100 |     100 |     100 |                   
  transformer.ts   |     100 |      100 |     100 |     100 |                   
 src/parsers       |    70.7 |       75 |    86.2 |    70.7 |                   
  ...CallParser.ts |    70.7 |       75 |    86.2 |    70.7 | ...1,983,989-1004 
 src/policy        |   83.85 |    80.13 |   91.42 |   83.85 |                   
  config.ts        |   70.08 |     72.3 |   85.71 |   70.08 | ...67,521,585-586 
  index.ts         |     100 |      100 |     100 |     100 |                   
  policy-engine.ts |   96.71 |    89.33 |     100 |   96.71 | 71-74,104         
  ...cy-helpers.ts |     100 |      100 |     100 |     100 |                   
  ...-stringify.ts |   80.23 |    60.52 |      50 |   80.23 | ...22-126,139-140 
  toml-loader.ts   |   89.88 |    83.52 |     100 |   89.88 | ...75,477,484,486 
  types.ts         |     100 |      100 |     100 |     100 |                   
  utils.ts         |   81.81 |    84.61 |     100 |   81.81 | 24-27,30-33       
 src/prompt-config |   75.67 |    84.67 |   85.55 |   75.67 |                   
  ...lateEngine.ts |   91.05 |    86.36 |     100 |   91.05 | ...18-321,332-335 
  index.ts         |       0 |      100 |     100 |       0 | 5-41              
  prompt-cache.ts  |   99.08 |    97.43 |     100 |   99.08 | 216-217           
  ...-installer.ts |   83.11 |    82.47 |     100 |   83.11 | ...1173,1253-1254 
  prompt-loader.ts |   88.02 |    91.57 |   76.92 |   88.02 | ...79-388,430-431 
  ...t-resolver.ts |   35.02 |    66.17 |   53.84 |   35.02 | ...21-772,775-803 
  ...pt-service.ts |   85.21 |     83.8 |      80 |   85.21 | ...30,547-554,585 
  ...delegation.ts |   93.54 |    91.66 |     100 |   93.54 | 33-34             
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...onfig/defaults |    50.4 |    43.53 |     100 |    50.4 |                   
  core-defaults.ts |   38.02 |    35.89 |     100 |   38.02 | ...73,284,290-298 
  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 |   42.61 |    31.57 |     100 |   42.61 | ...49,260,266-271 
  ...e-defaults.ts |     100 |      100 |     100 |     100 |                   
  tool-defaults.ts |   49.77 |    36.84 |     100 |   49.77 | ...14-220,233-238 
 src/prompts       |   27.77 |      100 |      25 |   27.77 |                   
  mcp-prompts.ts   |   18.18 |      100 |       0 |   18.18 | 11-19             
  ...t-registry.ts |   30.23 |      100 |   28.57 |   30.23 | ...43,49-56,69-74 
 src/providers     |   71.12 |    80.75 |   66.81 |   71.12 |                   
  BaseProvider.ts  |   80.07 |    78.57 |   78.84 |   80.07 | ...1192,1195-1196 
  ...eratorRole.ts |     100 |      100 |     100 |     100 |                   
  IModel.ts        |       0 |        0 |       0 |       0 |                   
  IProvider.ts     |       0 |        0 |       0 |       0 |                   
  ...derManager.ts |     100 |      100 |     100 |     100 |                   
  ITool.ts         |       0 |        0 |       0 |       0 |                   
  ...ngProvider.ts |   86.52 |    88.23 |   88.57 |   86.52 | ...1200,1236-1238 
  ...derWrapper.ts |    62.6 |    72.25 |    57.5 |    62.6 | ...1448,1467-1474 
  ...tGenerator.ts |    17.3 |      100 |       0 |    17.3 | ...59,62-79,82-85 
  ...derManager.ts |   57.93 |     75.1 |   60.46 |   57.93 | ...1564-1565,1568 
  ...chestrator.ts |   81.42 |    88.94 |   70.83 |   81.42 | ...77-681,683-690 
  ...taResolver.ts |   97.27 |    93.18 |     100 |   97.27 | 173-175           
  errors.ts        |   75.98 |    69.44 |   42.85 |   75.98 | ...82-283,292-293 
  ...ConfigKeys.ts |     100 |      100 |     100 |     100 |                   
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 ...ders/anthropic |   88.51 |    86.08 |   88.72 |   88.51 |                   
  ...iExecution.ts |     100 |     92.3 |     100 |     100 | 201,225           
  ...Normalizer.ts |   90.07 |    86.45 |     100 |   90.07 | ...89-693,698-703 
  ...eValidator.ts |   98.38 |    99.12 |     100 |   98.38 | ...99,413-414,449 
  ...cModelData.ts |   92.26 |       95 |      75 |   92.26 | 176-189,234-235   
  ...icProvider.ts |    78.6 |    77.77 |   73.17 |    78.6 | ...00-502,633-634 
  ...mitHandler.ts |   98.61 |     97.1 |     100 |   98.61 | 130,214-215       
  ...estBuilder.ts |    88.2 |       88 |     100 |    88.2 | ...97-198,211-212 
  ...reparation.ts |   95.92 |    83.13 |   93.33 |   95.92 | ...46,588,634,721 
  ...onseParser.ts |   75.89 |     61.9 |     100 |   75.89 | ...24-128,178-179 
  ...mProcessor.ts |   84.71 |    83.78 |     100 |   84.71 | ...20,379,468,490 
  ...aConverter.ts |   50.94 |    44.11 |   71.42 |   50.94 | ...60-264,279-287 
  usageInfo.ts     |   92.24 |    96.96 |     100 |   92.24 | ...02-107,117-119 
 ...pic/test-utils |       0 |        0 |       0 |       0 |                   
  ...cTestUtils.ts |       0 |        0 |       0 |       0 |                   
 ...oviders/chutes |   78.57 |       80 |     100 |   78.57 |                   
  usageInfo.ts     |   78.57 |       80 |     100 |   78.57 | ...68-170,185-199 
 ...providers/fake |   91.62 |    78.26 |     100 |   91.62 |                   
  FakeProvider.ts  |   91.62 |    78.26 |     100 |   91.62 | ...12-215,218-221 
 ...oviders/gemini |   53.86 |     70.4 |   45.23 |   53.86 |                   
  ...niProvider.ts |   51.99 |    60.96 |   44.73 |   51.99 | ...1877,1886-1887 
  ...Signatures.ts |     100 |    98.41 |     100 |     100 | 182               
  usageInfo.ts     |   16.66 |      100 |       0 |   16.66 | 41-149            
 ...providers/kimi |   86.34 |     84.9 |     100 |   86.34 |                   
  usageInfo.ts     |   86.34 |     84.9 |     100 |   86.34 | ...16-319,331-332 
 ...viders/logging |   42.94 |    85.71 |      75 |   42.94 |                   
  ...tExtractor.ts |       0 |        0 |       0 |       0 | 1-229             
  ...nceTracker.ts |   91.33 |       90 |   81.81 |   91.33 | ...73-175,193-194 
 ...oviders/openai |   73.54 |    78.92 |   63.31 |   73.54 |                   
  ...ationCache.ts |   65.57 |    83.33 |   82.35 |   65.57 | ...79-187,216-217 
  ...rateParams.ts |       0 |        0 |       0 |       0 |                   
  ...iExecution.ts |   23.36 |    41.66 |      25 |   23.36 | ...63-171,175-246 
  ...entFactory.ts |   87.87 |    97.91 |   71.42 |   87.87 | 76-81,85-94       
  ...eamHandler.ts |   56.71 |       28 |   33.33 |   56.71 | ...43-244,262-276 
  ...AIProvider.ts |   64.11 |    72.05 |   45.16 |   64.11 | ...07,734,742-751 
  ...estBuilder.ts |   87.89 |    92.24 |   91.66 |   87.89 | ...82-491,503-511 
  ...reparation.ts |   72.91 |    55.17 |      25 |   72.91 | ...83-186,190-191 
  ...onseParser.ts |    94.7 |    89.28 |   83.33 |    94.7 | ...82-186,254-255 
  ...mProcessor.ts |   57.71 |    59.37 |    9.52 |   57.71 | ...57,885,887-906 
  ...API_MODELS.ts |     100 |      100 |     100 |     100 |                   
  ...lCollector.ts |   93.33 |    89.28 |     100 |   93.33 | ...51-153,173-174 
  ...Normalizer.ts |   92.75 |    95.83 |     100 |   92.75 | 74-78             
  ...llPipeline.ts |   64.54 |    53.33 |      75 |   64.54 | ...34-143,174-184 
  ...eValidator.ts |   94.02 |    93.75 |     100 |   94.02 | 106-109           
  ...sesRequest.ts |   83.92 |    93.24 |     100 |   83.92 | ...59,293,298-303 
  ...xUsageInfo.ts |   91.57 |    90.24 |     100 |   91.57 | ...86,190,197-199 
  ...moteTokens.ts |   89.55 |     92.3 |     100 |   89.55 | 97-103            
  ...sonMapping.ts |   82.75 |    33.33 |   33.33 |   82.75 | 45-49             
  ...oviderInfo.ts |    86.2 |    73.52 |     100 |    86.2 | ...31-133,144-145 
  ...uestParams.ts |   87.27 |    57.69 |     100 |   87.27 | ...20-121,123-124 
  ...nsesStream.ts |   87.06 |    85.57 |     100 |   87.06 | ...65,524-531,555 
  ...aConverter.ts |    53.7 |    52.63 |   71.42 |    53.7 | ...59-260,283-291 
  ...lResponses.ts |   71.98 |    73.33 |      75 |   71.98 | ...97-301,321-335 
  test-types.ts    |       0 |        0 |       0 |       0 |                   
  toolNameUtils.ts |   96.79 |    95.45 |      50 |   96.79 | 102,127,239-241   
 ...enai-responses |   62.46 |    74.39 |   41.93 |   62.46 |                   
  CODEX_MODELS.ts  |     100 |      100 |     100 |     100 |                   
  ...esProvider.ts |   66.35 |    73.29 |      50 |   66.35 | ...1156,1177-1199 
  ...romContent.ts |      90 |     87.5 |     100 |      90 | 61-65,147,186-193 
  index.ts         |       0 |        0 |       0 |       0 | 1                 
  ...aConverter.ts |    7.97 |       20 |   14.28 |    7.97 | ...52-278,281-290 
 .../openai-vercel |   70.92 |     66.5 |   62.29 |   70.92 |                   
  ...elProvider.ts |   70.51 |     63.9 |   48.71 |   70.51 | ...1654,1664-1665 
  errors.ts        |   93.23 |    82.05 |     100 |   93.23 | ...50-151,165-169 
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...Conversion.ts |   71.42 |    74.68 |      80 |   71.42 | ...06-510,528-536 
  ...aConverter.ts |    53.7 |       50 |   71.42 |    53.7 | ...58-259,282-290 
  toolIdUtils.ts   |     100 |      100 |     100 |     100 |                   
 ...ders/reasoning |   47.13 |    89.65 |    87.5 |   47.13 |                   
  ...oningUtils.ts |   47.13 |    89.65 |    87.5 |   47.13 | ...47-205,241-280 
 ...ders/synthetic |    93.7 |    91.66 |     100 |    93.7 |                   
  usageInfo.ts     |    93.7 |    91.66 |     100 |    93.7 | ...19-121,155-156 
 ...ers/test-utils |     100 |      100 |     100 |     100 |                   
  ...TestConfig.ts |     100 |      100 |     100 |     100 |                   
 ...ers/tokenizers |      70 |    77.77 |      75 |      70 |                   
  ...cTokenizer.ts |   68.42 |       75 |     100 |   68.42 | 34-39             
  ITokenizer.ts    |       0 |        0 |       0 |       0 |                   
  ...ITokenizer.ts |   70.73 |       80 |   66.66 |   70.73 | 53-56,63-72       
 ...roviders/types |       0 |        0 |       0 |       0 |                   
  ...iderConfig.ts |       0 |        0 |       0 |       0 |                   
  ...derRuntime.ts |       0 |        0 |       0 |       0 |                   
 ...roviders/utils |   91.91 |    90.75 |   90.24 |   91.91 |                   
  authToken.ts     |   33.33 |       50 |      50 |   33.33 | 14-22,30-35       
  ...sExtractor.ts |   95.45 |     91.3 |     100 |   95.45 | 15-16             
  ...nerSandbox.ts |     100 |      100 |     100 |     100 |                   
  ...entPreview.ts |   88.88 |    77.77 |     100 |   88.88 | 51-52,58-59,66    
  dumpContext.ts   |    96.1 |    95.65 |     100 |    96.1 | 110-112           
  ...SDKContext.ts |   94.59 |       75 |     100 |   94.59 | 27,49             
  localEndpoint.ts |   89.28 |    92.68 |     100 |   89.28 | ...18-119,138-139 
  mediaUtils.ts    |     100 |    93.33 |     100 |     100 | 22,34             
  qwenEndpoint.ts  |     100 |      100 |     100 |     100 |                   
  retryStrategy.ts |   96.29 |    90.47 |      50 |   96.29 | 73,84             
  textSanitizer.ts |     100 |    91.66 |      50 |     100 | 54                
  ...Extraction.ts |     100 |    94.44 |      50 |     100 | 78                
  ...tDetection.ts |    97.5 |    94.44 |     100 |    97.5 | 38                
  ...malization.ts |     100 |      100 |     100 |     100 |                   
  ...malization.ts |     100 |      100 |     100 |     100 |                   
  ...nsePayload.ts |   92.63 |    86.88 |     100 |   92.63 | ...42-147,200-204 
  userMemory.ts    |   51.51 |       60 |     100 |   51.51 | 16-18,31-43       
 src/providers/zai |   89.93 |       80 |     100 |   89.93 |                   
  usageInfo.ts     |   89.93 |       80 |     100 |   89.93 | ...58-160,171-172 
 src/recording     |   90.34 |    84.51 |   98.43 |   90.34 |                   
  ...ntegration.ts |    83.9 |    74.07 |     100 |    83.9 | ...31-132,143-144 
  ReplayEngine.ts  |   98.38 |    92.53 |     100 |   98.38 | 272-275           
  ...nDiscovery.ts |   91.98 |    84.37 |     100 |   91.98 | ...29,245-247,296 
  ...ockManager.ts |   89.94 |    82.69 |     100 |   89.94 | ...95,210,247-248 
  ...ingService.ts |   82.37 |       92 |   95.23 |   82.37 | ...40,373-374,378 
  index.ts         |     100 |      100 |     100 |     100 |                   
  resumeSession.ts |    91.8 |    86.95 |     100 |    91.8 | ...32-133,174-179 
  ...eanupUtils.ts |      90 |    69.23 |     100 |      90 | ...29-230,256,269 
  ...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       |   88.27 |    85.22 |    82.5 |   88.27 |                   
  ...imeContext.ts |     100 |      100 |     100 |     100 |                   
  ...timeLoader.ts |    84.9 |    69.38 |      80 |    84.9 | ...85-188,226-229 
  ...ntimeState.ts |   95.49 |    91.89 |     100 |   95.49 | ...83-484,525-526 
  ...ionContext.ts |   85.89 |    94.11 |   85.71 |   85.89 | 80-82,149-156     
  ...imeContext.ts |   91.66 |    94.02 |    87.5 |   91.66 | ...25-230,232-239 
  index.ts         |       0 |        0 |       0 |       0 | 1-15              
  ...imeContext.ts |     100 |      100 |     100 |     100 |                   
  ...meAdapters.ts |   64.81 |       65 |   56.25 |   64.81 | ...,47-50,123-149 
  ...ateFactory.ts |   96.05 |    81.48 |     100 |   96.05 | 72,87,107         
 src/safety        |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  pathValidator.ts |     100 |      100 |     100 |     100 |                   
 src/scheduler     |   90.06 |    81.99 |   96.72 |   90.06 |                   
  ...oordinator.ts |   85.92 |    78.26 |     100 |   85.92 | ...18,741-742,797 
  ...aggregator.ts |   89.72 |    86.79 |     100 |   89.72 | ...04,412,416-423 
  ...ransitions.ts |   96.58 |       75 |     100 |   96.58 | ...,74-75,273-275 
  ...dispatcher.ts |   98.21 |       96 |     100 |   98.21 | 147-148           
  tool-executor.ts |   89.56 |    82.35 |   66.66 |   89.56 | ...63-165,168-169 
  types.ts         |     100 |      100 |     100 |     100 |                   
  utils.ts         |     100 |      100 |     100 |     100 |                   
 src/services      |   84.27 |    85.59 |   85.63 |   84.27 |                   
  ...ardService.ts |   93.33 |    92.85 |     100 |   93.33 | 63,67-68          
  ...utoTrigger.ts |   97.14 |    95.83 |     100 |   97.14 | 119-120           
  ...askManager.ts |   95.81 |    93.93 |     100 |   95.81 | 151-157,365-366   
  ...derService.ts |   98.98 |    94.28 |     100 |   98.98 | 173               
  ...y-analyzer.ts |   76.32 |    81.17 |   77.77 |   76.32 | ...79-507,513-514 
  ...extManager.ts |     100 |      100 |     100 |     100 |                   
  ...nitization.ts |   98.62 |     90.9 |     100 |   98.62 | 172-173           
  ...eryService.ts |   98.54 |    95.45 |     100 |   98.54 | 132-133           
  ...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 |   94.87 |     91.3 |     100 |   94.87 | ...90-291,301-302 
  ...ionService.ts |   79.18 |    80.51 |   78.37 |   79.18 | ...1199,1208-1230 
  ...xt-tracker.ts |   94.87 |       90 |    87.5 |   94.87 | 54-55             
  ...er-service.ts |    60.6 |    82.35 |      50 |    60.6 | ...36-139,142-160 
  ...er-service.ts |   69.45 |    55.88 |      80 |   69.45 | ...85-289,311-314 
 ...rvices/history |   83.54 |     85.2 |   90.27 |   83.54 |                   
  ...Converters.ts |   87.39 |    82.35 |   85.71 |   87.39 | ...22-334,345-351 
  HistoryEvents.ts |       0 |        0 |       0 |       0 |                   
  ...oryService.ts |   81.28 |     85.9 |   89.47 |   81.28 | ...1553,1589-1590 
  IContent.ts      |   88.05 |    80.76 |     100 |   88.05 | ...39-240,257-260 
  ...calToolIds.ts |   96.82 |     93.1 |     100 |   96.82 | 36-37             
 src/settings      |   81.55 |       87 |   56.52 |   81.55 |                   
  ...ngsService.ts |   91.69 |    75.75 |   95.23 |   91.69 | ...58-359,389-393 
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...gsRegistry.ts |    79.2 |    92.74 |   36.36 |    79.2 | ...1480,1483-1500 
  ...ceInstance.ts |     100 |      100 |     100 |     100 |                   
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 src/skills        |   74.87 |     85.1 |   73.07 |   74.87 |                   
  skillLoader.ts   |    56.7 |    83.33 |   71.42 |    56.7 | ...94-226,229-264 
  skillManager.ts  |    91.2 |     86.2 |   73.68 |    91.2 | ...52-353,359-360 
 src/storage       |    90.5 |    85.08 |   92.98 |    90.5 |                   
  ...FileWriter.ts |   83.75 |       80 |    87.5 |   83.75 | 41-42,72-82       
  ...nceService.ts |   98.67 |    96.96 |     100 |   98.67 | 293-294           
  ...ey-storage.ts |   92.64 |    90.47 |     100 |   92.64 | 35-37,83-84       
  secure-store.ts  |   89.09 |     82.6 |   89.28 |   89.09 | ...09-712,728-729 
  sessionTypes.ts  |     100 |      100 |     100 |     100 |                   
 src/telemetry     |   68.36 |    82.55 |    62.4 |   68.36 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  ...-exporters.ts |   28.08 |      100 |       0 |   28.08 | ...14-115,118-119 
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...t.circular.ts |       0 |        0 |       0 |       0 | 1-17              
  ...t.circular.ts |       0 |        0 |       0 |       0 | 1-132             
  loggers.ts       |   65.28 |    72.91 |   60.71 |   65.28 | ...94-607,615-631 
  metrics.ts       |   62.35 |    96.29 |   66.66 |   62.35 | ...41-163,166-189 
  sdk.ts           |   77.41 |    52.38 |     100 |   77.41 | ...62,166-167,169 
  ...l-decision.ts |     100 |      100 |     100 |     100 |                   
  types.ts         |   76.42 |       86 |    66.1 |   76.42 | ...60-662,665-669 
  uiTelemetry.ts   |   95.45 |    96.15 |   91.66 |   95.45 | 158,197-203       
 src/test-utils    |   90.86 |    88.05 |      60 |   90.86 |                   
  config.ts        |     100 |      100 |     100 |     100 |                   
  index.ts         |       0 |        0 |       0 |       0 | 1-9               
  mock-tool.ts     |   97.91 |      100 |   83.33 |   97.91 | 78-79             
  ...aceContext.ts |     100 |      100 |     100 |     100 |                   
  ...allOptions.ts |   93.92 |    91.66 |   63.63 |   93.92 | ...19,187,216-219 
  runtime.ts       |   89.44 |    84.84 |   42.55 |   89.44 | ...00-302,311-312 
  tools.ts         |   84.69 |    77.77 |      80 |   84.69 | ...58,180,184-185 
 src/todo          |   51.55 |    83.33 |      75 |   51.55 |                   
  todoFormatter.ts |   51.55 |    83.33 |      75 |   51.55 | ...56-160,198-199 
 src/tools         |   77.59 |     78.9 |   81.66 |   77.59 |                   
  ...lFormatter.ts |     100 |      100 |     100 |     100 |                   
  ToolFormatter.ts |   21.21 |    76.74 |   33.33 |   21.21 | ...27,534-632,647 
  ...IdStrategy.ts |   94.77 |       92 |     100 |   94.77 | ...30-231,267-270 
  ...vate-skill.ts |   92.51 |    72.22 |      90 |   92.51 | ...99,168-170,182 
  apply-patch.ts   |   52.54 |       50 |   53.84 |   52.54 | ...77-501,510-511 
  ast-edit.ts      |   95.28 |       96 |   92.85 |   95.28 | 159-167           
  ast-grep.ts      |   88.96 |    85.52 |   88.88 |   88.96 | ...57-259,280-281 
  ...sync-tasks.ts |   96.49 |    91.52 |    92.3 |   96.49 | 50-54,100,117,237 
  codesearch.ts    |   98.13 |    89.47 |    87.5 |   98.13 | 114-115,192       
  ...line_range.ts |   85.95 |    72.09 |      70 |   85.95 | ...09-310,318-319 
  diffOptions.ts   |     100 |      100 |     100 |     100 |                   
  ...-web-fetch.ts |   94.39 |    79.48 |      80 |   94.39 | ...98,218,237-238 
  ...scapeUtils.ts |   61.65 |    72.97 |      50 |   61.65 | ...93,309,311-321 
  edit.ts          |   79.11 |    82.65 |   76.47 |   79.11 | ...4-925,962-1006 
  ensure-dirs.ts   |     100 |      100 |     100 |     100 |                   
  ...web-search.ts |   98.13 |    88.23 |   85.71 |   98.13 | 136-137,216       
  ...y-replacer.ts |   85.71 |    84.35 |     100 |   85.71 | ...47-448,493-494 
  glob.ts          |      91 |    81.96 |      90 |      91 | ...69-270,379-380 
  ...-web-fetch.ts |   94.11 |    87.73 |    92.3 |   94.11 | ...88-389,399-400 
  ...invocation.ts |   55.07 |    38.88 |      75 |   55.07 | ...30-134,166-211 
  ...web-search.ts |     100 |      100 |     100 |     100 |                   
  grep.ts          |   63.56 |       80 |   73.68 |   63.56 | ...99,917,928-935 
  ...rt_at_line.ts |   82.95 |    78.43 |      70 |   82.95 | ...34-335,343-344 
  ...-subagents.ts |    87.5 |    69.56 |   88.88 |    87.5 | ...,83-91,100,156 
  ls.ts            |   97.59 |    89.23 |     100 |   97.59 | 157-162           
  ...ics-helper.ts |     100 |    71.42 |     100 |     100 | 56,65,70,77,82    
  ...nt-manager.ts |   51.75 |    68.18 |   36.84 |   51.75 | ...73-396,399-400 
  mcp-client.ts    |   52.11 |    75.27 |   70.37 |   52.11 | ...1947,1951-1954 
  mcp-tool.ts      |   92.52 |     93.1 |   84.61 |   92.52 | ...75-285,349-350 
  memoryTool.ts    |    78.6 |     84.5 |   88.88 |    78.6 | ...95-396,449-502 
  ...iable-tool.ts |   92.15 |    74.07 |     100 |   92.15 | 76-81,205-210     
  read-file.ts     |   91.69 |    80.26 |    90.9 |   91.69 | ...36-237,405-406 
  ...many-files.ts |    73.1 |     78.2 |   88.88 |    73.1 | ...33-534,541-542 
  ...line_range.ts |   78.49 |       64 |      80 |   78.49 | ...56-357,361-362 
  ripGrep.ts       |   83.29 |    86.81 |   86.66 |   83.29 | ...16,419,447-472 
  shell.ts         |   85.08 |    79.08 |    90.9 |   85.08 | ...90-891,896-897 
  ...l-analysis.ts |   81.76 |    62.28 |      92 |   81.76 | ...1185,1238,1249 
  task.ts          |   83.38 |    74.11 |    92.1 |   83.38 | ...1247,1250-1259 
  todo-events.ts   |    62.5 |      100 |       0 |    62.5 | 23-24,27-28,31-32 
  todo-pause.ts    |   87.09 |       80 |     100 |   87.09 | 64-69,73-78,93-98 
  todo-read.ts     |   89.24 |    94.73 |     100 |   89.24 | 113-124           
  todo-schemas.ts  |     100 |      100 |     100 |     100 |                   
  todo-store.ts    |   76.92 |    82.35 |   77.77 |   76.92 | ...31-133,140-145 
  todo-write.ts    |   88.23 |    80.48 |   88.88 |   88.23 | ...75,210-212,290 
  ...tion-types.ts |     100 |      100 |     100 |     100 |                   
  tool-context.ts  |     100 |      100 |     100 |     100 |                   
  tool-error.ts    |   88.23 |      100 |       0 |   88.23 | 109-116           
  ...ey-storage.ts |   86.02 |    80.51 |     100 |   86.02 | ...50-355,364-369 
  tool-names.ts    |     100 |      100 |     100 |     100 |                   
  tool-registry.ts |    83.4 |       75 |   82.05 |    83.4 | ...94-702,710-711 
  toolNameUtils.ts |      80 |     92.1 |     100 |      80 | 59-60,64-65,69-82 
  tools.ts         |   80.72 |     82.5 |   74.35 |   80.72 | ...16-917,920-927 
  write-file.ts    |    80.1 |    71.09 |   73.33 |    80.1 | ...10-711,737-776 
 ...tools/ast-edit |   78.98 |    76.78 |   91.89 |   78.98 |                   
  ast-config.ts    |     100 |      100 |     100 |     100 |                   
  ...invocation.ts |   84.12 |    76.62 |     100 |   84.12 | ...16-325,422-423 
  ...-extractor.ts |   82.19 |    64.51 |   66.66 |   82.19 | ...18-220,224-229 
  ...invocation.ts |    81.5 |       76 |      80 |    81.5 | ...53,155-156,162 
  constants.ts     |     100 |      100 |     100 |     100 |                   
  ...-collector.ts |    80.5 |       90 |     100 |    80.5 | 141-169           
  ...-optimizer.ts |   52.54 |       75 |      50 |   52.54 | ...0,77-78,95-100 
  ...e-analyzer.ts |   47.12 |    52.94 |     100 |   47.12 | ...18-319,327-328 
  ...calculator.ts |   91.39 |    91.07 |     100 |   91.39 | ...33-237,276-277 
  edit-helpers.ts  |   77.77 |    72.72 |     100 |   77.77 | 33-34,36-37       
  ...e-analysis.ts |   97.18 |       92 |     100 |   97.18 | 99-100            
  ...t-analyzer.ts |   84.95 |    83.01 |     100 |   84.95 | ...34-243,267-272 
  ...t-provider.ts |   91.15 |     64.7 |     100 |   91.15 | ...29-130,147-148 
  types.ts         |       0 |        0 |       0 |       0 | 1                 
  ...t-provider.ts |   64.28 |       50 |     100 |   64.28 | 42-47,52-55       
 src/types         |     100 |      100 |     100 |     100 |                   
  modelParams.ts   |     100 |      100 |     100 |     100 |                   
 src/utils         |    82.9 |    86.46 |   82.81 |    82.9 |                   
  LruCache.ts      |    82.6 |      100 |   71.42 |    82.6 | 29-30,33-34       
  ...grep-utils.ts |      98 |     87.5 |     100 |      98 | 135-136           
  asyncIterator.ts |   73.07 |    86.66 |   66.66 |   73.07 | ...71,75-86,93-94 
  bfsFileSearch.ts |   89.88 |     90.9 |     100 |   89.88 | 88-96             
  browser.ts       |    8.69 |      100 |       0 |    8.69 | 17-53             
  channel.ts       |     100 |      100 |     100 |     100 |                   
  ...pointUtils.ts |   95.58 |    95.23 |     100 |   95.58 | 149-154           
  debugLogger.ts   |     100 |      100 |     100 |     100 |                   
  delay.ts         |     100 |      100 |     100 |     100 |                   
  editor.ts        |   96.44 |    90.19 |    90.9 |   96.44 | ...25-226,228-229 
  ...entContext.ts |     100 |      100 |     100 |     100 |                   
  errorParsing.ts  |   90.22 |    76.78 |     100 |   90.22 | ...13,161,204,207 
  ...rReporting.ts |   83.72 |    84.61 |     100 |   83.72 | 83-87,108-116     
  errors.ts        |   85.61 |    93.75 |   53.33 |   85.61 | ...18-119,182-183 
  events.ts        |   64.42 |      100 |      60 |   64.42 | ...66-271,277-280 
  exitCodes.ts     |     100 |      100 |     100 |     100 |                   
  ...sionLoader.ts |   81.25 |    62.85 |    92.3 |   81.25 | ...67-168,221-229 
  fetch.ts         |   31.08 |    66.66 |      25 |   31.08 | ...37,40-85,88-89 
  fileDiffUtils.ts |     100 |      100 |     100 |     100 |                   
  fileUtils.ts     |   95.49 |    90.57 |     100 |   95.49 | ...36-240,458-464 
  formatters.ts    |   54.54 |       50 |     100 |   54.54 | 12-16             
  ...eUtilities.ts |   94.83 |    93.91 |     100 |   94.83 | ...58-262,319-320 
  ...rStructure.ts |   94.82 |    94.93 |     100 |   94.82 | ...20-123,351-356 
  getPty.ts        |    12.5 |      100 |       0 |    12.5 | 21-34             
  ...noreParser.ts |   93.33 |    88.46 |     100 |   93.33 | ...52,221-222,233 
  ...ineChanges.ts |   58.56 |    79.41 |      80 |   58.56 | ...18-256,264-270 
  gitUtils.ts      |   90.24 |       90 |     100 |   90.24 | 40-41,71-72       
  googleErrors.ts  |   72.05 |    67.56 |     100 |   72.05 | ...59,300,307-308 
  ...uotaErrors.ts |   94.58 |    81.42 |     100 |   94.58 | ...61-264,267-268 
  ide-trust.ts     |      60 |      100 |       0 |      60 | 14-15             
  ...rePatterns.ts |     100 |    96.55 |     100 |     100 | 248               
  ...ionManager.ts |     100 |       90 |     100 |     100 | 24                
  ...edit-fixer.ts |       0 |        0 |       0 |       0 | 1-156             
  ...yDiscovery.ts |   82.96 |     77.2 |   85.71 |   82.96 | ...11-712,715-716 
  ...tProcessor.ts |   93.44 |    86.51 |    92.3 |   93.44 | ...89-390,399-400 
  ...Inspectors.ts |   61.53 |      100 |      50 |   61.53 | 18-23             
  output-format.ts |   36.36 |      100 |       0 |   36.36 | ...53-154,164-185 
  package.ts       |     100 |      100 |     100 |     100 |                   
  ...erCoercion.ts |   83.78 |    81.15 |     100 |   83.78 | ...79-180,242-243 
  partUtils.ts     |   96.72 |    97.05 |     100 |   96.72 | 97-98             
  pathReader.ts    |       0 |        0 |       0 |       0 | 1-60              
  paths.ts         |    87.5 |     87.5 |     100 |    87.5 | ...35-236,250-251 
  ...rDetection.ts |    64.4 |       75 |     100 |    64.4 | ...4,88-89,99-100 
  ...archTarget.ts |   89.58 |    73.33 |     100 |   89.58 | 45-47,65-66       
  retry.ts         |   76.13 |    88.65 |   84.61 |   76.13 | ...23-726,731-732 
  ...thResolver.ts |      85 |    83.87 |     100 |      85 | ...07,130,179-182 
  ...nStringify.ts |     100 |      100 |     100 |     100 |                   
  sanitization.ts  |     100 |      100 |     100 |     100 |                   
  ...aValidator.ts |   83.52 |    82.75 |     100 |   83.52 | 70-81,125-126     
  ...r-launcher.ts |   88.88 |    79.48 |     100 |   88.88 | ...79-184,189-190 
  session.ts       |     100 |      100 |     100 |     100 |                   
  shell-parser.ts  |   22.46 |       56 |   42.85 |   22.46 | ...78-392,413-457 
  shell-utils.ts   |   86.88 |    85.71 |     100 |   86.88 | ...12-514,517-522 
  ...Completion.ts |   94.16 |     92.3 |     100 |   94.16 | 68-74             
  stdio.ts         |   84.21 |    59.09 |     100 |   84.21 | ...21-125,134-138 
  ...dleTimeout.ts |     100 |      100 |     100 |     100 |                   
  summarizer.ts    |     100 |    88.88 |     100 |     100 | 93                
  ...emEncoding.ts |   97.16 |    91.42 |     100 |   97.16 | 109-110,162       
  terminal.ts      |   34.09 |      100 |       0 |   34.09 | ...55,58-59,62-66 
  ...Serializer.ts |   98.16 |    92.18 |     100 |   98.16 | ...,98-99,151-153 
  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    |   67.76 |    78.04 |      75 |   67.76 | ...37-138,159-183 
  ...putLimiter.ts |   87.85 |    79.06 |     100 |   87.85 | ...19-224,268-275 
  unicodeUtils.ts  |     100 |      100 |     100 |     100 |                   
  ...untManager.ts |   89.65 |    88.23 |     100 |   89.65 | ...0,77-82,98-100 
  version.ts       |     100 |      100 |     100 |     100 |                   
  ...aceContext.ts |   96.85 |    95.34 |    92.3 |   96.85 | 95-96,110-111     
 ...ils/filesearch |   95.65 |    91.04 |     100 |   95.65 |                   
  crawlCache.ts    |     100 |      100 |     100 |     100 |                   
  crawler.ts       |   93.05 |       90 |     100 |   93.05 | 72-74,86-87       
  fileSearch.ts    |   93.25 |    86.95 |     100 |   93.25 | ...29-230,232-233 
  ignore.ts        |     100 |      100 |     100 |     100 |                   
  result-cache.ts  |     100 |    91.66 |     100 |     100 | 46                
-------------------|---------|----------|---------|---------|-------------------

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

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

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/storage/secure-store.ts (1)

416-439: ⚠️ Potential issue | 🟠 Major

Preserve the real keyring error on the deny path.

If adapter.setPassword() fails because the keyring is locked, denied, or times out, Lines 431-439 rewrite that into UNAVAILABLE. Downstream callers like packages/core/src/tools/tool-key-storage.ts already treat UNAVAILABLE as “fall back to file storage”, so this can silently bypass a locked/denied keychain and show the wrong remediation. Reserve UNAVAILABLE for the no-adapter case and rethrow the classified keyring error when the write itself failed.

Suggested fix
   const adapter = await this.getKeyring();
   let keyringWriteSucceeded = false;
+  let keyringWriteError: unknown = null;
   if (adapter !== null) {
     try {
       await adapter.setPassword(this.serviceName, key, value);
       this.recordKeyringSuccess();
       this.logger.debug(() => `[set] key='${key}' → keyring (OS keychain)`);
       keyringWriteSucceeded = true;
     } catch (error) {
+      keyringWriteError = error;
       this.recordKeyringFailure();
       const msg = error instanceof Error ? error.message : String(error);
       this.logger.debug(
         () => `[set] key='${key}' keyring write failed: ${msg}`,
       );
@@
   // If keyring unavailable or write failed, check fallback policy
   if (!keyringWriteSucceeded && this.fallbackPolicy === 'deny') {
+    if (adapter !== null && keyringWriteError !== null) {
+      const code = classifyError(keyringWriteError);
+      throw new SecureStoreError(
+        keyringWriteError instanceof Error
+          ? keyringWriteError.message
+          : String(keyringWriteError),
+        code,
+        getRemediation(code),
+      );
+    }
     this.logger.debug(
       () => `[set] key='${key}' fallback denied — throwing UNAVAILABLE`,
     );
     throw new SecureStoreError(
       'Keyring is unavailable and fallback is denied',
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/storage/secure-store.ts` around lines 416 - 439, When
adapter.setPassword() fails, capture and preserve the real error (instead of
losing it and always throwing a generic UNAVAILABLE) by storing the caught error
in a local variable (e.g., keyringWriteError) inside the catch that also calls
recordKeyringFailure(), and then in the deny-path check that currently inspects
keyringWriteSucceeded and this.fallbackPolicy, rethrow the preserved
keyringWriteError if present (or rethrow it as-is/convert to SecureStoreError if
needed); only throw the generic UNAVAILABLE when there was no adapter error at
all (the true “no-adapter” case). Reference: the catch around
adapter.setPassword(), recordKeyringFailure(), keyringWriteSucceeded, and the
fallbackPolicy === 'deny' branch.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@packages/core/src/storage/secure-store.ts`:
- Around line 416-439: When adapter.setPassword() fails, capture and preserve
the real error (instead of losing it and always throwing a generic UNAVAILABLE)
by storing the caught error in a local variable (e.g., keyringWriteError) inside
the catch that also calls recordKeyringFailure(), and then in the deny-path
check that currently inspects keyringWriteSucceeded and this.fallbackPolicy,
rethrow the preserved keyringWriteError if present (or rethrow it as-is/convert
to SecureStoreError if needed); only throw the generic UNAVAILABLE when there
was no adapter error at all (the true “no-adapter” case). Reference: the catch
around adapter.setPassword(), recordKeyringFailure(), keyringWriteSucceeded, and
the fallbackPolicy === 'deny' branch.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: f1f13356-99ca-4b63-8978-1c4d190ad0ec

📥 Commits

Reviewing files that changed from the base of the PR and between 66a7a33 and c50f8af.

📒 Files selected for processing (2)
  • packages/core/src/storage/secure-store.spec.ts
  • packages/core/src/storage/secure-store.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 270000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: E2E Test (macOS)
  • GitHub Check: E2E Test (Linux) - sandbox:docker
  • GitHub Check: E2E Test (Linux) - sandbox:none
  • GitHub Check: Lint (Javascript)
🧰 Additional context used
🧠 Learnings (29)
📓 Common learnings
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1778
File: packages/cli/src/auth/token-access-coordinator.ts:640-647
Timestamp: 2026-03-26T03:34:18.861Z
Learning: In `packages/cli/src/auth/token-access-coordinator.ts` (vybestack/llxprt-code PR `#1778`, decomposed from `oauth-manager.ts`), the locked disk-check path in `performDiskCheck()` calls `performDiskCheckUnderLock()` without a surrounding try-catch and does not call `scheduleProactiveRenewal()` on the result. This is pre-existing behavior faithfully extracted from the original `oauth-manager.ts` line ~1308 on main. The proactive renewal call on the unlocked fallback (line ~653) is a targeted addition specific to that bypass path. The locked path feeds into the standard refresh cycle which handles renewal scheduling. Do not flag the missing error guard or missing renewal scheduling on the locked disk-check path as a decomposition regression in future reviews — adding them would be scope expansion beyond the refactoring goal.
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1778
File: packages/cli/src/auth/auth-flow-orchestrator.ts:431-437
Timestamp: 2026-03-26T02:12:39.396Z
Learning: In `packages/cli/src/auth/auth-flow-orchestrator.ts` (vybestack/llxprt-code PR `#1778`, decomposed from `oauth-manager.ts`), the early return in `authenticateMultipleBuckets` when `unauthenticatedBuckets.length === 0` intentionally skips re-enabling OAuth in-memory/settings and skips installing a bucket failover handler. This is pre-existing behavior faithfully extracted from the original `oauth-manager.ts` around line 2547 on main. Do not flag the missing success-side-effects (provider enablement, failover handler installation) on the all-valid fast path as a bug in decomposition or future PRs — adding these side-effects would be a behavioral change beyond the refactoring scope.
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1874
File: packages/core/src/providers/__tests__/RetryOrchestrator.onAuthError.test.ts:79-404
Timestamp: 2026-04-03T05:57:51.304Z
Learning: In vybestack/llxprt-code, `RetryOrchestrator.onAuthError` tests (packages/core/src/providers/__tests__/RetryOrchestrator.onAuthError.test.ts, PR `#1874`) are intentionally scoped to the default/single-bucket path covering issue1861's core fix. Multi-bucket / non-default session-bucket regression coverage belongs at the OAuthManager/TokenAccessCoordinator layer (forceRefreshToken.test.ts), not in RetryOrchestrator tests. Do not flag the absence of multi-bucket bucket-context tests in RetryOrchestrator.onAuthError.test.ts as a coverage gap.
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 0
File: :0-0
Timestamp: 2026-03-29T16:31:31.631Z
Learning: In vybestack/llxprt-code issue `#1783` (OAuth bucket failover behavioral test spec), the formal scenario catalog was expanded from 39 to ~58 scenarios with four new categories: UE-01–UE-08 (User Entry Points/Lifecycle Triggers), SA-01–SA-04 (Subagent Isolation, tied to PR `#1720/`#1718/#1719), EC-01–EC-04 (Error & Edge Cases), and RO-01–RO-03 (Multi-bucket RetryOrchestrator Integration). Critical zero-coverage gaps are: SB-10 (auth flow mid-turn timeout), UE lifecycle triggers (useGeminiStream.ts turn boundary), SA subagent isolation regressions, and RO multi-bucket retry paths. Two mock-theater test files should be rewritten with MemoryTokenStore: `oauth-manager.failover-wiring.spec.ts` and `oauth-manager.getToken-bucket-peek.spec.ts`. Cross-process simulation uses shared SecureStore/lockDir (two KeyringTokenStore instances), not child_process.fork.
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1778
File: packages/cli/src/auth/qwen-oauth-provider.ts:234-242
Timestamp: 2026-03-26T00:30:20.796Z
Learning: In `packages/cli/src/auth/qwen-oauth-provider.ts` (vybestack/llxprt-code PR `#1778`, decomposed from `oauth-manager.ts`), the broad `catch` block in `openQwenBrowserIfInteractive` that silently swallows all errors from the dynamic import of `../runtime/runtimeSettings.js` (setting `noBrowser = false` as the default) is pre-existing behavior faithfully extracted from the original `oauth-manager.ts`. Do not flag the absence of debug logging or error discrimination in this catch block as a gap in decomposition or future PRs — adding error-type discrimination would be a behavioral change beyond the refactoring scope.
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1874
File: packages/cli/src/auth/__tests__/forceRefreshToken.test.ts:449-477
Timestamp: 2026-04-03T06:29:38.156Z
Learning: In `packages/cli/src/auth/token-access-coordinator.ts` (vybestack/llxprt-code PR `#1874`), `forceRefreshToken` uses a lock-first, single-read TOCTOU pattern: acquire refresh lock → read stored token once (under the lock) → compare stored token with failed access token → act. There is no pre-lock read. The test in `packages/cli/src/auth/__tests__/forceRefreshToken.test.ts` correctly simulates the "another process already refreshed" case by preloading an updated token in the store. Do not flag the absence of a second `getToken` call or suggest asserting `getToken` was called twice — the implementation intentionally reads only once under the lock.
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1778
File: packages/cli/src/auth/provider-usage-info.ts:36-37
Timestamp: 2026-03-26T01:28:37.959Z
Learning: In `packages/cli/src/auth/provider-usage-info.ts` (vybestack/llxprt-code PR `#1778`, decomposed from `oauth-manager.ts`), the `bucket ?? 'default'` normalization before calling `tokenStore.getToken(provider, bucket)` is correct and functionally identical to passing `undefined`. The production `KeyringTokenStore` (packages/core/src/auth/keyring-token-store.ts, line 94) already normalizes `undefined` to `DEFAULT_BUCKET` (the string `"default"`) internally via `const resolvedBucket = bucket ?? DEFAULT_BUCKET`. The `InMemoryTokenStore` used in test helpers does not define the production contract. Do not flag `bucket ?? 'default'` lookups as a contract violation or suggest splitting into `undefined`-for-lookup vs `'default'`-for-display in this codebase — the original `oauth-manager.ts` used the same pattern (line 2169) and the behavior is faithfully preserved.
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1778
File: packages/cli/src/auth/token-access-coordinator.ts:442-449
Timestamp: 2026-03-26T00:30:25.258Z
Learning: In `packages/cli/src/auth/token-access-coordinator.ts` (vybestack/llxprt-code PR `#1778`, decomposed from `oauth-manager.ts`), `getToken()` calls `peekOtherProfileBuckets()` even when `explicitBucket` is `true`, and the associated profile-bucket count check can suppress auth when multiple profile buckets exist. This is pre-existing behavior faithfully extracted from the original `oauth-manager.ts` getOAuthToken method (lines 1136-1412 on main). The bucket resolution logic intentionally supports profile-scoped session buckets with failover. Do not flag this as a bug in decomposition or future PRs — rearchitecting the bucket resolution chain would be a behavioral change beyond refactoring scope.
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1778
File: packages/cli/src/auth/provider-usage-info.ts:228-233
Timestamp: 2026-03-26T00:30:00.337Z
Learning: In `packages/cli/src/auth/provider-usage-info.ts` (vybestack/llxprt-code PR `#1778`, decomposed from `oauth-manager.ts`), `getHigherPriorityAuth` calls `getSettingsService().get('authOnly')` globally (without a try/catch guard) alongside the passed `LoadedSettings`. This is pre-existing behavior faithfully extracted from the original `getHigherPriorityAuth` method at line 1836 of `oauth-manager.ts` on main. Do not flag the unconditional `getSettingsService()` call or the `authOnly` handling pattern as a new issue or scope expansion in decomposition or future PRs — rearchitecting the auth-priority dependency chain is explicitly out of scope.
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 0
File: :0-0
Timestamp: 2026-02-16T19:05:47.580Z
Learning: Issue `#1442` resolution: Random Codex OAuth failures were caused by stale tokens from the old MultiProviderTokenStore after migration to KeyringTokenStore (commits 916605df, 8aeecbee). Old tokens failed CodexOAuthTokenSchema validation (missing account_id) causing random auth requests. Repeated logout/login manually cleaned up both storage locations. Codex provider lacks legacy cleanup methods that Gemini has (migrateFromLegacyTokens, clearLegacyTokens). Solution: add automatic legacy cleanup to Codex like Gemini.
📚 Learning: 2026-03-27T01:00:29.058Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1785
File: packages/cli/src/config/__tests__/approvalModeParity.test.ts:351-393
Timestamp: 2026-03-27T01:00:29.058Z
Learning: In `packages/cli/src/config/__tests__/approvalModeParity.test.ts` (vybestack/llxprt-code PR `#1785`), the test suite is intentionally scoped to verifying that the extracted approval-mode resolution logic in `approvalModeResolver.ts` produces identical results to the original inline logic. Adding new combination scenarios (e.g., admin-disabled YOLO combined with an untrusted folder) is considered scope expansion beyond parity coverage. The ordering of admin checks before trust-fallback checks is preserved from the original code. Do not flag missing cross-branch combination tests in this file as a gap in refactoring PRs.

Applied to files:

  • packages/core/src/storage/secure-store.spec.ts
  • packages/core/src/storage/secure-store.ts
📚 Learning: 2026-03-27T00:46:43.700Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1785
File: packages/cli/src/config/__tests__/folderTrustOriginalSettingsParity.test.ts:347-383
Timestamp: 2026-03-27T00:46:43.700Z
Learning: In `packages/cli/src/config/__tests__/folderTrustOriginalSettingsParity.test.ts` (vybestack/llxprt-code PR `#1785`), the last test ("profile ephemeral folderTrust value does NOT change the trust check") intentionally omits a real profile load. Its sole purpose is to assert that `isWorkspaceTrusted` is called with the original settings object (not a profile-merged copy) in the untrusted-folder branch. The profile-merge path is covered by other parity test files. Do not suggest adding an inline profile or `LLXPRT_PROFILE` env var to this test — that would be scope expansion beyond its intended parity coverage.

Applied to files:

  • packages/core/src/storage/secure-store.spec.ts
  • packages/core/src/storage/secure-store.ts
📚 Learning: 2026-03-29T16:31:31.631Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 0
File: :0-0
Timestamp: 2026-03-29T16:31:31.631Z
Learning: In vybestack/llxprt-code issue `#1783` (OAuth bucket failover behavioral test spec), the formal scenario catalog was expanded from 39 to ~58 scenarios with four new categories: UE-01–UE-08 (User Entry Points/Lifecycle Triggers), SA-01–SA-04 (Subagent Isolation, tied to PR `#1720/`#1718/#1719), EC-01–EC-04 (Error & Edge Cases), and RO-01–RO-03 (Multi-bucket RetryOrchestrator Integration). Critical zero-coverage gaps are: SB-10 (auth flow mid-turn timeout), UE lifecycle triggers (useGeminiStream.ts turn boundary), SA subagent isolation regressions, and RO multi-bucket retry paths. Two mock-theater test files should be rewritten with MemoryTokenStore: `oauth-manager.failover-wiring.spec.ts` and `oauth-manager.getToken-bucket-peek.spec.ts`. Cross-process simulation uses shared SecureStore/lockDir (two KeyringTokenStore instances), not child_process.fork.

Applied to files:

  • packages/core/src/storage/secure-store.spec.ts
  • packages/core/src/storage/secure-store.ts
📚 Learning: 2026-04-03T05:57:42.326Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1874
File: packages/core/src/auth/invalidateProviderCache.test.ts:107-163
Timestamp: 2026-04-03T05:57:42.326Z
Learning: In `packages/core/src/auth/invalidateProviderCache.test.ts` (vybestack/llxprt-code PR `#1874`), the profile-specific positive-match path for `invalidateProviderCache('anthropic', profileId)` is intentionally not directly tested because `resolveAuthentication` does not expose a `profileId` metadata parameter in its public API, making it impossible to construct a profile-keyed cache entry from outside. The wildcard invalidation test (`invalidateProviderCache('anthropic')` with no profileId) exercises the same matching predicate. Do not flag the missing profile-specific positive-match case as a test gap — adding it is a low-priority follow-up that requires internal API changes.

Applied to files:

  • packages/core/src/storage/secure-store.spec.ts
  • packages/core/src/storage/secure-store.ts
📚 Learning: 2026-03-26T03:34:18.861Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1778
File: packages/cli/src/auth/token-access-coordinator.ts:640-647
Timestamp: 2026-03-26T03:34:18.861Z
Learning: In `packages/cli/src/auth/token-access-coordinator.ts` (vybestack/llxprt-code PR `#1778`, decomposed from `oauth-manager.ts`), the locked disk-check path in `performDiskCheck()` calls `performDiskCheckUnderLock()` without a surrounding try-catch and does not call `scheduleProactiveRenewal()` on the result. This is pre-existing behavior faithfully extracted from the original `oauth-manager.ts` line ~1308 on main. The proactive renewal call on the unlocked fallback (line ~653) is a targeted addition specific to that bypass path. The locked path feeds into the standard refresh cycle which handles renewal scheduling. Do not flag the missing error guard or missing renewal scheduling on the locked disk-check path as a decomposition regression in future reviews — adding them would be scope expansion beyond the refactoring goal.

Applied to files:

  • packages/core/src/storage/secure-store.spec.ts
  • packages/core/src/storage/secure-store.ts
📚 Learning: 2026-03-26T00:29:42.510Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1778
File: packages/cli/src/auth/BucketFailoverHandlerImpl.spec.ts:500-503
Timestamp: 2026-03-26T00:29:42.510Z
Learning: In `packages/cli/src/auth/BucketFailoverHandlerImpl.spec.ts` (vybestack/llxprt-code), the `if (provider)` guard pattern used after `oauthManager.getProvider(...)` to conditionally stub `provider.refreshToken` is pre-existing from the original test suite. Do not flag this as a silent-skip risk or suggest hardening (e.g., `expect(provider).toBeDefined()`) in decomposition or refactoring PRs — changing test structure is explicitly out of scope for those PRs.

Applied to files:

  • packages/core/src/storage/secure-store.spec.ts
📚 Learning: 2026-04-03T06:29:38.156Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1874
File: packages/cli/src/auth/__tests__/forceRefreshToken.test.ts:449-477
Timestamp: 2026-04-03T06:29:38.156Z
Learning: In `packages/cli/src/auth/token-access-coordinator.ts` (vybestack/llxprt-code PR `#1874`), `forceRefreshToken` uses a lock-first, single-read TOCTOU pattern: acquire refresh lock → read stored token once (under the lock) → compare stored token with failed access token → act. There is no pre-lock read. The test in `packages/cli/src/auth/__tests__/forceRefreshToken.test.ts` correctly simulates the "another process already refreshed" case by preloading an updated token in the store. Do not flag the absence of a second `getToken` call or suggest asserting `getToken` was called twice — the implementation intentionally reads only once under the lock.

Applied to files:

  • packages/core/src/storage/secure-store.spec.ts
  • packages/core/src/storage/secure-store.ts
📚 Learning: 2026-03-27T01:00:28.649Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1785
File: packages/cli/src/config/__tests__/toolGovernanceParity.test.ts:458-472
Timestamp: 2026-03-27T01:00:28.649Z
Learning: In `packages/cli/src/config/__tests__/toolGovernanceParity.test.ts` (vybestack/llxprt-code PR `#1785`), the "non-interactive DEFAULT with explicit --allowed-tools" and corresponding YOLO test cases intentionally use `read_file` (a tool already in `READ_ONLY_TOOL_NAMES`) as the explicit `--allowed-tools` value. The tests are scoped to verifying that existing allowlist behavior is preserved through the refactor, not to proving union/exclusion semantics with non-read-only tools. Do not flag the choice of `read_file` as insufficient for proving merging behavior in parity or refactoring PRs — improving assertion specificity is new test design work beyond the refactoring scope.

Applied to files:

  • packages/core/src/storage/secure-store.spec.ts
📚 Learning: 2026-03-27T02:12:12.434Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1785
File: packages/cli/src/config/__tests__/profileOverridePrecedenceParity.test.ts:212-306
Timestamp: 2026-03-27T02:12:12.434Z
Learning: In `packages/cli/src/config/__tests__/profileOverridePrecedenceParity.test.ts` (vybestack/llxprt-code PR `#1785`), `applyProfileSnapshot` is intentionally mocked in both `../../runtime/profileSnapshot.js` (the primary call-tracking mock, capturing calls into `profileSnapshotCalls`) and `../../runtime/runtimeSettings.js` (a fallback mock). This dual mocking is required because `config.ts` imports `applyProfileSnapshot` from both paths. Do not flag this as confusing duplication or suggest collapsing into a single mock in future reviews.

Applied to files:

  • packages/core/src/storage/secure-store.spec.ts
📚 Learning: 2026-03-29T20:44:28.357Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1841
File: packages/cli/src/auth/__tests__/behavioral/user-entry-points.behavioral.spec.ts:131-159
Timestamp: 2026-03-29T20:44:28.357Z
Learning: In `packages/cli/src/auth/__tests__/behavioral/user-entry-points.behavioral.spec.ts` (vybestack/llxprt-code PR `#1841`), UE-03 intentionally calls `handler.resetSession()` directly rather than triggering it through the actual turn-boundary entry point in `useGeminiStream.ts` (L73). This is an explicit scope boundary: `useGeminiStream.ts` is a React hook that requires a full UI render context; testing through it would require mounting React components and simulating user input, which is a different category of integration test. The behavioral spec verifies the handler-level contract (resetSession clears triedBuckets and enables fresh failover). Do not flag the direct `resetSession()` call in this test as missing turn-boundary wiring coverage.

Applied to files:

  • packages/core/src/storage/secure-store.spec.ts
📚 Learning: 2025-11-25T16:56:18.980Z
Learnt from: CR
Repo: vybestack/llxprt-code PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T16:56:18.980Z
Learning: Before reporting a task as finished, run `npm run format` from the repository root and ensure it succeeds (exit code 0)

Applied to files:

  • packages/core/src/storage/secure-store.spec.ts
📚 Learning: 2026-02-26T19:06:23.993Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1627
File: integration-tests/run_shell_command.test.ts:550-557
Timestamp: 2026-02-26T19:06:23.993Z
Learning: In `integration-tests/run_shell_command.test.ts`, the "rejects invalid shell expressions" test intentionally does not assert `toolRequest.success === false` for shell syntax errors because issue `#1625` tracks that `run_shell_command` currently reports `success: true` for commands that fail with non-zero exit codes (it only sets `result.error` on spawn failures, not non-zero exits). The test uses FakeProvider to script model responses but executes the real tool, so asserting `success === false` would fail until `#1625` is resolved. The test correctly verifies the tool was invoked with the invalid syntax and the model responded with FAIL.
<!--

Applied to files:

  • packages/core/src/storage/secure-store.spec.ts
📚 Learning: 2026-03-24T21:07:40.805Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1767
File: packages/cli/src/ui/components/shared/golden-snapshot.test.ts:64-65
Timestamp: 2026-03-24T21:07:40.805Z
Learning: In `packages/cli/src/ui/components/shared/golden-snapshot.test.ts` (vybestack/llxprt-code PR `#1767`), `parseAction` uses `actionStr.split(':')` to parse action corpus entries. The action corpus (`project-plans/issue1577/action-corpus.json`) has been confirmed to contain zero multi-colon action strings, so the current two-element destructuring is correct for all existing entries. Do not flag this as a truncation bug in future reviews — the corpus format is validated and the parsing matches it.

Applied to files:

  • packages/core/src/storage/secure-store.spec.ts
📚 Learning: 2026-03-24T21:35:42.622Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1766
File: packages/cli/src/runtime/settingsResolver.ts:96-103
Timestamp: 2026-03-24T21:35:42.622Z
Learning: In `packages/cli/src/runtime/settingsResolver.ts` (vybestack/llxprt-code PR `#1766`), the `--key` and `--keyfile` branches both call `updateActiveProviderApiKey`, which internally calls `config.setEphemeralSetting('auth-key-name', undefined)` at line 289 of `providerMutations.ts` (update branch) and line 265 (remove branch). Do not flag missing `auth-key-name` clearing at the `settingsResolver.ts` call sites — it is already handled inside the mutation function. Trace the full call chain into `updateActiveProviderApiKey` before raising such a comment.

Applied to files:

  • packages/core/src/storage/secure-store.spec.ts
  • packages/core/src/storage/secure-store.ts
📚 Learning: 2026-03-20T01:26:21.401Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1736
File: packages/core/src/providers/openai/OpenAIClientFactory.test.ts:241-246
Timestamp: 2026-03-20T01:26:21.401Z
Learning: In `packages/core/src/providers/openai/OpenAIClientFactory.test.ts` (vybestack/llxprt-code PR `#1736`), the `instantiateClient` tests intentionally inspect the OpenAI SDK's internal `_options` field (e.g., `(client as unknown as Record<string, unknown>)._options`) to assert `defaultHeaders` and HTTP agent propagation. This is a deliberate pragmatic tradeoff over mocking the OpenAI constructor (which would require module-level `vi.mock`, constructor spy setup, and restore lifecycle). The `_options` field has been stable across many SDK versions, and the approach is considered acceptable. Do not flag `_options` inspection in this test file as relying on unstable internals.

Applied to files:

  • packages/core/src/storage/secure-store.spec.ts
📚 Learning: 2026-04-03T05:57:51.304Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1874
File: packages/core/src/providers/__tests__/RetryOrchestrator.onAuthError.test.ts:79-404
Timestamp: 2026-04-03T05:57:51.304Z
Learning: In vybestack/llxprt-code, `RetryOrchestrator.onAuthError` tests (packages/core/src/providers/__tests__/RetryOrchestrator.onAuthError.test.ts, PR `#1874`) are intentionally scoped to the default/single-bucket path covering issue1861's core fix. Multi-bucket / non-default session-bucket regression coverage belongs at the OAuthManager/TokenAccessCoordinator layer (forceRefreshToken.test.ts), not in RetryOrchestrator tests. Do not flag the absence of multi-bucket bucket-context tests in RetryOrchestrator.onAuthError.test.ts as a coverage gap.

Applied to files:

  • packages/core/src/storage/secure-store.spec.ts
  • packages/core/src/storage/secure-store.ts
📚 Learning: 2026-03-03T17:18:48.615Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1656
File: packages/cli/src/auth/oauth-manager.auth-lock.spec.ts:47-70
Timestamp: 2026-03-03T17:18:48.615Z
Learning: In vybestack/llxprt-code TOCTOU defense tests (e.g., packages/cli/src/auth/oauth-manager.auth-lock.spec.ts), call-count assertions like `expect(getTokenCallCount).toBe(4)` are intentional structural guards that validate the double-check pattern (upfront checks + re-checks under lock). Behavioral assertions (e.g., authenticate() call counts per bucket) are primary, but call counts ensure the re-check path executes and catch regressions that might remove the defensive re-read while still passing behavioral tests.
```

Applied to files:

  • packages/core/src/storage/secure-store.spec.ts
📚 Learning: 2026-03-25T18:17:59.248Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1768
File: packages/cli/src/ui/__tests__/AppContainer.render-budget.test.tsx:555-597
Timestamp: 2026-03-25T18:17:59.248Z
Learning: In `packages/cli/src/ui/__tests__/AppContainer.render-budget.test.tsx` (vybestack/llxprt-code PR `#1768`), the `performance.now()` assertions with 1s (mount) and 2s (10 re-renders) time limits are intentionally conservative and stable by design. Do not flag these absolute time thresholds as flaky or suggest replacing them with deterministic render-count signals in decomposition or future PRs — any test strategy redesign is out of scope for the `#1576` refactoring.

Applied to files:

  • packages/core/src/storage/secure-store.spec.ts
📚 Learning: 2026-03-26T01:28:01.197Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1778
File: packages/cli/src/auth/auth-flow-orchestrator.ts:692-705
Timestamp: 2026-03-26T01:28:01.197Z
Learning: In vybestack/llxprt-code, the production `KeyringTokenStore` (at `packages/core/src/auth/keyring-token-store.ts` line 94) normalizes an `undefined` bucket argument to `DEFAULT_BUCKET` (the string `"default"`) internally via `const resolvedBucket = bucket ?? DEFAULT_BUCKET`. As a result, `getToken(provider, undefined)` and `getToken(provider, "default")` are functionally identical in production. The original `oauth-manager.ts` also applied the same `bucket ?? "default"` normalization (line 2169). Do not flag the omission of explicit `"default"` bucket strings in `auth-flow-orchestrator.ts` or related decomposed modules as a behavioral divergence — passing `undefined` is equivalent and is a faithful extraction of pre-existing behavior. InMemoryTokenStore behavior in test helpers does not govern the production contract.

Applied to files:

  • packages/core/src/storage/secure-store.spec.ts
  • packages/core/src/storage/secure-store.ts
📚 Learning: 2026-03-26T01:28:37.959Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1778
File: packages/cli/src/auth/provider-usage-info.ts:36-37
Timestamp: 2026-03-26T01:28:37.959Z
Learning: In `packages/cli/src/auth/provider-usage-info.ts` (vybestack/llxprt-code PR `#1778`, decomposed from `oauth-manager.ts`), the `bucket ?? 'default'` normalization before calling `tokenStore.getToken(provider, bucket)` is correct and functionally identical to passing `undefined`. The production `KeyringTokenStore` (packages/core/src/auth/keyring-token-store.ts, line 94) already normalizes `undefined` to `DEFAULT_BUCKET` (the string `"default"`) internally via `const resolvedBucket = bucket ?? DEFAULT_BUCKET`. The `InMemoryTokenStore` used in test helpers does not define the production contract. Do not flag `bucket ?? 'default'` lookups as a contract violation or suggest splitting into `undefined`-for-lookup vs `'default'`-for-display in this codebase — the original `oauth-manager.ts` used the same pattern (line 2169) and the behavior is faithfully preserved.

Applied to files:

  • packages/core/src/storage/secure-store.spec.ts
  • packages/core/src/storage/secure-store.ts
📚 Learning: 2026-02-06T15:52:42.315Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1305
File: scripts/generate-keybindings-doc.ts:1-5
Timestamp: 2026-02-06T15:52:42.315Z
Learning: In reviews of vybestack/llxprt-code, do not suggest changing existing copyright headers from 'Google LLC' to 'Vybestack LLC' for files that originated from upstream. Preserve upstream copyrights in files that came from upstream, and only apply 'Vybestack LLC' copyright on newly created, original LLxprt files. If a file is clearly LLxprt-original, it may carry the Vybestack header; if it is upstream-originated, keep the original sponsor header.

Applied to files:

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

Applied to files:

  • packages/core/src/storage/secure-store.spec.ts
  • packages/core/src/storage/secure-store.ts
📚 Learning: 2026-03-24T21:33:43.130Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1766
File: packages/cli/src/runtime/providerMutations.ts:258-265
Timestamp: 2026-03-24T21:33:43.130Z
Learning: In `packages/cli/src/runtime/providerMutations.ts` (vybestack/llxprt-code PR `#1766`, decomposed from the original `runtimeSettings.ts`), `updateActiveProviderApiKey` intentionally does NOT clear `auth-key` in `settingsService` during the update (non-null key) branch. The update branch sets the ephemeral `auth-key` to the new value instead; only the remove (null/empty key) branch clears all aliases in both `settingsService` and config ephemeral settings. This asymmetry is pre-existing behavior from the original `runtimeSettings.ts` (lines 2182-2187 on main). Do not flag this as a credential-leak or stale-alias bug in decomposition reviews.

Applied to files:

  • packages/core/src/storage/secure-store.ts
📚 Learning: 2026-03-27T19:31:04.895Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1797
File: packages/cli/src/config/settings.ts:903-904
Timestamp: 2026-03-27T19:31:04.895Z
Learning: In `packages/cli/src/config/settings.ts` (vybestack/llxprt-code PR `#1797`), calling `migrateDeprecatedSettings(loadedSettings)` inside `loadSettings()` at the end (before returning) is intentional. Persisting one-time deprecated-settings migrations (e.g., `disableAutoUpdate` → `enableAutoUpdate`, `disableLoadingPhrases` → `enableLoadingPhrases`) during startup via `setValue()` is by design in this code path. The default `removeDeprecated = false` means deprecated keys are only supplemented with new equivalents, not deleted. Do not flag this as an unintended side-effect or mutating admin/system settings in future reviews.

Applied to files:

  • packages/core/src/storage/secure-store.ts
📚 Learning: 2026-03-26T00:30:00.337Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1778
File: packages/cli/src/auth/provider-usage-info.ts:228-233
Timestamp: 2026-03-26T00:30:00.337Z
Learning: In `packages/cli/src/auth/provider-usage-info.ts` (vybestack/llxprt-code PR `#1778`, decomposed from `oauth-manager.ts`), `getHigherPriorityAuth` calls `getSettingsService().get('authOnly')` globally (without a try/catch guard) alongside the passed `LoadedSettings`. This is pre-existing behavior faithfully extracted from the original `getHigherPriorityAuth` method at line 1836 of `oauth-manager.ts` on main. Do not flag the unconditional `getSettingsService()` call or the `authOnly` handling pattern as a new issue or scope expansion in decomposition or future PRs — rearchitecting the auth-priority dependency chain is explicitly out of scope.

Applied to files:

  • packages/core/src/storage/secure-store.ts
📚 Learning: 2026-03-27T00:46:47.069Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1785
File: packages/cli/src/config/configBuilder.ts:104-111
Timestamp: 2026-03-27T00:46:47.069Z
Learning: In `packages/cli/src/config/configBuilder.ts` (vybestack/llxprt-code PR `#1785`, decomposed from `config.ts`), the `onReload` async callback in `buildHooksConfig` calls `loadSettings(cwd)` without a try/catch guard. This is pre-existing behavior faithfully extracted from the original `loadCliConfig` in `config.ts`. Do not flag the missing error handling around `loadSettings` in the `onReload` callback as a decomposition regression in future reviews — adding error handling would be a behavioral change beyond the refactoring scope, and a follow-up improvement has been filed.

Applied to files:

  • packages/core/src/storage/secure-store.ts
📚 Learning: 2026-03-27T19:31:15.215Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1797
File: packages/cli/src/ui/utils/commandUtils.ts:194-205
Timestamp: 2026-03-27T19:31:15.215Z
Learning: In `packages/cli/src/ui/utils/commandUtils.ts` (vybestack/llxprt-code), the Windows OSC-52 clipboard path calls `fs.writeSync(fd, data)` without a short-write loop. The partial-write concern is acknowledged as theoretically valid but intentionally deferred because OSC-52 payloads are small terminal escape sequences in practice. Do not re-flag the missing loop as a blocking issue in future reviews — it is an accepted known limitation.

Applied to files:

  • packages/core/src/storage/secure-store.ts
📚 Learning: 2026-03-29T05:46:51.084Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1827
File: packages/core/src/core/compression/CompressionHandler.ts:714-722
Timestamp: 2026-03-29T05:46:51.084Z
Learning: In `packages/core/src/core/compression/CompressionHandler.ts` (vybestack/llxprt-code PR `#1827`), `lastSuccessfulCompressionTime` is intentionally set in two places when fallback compression succeeds via `runCompressionWithRetryAndFallback`: once inside `performFallbackCompression` (needed for the `forceTruncationIfIneffective`-only call path) and once in `performCompression` after `runCompressionWithRetryAndFallback` returns. The duplicate assignment is harmless (both use `Date.now()`) and is deliberately left without extra branching or flags to keep the code simple. Do not flag this dual assignment as a redundancy in future reviews.

Applied to files:

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

@acoliver
Copy link
Copy Markdown
Collaborator Author

Addressed the remaining SecureStore deny-path review concern.

Action taken:

  • SecureStore.set() now preserves and rethrows the classified keyring write error when fallbackPolicy is deny and a keyring adapter exists.
  • The generic UNAVAILABLE error is now reserved for the true no-adapter case.
  • Added a regression split in secure-store.spec.ts covering both behaviors:
    • deny + no adapter => UNAVAILABLE
    • deny + keyring write failure such as 'Keyring locked' => LOCKED with matching remediation

Verification run for this update:

  • npx vitest run packages/core/src/storage/secure-store.spec.ts packages/core/src/storage/secure-store.test.ts
  • npm run test
  • npm run typecheck
  • npm run build
  • npm run format

Additional repo verification notes:

  • npm run lint still reports pre-existing repo-wide errors outside this PR scope, including prompt .d.ts project-service parsing issues and import/no-internal-modules findings in MCP tool files.
  • node scripts/start.js --profile-load synthetic "write me a haiku and nothing else" now reaches the provider call path and exits with an OpenAI API error rather than a local build/linking failure.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/core/src/auth/precedence.ts`:
- Around line 695-696: The sentinel string 'no-profile' used for profileScopeId
can collide with a real profile named the same; replace it with a
guaranteed-unique sentinel constant (e.g. const NO_PROFILE_SENTINEL =
'\0NO_PROFILE' or similar non-printable/prefixed value) and use it wherever
profileScopeId is computed (variable profileScopeId and the other occurrences
noted), i.e. change lines that do const profileScopeId = profileId ??
'no-profile' to const profileScopeId = profileId ?? NO_PROFILE_SENTINEL and
ensure the same NO_PROFILE_SENTINEL is used for all token-scoping/cache-key
generation to avoid aliasing.
🪄 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

Run ID: 816aa25b-811f-4a98-bfab-4b8c43734c13

📥 Commits

Reviewing files that changed from the base of the PR and between 73d8f36 and 72c5210.

📒 Files selected for processing (2)
  • packages/core/src/auth/precedence.test.ts
  • packages/core/src/auth/precedence.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 270000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (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: Run LLxprt review
🧰 Additional context used
🧠 Learnings (24)
📓 Common learnings
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1778
File: packages/cli/src/auth/auth-flow-orchestrator.ts:431-437
Timestamp: 2026-03-26T02:12:39.396Z
Learning: In `packages/cli/src/auth/auth-flow-orchestrator.ts` (vybestack/llxprt-code PR `#1778`, decomposed from `oauth-manager.ts`), the early return in `authenticateMultipleBuckets` when `unauthenticatedBuckets.length === 0` intentionally skips re-enabling OAuth in-memory/settings and skips installing a bucket failover handler. This is pre-existing behavior faithfully extracted from the original `oauth-manager.ts` around line 2547 on main. Do not flag the missing success-side-effects (provider enablement, failover handler installation) on the all-valid fast path as a bug in decomposition or future PRs — adding these side-effects would be a behavioral change beyond the refactoring scope.
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 0
File: :0-0
Timestamp: 2026-03-29T16:31:31.631Z
Learning: In vybestack/llxprt-code issue `#1783` (OAuth bucket failover behavioral test spec), the formal scenario catalog was expanded from 39 to ~58 scenarios with four new categories: UE-01–UE-08 (User Entry Points/Lifecycle Triggers), SA-01–SA-04 (Subagent Isolation, tied to PR `#1720/`#1718/#1719), EC-01–EC-04 (Error & Edge Cases), and RO-01–RO-03 (Multi-bucket RetryOrchestrator Integration). Critical zero-coverage gaps are: SB-10 (auth flow mid-turn timeout), UE lifecycle triggers (useGeminiStream.ts turn boundary), SA subagent isolation regressions, and RO multi-bucket retry paths. Two mock-theater test files should be rewritten with MemoryTokenStore: `oauth-manager.failover-wiring.spec.ts` and `oauth-manager.getToken-bucket-peek.spec.ts`. Cross-process simulation uses shared SecureStore/lockDir (two KeyringTokenStore instances), not child_process.fork.
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1778
File: packages/cli/src/auth/token-access-coordinator.ts:640-647
Timestamp: 2026-03-26T03:34:18.861Z
Learning: In `packages/cli/src/auth/token-access-coordinator.ts` (vybestack/llxprt-code PR `#1778`, decomposed from `oauth-manager.ts`), the locked disk-check path in `performDiskCheck()` calls `performDiskCheckUnderLock()` without a surrounding try-catch and does not call `scheduleProactiveRenewal()` on the result. This is pre-existing behavior faithfully extracted from the original `oauth-manager.ts` line ~1308 on main. The proactive renewal call on the unlocked fallback (line ~653) is a targeted addition specific to that bypass path. The locked path feeds into the standard refresh cycle which handles renewal scheduling. Do not flag the missing error guard or missing renewal scheduling on the locked disk-check path as a decomposition regression in future reviews — adding them would be scope expansion beyond the refactoring goal.
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1874
File: packages/core/src/providers/__tests__/RetryOrchestrator.onAuthError.test.ts:79-404
Timestamp: 2026-04-03T05:57:51.304Z
Learning: In vybestack/llxprt-code, `RetryOrchestrator.onAuthError` tests (packages/core/src/providers/__tests__/RetryOrchestrator.onAuthError.test.ts, PR `#1874`) are intentionally scoped to the default/single-bucket path covering issue1861's core fix. Multi-bucket / non-default session-bucket regression coverage belongs at the OAuthManager/TokenAccessCoordinator layer (forceRefreshToken.test.ts), not in RetryOrchestrator tests. Do not flag the absence of multi-bucket bucket-context tests in RetryOrchestrator.onAuthError.test.ts as a coverage gap.
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1778
File: packages/cli/src/auth/token-access-coordinator.ts:442-449
Timestamp: 2026-03-26T00:30:25.258Z
Learning: In `packages/cli/src/auth/token-access-coordinator.ts` (vybestack/llxprt-code PR `#1778`, decomposed from `oauth-manager.ts`), `getToken()` calls `peekOtherProfileBuckets()` even when `explicitBucket` is `true`, and the associated profile-bucket count check can suppress auth when multiple profile buckets exist. This is pre-existing behavior faithfully extracted from the original `oauth-manager.ts` getOAuthToken method (lines 1136-1412 on main). The bucket resolution logic intentionally supports profile-scoped session buckets with failover. Do not flag this as a bug in decomposition or future PRs — rearchitecting the bucket resolution chain would be a behavioral change beyond refactoring scope.
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1874
File: packages/core/src/auth/invalidateProviderCache.test.ts:107-163
Timestamp: 2026-04-03T05:57:42.326Z
Learning: In `packages/core/src/auth/invalidateProviderCache.test.ts` (vybestack/llxprt-code PR `#1874`), the profile-specific positive-match path for `invalidateProviderCache('anthropic', profileId)` is intentionally not directly tested because `resolveAuthentication` does not expose a `profileId` metadata parameter in its public API, making it impossible to construct a profile-keyed cache entry from outside. The wildcard invalidation test (`invalidateProviderCache('anthropic')` with no profileId) exercises the same matching predicate. Do not flag the missing profile-specific positive-match case as a test gap — adding it is a low-priority follow-up that requires internal API changes.
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1874
File: packages/core/src/providers/RetryOrchestrator.ts:362-374
Timestamp: 2026-04-03T05:57:34.290Z
Learning: In vybestack/llxprt-code, `OnAuthErrorHandler.handleAuthError` declares `profileId` as optional because `profileId` is not available at the `RetryOrchestrator` level: `GenerateChatOptions` does not carry a `profileId` field and the runtime context does not expose it. The `forceRefreshToken` TOCTOU pattern in `TokenAccessCoordinator` works correctly without a profile qualifier. Do not flag the missing `profileId` in `RetryOrchestrator`'s `handleAuthError` call as a bug — propagating `profileId` through the entire provider call chain is a tracked follow-up, not a defect in the current fix (issue `#1861` / PR `#1874`).
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1778
File: packages/cli/src/auth/qwen-oauth-provider.ts:234-242
Timestamp: 2026-03-26T00:30:20.796Z
Learning: In `packages/cli/src/auth/qwen-oauth-provider.ts` (vybestack/llxprt-code PR `#1778`, decomposed from `oauth-manager.ts`), the broad `catch` block in `openQwenBrowserIfInteractive` that silently swallows all errors from the dynamic import of `../runtime/runtimeSettings.js` (setting `noBrowser = false` as the default) is pre-existing behavior faithfully extracted from the original `oauth-manager.ts`. Do not flag the absence of debug logging or error discrimination in this catch block as a gap in decomposition or future PRs — adding error-type discrimination would be a behavioral change beyond the refactoring scope.
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 0
File: :0-0
Timestamp: 2026-02-16T19:05:47.580Z
Learning: Issue `#1442` resolution: Random Codex OAuth failures were caused by stale tokens from the old MultiProviderTokenStore after migration to KeyringTokenStore (commits 916605df, 8aeecbee). Old tokens failed CodexOAuthTokenSchema validation (missing account_id) causing random auth requests. Repeated logout/login manually cleaned up both storage locations. Codex provider lacks legacy cleanup methods that Gemini has (migrateFromLegacyTokens, clearLegacyTokens). Solution: add automatic legacy cleanup to Codex like Gemini.
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1778
File: packages/cli/src/auth/provider-usage-info.ts:36-37
Timestamp: 2026-03-26T01:28:37.959Z
Learning: In `packages/cli/src/auth/provider-usage-info.ts` (vybestack/llxprt-code PR `#1778`, decomposed from `oauth-manager.ts`), the `bucket ?? 'default'` normalization before calling `tokenStore.getToken(provider, bucket)` is correct and functionally identical to passing `undefined`. The production `KeyringTokenStore` (packages/core/src/auth/keyring-token-store.ts, line 94) already normalizes `undefined` to `DEFAULT_BUCKET` (the string `"default"`) internally via `const resolvedBucket = bucket ?? DEFAULT_BUCKET`. The `InMemoryTokenStore` used in test helpers does not define the production contract. Do not flag `bucket ?? 'default'` lookups as a contract violation or suggest splitting into `undefined`-for-lookup vs `'default'`-for-display in this codebase — the original `oauth-manager.ts` used the same pattern (line 2169) and the behavior is faithfully preserved.
📚 Learning: 2026-04-03T05:57:42.326Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1874
File: packages/core/src/auth/invalidateProviderCache.test.ts:107-163
Timestamp: 2026-04-03T05:57:42.326Z
Learning: In `packages/core/src/auth/invalidateProviderCache.test.ts` (vybestack/llxprt-code PR `#1874`), the profile-specific positive-match path for `invalidateProviderCache('anthropic', profileId)` is intentionally not directly tested because `resolveAuthentication` does not expose a `profileId` metadata parameter in its public API, making it impossible to construct a profile-keyed cache entry from outside. The wildcard invalidation test (`invalidateProviderCache('anthropic')` with no profileId) exercises the same matching predicate. Do not flag the missing profile-specific positive-match case as a test gap — adding it is a low-priority follow-up that requires internal API changes.

Applied to files:

  • packages/core/src/auth/precedence.test.ts
  • packages/core/src/auth/precedence.ts
📚 Learning: 2026-03-26T00:29:42.510Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1778
File: packages/cli/src/auth/BucketFailoverHandlerImpl.spec.ts:500-503
Timestamp: 2026-03-26T00:29:42.510Z
Learning: In `packages/cli/src/auth/BucketFailoverHandlerImpl.spec.ts` (vybestack/llxprt-code), the `if (provider)` guard pattern used after `oauthManager.getProvider(...)` to conditionally stub `provider.refreshToken` is pre-existing from the original test suite. Do not flag this as a silent-skip risk or suggest hardening (e.g., `expect(provider).toBeDefined()`) in decomposition or refactoring PRs — changing test structure is explicitly out of scope for those PRs.

Applied to files:

  • packages/core/src/auth/precedence.test.ts
📚 Learning: 2026-03-27T02:12:12.434Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1785
File: packages/cli/src/config/__tests__/profileOverridePrecedenceParity.test.ts:212-306
Timestamp: 2026-03-27T02:12:12.434Z
Learning: In `packages/cli/src/config/__tests__/profileOverridePrecedenceParity.test.ts` (vybestack/llxprt-code PR `#1785`), `applyProfileSnapshot` is intentionally mocked in both `../../runtime/profileSnapshot.js` (the primary call-tracking mock, capturing calls into `profileSnapshotCalls`) and `../../runtime/runtimeSettings.js` (a fallback mock). This dual mocking is required because `config.ts` imports `applyProfileSnapshot` from both paths. Do not flag this as confusing duplication or suggest collapsing into a single mock in future reviews.

Applied to files:

  • packages/core/src/auth/precedence.test.ts
  • packages/core/src/auth/precedence.ts
📚 Learning: 2026-03-26T00:30:00.337Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1778
File: packages/cli/src/auth/provider-usage-info.ts:228-233
Timestamp: 2026-03-26T00:30:00.337Z
Learning: In `packages/cli/src/auth/provider-usage-info.ts` (vybestack/llxprt-code PR `#1778`, decomposed from `oauth-manager.ts`), `getHigherPriorityAuth` calls `getSettingsService().get('authOnly')` globally (without a try/catch guard) alongside the passed `LoadedSettings`. This is pre-existing behavior faithfully extracted from the original `getHigherPriorityAuth` method at line 1836 of `oauth-manager.ts` on main. Do not flag the unconditional `getSettingsService()` call or the `authOnly` handling pattern as a new issue or scope expansion in decomposition or future PRs — rearchitecting the auth-priority dependency chain is explicitly out of scope.

Applied to files:

  • packages/core/src/auth/precedence.test.ts
  • packages/core/src/auth/precedence.ts
📚 Learning: 2026-03-27T00:46:43.700Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1785
File: packages/cli/src/config/__tests__/folderTrustOriginalSettingsParity.test.ts:347-383
Timestamp: 2026-03-27T00:46:43.700Z
Learning: In `packages/cli/src/config/__tests__/folderTrustOriginalSettingsParity.test.ts` (vybestack/llxprt-code PR `#1785`), the last test ("profile ephemeral folderTrust value does NOT change the trust check") intentionally omits a real profile load. Its sole purpose is to assert that `isWorkspaceTrusted` is called with the original settings object (not a profile-merged copy) in the untrusted-folder branch. The profile-merge path is covered by other parity test files. Do not suggest adding an inline profile or `LLXPRT_PROFILE` env var to this test — that would be scope expansion beyond its intended parity coverage.

Applied to files:

  • packages/core/src/auth/precedence.test.ts
📚 Learning: 2026-03-26T02:12:35.416Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1778
File: packages/cli/src/auth/auth-status-service.ts:241-263
Timestamp: 2026-03-26T02:12:35.416Z
Learning: In `packages/cli/src/auth/auth-status-service.ts` (vybestack/llxprt-code PR `#1778`, decomposed from `oauth-manager.ts`), `logoutAll()` only iterates `tokenStore.listProviders()` and does not include providers whose auth state is managed exclusively via `provider.isAuthenticated()` (i.e., providers with no persisted token store entry). This is pre-existing behavior faithfully extracted from the original `oauth-manager.ts` `logoutAll()`. Do not flag this as a regression or gap in decomposition PRs — improving coverage to include registry-only providers is a follow-up enhancement, not a refactoring concern.

Applied to files:

  • packages/core/src/auth/precedence.test.ts
  • packages/core/src/auth/precedence.ts
📚 Learning: 2026-03-26T02:12:39.396Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1778
File: packages/cli/src/auth/auth-flow-orchestrator.ts:431-437
Timestamp: 2026-03-26T02:12:39.396Z
Learning: In `packages/cli/src/auth/auth-flow-orchestrator.ts` (vybestack/llxprt-code PR `#1778`, decomposed from `oauth-manager.ts`), the early return in `authenticateMultipleBuckets` when `unauthenticatedBuckets.length === 0` intentionally skips re-enabling OAuth in-memory/settings and skips installing a bucket failover handler. This is pre-existing behavior faithfully extracted from the original `oauth-manager.ts` around line 2547 on main. Do not flag the missing success-side-effects (provider enablement, failover handler installation) on the all-valid fast path as a bug in decomposition or future PRs — adding these side-effects would be a behavioral change beyond the refactoring scope.

Applied to files:

  • packages/core/src/auth/precedence.test.ts
  • packages/core/src/auth/precedence.ts
📚 Learning: 2026-04-03T05:57:51.304Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1874
File: packages/core/src/providers/__tests__/RetryOrchestrator.onAuthError.test.ts:79-404
Timestamp: 2026-04-03T05:57:51.304Z
Learning: In vybestack/llxprt-code, `RetryOrchestrator.onAuthError` tests (packages/core/src/providers/__tests__/RetryOrchestrator.onAuthError.test.ts, PR `#1874`) are intentionally scoped to the default/single-bucket path covering issue1861's core fix. Multi-bucket / non-default session-bucket regression coverage belongs at the OAuthManager/TokenAccessCoordinator layer (forceRefreshToken.test.ts), not in RetryOrchestrator tests. Do not flag the absence of multi-bucket bucket-context tests in RetryOrchestrator.onAuthError.test.ts as a coverage gap.

Applied to files:

  • packages/core/src/auth/precedence.test.ts
📚 Learning: 2026-03-26T00:30:25.258Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1778
File: packages/cli/src/auth/token-access-coordinator.ts:442-449
Timestamp: 2026-03-26T00:30:25.258Z
Learning: In `packages/cli/src/auth/token-access-coordinator.ts` (vybestack/llxprt-code PR `#1778`, decomposed from `oauth-manager.ts`), `getToken()` calls `peekOtherProfileBuckets()` even when `explicitBucket` is `true`, and the associated profile-bucket count check can suppress auth when multiple profile buckets exist. This is pre-existing behavior faithfully extracted from the original `oauth-manager.ts` getOAuthToken method (lines 1136-1412 on main). The bucket resolution logic intentionally supports profile-scoped session buckets with failover. Do not flag this as a bug in decomposition or future PRs — rearchitecting the bucket resolution chain would be a behavioral change beyond refactoring scope.

Applied to files:

  • packages/core/src/auth/precedence.test.ts
  • packages/core/src/auth/precedence.ts
📚 Learning: 2026-04-03T06:29:38.156Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1874
File: packages/cli/src/auth/__tests__/forceRefreshToken.test.ts:449-477
Timestamp: 2026-04-03T06:29:38.156Z
Learning: In `packages/cli/src/auth/token-access-coordinator.ts` (vybestack/llxprt-code PR `#1874`), `forceRefreshToken` uses a lock-first, single-read TOCTOU pattern: acquire refresh lock → read stored token once (under the lock) → compare stored token with failed access token → act. There is no pre-lock read. The test in `packages/cli/src/auth/__tests__/forceRefreshToken.test.ts` correctly simulates the "another process already refreshed" case by preloading an updated token in the store. Do not flag the absence of a second `getToken` call or suggest asserting `getToken` was called twice — the implementation intentionally reads only once under the lock.

Applied to files:

  • packages/core/src/auth/precedence.test.ts
📚 Learning: 2026-03-21T16:36:12.168Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1740
File: packages/core/src/providers/anthropic/AnthropicRequestBuilder.ts:386-408
Timestamp: 2026-03-21T16:36:12.168Z
Learning: In `packages/core/src/providers/anthropic/AnthropicRequestBuilder.ts` (vybestack/llxprt-code PR `#1740`), `buildAnthropicRequestBody` intentionally spreads `options.modelParams` after the validated base fields (`model`, `messages`, `max_tokens`, `stream`). This allows user-specified model parameters to override defaults and is pre-existing behavior faithfully preserved from the original `AnthropicProvider.ts`. Do not flag this spread order as a security or correctness issue in decomposition PRs — restricting which keys can be spread would be a behavioral change beyond refactoring scope.

Applied to files:

  • packages/core/src/auth/precedence.test.ts
📚 Learning: 2026-02-06T15:52:42.315Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1305
File: scripts/generate-keybindings-doc.ts:1-5
Timestamp: 2026-02-06T15:52:42.315Z
Learning: In reviews of vybestack/llxprt-code, do not suggest changing existing copyright headers from 'Google LLC' to 'Vybestack LLC' for files that originated from upstream. Preserve upstream copyrights in files that came from upstream, and only apply 'Vybestack LLC' copyright on newly created, original LLxprt files. If a file is clearly LLxprt-original, it may carry the Vybestack header; if it is upstream-originated, keep the original sponsor header.

Applied to files:

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

Applied to files:

  • packages/core/src/auth/precedence.test.ts
  • packages/core/src/auth/precedence.ts
📚 Learning: 2026-04-03T05:57:34.290Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1874
File: packages/core/src/providers/RetryOrchestrator.ts:362-374
Timestamp: 2026-04-03T05:57:34.290Z
Learning: In vybestack/llxprt-code, `OnAuthErrorHandler.handleAuthError` declares `profileId` as optional because `profileId` is not available at the `RetryOrchestrator` level: `GenerateChatOptions` does not carry a `profileId` field and the runtime context does not expose it. The `forceRefreshToken` TOCTOU pattern in `TokenAccessCoordinator` works correctly without a profile qualifier. Do not flag the missing `profileId` in `RetryOrchestrator`'s `handleAuthError` call as a bug — propagating `profileId` through the entire provider call chain is a tracked follow-up, not a defect in the current fix (issue `#1861` / PR `#1874`).

Applied to files:

  • packages/core/src/auth/precedence.ts
📚 Learning: 2026-03-26T02:22:24.428Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1780
File: packages/cli/src/ui/hooks/geminiStream/streamUtils.ts:264-267
Timestamp: 2026-03-26T02:22:24.428Z
Learning: In `packages/cli/src/ui/hooks/geminiStream/streamUtils.ts` (vybestack/llxprt-code PR `#1780`, decomposed from the original `useGeminiStream.ts`), `buildFullSplitItem` uses `const profileName = liveProfileName ?? existingProfileName` — this is intentional pre-existing behavior faithfully extracted from the original `useGeminiStream.ts`. The precedence (liveProfileName first, existingProfileName as fallback) is identical to the source implementation. Changing to `existingProfileName ?? liveProfileName` would be a behavioral modification, not a decomposition fix. Do not flag this precedence order in decomposition or future PRs — any fix should be a dedicated follow-up.

Applied to files:

  • packages/core/src/auth/precedence.ts
📚 Learning: 2026-03-27T01:00:36.000Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1785
File: packages/cli/src/config/profileResolution.ts:287-305
Timestamp: 2026-03-27T01:00:36.000Z
Learning: In `packages/cli/src/config/profileResolution.ts` (vybestack/llxprt-code PR `#1785`), `loadAndPrepareProfile` contains two sequential branches: one for inline profile (`bootstrapArgs.profileJson != null`) and one for file-based profile (`profileToLoad`). There is intentionally no guard between them preventing both from running, because the caller (`resolveProfileToLoad`) already returns `profileToLoad: undefined` when `bootstrapArgs.profileJson` is non-null, ensuring the file branch is never reached with a real inline profile. Adding `&& bootstrapArgs.profileJson == null` to the file-branch guard would be a redundant behavioral change beyond the refactoring scope. Do not flag this pattern as a missing guard in future reviews.

Applied to files:

  • packages/core/src/auth/precedence.ts
📚 Learning: 2026-04-02T11:09:51.504Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1870
File: packages/cli/src/runtime/profileApplication.ts:460-462
Timestamp: 2026-04-02T11:09:51.504Z
Learning: In vybestack/llxprt-code, core type Profile requires ephemeralSettings (non-optional). In packages/cli/src/runtime/profileApplication.ts, directly indexing subProfile.ephemeralSettings[...] for load-balancer sub-profile resolution is correct; do not flag missing-defaults for ephemeralSettings on sub-profiles in future reviews.

Applied to files:

  • packages/core/src/auth/precedence.ts
📚 Learning: 2026-04-02T11:09:42.031Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1870
File: packages/cli/src/gemini.tsx:561-565
Timestamp: 2026-04-02T11:09:42.031Z
Learning: In packages/cli/src/gemini.tsx, the bootstrapProfileName calculation intentionally uses `argv.profileLoad?.trim() ?? <env>` so that a trimmed empty string ('') does not fall back to LLXPRT_BOOTSTRAP_PROFILE; only null/undefined should trigger the env fallback.

Applied to files:

  • packages/core/src/auth/precedence.ts
📚 Learning: 2026-03-24T21:35:22.678Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1766
File: packages/cli/src/runtime/runtimeRegistry.ts:68-72
Timestamp: 2026-03-24T21:35:22.678Z
Learning: In `packages/cli/src/runtime/runtimeRegistry.ts` (vybestack/llxprt-code PR `#1766`, decomposed from `runtimeSettings.ts`), `resolveActiveRuntimeIdentity` falls back to the first registered `runtimeId` (`runtimeRegistry.keys().next().value`) when the active provider context carries an unregistered per-call `runtimeId` (e.g. a per-call UUID from BaseProvider). This is intentional pre-existing behavior identical to the original `resolveActiveRuntimeIdentity` on main (lines 269-305). The fallback is a deliberate heuristic for the legacy singleton pattern. Do not flag this as a cross-runtime state bug in decomposition or future PRs.

Applied to files:

  • packages/core/src/auth/precedence.ts
📚 Learning: 2026-03-24T21:34:55.312Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1766
File: packages/cli/src/runtime/providerSwitch.ts:736-745
Timestamp: 2026-03-24T21:34:55.312Z
Learning: In `packages/cli/src/runtime/providerSwitch.ts` (vybestack/llxprt-code PR `#1766`, decomposed from the original `runtimeSettings.ts`), `switchActiveProvider` uses a linear, non-atomic sequence: `clearPreviousProviderSettings` → `activateProviderContext` → `switchSettingsProvider` → base-URL/model/defaults initialization, with no rollback on failure. This is intentional pre-existing behavior faithfully preserved from the original `switchActiveProvider` on main. Do not flag the absence of transactional/rollback semantics as a regression or decomposition bug — it is tracked as a known limitation for a future follow-up.

Applied to files:

  • packages/core/src/auth/precedence.ts
📚 Learning: 2026-03-24T21:33:43.130Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1766
File: packages/cli/src/runtime/providerMutations.ts:258-265
Timestamp: 2026-03-24T21:33:43.130Z
Learning: In `packages/cli/src/runtime/providerMutations.ts` (vybestack/llxprt-code PR `#1766`, decomposed from the original `runtimeSettings.ts`), `updateActiveProviderApiKey` intentionally does NOT clear `auth-key` in `settingsService` during the update (non-null key) branch. The update branch sets the ephemeral `auth-key` to the new value instead; only the remove (null/empty key) branch clears all aliases in both `settingsService` and config ephemeral settings. This asymmetry is pre-existing behavior from the original `runtimeSettings.ts` (lines 2182-2187 on main). Do not flag this as a credential-leak or stale-alias bug in decomposition reviews.

Applied to files:

  • packages/core/src/auth/precedence.ts
📚 Learning: 2026-03-24T21:35:42.622Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1766
File: packages/cli/src/runtime/settingsResolver.ts:96-103
Timestamp: 2026-03-24T21:35:42.622Z
Learning: In `packages/cli/src/runtime/settingsResolver.ts` (vybestack/llxprt-code PR `#1766`), the `--key` and `--keyfile` branches both call `updateActiveProviderApiKey`, which internally calls `config.setEphemeralSetting('auth-key-name', undefined)` at line 289 of `providerMutations.ts` (update branch) and line 265 (remove branch). Do not flag missing `auth-key-name` clearing at the `settingsResolver.ts` call sites — it is already handled inside the mutation function. Trace the full call chain into `updateActiveProviderApiKey` before raising such a comment.

Applied to files:

  • packages/core/src/auth/precedence.ts
📚 Learning: 2026-01-09T07:46:06.289Z
Learnt from: sogoiii
Repo: vybestack/llxprt-code PR: 1052
File: packages/cli/src/ui/components/ProfileCreateWizard/utils.ts:35-40
Timestamp: 2026-01-09T07:46:06.289Z
Learning: In the Profile Create Wizard (packages/cli/src/ui/components/ProfileCreateWizard), provider values are always passed as `provider.value` from provider objects that originate from PROVIDER_OPTIONS, ensuring consistent provider ID lookups without needing normalization.

Applied to files:

  • packages/core/src/auth/precedence.ts
🔇 Additional comments (2)
packages/core/src/auth/precedence.test.ts (1)

367-367: Updated metadata assertion is correct.

Expecting profileId: undefined here correctly validates the no-profile OAuth metadata behavior.

packages/core/src/auth/precedence.ts (1)

159-178: No-profile metadata handling is improved.

Returning null from profile resolution and passing profileId as undefined in request metadata correctly avoids emitting a synthetic default profile identifier.

Also applies to: 774-775

Comment on lines +695 to 696
const profileScopeId = profileId ?? 'no-profile';

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.

⚠️ Potential issue | 🟠 Major

Prevent cache-key aliasing with real 'no-profile' profile names.

At Line 695, profileScopeId uses the literal 'no-profile' as a sentinel. If a user creates a profile named 'no-profile', runtime cache keys collide and token scoping/invalidation can cross-contaminate between “no profile loaded” and that real profile.

Suggested fix
-      const profileId = resolveProfileId(settingsService);
-      const profileScopeId = profileId ?? 'no-profile';
+      const profileId = resolveProfileId(settingsService);
+      const profileScopeId =
+        profileId === null ? '__scope:no-profile__' : `profile:${profileId}`;

Also applies to: 746-747, 760-761, 813-814

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

In `@packages/core/src/auth/precedence.ts` around lines 695 - 696, The sentinel
string 'no-profile' used for profileScopeId can collide with a real profile
named the same; replace it with a guaranteed-unique sentinel constant (e.g.
const NO_PROFILE_SENTINEL = '\0NO_PROFILE' or similar non-printable/prefixed
value) and use it wherever profileScopeId is computed (variable profileScopeId
and the other occurrences noted), i.e. change lines that do const profileScopeId
= profileId ?? 'no-profile' to const profileScopeId = profileId ??
NO_PROFILE_SENTINEL and ensure the same NO_PROFILE_SENTINEL is used for all
token-scoping/cache-key generation to avoid aliasing.

@acoliver acoliver merged commit a497ee2 into main Apr 10, 2026
22 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.

OpenAI /Anthropic Oauth broken on linux

1 participant