Skip to content

fix(auth): enable auth cache invalidation for unbucketed profiles (Fixes #1739)#1896

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

fix(auth): enable auth cache invalidation for unbucketed profiles (Fixes #1739)#1896
acoliver merged 5 commits intomainfrom
issue1739

Conversation

@acoliver
Copy link
Copy Markdown
Collaborator

@acoliver acoliver commented Apr 9, 2026

Summary

Fixes #1739 - unbucketed profiles should check keychain on 401/etc or new turn

Problem

Unbucketed profiles (single-bucket OAuth profiles) do not properly handle auth token refresh when they encounter 401/403 errors. When a key expires and the user re-authenticates, other agents can continue using cached invalid credentials instead of picking up the new token from the keychain.

Root Cause

  1. StreamProcessor._handleBucketFailover() gated tryFailover() behind failoverHandler.isEnabled(), which returns false for single-bucket profiles. That blocked single-bucket profiles from reaching Pass 3 foreground re-auth.
  2. There was no turn-boundary auth cache invalidation path for single-bucket profiles, so agents could keep using stale cached credentials instead of re-reading from the keychain.

Solution

  1. Remove the isEnabled() gate so any configured failover handler can reach tryFailover().
  2. Add invalidateAuthCache() to the BucketFailoverHandler interface.
  3. Implement invalidateAuthCache() in BucketFailoverHandlerImpl using flushRuntimeAuthScope().
  4. Call invalidateAuthCache() at new-turn boundaries in useGeminiStream before ensureBucketsAuthenticated().

Changes

  • packages/core/src/core/StreamProcessor.ts
    • Changed the failover guard from checking isEnabled() to checking handler existence only.
  • packages/core/src/config/configTypes.ts
    • Added optional invalidateAuthCache(runtimeId: string): void to BucketFailoverHandler.
  • packages/cli/src/auth/BucketFailoverHandlerImpl.ts
    • Implemented invalidateAuthCache() by calling flushRuntimeAuthScope(runtimeId).
  • packages/cli/src/ui/hooks/geminiStream/useGeminiStream.ts
    • Invalidate auth cache at new-turn boundaries so updated tokens written by other processes are picked up.

Verification

  • cd packages/core && npm run test
  • cd packages/core && npm run typecheck
  • cd packages/cli && npm run typecheck
  • cd packages/cli && npm run lint
  • npm run build
  • node scripts/start.js --profile-load synthetic "write me a haiku and nothing else"

Notes

This keeps multi-bucket behavior intact while allowing single-bucket profiles to use the existing Pass 3 foreground re-auth path and refresh keychain state on new turns.

Fixes #1739

 #1739)

Fixes unbucketed profiles not checking keychain on 401 errors or new turns.

Changes: Remove isEnabled() check blocking single-bucket failover, add invalidateAuthCache to BucketFailoverHandler interface, implement cache invalidation in BucketFailoverHandlerImpl, call invalidateAuthCache at turn boundaries in useGeminiStream.
@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

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: ae3c2b2a-5d3a-4520-903c-05527605c9c4

📥 Commits

Reviewing files that changed from the base of the PR and between 611715b and 9831a5e.

📒 Files selected for processing (3)
  • packages/cli/src/auth/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.test.ts
  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.ts
  • packages/core/src/core/StreamProcessor.unbucketed-auth-failover.test.ts
📜 Recent review details
⏰ Context from checks skipped due to timeout of 270000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (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 (44)
📓 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: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/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: 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: 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: 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.
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: 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/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: 1459
File: packages/core/src/providers/LoadBalancingProvider.ts:631-648
Timestamp: 2026-02-18T01:44:54.715Z
Learning: Load balancer failover and bucket failover are two separate mechanisms: Load balancer failover (LoadBalancingProvider) distributes requests across different backends/providers and treats 401 as an immediate failover error. Bucket failover (BucketFailoverHandlerImpl) handles credential rotation within a single provider and may implement auto-renew semantics for 401. These systems have different 401 handling behaviors by design.
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 0
File: :0-0
Timestamp: 2025-12-13T16:04:07.079Z
Learning: Support multi-bucket failover on a single profile: ordered buckets tried in sequence; on 429 or 402 advance to next bucket; on 401 attempt auto-renew then retry once before advancing.
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 0
File: :0-0
Timestamp: 2026-02-20T04:32:08.940Z
Learning: In vybestack/llxprt-code, provider retries and OAuth bucket failover are centralized in packages/core/src/providers/RetryOrchestrator.ts. Failover triggers: 2×429, immediate 402, or 2nd 401/403. On success, counters and failover session reset; on switch, attempt-- so retries don’t burn on bucket change.
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 0
File: :0-0
Timestamp: 2026-01-13T23:04:39.246Z
Learning: Treat Anthropic 403 permission_error "OAuth token has been revoked" as an expired/auth error: trigger a one-time refresh retry, then bucket failover if refresh fails. Avoid auto-switching providers; only switch buckets within the same provider. This error likely means that we failed to lock when refreshing and multiple instances refreshed the same token.
📚 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/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.test.ts
  • packages/core/src/core/StreamProcessor.unbucketed-auth-failover.test.ts
  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.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/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.test.ts
  • packages/core/src/core/StreamProcessor.unbucketed-auth-failover.test.ts
  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.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/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.test.ts
  • packages/core/src/core/StreamProcessor.unbucketed-auth-failover.test.ts
  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.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/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.test.ts
  • packages/core/src/core/StreamProcessor.unbucketed-auth-failover.test.ts
  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.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/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.test.ts
  • packages/core/src/core/StreamProcessor.unbucketed-auth-failover.test.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/cli/src/auth/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.test.ts
  • packages/core/src/core/StreamProcessor.unbucketed-auth-failover.test.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/cli/src/auth/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.test.ts
  • packages/core/src/core/StreamProcessor.unbucketed-auth-failover.test.ts
  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.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/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.test.ts
  • packages/core/src/core/StreamProcessor.unbucketed-auth-failover.test.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/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.test.ts
  • packages/core/src/core/StreamProcessor.unbucketed-auth-failover.test.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/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.test.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/cli/src/auth/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.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/cli/src/auth/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.test.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/cli/src/auth/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.test.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/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.test.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/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.test.ts
  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.ts
📚 Learning: 2026-03-26T02:05:51.733Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1779
File: packages/core/src/core/subagentChatSetup.ts:88-120
Timestamp: 2026-03-26T02:05:51.733Z
Learning: In `packages/core/src/core/subagentChatSetup.ts` (vybestack/llxprt-code PR `#1779`, decomposed from `subagent.ts`), the tool name normalization inconsistency between `validateToolsAgainstRuntime()` (which normalizes via `moduleNormalizeToolName` for the allowlist check but uses the raw name for `toolRegistry.getTool`) and `buildRuntimeFunctionDeclarations` (which calls `getToolMetadata(entry)` with the raw name) is pre-existing behavior faithfully moved from the original `subagent.ts`. Do not flag this inconsistency as a bug introduced by decomposition PRs — any fix to canonicalize tool names before both validation and declaration lookup should be addressed in a dedicated follow-up PR.

Applied to files:

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

Applied to files:

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

Applied to files:

  • packages/cli/src/auth/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.test.ts
  • packages/core/src/core/StreamProcessor.unbucketed-auth-failover.test.ts
  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.ts
📚 Learning: 2026-03-21T17:07:33.700Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1743
File: packages/core/src/core/StreamProcessor.ts:123-135
Timestamp: 2026-03-21T17:07:33.700Z
Learning: In `packages/core/src/core/StreamProcessor.ts` (vybestack/llxprt-code PR `#1743`), the retry boundary in `_executeStreamApiCall` only protects async generator *construction* (via `_buildAndSendStreamRequest`), not the actual network calls that occur during iteration inside `_aggregateStreamChunks`. This is a known pre-existing architectural limitation faithfully preserved from the original `geminiChat.ts`. The issue is tracked as `#1750` for the 0.10.0 improvement effort. Do not re-flag this as a regression or decomposition bug in future reviews — it is intentionally deferred.

Applied to files:

  • packages/core/src/core/StreamProcessor.unbucketed-auth-failover.test.ts
📚 Learning: 2026-02-15T19:33:03.569Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1405
File: packages/core/src/lsp/__tests__/lsp-service-client-integration.test.ts:93-102
Timestamp: 2026-02-15T19:33:03.569Z
Learning: In the llxprt-code codebase (`packages/core/src/lsp/__tests__/lsp-service-client-integration.test.ts`), the LspServiceClient integration tests use a synthetic/stub implementation with PassThrough streams for testing. The test config may include fields like `filetypes` that differ from production types (`LspServerConfig`), as these tests verify the integration contract rather than exact production type conformance. Future work may add more realistic subprocess tests.

Applied to files:

  • packages/core/src/core/StreamProcessor.unbucketed-auth-failover.test.ts
  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.ts
📚 Learning: 2026-02-20T04:32:08.940Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 0
File: :0-0
Timestamp: 2026-02-20T04:32:08.940Z
Learning: In vybestack/llxprt-code, provider retries and OAuth bucket failover are centralized in packages/core/src/providers/RetryOrchestrator.ts. Failover triggers: 2×429, immediate 402, or 2nd 401/403. On success, counters and failover session reset; on switch, attempt-- so retries don’t burn on bucket change.

Applied to files:

  • packages/core/src/core/StreamProcessor.unbucketed-auth-failover.test.ts
📚 Learning: 2026-02-15T21:44:56.598Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1407
File: packages/core/src/core/geminiChatHookTriggers.ts:56-65
Timestamp: 2026-02-15T21:44:56.598Z
Learning: Enforce the canonical speaker-to-role mapping used by GeminiChat hooks: in IContent.speaker, which is strictly typed as 'human | ai | tool' (no 'system'), map 'human' to the 'user' role, 'ai' to the 'model' role, and 'tool' to the 'user' role in all hook payloads. This pattern should be applied across related hook files within packages/core/src/core/ (not just the single file) to ensure consistent role assignment.

Applied to files:

  • packages/core/src/core/StreamProcessor.unbucketed-auth-failover.test.ts
📚 Learning: 2026-02-16T19:18:56.265Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1436
File: packages/core/src/core/nonInteractiveToolExecutor.ts:0-0
Timestamp: 2026-02-16T19:18:56.265Z
Learning: Guideline: In the core scheduler architecture, the system runs in a single mode at a time—either interactive or non-interactive, never both on the same scheduler instance. Non-interactive (CLI one-shot) runs without any interactive session; interactive mode subagents run within the parent's interactive context and inherit its mode. When reviewing code, ensure non-interactive tool executions (e.g., in nonInteractiveToolExecutor.ts) create and use a fresh completionResolver per executeToolCall, and that there is no race with interactive sessions since they cannot coexist on the same scheduler instance. This pattern applies across files in packages/core/src/core/. Only apply to relevant files, not globally.

Applied to files:

  • packages/core/src/core/StreamProcessor.unbucketed-auth-failover.test.ts
📚 Learning: 2026-03-22T04:06:53.600Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1743
File: packages/core/src/core/TurnProcessor.ts:391-402
Timestamp: 2026-03-22T04:06:53.600Z
Learning: When computing `lastPromptTokenCount` (e.g., in the streaming path like `_convertIContentStream`/equivalent), ensure it includes the full prompt token footprint: `lastPromptTokenCount = promptTokens + cache_read_input_tokens + cache_creation_input_tokens`. Do not use `promptTokens` alone, because cached context would otherwise cause `CompressionHandler.shouldCompress()` to underestimate context usage and may incorrectly suppress needed compression. Keep this combined computation consistent with the non-streaming path (e.g., `TurnProcessor._executeProviderCall`), and do not treat the presence of cache-token additions as redundant—both token types are required for correctness when cached context is active.

Applied to files:

  • packages/core/src/core/StreamProcessor.unbucketed-auth-failover.test.ts
📚 Learning: 2026-03-26T20:52:08.720Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1780
File: packages/cli/src/ui/hooks/geminiStream/useStreamEventHandlers.ts:140-149
Timestamp: 2026-03-26T20:52:08.720Z
Learning: In `packages/cli/src/ui/hooks/geminiStream/useStreamEventHandlers.ts` (vybestack/llxprt-code PR `#1780`), the `applyThoughtToState` function's `setPendingHistoryItem` updater casts `item?.type as 'gemini' | 'gemini_content'` and uses `item?.text || ''` — this is intentional pre-existing behavior faithfully extracted verbatim from the original `useGeminiStream.ts` (lines 1110–1111 on main). The risk that a `tool_group` pending item type could be preserved is a known pre-existing pattern; fixing it requires careful testing of all thinking block rendering paths and is a behavioral change beyond decomposition scope. Do not flag this type cast as a bug in decomposition or refactoring PRs.

Applied to files:

  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.ts
📚 Learning: 2026-03-26T21:40:39.044Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1780
File: packages/cli/src/ui/hooks/geminiStream/useStreamEventHandlers.ts:521-525
Timestamp: 2026-03-26T21:40:39.044Z
Learning: In `packages/cli/src/ui/hooks/geminiStream/useStreamEventHandlers.ts` (vybestack/llxprt-code PR `#1780`), `processGeminiStreamEvents` previously always returned `StreamProcessingStatus.Completed` even when a `UserCancelled` or `Error` event was received — this was pre-existing dead code from the original `useGeminiStream.ts` (line 1371 checked for UserCancelled but the function always returned Completed). Fixed in commit 4a28363bc by adding a `processingResult` variable that tracks the status through the event loop, setting it to `StreamProcessingStatus.UserCancelled` or `StreamProcessingStatus.Error` as appropriate, and returning it at the end instead of always returning `Completed`.

Applied to files:

  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.ts
📚 Learning: 2026-03-26T02:06:03.086Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1779
File: packages/core/src/core/subagentChatSetup.ts:339-453
Timestamp: 2026-03-26T02:06:03.086Z
Learning: In `packages/core/src/core/subagentChatSetup.ts` (vybestack/llxprt-code PR `#1779`, decomposed from `subagent.ts`), the `assembleChatSession` function's `try/catch` block wraps only `new GeminiChat(...)` and not the preceding `await ctx.environmentContextLoader(...)` or `await getCoreSystemPromptAsync(...)` calls. This partial error boundary is pre-existing behavior faithfully preserved from the original `createChatObject` method in `subagent.ts`. Do not flag the missing async-await coverage as a decomposition regression in future reviews — it is an acknowledged pre-existing limitation, and any fix would be a behavioral change requiring a dedicated follow-up PR.

Applied to files:

  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.ts
📚 Learning: 2026-03-26T20:01:50.052Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1780
File: packages/cli/src/ui/hooks/geminiStream/checkpointPersistence.ts:0-0
Timestamp: 2026-03-26T20:01:50.052Z
Learning: In `packages/cli/src/ui/hooks/geminiStream/checkpointPersistence.ts` (vybestack/llxprt-code PR `#1780`), `saveRestorableToolCalls` reserves the `callId` in `checkpointedCallIds` *before* calling `await createToolCheckpoint(...)` to prevent concurrent duplicate attempts. On failure (exception or false/no-write return), the `callId` is deleted from the set so the next effect run can retry. This reserve-before-await, delete-on-failure pattern was introduced in commit a41b97759.

Applied to files:

  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.ts
📚 Learning: 2026-03-27T00:46:42.630Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1785
File: packages/cli/src/config/__tests__/parseArgumentsParity.test.ts:7-16
Timestamp: 2026-03-27T00:46:42.630Z
Learning: In `packages/cli/src/config/__tests__/parseArgumentsParity.test.ts` (vybestack/llxprt-code PR `#1785`), the test suite is intentionally scoped to verifying that the extracted `parseArguments` function produces identical output to the original inline parsing. It deliberately does NOT cover subcommand exit behavior (mcp, hooks, extensions) via `handleSubcommandExit()` — that function is a direct mechanical extraction and adding integration tests for it would be new coverage beyond the refactoring scope. Do not flag the absence of subcommand-exit test cases as a gap in this file or in refactoring PRs that extract it.

Applied to files:

  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.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/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.ts
📚 Learning: 2026-04-03T20:43:35.912Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1876
File: packages/core/src/core/subagent.ts:441-464
Timestamp: 2026-04-03T20:43:35.912Z
Learning: In `packages/core/src/core/subagent.ts` (vybestack/llxprt-code), `runInteractiveTurn`'s `catch` block should only call `throw createAbortError()` when `abortController.signal.aborted` — it must NOT infer `SubagentTerminateMode.TIMEOUT` based on `!this.parentAbortSignal?.aborted`. `Turn.run()` absorbs idle-timeout events internally and emits `GeminiEventType.UserCancelled` before the generator exits, so the catch only fires for genuine errors or explicit cancel aborts. TIMEOUT is authoritatively set in the `onTimeout` callback of `nextStreamEventWithIdleTimeout` inside `runNonInteractiveTurn`. Do not conflate these two paths in future reviews.

Applied to files:

  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.ts
📚 Learning: 2026-03-25T19:21:43.266Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1771
File: packages/core/src/core/AgentHookManager.ts:78-96
Timestamp: 2026-03-25T19:21:43.266Z
Learning: In `packages/core/src/core/AgentHookManager.ts` (vybestack/llxprt-code PR `#1771`), `cleanupOldHookState(newPromptId, oldPromptId)` is always called at the start of a new prompt turn (when `prompt_id` changes), after the previous prompt's stream has been fully consumed by `MessageStreamOrchestrator`. Because JS is single-threaded, there is no concurrent execution path where an in-flight `fireAfterAgentHookSafe` for the old `prompt_id` could race with the cleanup. Do not flag this pattern as a race condition in future reviews — the sequential flow guarantees: previous prompt finishes → new prompt starts → cleanup runs → fresh hook state created.

Applied to files:

  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.ts
📚 Learning: 2026-03-26T02:22:19.732Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1780
File: packages/cli/src/ui/hooks/geminiStream/streamUtils.ts:100-116
Timestamp: 2026-03-26T02:22:19.732Z
Learning: In `packages/cli/src/ui/hooks/geminiStream/streamUtils.ts` (vybestack/llxprt-code PR `#1780`), the `filteredPendingTools` predicate in `mergePendingToolGroupsForDisplay` only removes overlapping shell entries from the scheduler side, leaving overlapping non-shell tool callIds potentially duplicated. This is pre-existing behavior faithfully extracted verbatim from the original `useGeminiStream.ts` (lines 100-140). Do not flag this as a dedup bug in decomposition or refactoring PRs — any improvement to deduplicate non-shell overlapping callIds would be a separate enhancement, not a structural fix.

Applied to files:

  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.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/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.ts
📚 Learning: 2026-03-26T02:05:48.262Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1779
File: packages/core/src/core/subagent.ts:552-597
Timestamp: 2026-03-26T02:05:48.262Z
Learning: In `packages/core/src/core/subagent.ts` (vybestack/llxprt-code), `processNonInteractiveText` intentionally calls `this.ctx.onMessage(filtered.displayText)` with the raw `textResponse` *before* `parseTextToolCalls` strips tool-call syntax into `cleanedText`. This ordering is pre-existing behavior faithfully preserved from the original `runNonInteractive` implementation. Do not flag the early `onMessage` emission (before tool-call stripping) as a bug in decomposition or refactoring PRs — any change to emit only `cleanedText` would be a behavioral improvement, not a structural fix, and should be tracked as a dedicated follow-up issue.

Applied to files:

  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.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/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.ts
📚 Learning: 2026-03-25T18:17:38.768Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1768
File: packages/cli/src/ui/containers/AppContainer/hooks/useInputHandling.ts:127-135
Timestamp: 2026-03-25T18:17:38.768Z
Learning: In `packages/cli/src/ui/containers/AppContainer/hooks/useInputHandling.ts` (vybestack/llxprt-code PR `#1768`), the `hadToolCallsRef.current = false` reset inside `handleFinalSubmit` (before calling `submitQuery`) is intentional behavior preserved from the original `AppContainer.tsx` continuation flow contract. Do not flag this as a premature reset or race condition in decomposition or future PRs — any turn-boundary redesign (e.g., only clearing after `handleStreamCompleted`) is out of scope for the `#1576` refactoring and would constitute a behavioral change.

Applied to files:

  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.ts
📚 Learning: 2026-04-03T20:43:54.493Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1876
File: packages/core/src/core/subagent.ts:675-710
Timestamp: 2026-04-03T20:43:54.493Z
Learning: In `packages/core/src/core/subagent.ts` (vybestack/llxprt-code PR `#1876`), `runNonInteractiveTurn` intentionally returns `{ functionCalls: [], textResponse: '' }` (instead of throwing) when `abortController.signal.aborted` is detected — both in the pre-loop early-abort check and inside the stream iteration loop. This is the correct design because: (1) `armTimeout` sets `output.terminate_reason = SubagentTerminateMode.TIMEOUT` *before* aborting, so abort-reason state is already recorded; (2) the caller in `runNonInteractive` checks `if (abortController.signal.aborted) return;` immediately after the call, resolving `runNonInteractive` as a normal `Promise<void>` (not a rejection); (3) existing TIMEOUT tests assert this resolution behavior and would break if `createAbortError()` were thrown instead. Do not flag the return-empty-on-abort pattern as dropping `finalizeOutput` or treating abort as success — it is intentional and test-validated.

Applied to files:

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

Applied to files:

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

Applied to files:

  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.ts
🔇 Additional comments (5)
packages/cli/src/auth/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.test.ts (1)

25-53: Strong contract test for unbucketed auth-cache invalidation.

This precisely validates the new invalidateAuthCache(runtimeId) behavior end-to-end at handler level (including runtime-id passthrough to flushRuntimeAuthScope).

packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.ts (3)

18-65: New-turn ordering coverage is solid.

The test captures the critical call sequence and state reset semantics introduced for auth refresh at turn boundaries.


67-110: Continuation-path expectations are correctly isolated.

Good assertions that continuation uses resetSession and avoids new-turn-only side effects.


112-136: Runtime-id fallback test is correctly targeted.

This validates the default runtime-id invalidation path when getSessionId() is unavailable.

packages/core/src/core/StreamProcessor.unbucketed-auth-failover.test.ts (1)

27-63: Regression test correctly verifies unbucketed failover execution.

This directly protects the removed isEnabled() gate behavior and confirms auth-scope invalidation uses the provider runtime id on successful failover.


Summary by CodeRabbit

  • Bug Fixes
    • More reliable authentication cache invalidation between conversation turns to prevent stale credentials.
    • Bucket failover now consistently resets auth state across runtimes, improving multi-runtime and unbucketed session consistency.
  • Tests
    • Added tests covering auth-cache invalidation and failover behaviors to ensure robustness.

Walkthrough

Adds an optional auth-cache invalidation hook to the bucket-failover interface, implements it in the CLI handler to call flushRuntimeAuthScope, invokes it on new-turns in the Gemini UI hook, and relaxes a StreamProcessor guard so failover runs whenever a handler object exists. (47 words)

Changes

Cohort / File(s) Summary
Core Interface
packages/core/src/config/configTypes.ts
Added optional invalidateAuthCache?(runtimeId: string): void to BucketFailoverHandler.
CLI Failover Implementation
packages/cli/src/auth/BucketFailoverHandlerImpl.ts
Imported flushRuntimeAuthScope and added public invalidateAuthCache(runtimeId: string) that calls the flush and logs the invalidation.
Turn Preparation / UI Hook
packages/cli/src/ui/hooks/geminiStream/useGeminiStream.ts
Exported prepareTurnForQuery and added call to handler.invalidateAuthCache(runtimeId) on new (non-continuation) turns using config.getSessionId?.() with 'default' fallback.
Core Failover Flow
packages/core/src/core/StreamProcessor.ts
Changed _handleBucketFailover guard to proceed whenever a handler object exists (removed dependence on failoverHandler?.isEnabled()).
Tests
packages/cli/src/auth/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.test.ts, packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.ts, packages/core/src/core/StreamProcessor.unbucketed-auth-failover.test.ts
Added tests asserting invalidateAuthCache calls flushRuntimeAuthScope, turn-preparation call order including runtime-id fallback, and StreamProcessor triggers flushRuntimeAuthScope during unbucketed failover.

Sequence Diagram(s)

sequenceDiagram
  participant UI as "UI Hook\nprepareTurnForQuery"
  participant Handler as "BucketFailoverHandlerImpl\ninvalidateAuthCache"
  participant AuthCore as "Auth Core\nflushRuntimeAuthScope"
  participant Logger as "Logger"

  UI->>Handler: invalidateAuthCache(runtimeId)
  Handler->>AuthCore: flushRuntimeAuthScope(runtimeId)
  AuthCore-->>Handler: ack
  Handler->>Logger: debug("invalidated auth cache", runtimeId)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 I hopped through turns to clear the stale,
Flushed runtimes so old tokens won't prevail.
A tiny thump, a debug cheer—
New scope, new keys, the path is clear.
Hooray! 🥕

📋 Issue Planner

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

View plan used: #1739

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

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 9, 2026

ReadManyFiles Result (Target Dir: /home/runner/work/llxprt-code/llxprt-code)

Successfully read and concatenated content from 2 file(s) (approximately 1,457 tokens).

Processed Files:

  • review/context.md
  • review/instructions.md

Todo Progress

5 tasks: 0 completed, 1 in progress, 4 pending

→ Understand PR scope via changed-files.txt and diffstat.txt ← current

○ Review critical files (StreamProcessor, BucketFailoverHandler)

○ Examine test coverage in modified test files

○ Assess issue alignment and side effects

○ Write final verdict to review/verdict.md

ReadManyFiles Result (Target Dir: /home/runner/work/llxprt-code/llxprt-code)

Successfully read and concatenated content from 3 file(s) (approximately 415 tokens).

Processed Files:

  • review/changed-files.txt
  • review/diffstat.txt
  • review/numstat.txt

ReadManyFiles Result (Target Dir: /home/runner/work/llxprt-code/llxprt-code)

Successfully read and concatenated content from 3 file(s) (approximately 657 tokens).

Processed Files:

  • review/diffs/packages__cli__src__auth__BucketFailoverHandlerImpl.ts.diff
  • review/diffs/packages__core__src__config__configTypes.ts.diff
  • review/diffs/packages__core__src__core__StreamProcessor.ts.diff

ReadManyFiles Result (Target Dir: /home/runner/work/llxprt-code/llxprt-code)

Successfully read and concatenated content from 1 file(s) (approximately 556 tokens).

Processed Files:

  • review/diffs/packages__core__src__core__StreamProcessor.unbucketed-auth-failover.test.ts.diff

ReadManyFiles Result (Target Dir: /home/runner/work/llxprt-code/llxprt-code)

Successfully read and concatenated content from 1 file(s) (approximately 358 tokens).

Processed Files:

  • review/diffs/packages__cli__src__ui__hooks__geminiStream__useGeminiStream.ts.diff
    Found 21 matches
    Read lines 460-480 of 928 from packages/core/src/core/StreamProcessor.ts
    Read lines 458-470 of 928 from packages/core/src/core/StreamProcessor.ts
    Read lines 460-495 of 928 from packages/core/src/core/StreamProcessor.ts
    Read lines 55-80 of 670 from packages/cli/src/ui/hooks/geminiStream/useGeminiStream.ts
    Read lines 65-85 of 670 from packages/cli/src/ui/hooks/geminiStream/useGeminiStream.ts
    Listed 7 item(s).

ReadManyFiles Result (Target Dir: /home/runner/work/llxprt-code/llxprt-code)

Successfully read and concatenated content from 2 file(s) (approximately 1,682 tokens).

Processed Files:

  • review/diffs/packages__cli__src__auth____tests____BucketFailoverHandlerImpl.invalidateAuthCache.test.ts.diff
  • review/diffs/packages__cli__src__ui__hooks__geminiStream____tests____useGeminiStream.turnPreparation.test.ts.diff

Todo Progress

5 tasks: 3 completed, 1 in progress, 1 pending

→ Assess issue alignment and side effects ← current

○ Write final verdict to review/verdict.md

Understand PR scope via changed-files.txt and diffstat.txt

Review critical files (StreamProcessor, BucketFailoverHandler)

Examine test coverage in modified test files

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/cli/src/ui/hooks/geminiStream/useGeminiStream.ts (1)

65-83: 🧹 Nitpick | 🔵 Trivial

Add regression coverage for turn-boundary invalidation ordering.

Please add a targeted test that locks the non-continuation sequence (resetinvalidateAuthCacheensureBucketsAuthenticated) so this auth-refresh behavior doesn’t regress.

Based on learnings: issue #1783 identifies useGeminiStream.ts turn-boundary lifecycle triggers as a critical zero-coverage gap.

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

In `@packages/cli/src/ui/hooks/geminiStream/useGeminiStream.ts` around lines 65 -
83, Add a targeted unit/integration test for useGeminiStream that asserts the
non-continuation turn sequence calls happen in order: when isContinuation is
false the handler.reset(), then handler.invalidateAuthCache(runtimeId) (with
sessionId from config.getSessionId or 'default'), and finally
handler.ensureBucketsAuthenticated(); also ensure the continuation branch calls
resetSession() instead of reset(); mock config.getBucketFailoverHandler to
expose spies for reset, invalidateAuthCache, resetSession, and
ensureBucketsAuthenticated and lock/assert call order (e.g., using jest.fn()
call order or a promise chain) to prevent regressions of the reset →
invalidateAuthCache → ensureBucketsAuthenticated sequence.
🤖 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/cli/src/ui/hooks/geminiStream/useGeminiStream.ts`:
- Around line 65-83: Add a targeted unit/integration test for useGeminiStream
that asserts the non-continuation turn sequence calls happen in order: when
isContinuation is false the handler.reset(), then
handler.invalidateAuthCache(runtimeId) (with sessionId from config.getSessionId
or 'default'), and finally handler.ensureBucketsAuthenticated(); also ensure the
continuation branch calls resetSession() instead of reset(); mock
config.getBucketFailoverHandler to expose spies for reset, invalidateAuthCache,
resetSession, and ensureBucketsAuthenticated and lock/assert call order (e.g.,
using jest.fn() call order or a promise chain) to prevent regressions of the
reset → invalidateAuthCache → ensureBucketsAuthenticated sequence.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: f3a14921-dfd2-4004-bc9b-d68821f3ecf4

📥 Commits

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

📒 Files selected for processing (4)
  • packages/cli/src/auth/BucketFailoverHandlerImpl.ts
  • packages/cli/src/ui/hooks/geminiStream/useGeminiStream.ts
  • packages/core/src/config/configTypes.ts
  • packages/core/src/core/StreamProcessor.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 (Linux) - sandbox:none
  • GitHub Check: E2E Test (Linux) - sandbox:docker
  • GitHub Check: E2E Test (macOS)
  • GitHub Check: Lint (Javascript)
🧰 Additional context used
🧠 Learnings (39)
📓 Common learnings
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/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: 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/__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: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/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: 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: 0
File: :0-0
Timestamp: 2026-02-16T18:58:32.519Z
Learning: Issue `#1442`: Codex OAuth randomly fails with default bucket because `isOAuthEnabled()` checks are unreliable. After authentication, `setOAuthEnabledState()` updates in-memory settings but doesn't flush to disk, causing new processes to see OAuth as disabled. This triggers constant re-authentication requests. Subagents are affected 100% of the time because they create OAuthManager without LoadedSettings, so isOAuthEnabled() always returns false.
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: 0
File: :0-0
Timestamp: 2025-12-13T16:04:07.079Z
Learning: Support multi-bucket failover on a single profile: ordered buckets tried in sequence; on 429 or 402 advance to next bucket; on 401 attempt auto-renew then retry once before advancing.
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.
📚 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/config/configTypes.ts
  • packages/cli/src/ui/hooks/geminiStream/useGeminiStream.ts
  • packages/cli/src/auth/BucketFailoverHandlerImpl.ts
  • packages/core/src/core/StreamProcessor.ts
📚 Learning: 2026-03-22T03:20:15.367Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1740
File: packages/core/src/providers/anthropic/AnthropicRateLimitHandler.ts:175-181
Timestamp: 2026-03-22T03:20:15.367Z
Learning: In `packages/core/src/providers/anthropic/AnthropicRateLimitHandler.ts` (vybestack/llxprt-code PR `#1740`), `calculateWaitTime` was refactored in commit 6f62ce987 so that all three buckets (requests, tokens, input tokens) are evaluated before returning. A `shouldWait: true` decision from any bucket takes precedence over warning-only results (where `shouldWait: false` but no reset time is available). The old early-return-on-warning-only pattern was removed. Do not expect or re-introduce the early-exit behavior.

Applied to files:

  • packages/core/src/config/configTypes.ts
  • packages/cli/src/ui/hooks/geminiStream/useGeminiStream.ts
  • packages/cli/src/auth/BucketFailoverHandlerImpl.ts
  • packages/core/src/core/StreamProcessor.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/config/configTypes.ts
  • packages/cli/src/auth/BucketFailoverHandlerImpl.ts
📚 Learning: 2026-03-21T17:15:03.717Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1743
File: packages/core/src/core/TurnProcessor.ts:275-318
Timestamp: 2026-03-21T17:15:03.717Z
Learning: In `packages/core/src/core/TurnProcessor.ts` (vybestack/llxprt-code PR `#1743`), the non-streaming `sendMessage()` path in `_executeSendWithRetry` was improved to pass `params.config?.abortSignal` to `retryWithBackoff` (added in commit 870e85a91, retained). A matching config merge (`params.config` into the provider runtime context) was attempted but reverted in commit 88d894840 because spreading `GenerateContentConfig` into a `Config` class instance loses prototype methods (e.g., `getUserMemory()`), causing TS2339 errors in CI. Do not suggest re-adding the object-spread config merge — the correct approach would require a targeted method that selectively forwards GenerateContentConfig fields without destroying the Config class prototype. The abortSignal improvement is retained and should not be reverted.

Applied to files:

  • packages/core/src/config/configTypes.ts
  • packages/cli/src/ui/hooks/geminiStream/useGeminiStream.ts
  • packages/core/src/core/StreamProcessor.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/config/configTypes.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/config/configTypes.ts
  • packages/cli/src/auth/BucketFailoverHandlerImpl.ts
  • packages/core/src/core/StreamProcessor.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/config/configTypes.ts
  • packages/cli/src/auth/BucketFailoverHandlerImpl.ts
📚 Learning: 2026-02-20T04:32:08.940Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 0
File: :0-0
Timestamp: 2026-02-20T04:32:08.940Z
Learning: In vybestack/llxprt-code, provider retries and OAuth bucket failover are centralized in packages/core/src/providers/RetryOrchestrator.ts. Failover triggers: 2×429, immediate 402, or 2nd 401/403. On success, counters and failover session reset; on switch, attempt-- so retries don’t burn on bucket change.

Applied to files:

  • packages/core/src/config/configTypes.ts
  • packages/cli/src/ui/hooks/geminiStream/useGeminiStream.ts
  • packages/cli/src/auth/BucketFailoverHandlerImpl.ts
  • packages/core/src/core/StreamProcessor.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/config/configTypes.ts
  • packages/cli/src/auth/BucketFailoverHandlerImpl.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/config/configTypes.ts
  • packages/cli/src/ui/hooks/geminiStream/useGeminiStream.ts
  • packages/cli/src/auth/BucketFailoverHandlerImpl.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/config/configTypes.ts
  • packages/cli/src/auth/BucketFailoverHandlerImpl.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/config/configTypes.ts
  • packages/cli/src/ui/hooks/geminiStream/useGeminiStream.ts
  • packages/cli/src/auth/BucketFailoverHandlerImpl.ts
  • packages/core/src/core/StreamProcessor.ts
📚 Learning: 2026-03-21T00:08:34.456Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1741
File: packages/core/src/config/configTypes.ts:293-293
Timestamp: 2026-03-21T00:08:34.456Z
Learning: Do not flag or refactor the inline type pattern like `lsp?: import('../lsp/types.js').LspConfig | boolean` in `packages/core/src/config/configTypes.ts` and `packages/core/src/config/config.ts`. This deliberate inline import is used to represent optional LSP dependency types, and reviewers should avoid suggesting a replacement with a top-level `import type` statement since the optionality signal is intentional.

Applied to files:

  • packages/core/src/config/configTypes.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/config/configTypes.ts
  • packages/cli/src/ui/hooks/geminiStream/useGeminiStream.ts
  • packages/cli/src/auth/BucketFailoverHandlerImpl.ts
  • packages/core/src/core/StreamProcessor.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/cli/src/ui/hooks/geminiStream/useGeminiStream.ts
📚 Learning: 2026-03-26T20:01:50.052Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1780
File: packages/cli/src/ui/hooks/geminiStream/checkpointPersistence.ts:0-0
Timestamp: 2026-03-26T20:01:50.052Z
Learning: In `packages/cli/src/ui/hooks/geminiStream/checkpointPersistence.ts` (vybestack/llxprt-code PR `#1780`), `saveRestorableToolCalls` reserves the `callId` in `checkpointedCallIds` *before* calling `await createToolCheckpoint(...)` to prevent concurrent duplicate attempts. On failure (exception or false/no-write return), the `callId` is deleted from the set so the next effect run can retry. This reserve-before-await, delete-on-failure pattern was introduced in commit a41b97759.

Applied to files:

  • packages/cli/src/ui/hooks/geminiStream/useGeminiStream.ts
📚 Learning: 2026-03-26T21:40:39.044Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1780
File: packages/cli/src/ui/hooks/geminiStream/useStreamEventHandlers.ts:521-525
Timestamp: 2026-03-26T21:40:39.044Z
Learning: In `packages/cli/src/ui/hooks/geminiStream/useStreamEventHandlers.ts` (vybestack/llxprt-code PR `#1780`), `processGeminiStreamEvents` previously always returned `StreamProcessingStatus.Completed` even when a `UserCancelled` or `Error` event was received — this was pre-existing dead code from the original `useGeminiStream.ts` (line 1371 checked for UserCancelled but the function always returned Completed). Fixed in commit 4a28363bc by adding a `processingResult` variable that tracks the status through the event loop, setting it to `StreamProcessingStatus.UserCancelled` or `StreamProcessingStatus.Error` as appropriate, and returning it at the end instead of always returning `Completed`.

Applied to files:

  • packages/cli/src/ui/hooks/geminiStream/useGeminiStream.ts
  • packages/core/src/core/StreamProcessor.ts
📚 Learning: 2026-04-03T20:43:35.912Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1876
File: packages/core/src/core/subagent.ts:441-464
Timestamp: 2026-04-03T20:43:35.912Z
Learning: In `packages/core/src/core/subagent.ts` (vybestack/llxprt-code), `runInteractiveTurn`'s `catch` block should only call `throw createAbortError()` when `abortController.signal.aborted` — it must NOT infer `SubagentTerminateMode.TIMEOUT` based on `!this.parentAbortSignal?.aborted`. `Turn.run()` absorbs idle-timeout events internally and emits `GeminiEventType.UserCancelled` before the generator exits, so the catch only fires for genuine errors or explicit cancel aborts. TIMEOUT is authoritatively set in the `onTimeout` callback of `nextStreamEventWithIdleTimeout` inside `runNonInteractiveTurn`. Do not conflate these two paths in future reviews.

Applied to files:

  • packages/cli/src/ui/hooks/geminiStream/useGeminiStream.ts
📚 Learning: 2026-03-26T20:52:08.720Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1780
File: packages/cli/src/ui/hooks/geminiStream/useStreamEventHandlers.ts:140-149
Timestamp: 2026-03-26T20:52:08.720Z
Learning: In `packages/cli/src/ui/hooks/geminiStream/useStreamEventHandlers.ts` (vybestack/llxprt-code PR `#1780`), the `applyThoughtToState` function's `setPendingHistoryItem` updater casts `item?.type as 'gemini' | 'gemini_content'` and uses `item?.text || ''` — this is intentional pre-existing behavior faithfully extracted verbatim from the original `useGeminiStream.ts` (lines 1110–1111 on main). The risk that a `tool_group` pending item type could be preserved is a known pre-existing pattern; fixing it requires careful testing of all thinking block rendering paths and is a behavioral change beyond decomposition scope. Do not flag this type cast as a bug in decomposition or refactoring PRs.

Applied to files:

  • packages/cli/src/ui/hooks/geminiStream/useGeminiStream.ts
📚 Learning: 2026-03-26T02:22:12.153Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1780
File: packages/cli/src/ui/hooks/geminiStream/checkpointPersistence.ts:145-153
Timestamp: 2026-03-26T02:22:12.153Z
Learning: In `packages/cli/src/ui/hooks/geminiStream/checkpointPersistence.ts` (vybestack/llxprt-code PR `#1780`), `saveRestorableToolCalls` intentionally does NOT deduplicate checkpoint writes by `callId`. Each effect re-run may re-checkpoint the same `awaiting_approval` tool call (producing multiple snapshot files/git snapshots). This is pre-existing behavior faithfully extracted verbatim from the original `useGeminiStream.ts`. Adding per-callId deduplication would be a new feature beyond the decomposition scope. Do not flag the absence of a checkpointed-callId Set as a bug in decomposition or refactoring PRs.

Applied to files:

  • packages/cli/src/ui/hooks/geminiStream/useGeminiStream.ts
📚 Learning: 2026-03-21T15:17:37.899Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1743
File: packages/core/src/core/TurnProcessor.ts:410-421
Timestamp: 2026-03-21T15:17:37.899Z
Learning: In `packages/core/src/core/TurnProcessor.ts` and `packages/core/src/core/compression/CompressionHandler.ts` (vybestack/llxprt-code PR `#1743`), both classes maintain a `lastPromptTokenCount` field. After the decomposition of `geminiChat.ts`, `TurnProcessor._executeProviderCall` must update both `this.lastPromptTokenCount` AND `this.compressionHandler.lastPromptTokenCount` (via `setLastPromptTokenCount`) whenever prompt token counts are received from the non-streaming provider response. The streaming path in `StreamProcessor` already updates `compressionHandler.lastPromptTokenCount` directly. Do not flag the dual-update pattern as redundant — `CompressionHandler.shouldCompress()` reads its own field and will use stale data if only `TurnProcessor.lastPromptTokenCount` is updated. Fixed in commit bac2e4153.

Applied to files:

  • packages/cli/src/ui/hooks/geminiStream/useGeminiStream.ts
📚 Learning: 2026-03-21T17:07:33.700Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1743
File: packages/core/src/core/StreamProcessor.ts:123-135
Timestamp: 2026-03-21T17:07:33.700Z
Learning: In `packages/core/src/core/StreamProcessor.ts` (vybestack/llxprt-code PR `#1743`), the retry boundary in `_executeStreamApiCall` only protects async generator *construction* (via `_buildAndSendStreamRequest`), not the actual network calls that occur during iteration inside `_aggregateStreamChunks`. This is a known pre-existing architectural limitation faithfully preserved from the original `geminiChat.ts`. The issue is tracked as `#1750` for the 0.10.0 improvement effort. Do not re-flag this as a regression or decomposition bug in future reviews — it is intentionally deferred.

Applied to files:

  • packages/cli/src/ui/hooks/geminiStream/useGeminiStream.ts
  • packages/core/src/core/StreamProcessor.ts
📚 Learning: 2026-03-26T02:22:19.732Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1780
File: packages/cli/src/ui/hooks/geminiStream/streamUtils.ts:100-116
Timestamp: 2026-03-26T02:22:19.732Z
Learning: In `packages/cli/src/ui/hooks/geminiStream/streamUtils.ts` (vybestack/llxprt-code PR `#1780`), the `filteredPendingTools` predicate in `mergePendingToolGroupsForDisplay` only removes overlapping shell entries from the scheduler side, leaving overlapping non-shell tool callIds potentially duplicated. This is pre-existing behavior faithfully extracted verbatim from the original `useGeminiStream.ts` (lines 100-140). Do not flag this as a dedup bug in decomposition or refactoring PRs — any improvement to deduplicate non-shell overlapping callIds would be a separate enhancement, not a structural fix.

Applied to files:

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

Applied to files:

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

Applied to files:

  • packages/cli/src/ui/hooks/geminiStream/useGeminiStream.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/cli/src/auth/BucketFailoverHandlerImpl.ts
📚 Learning: 2026-02-18T01:44:54.715Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1459
File: packages/core/src/providers/LoadBalancingProvider.ts:631-648
Timestamp: 2026-02-18T01:44:54.715Z
Learning: Load balancer failover and bucket failover are two separate mechanisms: Load balancer failover (LoadBalancingProvider) distributes requests across different backends/providers and treats 401 as an immediate failover error. Bucket failover (BucketFailoverHandlerImpl) handles credential rotation within a single provider and may implement auto-renew semantics for 401. These systems have different 401 handling behaviors by design.

Applied to files:

  • packages/cli/src/auth/BucketFailoverHandlerImpl.ts
  • packages/core/src/core/StreamProcessor.ts
📚 Learning: 2026-01-13T23:04:39.246Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 0
File: :0-0
Timestamp: 2026-01-13T23:04:39.246Z
Learning: Treat Anthropic 403 permission_error "OAuth token has been revoked" as an expired/auth error: trigger a one-time refresh retry, then bucket failover if refresh fails. Avoid auto-switching providers; only switch buckets within the same provider. This error likely means that we failed to lock when refreshing and multiple instances refreshed the same token.

Applied to files:

  • packages/cli/src/auth/BucketFailoverHandlerImpl.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/BucketFailoverHandlerImpl.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/BucketFailoverHandlerImpl.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/BucketFailoverHandlerImpl.ts
📚 Learning: 2026-03-21T15:50:32.992Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1740
File: packages/core/src/providers/anthropic/AnthropicStreamProcessor.ts:75-192
Timestamp: 2026-03-21T15:50:32.992Z
Learning: In `packages/core/src/providers/anthropic/AnthropicStreamProcessor.ts` (vybestack/llxprt-code PR `#1740`), stream retry after transient errors is guarded by a `hasYieldedContent` flag. If a transient network error occurs mid-stream after text, tool calls, or thinking blocks have been yielded, the generator throws immediately instead of retrying (to avoid duplicate/corrupted output), delegating recovery to the upper-layer RetryOrchestrator. Metadata-only yields (usage from `message_start`) do NOT set this flag, so retries before any real content are still allowed. Fixed in commit e5aa5043.

Applied to files:

  • packages/core/src/core/StreamProcessor.ts
📚 Learning: 2026-03-21T15:18:51.729Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1743
File: packages/core/src/core/StreamProcessor.ts:123-135
Timestamp: 2026-03-21T15:18:51.729Z
Learning: In `packages/core/src/core/StreamProcessor.ts` and original `packages/core/src/core/geminiChat.ts` (vybestack/llxprt-code PR `#1743`), the streaming path (`makeApiCallAndProcessStream` / `sendMessageStream`) intentionally does NOT call `_enrichSchemaDepthError` (formerly `maybeIncludeSchemaDepthContext`). In the original `geminiChat.ts`, `maybeIncludeSchemaDepthContext` was only called at approximately line 1106 inside the `sendMessage()` catch block. The `StreamProcessor._enrichSchemaDepthError` method exists for potential future use but was never wired in the streaming path. Do not flag this omission as a bug in future reviews — it faithfully preserves the original behavior.

Applied to files:

  • packages/core/src/core/StreamProcessor.ts
📚 Learning: 2026-03-21T17:57:02.742Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1740
File: packages/core/src/providers/anthropic/AnthropicStreamProcessor.ts:0-0
Timestamp: 2026-03-21T17:57:02.742Z
Learning: In `packages/core/src/providers/anthropic/AnthropicStreamProcessor.ts` (vybestack/llxprt-code PR `#1740`), the guard `chunk.type === 'message_delta' && chunk.usage` (around line 149) is intentional pre-existing behavior faithfully extracted verbatim from the original `AnthropicProvider.ts`. `message_delta` events without a `usage` field are intentionally skipped. Do not flag the `&& chunk.usage` condition as a bug or suggest removing it in decomposition reviews — any change to process usage-less `message_delta` events would be a behavioral modification beyond the decomposition scope.

Applied to files:

  • packages/core/src/core/StreamProcessor.ts
📚 Learning: 2026-02-15T21:44:56.598Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1407
File: packages/core/src/core/geminiChatHookTriggers.ts:56-65
Timestamp: 2026-02-15T21:44:56.598Z
Learning: Enforce the canonical speaker-to-role mapping used by GeminiChat hooks: in IContent.speaker, which is strictly typed as 'human | ai | tool' (no 'system'), map 'human' to the 'user' role, 'ai' to the 'model' role, and 'tool' to the 'user' role in all hook payloads. This pattern should be applied across related hook files within packages/core/src/core/ (not just the single file) to ensure consistent role assignment.

Applied to files:

  • packages/core/src/core/StreamProcessor.ts
📚 Learning: 2026-02-16T19:18:56.265Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1436
File: packages/core/src/core/nonInteractiveToolExecutor.ts:0-0
Timestamp: 2026-02-16T19:18:56.265Z
Learning: Guideline: In the core scheduler architecture, the system runs in a single mode at a time—either interactive or non-interactive, never both on the same scheduler instance. Non-interactive (CLI one-shot) runs without any interactive session; interactive mode subagents run within the parent's interactive context and inherit its mode. When reviewing code, ensure non-interactive tool executions (e.g., in nonInteractiveToolExecutor.ts) create and use a fresh completionResolver per executeToolCall, and that there is no race with interactive sessions since they cannot coexist on the same scheduler instance. This pattern applies across files in packages/core/src/core/. Only apply to relevant files, not globally.

Applied to files:

  • packages/core/src/core/StreamProcessor.ts
📚 Learning: 2026-03-21T17:07:10.889Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1743
File: packages/core/src/core/ConversationManager.ts:94-101
Timestamp: 2026-03-21T17:07:10.889Z
Learning: In these core processor modules, ensure `makePositionMatcher()` is created once and reused across the entire batch (i.e., hoist it outside any per-`content` loops) rather than rebuilding it for each content item. Also ensure the `unmatched-tool` queue is consumed in-order across all batch items (not reset/handled independently per item), since that preserves correct batch-wide behavior.

Applied to files:

  • packages/core/src/core/StreamProcessor.ts
📚 Learning: 2026-03-22T04:06:53.600Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1743
File: packages/core/src/core/TurnProcessor.ts:391-402
Timestamp: 2026-03-22T04:06:53.600Z
Learning: When computing `lastPromptTokenCount` (e.g., in the streaming path like `_convertIContentStream`/equivalent), ensure it includes the full prompt token footprint: `lastPromptTokenCount = promptTokens + cache_read_input_tokens + cache_creation_input_tokens`. Do not use `promptTokens` alone, because cached context would otherwise cause `CompressionHandler.shouldCompress()` to underestimate context usage and may incorrectly suppress needed compression. Keep this combined computation consistent with the non-streaming path (e.g., `TurnProcessor._executeProviderCall`), and do not treat the presence of cache-token additions as redundant—both token types are required for correctness when cached context is active.

Applied to files:

  • packages/core/src/core/StreamProcessor.ts
🔇 Additional comments (4)
packages/core/src/config/configTypes.ts (1)

330-334: Backward-compatible interface extension looks correct.

Adding invalidateAuthCache as an optional method is the right shape for incremental adoption across handler implementations.

packages/cli/src/auth/BucketFailoverHandlerImpl.ts (1)

667-670: invalidateAuthCache implementation is clean and focused.

This correctly delegates to runtime-scope auth cache flushing and keeps observability with a debug log.

packages/core/src/core/StreamProcessor.ts (1)

463-463: Failover guard simplification is correct for single-bucket support.

Proceeding when a handler exists (instead of checking isEnabled()) aligns with the intended unbucketed-profile recovery behavior.

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

75-76: No action required.

The call to invalidateAuthCache correctly uses getSessionId() as the runtimeId parameter. This identifier aligns with how the main runtime is keyed when created—resolveRuntimeId(config) defaults to config.getSessionId() when no explicit runtimeId override is provided. The flushRuntimeAuthScope(runtimeId) function looks up the runtime's auth scope using this same key, so there is no mismatch or silent no-op risk.

Adds regression coverage for BucketFailoverHandlerImpl.invalidateAuthCache and single-bucket StreamProcessor failover handling for issue #1739.
@acoliver
Copy link
Copy Markdown
Collaborator Author

acoliver commented Apr 9, 2026

Addressed the missing automated coverage noted in review.

What I added:

  • packages/cli/src/auth/tests/BucketFailoverHandlerImpl.invalidateAuthCache.test.ts
    • Verifies invalidateAuthCache() flushes the runtime auth scope for the unbucketed path.
  • packages/core/src/core/StreamProcessor.unbucketed-auth-failover.test.ts
    • Verifies single-bucket handlers still execute tryFailover() and flush auth scope, even when isEnabled() would be false.

Targeted verification run:

  • cd packages/cli && npx vitest run src/auth/tests/BucketFailoverHandlerImpl.invalidateAuthCache.test.ts
  • cd packages/core && npx vitest run src/core/StreamProcessor.unbucketed-auth-failover.test.ts

Both targeted regression tests pass.

Exports prepareTurnForQuery for direct unit coverage and adds regression tests for new-turn and continuation ordering in issue #1739.
@acoliver
Copy link
Copy Markdown
Collaborator Author

acoliver commented Apr 9, 2026

Addressed the remaining turn-boundary ordering review comment.

What I changed:

  • Exported prepareTurnForQuery for direct unit coverage.
  • Added packages/cli/src/ui/hooks/geminiStream/tests/useGeminiStream.turnPreparation.test.ts
    • Verifies the non-continuation branch calls happen in order:
      reset -> invalidateAuthCache(runtimeId) -> ensureBucketsAuthenticated
    • Verifies the continuation branch uses resetSession() instead of reset().
    • Verifies runtimeId falls back correctly when needed.

Targeted verification run:

  • cd packages/cli && npx vitest run src/ui/hooks/geminiStream/tests/useGeminiStream.turnPreparation.test.ts

The new targeted regression tests pass.

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/cli/src/auth/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.test.ts`:
- Around line 26-33: The oauthManager mock for the
BucketFailoverOAuthManagerLike interface is missing the required
forceRefreshToken method causing TS2741; update the oauthManager object to
include a forceRefreshToken property mocked with vi.fn() (matching how other
tests like auth-flow-orchestrator.spec.ts and token-access-coordinator.spec.ts
implement it) so the mock satisfies the interface contract and compiles.

In
`@packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.ts`:
- Around line 59-99: The test labeled as covering the default runtime-id
actually calls prepareTurnForQuery with isContinuation = true so the default
fallback path (and invalidateAuthCache behavior) is not exercised; add a new
test that calls prepareTurnForQuery with isContinuation = false (or duplicate
the existing test but set the first arg to false) and assert that
handler.invalidateAuthCache is called with the expected default runtime id and
that the call order reflects invalidate before ensure/reset as appropriate;
reference prepareTurnForQuery and handler.invalidateAuthCache to locate where to
change/add the test and mirror the existing test setup (startNewPrompt,
setThought, thinkingBlocksRef) while adjusting expectations for
invalidateAuthCache and any related handler.reset/startNewPrompt calls.
🪄 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: c376d375-a28d-4a2e-a61e-3dac57cdd742

📥 Commits

Reviewing files that changed from the base of the PR and between fd18be5 and db458f1.

📒 Files selected for processing (4)
  • packages/cli/src/auth/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.test.ts
  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.ts
  • packages/cli/src/ui/hooks/geminiStream/useGeminiStream.ts
  • packages/core/src/core/StreamProcessor.unbucketed-auth-failover.test.ts
📜 Review details
🧰 Additional context used
🧠 Learnings (45)
📓 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: 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: 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.
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/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: 1743
File: packages/core/src/core/TurnProcessor.ts:275-318
Timestamp: 2026-03-21T17:15:03.717Z
Learning: In `packages/core/src/core/TurnProcessor.ts` (vybestack/llxprt-code PR `#1743`), the non-streaming `sendMessage()` path in `_executeSendWithRetry` was improved to pass `params.config?.abortSignal` to `retryWithBackoff` (added in commit 870e85a91, retained). A matching config merge (`params.config` into the provider runtime context) was attempted but reverted in commit 88d894840 because spreading `GenerateContentConfig` into a `Config` class instance loses prototype methods (e.g., `getUserMemory()`), causing TS2339 errors in CI. Do not suggest re-adding the object-spread config merge — the correct approach would require a targeted method that selectively forwards GenerateContentConfig fields without destroying the Config class prototype. The abortSignal improvement is retained and should not be reverted.
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: 1459
File: packages/core/src/providers/LoadBalancingProvider.ts:631-648
Timestamp: 2026-02-18T01:44:54.715Z
Learning: Load balancer failover and bucket failover are two separate mechanisms: Load balancer failover (LoadBalancingProvider) distributes requests across different backends/providers and treats 401 as an immediate failover error. Bucket failover (BucketFailoverHandlerImpl) handles credential rotation within a single provider and may implement auto-renew semantics for 401. These systems have different 401 handling behaviors by design.
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 0
File: :0-0
Timestamp: 2025-12-13T16:04:07.079Z
Learning: Support multi-bucket failover on a single profile: ordered buckets tried in sequence; on 429 or 402 advance to next bucket; on 401 attempt auto-renew then retry once before advancing.
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 0
File: :0-0
Timestamp: 2026-02-20T04:32:08.940Z
Learning: In vybestack/llxprt-code, provider retries and OAuth bucket failover are centralized in packages/core/src/providers/RetryOrchestrator.ts. Failover triggers: 2×429, immediate 402, or 2nd 401/403. On success, counters and failover session reset; on switch, attempt-- so retries don’t burn on bucket change.
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 0
File: :0-0
Timestamp: 2026-01-13T23:04:39.246Z
Learning: Treat Anthropic 403 permission_error "OAuth token has been revoked" as an expired/auth error: trigger a one-time refresh retry, then bucket failover if refresh fails. Avoid auto-switching providers; only switch buckets within the same provider. This error likely means that we failed to lock when refreshing and multiple instances refreshed the same token.
📚 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/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.test.ts
  • packages/core/src/core/StreamProcessor.unbucketed-auth-failover.test.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/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.test.ts
  • packages/core/src/core/StreamProcessor.unbucketed-auth-failover.test.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/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.test.ts
  • packages/core/src/core/StreamProcessor.unbucketed-auth-failover.test.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/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.test.ts
  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.ts
  • packages/core/src/core/StreamProcessor.unbucketed-auth-failover.test.ts
  • packages/cli/src/ui/hooks/geminiStream/useGeminiStream.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/cli/src/auth/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.test.ts
  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.ts
  • packages/core/src/core/StreamProcessor.unbucketed-auth-failover.test.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/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.test.ts
  • packages/core/src/core/StreamProcessor.unbucketed-auth-failover.test.ts
  • packages/cli/src/ui/hooks/geminiStream/useGeminiStream.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/cli/src/auth/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.test.ts
  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.ts
  • packages/core/src/core/StreamProcessor.unbucketed-auth-failover.test.ts
  • packages/cli/src/ui/hooks/geminiStream/useGeminiStream.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/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.test.ts
  • packages/core/src/core/StreamProcessor.unbucketed-auth-failover.test.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/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.test.ts
  • packages/core/src/core/StreamProcessor.unbucketed-auth-failover.test.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/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.test.ts
  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.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/cli/src/auth/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.test.ts
  • packages/core/src/core/StreamProcessor.unbucketed-auth-failover.test.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/cli/src/auth/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.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/cli/src/auth/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.test.ts
  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.ts
  • packages/core/src/core/StreamProcessor.unbucketed-auth-failover.test.ts
  • packages/cli/src/ui/hooks/geminiStream/useGeminiStream.ts
📚 Learning: 2026-03-26T00:49:43.150Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1778
File: packages/cli/src/auth/__tests__/auth-flow-orchestrator.spec.ts:309-324
Timestamp: 2026-03-26T00:49:43.150Z
Learning: In this repository’s Jest (or Jest-like) test files, it is acceptable to use `expect(promiseReturningFunction).resolves.not.toThrow()` when the function returns `Promise<void>`. Do not flag this as an incorrect or suboptimal matcher; for `Promise<void>` it is functionally equivalent to using `resolves.toBeUndefined()` to assert successful resolution.

Applied to files:

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

Applied to files:

  • packages/cli/src/auth/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.test.ts
  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.ts
  • packages/core/src/core/StreamProcessor.unbucketed-auth-failover.test.ts
  • packages/cli/src/ui/hooks/geminiStream/useGeminiStream.ts
📚 Learning: 2026-03-26T20:52:08.720Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1780
File: packages/cli/src/ui/hooks/geminiStream/useStreamEventHandlers.ts:140-149
Timestamp: 2026-03-26T20:52:08.720Z
Learning: In `packages/cli/src/ui/hooks/geminiStream/useStreamEventHandlers.ts` (vybestack/llxprt-code PR `#1780`), the `applyThoughtToState` function's `setPendingHistoryItem` updater casts `item?.type as 'gemini' | 'gemini_content'` and uses `item?.text || ''` — this is intentional pre-existing behavior faithfully extracted verbatim from the original `useGeminiStream.ts` (lines 1110–1111 on main). The risk that a `tool_group` pending item type could be preserved is a known pre-existing pattern; fixing it requires careful testing of all thinking block rendering paths and is a behavioral change beyond decomposition scope. Do not flag this type cast as a bug in decomposition or refactoring PRs.

Applied to files:

  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.ts
  • packages/cli/src/ui/hooks/geminiStream/useGeminiStream.ts
📚 Learning: 2026-03-27T00:46:42.630Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1785
File: packages/cli/src/config/__tests__/parseArgumentsParity.test.ts:7-16
Timestamp: 2026-03-27T00:46:42.630Z
Learning: In `packages/cli/src/config/__tests__/parseArgumentsParity.test.ts` (vybestack/llxprt-code PR `#1785`), the test suite is intentionally scoped to verifying that the extracted `parseArguments` function produces identical output to the original inline parsing. It deliberately does NOT cover subcommand exit behavior (mcp, hooks, extensions) via `handleSubcommandExit()` — that function is a direct mechanical extraction and adding integration tests for it would be new coverage beyond the refactoring scope. Do not flag the absence of subcommand-exit test cases as a gap in this file or in refactoring PRs that extract it.

Applied to files:

  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.ts
📚 Learning: 2026-03-26T21:40:39.044Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1780
File: packages/cli/src/ui/hooks/geminiStream/useStreamEventHandlers.ts:521-525
Timestamp: 2026-03-26T21:40:39.044Z
Learning: In `packages/cli/src/ui/hooks/geminiStream/useStreamEventHandlers.ts` (vybestack/llxprt-code PR `#1780`), `processGeminiStreamEvents` previously always returned `StreamProcessingStatus.Completed` even when a `UserCancelled` or `Error` event was received — this was pre-existing dead code from the original `useGeminiStream.ts` (line 1371 checked for UserCancelled but the function always returned Completed). Fixed in commit 4a28363bc by adding a `processingResult` variable that tracks the status through the event loop, setting it to `StreamProcessingStatus.UserCancelled` or `StreamProcessingStatus.Error` as appropriate, and returning it at the end instead of always returning `Completed`.

Applied to files:

  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.ts
  • packages/cli/src/ui/hooks/geminiStream/useGeminiStream.ts
📚 Learning: 2026-02-15T19:33:03.569Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1405
File: packages/core/src/lsp/__tests__/lsp-service-client-integration.test.ts:93-102
Timestamp: 2026-02-15T19:33:03.569Z
Learning: In the llxprt-code codebase (`packages/core/src/lsp/__tests__/lsp-service-client-integration.test.ts`), the LspServiceClient integration tests use a synthetic/stub implementation with PassThrough streams for testing. The test config may include fields like `filetypes` that differ from production types (`LspServerConfig`), as these tests verify the integration contract rather than exact production type conformance. Future work may add more realistic subprocess tests.

Applied to files:

  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.ts
📚 Learning: 2026-03-27T00:46:42.685Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1785
File: packages/cli/src/config/__tests__/parseArgumentsParity.test.ts:7-16
Timestamp: 2026-03-27T00:46:42.685Z
Learning: In `packages/cli/src/config/__tests__/parseArgumentsParity.test.ts` (vybestack/llxprt-code PR `#1785`), the test suite intentionally does NOT cover subcommand exit behavior (`mcp`, `hooks`, `extensions` via `handleSubcommandExit()`). The suite's scope is limited to verifying that the extracted `parseArguments` function produces identical results to the original inline parsing. `handleSubcommandExit()` is a direct mechanical extraction and adding integration tests for it would be new coverage beyond the refactor's scope. Do not flag missing subcommand-exit test cases in this file as a gap in future reviews.

Applied to files:

  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.ts
📚 Learning: 2026-03-26T02:06:03.086Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1779
File: packages/core/src/core/subagentChatSetup.ts:339-453
Timestamp: 2026-03-26T02:06:03.086Z
Learning: In `packages/core/src/core/subagentChatSetup.ts` (vybestack/llxprt-code PR `#1779`, decomposed from `subagent.ts`), the `assembleChatSession` function's `try/catch` block wraps only `new GeminiChat(...)` and not the preceding `await ctx.environmentContextLoader(...)` or `await getCoreSystemPromptAsync(...)` calls. This partial error boundary is pre-existing behavior faithfully preserved from the original `createChatObject` method in `subagent.ts`. Do not flag the missing async-await coverage as a decomposition regression in future reviews — it is an acknowledged pre-existing limitation, and any fix would be a behavioral change requiring a dedicated follow-up PR.

Applied to files:

  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.ts
  • packages/cli/src/ui/hooks/geminiStream/useGeminiStream.ts
📚 Learning: 2026-03-25T19:21:43.266Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1771
File: packages/core/src/core/AgentHookManager.ts:78-96
Timestamp: 2026-03-25T19:21:43.266Z
Learning: In `packages/core/src/core/AgentHookManager.ts` (vybestack/llxprt-code PR `#1771`), `cleanupOldHookState(newPromptId, oldPromptId)` is always called at the start of a new prompt turn (when `prompt_id` changes), after the previous prompt's stream has been fully consumed by `MessageStreamOrchestrator`. Because JS is single-threaded, there is no concurrent execution path where an in-flight `fireAfterAgentHookSafe` for the old `prompt_id` could race with the cleanup. Do not flag this pattern as a race condition in future reviews — the sequential flow guarantees: previous prompt finishes → new prompt starts → cleanup runs → fresh hook state created.

Applied to files:

  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.ts
  • packages/cli/src/ui/hooks/geminiStream/useGeminiStream.ts
📚 Learning: 2026-04-03T20:43:35.912Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1876
File: packages/core/src/core/subagent.ts:441-464
Timestamp: 2026-04-03T20:43:35.912Z
Learning: In `packages/core/src/core/subagent.ts` (vybestack/llxprt-code), `runInteractiveTurn`'s `catch` block should only call `throw createAbortError()` when `abortController.signal.aborted` — it must NOT infer `SubagentTerminateMode.TIMEOUT` based on `!this.parentAbortSignal?.aborted`. `Turn.run()` absorbs idle-timeout events internally and emits `GeminiEventType.UserCancelled` before the generator exits, so the catch only fires for genuine errors or explicit cancel aborts. TIMEOUT is authoritatively set in the `onTimeout` callback of `nextStreamEventWithIdleTimeout` inside `runNonInteractiveTurn`. Do not conflate these two paths in future reviews.

Applied to files:

  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.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/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.ts
📚 Learning: 2026-03-25T18:17:38.768Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1768
File: packages/cli/src/ui/containers/AppContainer/hooks/useInputHandling.ts:127-135
Timestamp: 2026-03-25T18:17:38.768Z
Learning: In `packages/cli/src/ui/containers/AppContainer/hooks/useInputHandling.ts` (vybestack/llxprt-code PR `#1768`), the `hadToolCallsRef.current = false` reset inside `handleFinalSubmit` (before calling `submitQuery`) is intentional behavior preserved from the original `AppContainer.tsx` continuation flow contract. Do not flag this as a premature reset or race condition in decomposition or future PRs — any turn-boundary redesign (e.g., only clearing after `handleStreamCompleted`) is out of scope for the `#1576` refactoring and would constitute a behavioral change.

Applied to files:

  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.ts
📚 Learning: 2026-04-03T20:43:54.493Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1876
File: packages/core/src/core/subagent.ts:675-710
Timestamp: 2026-04-03T20:43:54.493Z
Learning: In `packages/core/src/core/subagent.ts` (vybestack/llxprt-code PR `#1876`), `runNonInteractiveTurn` intentionally returns `{ functionCalls: [], textResponse: '' }` (instead of throwing) when `abortController.signal.aborted` is detected — both in the pre-loop early-abort check and inside the stream iteration loop. This is the correct design because: (1) `armTimeout` sets `output.terminate_reason = SubagentTerminateMode.TIMEOUT` *before* aborting, so abort-reason state is already recorded; (2) the caller in `runNonInteractive` checks `if (abortController.signal.aborted) return;` immediately after the call, resolving `runNonInteractive` as a normal `Promise<void>` (not a rejection); (3) existing TIMEOUT tests assert this resolution behavior and would break if `createAbortError()` were thrown instead. Do not flag the return-empty-on-abort pattern as dropping `finalizeOutput` or treating abort as success — it is intentional and test-validated.

Applied to files:

  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.ts
📚 Learning: 2026-03-26T20:01:50.052Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1780
File: packages/cli/src/ui/hooks/geminiStream/checkpointPersistence.ts:0-0
Timestamp: 2026-03-26T20:01:50.052Z
Learning: In `packages/cli/src/ui/hooks/geminiStream/checkpointPersistence.ts` (vybestack/llxprt-code PR `#1780`), `saveRestorableToolCalls` reserves the `callId` in `checkpointedCallIds` *before* calling `await createToolCheckpoint(...)` to prevent concurrent duplicate attempts. On failure (exception or false/no-write return), the `callId` is deleted from the set so the next effect run can retry. This reserve-before-await, delete-on-failure pattern was introduced in commit a41b97759.

Applied to files:

  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.ts
  • packages/cli/src/ui/hooks/geminiStream/useGeminiStream.ts
📚 Learning: 2026-03-21T17:15:03.717Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1743
File: packages/core/src/core/TurnProcessor.ts:275-318
Timestamp: 2026-03-21T17:15:03.717Z
Learning: In `packages/core/src/core/TurnProcessor.ts` (vybestack/llxprt-code PR `#1743`), the non-streaming `sendMessage()` path in `_executeSendWithRetry` was improved to pass `params.config?.abortSignal` to `retryWithBackoff` (added in commit 870e85a91, retained). A matching config merge (`params.config` into the provider runtime context) was attempted but reverted in commit 88d894840 because spreading `GenerateContentConfig` into a `Config` class instance loses prototype methods (e.g., `getUserMemory()`), causing TS2339 errors in CI. Do not suggest re-adding the object-spread config merge — the correct approach would require a targeted method that selectively forwards GenerateContentConfig fields without destroying the Config class prototype. The abortSignal improvement is retained and should not be reverted.

Applied to files:

  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.ts
  • packages/cli/src/ui/hooks/geminiStream/useGeminiStream.ts
📚 Learning: 2026-03-21T17:07:15.661Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1743
File: packages/core/src/core/ConversationManager.ts:94-101
Timestamp: 2026-03-21T17:07:15.661Z
Learning: In `packages/core/src/core/ConversationManager.ts`, `packages/core/src/core/TurnProcessor.ts`, `packages/core/src/core/StreamProcessor.ts`, and `packages/core/src/core/DirectMessageProcessor.ts` (vybestack/llxprt-code PR `#1743`, commit 870e85a91), `makePositionMatcher()` was hoisted outside all per-Content loops so that a single position matcher is shared across the entire batch. This supersedes the prior preserved-behavior pattern (original `geminiChat.ts` called it per-Content). The unmatched-tool queue is now consumed in order across all items in a batch, which is the correct behavior.

Applied to files:

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

Applied to files:

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

Applied to files:

  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.ts
  • packages/cli/src/ui/hooks/geminiStream/useGeminiStream.ts
📚 Learning: 2026-03-21T17:07:33.700Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1743
File: packages/core/src/core/StreamProcessor.ts:123-135
Timestamp: 2026-03-21T17:07:33.700Z
Learning: In `packages/core/src/core/StreamProcessor.ts` (vybestack/llxprt-code PR `#1743`), the retry boundary in `_executeStreamApiCall` only protects async generator *construction* (via `_buildAndSendStreamRequest`), not the actual network calls that occur during iteration inside `_aggregateStreamChunks`. This is a known pre-existing architectural limitation faithfully preserved from the original `geminiChat.ts`. The issue is tracked as `#1750` for the 0.10.0 improvement effort. Do not re-flag this as a regression or decomposition bug in future reviews — it is intentionally deferred.

Applied to files:

  • packages/core/src/core/StreamProcessor.unbucketed-auth-failover.test.ts
📚 Learning: 2026-03-21T15:50:32.992Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1740
File: packages/core/src/providers/anthropic/AnthropicStreamProcessor.ts:75-192
Timestamp: 2026-03-21T15:50:32.992Z
Learning: In `packages/core/src/providers/anthropic/AnthropicStreamProcessor.ts` (vybestack/llxprt-code PR `#1740`), stream retry after transient errors is guarded by a `hasYieldedContent` flag. If a transient network error occurs mid-stream after text, tool calls, or thinking blocks have been yielded, the generator throws immediately instead of retrying (to avoid duplicate/corrupted output), delegating recovery to the upper-layer RetryOrchestrator. Metadata-only yields (usage from `message_start`) do NOT set this flag, so retries before any real content are still allowed. Fixed in commit e5aa5043.

Applied to files:

  • packages/core/src/core/StreamProcessor.unbucketed-auth-failover.test.ts
📚 Learning: 2026-02-20T04:32:08.940Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 0
File: :0-0
Timestamp: 2026-02-20T04:32:08.940Z
Learning: In vybestack/llxprt-code, provider retries and OAuth bucket failover are centralized in packages/core/src/providers/RetryOrchestrator.ts. Failover triggers: 2×429, immediate 402, or 2nd 401/403. On success, counters and failover session reset; on switch, attempt-- so retries don’t burn on bucket change.

Applied to files:

  • packages/core/src/core/StreamProcessor.unbucketed-auth-failover.test.ts
  • packages/cli/src/ui/hooks/geminiStream/useGeminiStream.ts
📚 Learning: 2026-02-15T21:44:56.598Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1407
File: packages/core/src/core/geminiChatHookTriggers.ts:56-65
Timestamp: 2026-02-15T21:44:56.598Z
Learning: Enforce the canonical speaker-to-role mapping used by GeminiChat hooks: in IContent.speaker, which is strictly typed as 'human | ai | tool' (no 'system'), map 'human' to the 'user' role, 'ai' to the 'model' role, and 'tool' to the 'user' role in all hook payloads. This pattern should be applied across related hook files within packages/core/src/core/ (not just the single file) to ensure consistent role assignment.

Applied to files:

  • packages/core/src/core/StreamProcessor.unbucketed-auth-failover.test.ts
📚 Learning: 2026-02-16T19:18:56.265Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1436
File: packages/core/src/core/nonInteractiveToolExecutor.ts:0-0
Timestamp: 2026-02-16T19:18:56.265Z
Learning: Guideline: In the core scheduler architecture, the system runs in a single mode at a time—either interactive or non-interactive, never both on the same scheduler instance. Non-interactive (CLI one-shot) runs without any interactive session; interactive mode subagents run within the parent's interactive context and inherit its mode. When reviewing code, ensure non-interactive tool executions (e.g., in nonInteractiveToolExecutor.ts) create and use a fresh completionResolver per executeToolCall, and that there is no race with interactive sessions since they cannot coexist on the same scheduler instance. This pattern applies across files in packages/core/src/core/. Only apply to relevant files, not globally.

Applied to files:

  • packages/core/src/core/StreamProcessor.unbucketed-auth-failover.test.ts
📚 Learning: 2026-03-22T04:06:53.600Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1743
File: packages/core/src/core/TurnProcessor.ts:391-402
Timestamp: 2026-03-22T04:06:53.600Z
Learning: When computing `lastPromptTokenCount` (e.g., in the streaming path like `_convertIContentStream`/equivalent), ensure it includes the full prompt token footprint: `lastPromptTokenCount = promptTokens + cache_read_input_tokens + cache_creation_input_tokens`. Do not use `promptTokens` alone, because cached context would otherwise cause `CompressionHandler.shouldCompress()` to underestimate context usage and may incorrectly suppress needed compression. Keep this combined computation consistent with the non-streaming path (e.g., `TurnProcessor._executeProviderCall`), and do not treat the presence of cache-token additions as redundant—both token types are required for correctness when cached context is active.

Applied to files:

  • packages/core/src/core/StreamProcessor.unbucketed-auth-failover.test.ts
📚 Learning: 2026-03-21T15:17:37.899Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1743
File: packages/core/src/core/TurnProcessor.ts:410-421
Timestamp: 2026-03-21T15:17:37.899Z
Learning: In `packages/core/src/core/TurnProcessor.ts` and `packages/core/src/core/compression/CompressionHandler.ts` (vybestack/llxprt-code PR `#1743`), both classes maintain a `lastPromptTokenCount` field. After the decomposition of `geminiChat.ts`, `TurnProcessor._executeProviderCall` must update both `this.lastPromptTokenCount` AND `this.compressionHandler.lastPromptTokenCount` (via `setLastPromptTokenCount`) whenever prompt token counts are received from the non-streaming provider response. The streaming path in `StreamProcessor` already updates `compressionHandler.lastPromptTokenCount` directly. Do not flag the dual-update pattern as redundant — `CompressionHandler.shouldCompress()` reads its own field and will use stale data if only `TurnProcessor.lastPromptTokenCount` is updated. Fixed in commit bac2e4153.

Applied to files:

  • packages/cli/src/ui/hooks/geminiStream/useGeminiStream.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/cli/src/ui/hooks/geminiStream/useGeminiStream.ts
📚 Learning: 2026-03-26T02:22:19.732Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1780
File: packages/cli/src/ui/hooks/geminiStream/streamUtils.ts:100-116
Timestamp: 2026-03-26T02:22:19.732Z
Learning: In `packages/cli/src/ui/hooks/geminiStream/streamUtils.ts` (vybestack/llxprt-code PR `#1780`), the `filteredPendingTools` predicate in `mergePendingToolGroupsForDisplay` only removes overlapping shell entries from the scheduler side, leaving overlapping non-shell tool callIds potentially duplicated. This is pre-existing behavior faithfully extracted verbatim from the original `useGeminiStream.ts` (lines 100-140). Do not flag this as a dedup bug in decomposition or refactoring PRs — any improvement to deduplicate non-shell overlapping callIds would be a separate enhancement, not a structural fix.

Applied to files:

  • packages/cli/src/ui/hooks/geminiStream/useGeminiStream.ts
📚 Learning: 2026-03-22T03:20:15.367Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1740
File: packages/core/src/providers/anthropic/AnthropicRateLimitHandler.ts:175-181
Timestamp: 2026-03-22T03:20:15.367Z
Learning: In `packages/core/src/providers/anthropic/AnthropicRateLimitHandler.ts` (vybestack/llxprt-code PR `#1740`), `calculateWaitTime` was refactored in commit 6f62ce987 so that all three buckets (requests, tokens, input tokens) are evaluated before returning. A `shouldWait: true` decision from any bucket takes precedence over warning-only results (where `shouldWait: false` but no reset time is available). The old early-return-on-warning-only pattern was removed. Do not expect or re-introduce the early-exit behavior.

Applied to files:

  • packages/cli/src/ui/hooks/geminiStream/useGeminiStream.ts
🪛 GitHub Actions: LLxprt Code CI
packages/cli/src/auth/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.test.ts

[error] 26-26: TypeScript build failed (TS2741): Property 'forceRefreshToken' is missing in type '{ getSessionBucket: Mock; setSessionBucket: Mock; getTokenStore: Mock; getOAuthToken: Mock; authenticate: Mock<...>; authenticateMultipleBuckets: Mock<...>; }' but required in type 'BucketFailoverOAuthManagerLike'.

🔇 Additional comments (3)
packages/core/src/core/StreamProcessor.unbucketed-auth-failover.test.ts (1)

27-63: Good targeted regression coverage for the unbucketed failover path

This test correctly guards the intended behavior change: single-bucket handlers still execute tryFailover() and auth scope invalidation even when isEnabled() is false.

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

58-83: Turn-boundary invalidation ordering looks correct

The new-turn path performs cache invalidation before ensureBucketsAuthenticated, and the continuation path remains isolated to resetSession as intended.

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

12-57: Strong order assertion for the non-continuation path

This test gives good protection for the required sequencing (resetinvalidateAuthCache(runtimeId)ensureBucketsAuthenticated) and state resets.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 9, 2026

Code Coverage Summary

Package Lines Statements Functions Branches
CLI 58.29% 58.29% 66.74% 80.13%
Core 78.18% 78.18% 78.14% 81.52%
CLI Package - Full Text Report
-------------------|---------|----------|---------|---------|-------------------
File               | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-------------------|---------|----------|---------|---------|-------------------
All files          |   58.29 |    80.13 |   66.74 |   58.29 |                   
 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          |   79.21 |    88.77 |   87.31 |   79.21 |                   
  ...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 |   52.46 |       70 |   68.75 |   52.46 | ...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.63 |    83.85 |   73.68 |   62.63 |                   
  ...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.42 |    88.77 |     100 |   94.42 | ...19,342,388-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.18 |    81.52 |   78.14 |   78.18 |                   
 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.26 |    81.34 |   79.81 |   68.26 |                   
  ...evice-flow.ts |    7.21 |        0 |       0 |    7.21 | ...49-268,274-282 
  ...evice-flow.ts |   46.65 |    57.14 |   63.63 |   46.65 | ...95-484,494-580 
  ...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 |    80.07 |   94.73 |      78 | ...1072,1078-1081 
  ...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.31 |    84.74 |   88.04 |   84.31 |                   
  ...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         |   70.61 |    87.17 |   88.88 |   70.61 | ...70-371,388-389 
 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.79 |     100 |   99.19 |                   
  EmojiFilter.ts   |   99.19 |    98.79 |     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.64 |   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.4 |     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 |    81.39 |   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 |    92.59 |   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.73 |   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.1 |     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.46 |   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.21 |     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.34 |    85.75 |   85.63 |   84.34 |                   
  ...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 |   95.72 |    92.85 |     100 |   95.72 | ...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.23 |   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.94 |   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.22 |    83.25 |   92.98 |   90.22 |                   
  ...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  |   88.57 |    79.75 |   89.28 |   88.57 | ...66-669,685-686 
  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 |    57.69 |   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.

Aligns the new auth regression tests with the real CLI/core types so build, lint, and E2E workflows can compile the branch for issue #1739.
@acoliver
Copy link
Copy Markdown
Collaborator Author

Addressed the current PR blockers from the failing lint and E2E jobs.

Root cause:

  • The new regression tests compiled locally in focused runs, but CI builds the CLI package strictly and caught two type issues in the new tests:
    • the BucketFailoverOAuthManagerLike test double was missing forceRefreshToken
    • the turn-preparation test used an invalid ThinkingBlock fixture shape

Remediation:

  • Added forceRefreshToken to the BucketFailoverHandlerImpl.invalidateAuthCache test double
  • Updated the useGeminiStream turn-preparation test to use the real ThinkingBlock shape from core
  • Rechecked the affected surfaces locally:
    • cd packages/cli && npm run build
    • cd packages/cli && npm run lint
    • cd packages/cli && npx vitest run src/auth/tests/BucketFailoverHandlerImpl.invalidateAuthCache.test.ts src/ui/hooks/geminiStream/tests/useGeminiStream.turnPreparation.test.ts

Current local result:

  • build passes
  • lint exits 0
  • targeted regression tests pass

Applies the formatter output required by the PR lint workflow to the new auth regression tests for issue #1739 without touching project memory files.
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/cli/src/auth/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.test.ts`:
- Around line 1-53: The test file has Prettier/formatting issues; run the
project's formatter (e.g., npm run format or prettier --write) on the test file
containing the describe('BucketFailoverHandlerImpl.invalidateAuthCache'...) and
related imports (flushRuntimeAuthScope, BucketFailoverHandlerImpl,
OAuthTokenRequestMetadata) to apply Prettier rules, then commit the reformatted
file so CI's format check passes.

In
`@packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.ts`:
- Around line 1-141: The test file has formatting drift detected by Prettier;
run the project's formatter (e.g., npm run format or npx prettier --write) on
packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.ts
(the file containing the prepareTurnForQuery tests), review the changed
formatting, stage and commit the updated file so CI no longer reports
uncommitted Prettier changes.
🪄 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: b3ebf2a7-92cd-4c62-aab7-66f8b00e54aa

📥 Commits

Reviewing files that changed from the base of the PR and between db458f1 and 611715b.

📒 Files selected for processing (2)
  • packages/cli/src/auth/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.test.ts
  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.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: E2E Test (macOS)
🧰 Additional context used
🧠 Learnings (35)
📓 Common learnings
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: 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/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: 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.
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/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/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: 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: 1459
File: packages/core/src/providers/LoadBalancingProvider.ts:631-648
Timestamp: 2026-02-18T01:44:54.715Z
Learning: Load balancer failover and bucket failover are two separate mechanisms: Load balancer failover (LoadBalancingProvider) distributes requests across different backends/providers and treats 401 as an immediate failover error. Bucket failover (BucketFailoverHandlerImpl) handles credential rotation within a single provider and may implement auto-renew semantics for 401. These systems have different 401 handling behaviors by design.
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 0
File: :0-0
Timestamp: 2025-12-13T16:04:07.079Z
Learning: Support multi-bucket failover on a single profile: ordered buckets tried in sequence; on 429 or 402 advance to next bucket; on 401 attempt auto-renew then retry once before advancing.
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 0
File: :0-0
Timestamp: 2026-02-20T04:32:08.940Z
Learning: In vybestack/llxprt-code, provider retries and OAuth bucket failover are centralized in packages/core/src/providers/RetryOrchestrator.ts. Failover triggers: 2×429, immediate 402, or 2nd 401/403. On success, counters and failover session reset; on switch, attempt-- so retries don’t burn on bucket change.
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 0
File: :0-0
Timestamp: 2026-01-13T23:04:39.246Z
Learning: Treat Anthropic 403 permission_error "OAuth token has been revoked" as an expired/auth error: trigger a one-time refresh retry, then bucket failover if refresh fails. Avoid auto-switching providers; only switch buckets within the same provider. This error likely means that we failed to lock when refreshing and multiple instances refreshed the same token.
📚 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/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.test.ts
  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.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/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.test.ts
  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.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/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.test.ts
  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.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/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.test.ts
  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.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/cli/src/auth/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.test.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/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.test.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/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.test.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/cli/src/auth/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.test.ts
  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.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/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.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/cli/src/auth/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.test.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/cli/src/auth/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.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/cli/src/auth/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.test.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/cli/src/auth/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.test.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/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.test.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/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.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/cli/src/auth/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.test.ts
  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.ts
📚 Learning: 2026-03-26T00:49:43.150Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1778
File: packages/cli/src/auth/__tests__/auth-flow-orchestrator.spec.ts:309-324
Timestamp: 2026-03-26T00:49:43.150Z
Learning: In this repository’s Jest (or Jest-like) test files, it is acceptable to use `expect(promiseReturningFunction).resolves.not.toThrow()` when the function returns `Promise<void>`. Do not flag this as an incorrect or suboptimal matcher; for `Promise<void>` it is functionally equivalent to using `resolves.toBeUndefined()` to assert successful resolution.

Applied to files:

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

Applied to files:

  • packages/cli/src/auth/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.test.ts
  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.ts
📚 Learning: 2026-03-26T20:52:08.720Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1780
File: packages/cli/src/ui/hooks/geminiStream/useStreamEventHandlers.ts:140-149
Timestamp: 2026-03-26T20:52:08.720Z
Learning: In `packages/cli/src/ui/hooks/geminiStream/useStreamEventHandlers.ts` (vybestack/llxprt-code PR `#1780`), the `applyThoughtToState` function's `setPendingHistoryItem` updater casts `item?.type as 'gemini' | 'gemini_content'` and uses `item?.text || ''` — this is intentional pre-existing behavior faithfully extracted verbatim from the original `useGeminiStream.ts` (lines 1110–1111 on main). The risk that a `tool_group` pending item type could be preserved is a known pre-existing pattern; fixing it requires careful testing of all thinking block rendering paths and is a behavioral change beyond decomposition scope. Do not flag this type cast as a bug in decomposition or refactoring PRs.

Applied to files:

  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.ts
📚 Learning: 2026-03-26T21:40:39.044Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1780
File: packages/cli/src/ui/hooks/geminiStream/useStreamEventHandlers.ts:521-525
Timestamp: 2026-03-26T21:40:39.044Z
Learning: In `packages/cli/src/ui/hooks/geminiStream/useStreamEventHandlers.ts` (vybestack/llxprt-code PR `#1780`), `processGeminiStreamEvents` previously always returned `StreamProcessingStatus.Completed` even when a `UserCancelled` or `Error` event was received — this was pre-existing dead code from the original `useGeminiStream.ts` (line 1371 checked for UserCancelled but the function always returned Completed). Fixed in commit 4a28363bc by adding a `processingResult` variable that tracks the status through the event loop, setting it to `StreamProcessingStatus.UserCancelled` or `StreamProcessingStatus.Error` as appropriate, and returning it at the end instead of always returning `Completed`.

Applied to files:

  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.ts
📚 Learning: 2026-03-26T02:06:03.086Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1779
File: packages/core/src/core/subagentChatSetup.ts:339-453
Timestamp: 2026-03-26T02:06:03.086Z
Learning: In `packages/core/src/core/subagentChatSetup.ts` (vybestack/llxprt-code PR `#1779`, decomposed from `subagent.ts`), the `assembleChatSession` function's `try/catch` block wraps only `new GeminiChat(...)` and not the preceding `await ctx.environmentContextLoader(...)` or `await getCoreSystemPromptAsync(...)` calls. This partial error boundary is pre-existing behavior faithfully preserved from the original `createChatObject` method in `subagent.ts`. Do not flag the missing async-await coverage as a decomposition regression in future reviews — it is an acknowledged pre-existing limitation, and any fix would be a behavioral change requiring a dedicated follow-up PR.

Applied to files:

  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.ts
📚 Learning: 2026-02-15T19:33:03.569Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1405
File: packages/core/src/lsp/__tests__/lsp-service-client-integration.test.ts:93-102
Timestamp: 2026-02-15T19:33:03.569Z
Learning: In the llxprt-code codebase (`packages/core/src/lsp/__tests__/lsp-service-client-integration.test.ts`), the LspServiceClient integration tests use a synthetic/stub implementation with PassThrough streams for testing. The test config may include fields like `filetypes` that differ from production types (`LspServerConfig`), as these tests verify the integration contract rather than exact production type conformance. Future work may add more realistic subprocess tests.

Applied to files:

  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.ts
📚 Learning: 2026-03-26T20:01:50.052Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1780
File: packages/cli/src/ui/hooks/geminiStream/checkpointPersistence.ts:0-0
Timestamp: 2026-03-26T20:01:50.052Z
Learning: In `packages/cli/src/ui/hooks/geminiStream/checkpointPersistence.ts` (vybestack/llxprt-code PR `#1780`), `saveRestorableToolCalls` reserves the `callId` in `checkpointedCallIds` *before* calling `await createToolCheckpoint(...)` to prevent concurrent duplicate attempts. On failure (exception or false/no-write return), the `callId` is deleted from the set so the next effect run can retry. This reserve-before-await, delete-on-failure pattern was introduced in commit a41b97759.

Applied to files:

  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.ts
📚 Learning: 2026-03-27T00:46:42.630Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1785
File: packages/cli/src/config/__tests__/parseArgumentsParity.test.ts:7-16
Timestamp: 2026-03-27T00:46:42.630Z
Learning: In `packages/cli/src/config/__tests__/parseArgumentsParity.test.ts` (vybestack/llxprt-code PR `#1785`), the test suite is intentionally scoped to verifying that the extracted `parseArguments` function produces identical output to the original inline parsing. It deliberately does NOT cover subcommand exit behavior (mcp, hooks, extensions) via `handleSubcommandExit()` — that function is a direct mechanical extraction and adding integration tests for it would be new coverage beyond the refactoring scope. Do not flag the absence of subcommand-exit test cases as a gap in this file or in refactoring PRs that extract it.

Applied to files:

  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.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/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.ts
📚 Learning: 2026-03-21T17:07:15.661Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1743
File: packages/core/src/core/ConversationManager.ts:94-101
Timestamp: 2026-03-21T17:07:15.661Z
Learning: In `packages/core/src/core/ConversationManager.ts`, `packages/core/src/core/TurnProcessor.ts`, `packages/core/src/core/StreamProcessor.ts`, and `packages/core/src/core/DirectMessageProcessor.ts` (vybestack/llxprt-code PR `#1743`, commit 870e85a91), `makePositionMatcher()` was hoisted outside all per-Content loops so that a single position matcher is shared across the entire batch. This supersedes the prior preserved-behavior pattern (original `geminiChat.ts` called it per-Content). The unmatched-tool queue is now consumed in order across all items in a batch, which is the correct behavior.

Applied to files:

  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.ts
📚 Learning: 2026-04-03T20:43:35.912Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1876
File: packages/core/src/core/subagent.ts:441-464
Timestamp: 2026-04-03T20:43:35.912Z
Learning: In `packages/core/src/core/subagent.ts` (vybestack/llxprt-code), `runInteractiveTurn`'s `catch` block should only call `throw createAbortError()` when `abortController.signal.aborted` — it must NOT infer `SubagentTerminateMode.TIMEOUT` based on `!this.parentAbortSignal?.aborted`. `Turn.run()` absorbs idle-timeout events internally and emits `GeminiEventType.UserCancelled` before the generator exits, so the catch only fires for genuine errors or explicit cancel aborts. TIMEOUT is authoritatively set in the `onTimeout` callback of `nextStreamEventWithIdleTimeout` inside `runNonInteractiveTurn`. Do not conflate these two paths in future reviews.

Applied to files:

  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.ts
📚 Learning: 2026-03-25T19:21:43.266Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1771
File: packages/core/src/core/AgentHookManager.ts:78-96
Timestamp: 2026-03-25T19:21:43.266Z
Learning: In `packages/core/src/core/AgentHookManager.ts` (vybestack/llxprt-code PR `#1771`), `cleanupOldHookState(newPromptId, oldPromptId)` is always called at the start of a new prompt turn (when `prompt_id` changes), after the previous prompt's stream has been fully consumed by `MessageStreamOrchestrator`. Because JS is single-threaded, there is no concurrent execution path where an in-flight `fireAfterAgentHookSafe` for the old `prompt_id` could race with the cleanup. Do not flag this pattern as a race condition in future reviews — the sequential flow guarantees: previous prompt finishes → new prompt starts → cleanup runs → fresh hook state created.

Applied to files:

  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.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/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.ts
📚 Learning: 2026-03-25T18:17:38.768Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1768
File: packages/cli/src/ui/containers/AppContainer/hooks/useInputHandling.ts:127-135
Timestamp: 2026-03-25T18:17:38.768Z
Learning: In `packages/cli/src/ui/containers/AppContainer/hooks/useInputHandling.ts` (vybestack/llxprt-code PR `#1768`), the `hadToolCallsRef.current = false` reset inside `handleFinalSubmit` (before calling `submitQuery`) is intentional behavior preserved from the original `AppContainer.tsx` continuation flow contract. Do not flag this as a premature reset or race condition in decomposition or future PRs — any turn-boundary redesign (e.g., only clearing after `handleStreamCompleted`) is out of scope for the `#1576` refactoring and would constitute a behavioral change.

Applied to files:

  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.ts
📚 Learning: 2026-04-03T20:43:54.493Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 1876
File: packages/core/src/core/subagent.ts:675-710
Timestamp: 2026-04-03T20:43:54.493Z
Learning: In `packages/core/src/core/subagent.ts` (vybestack/llxprt-code PR `#1876`), `runNonInteractiveTurn` intentionally returns `{ functionCalls: [], textResponse: '' }` (instead of throwing) when `abortController.signal.aborted` is detected — both in the pre-loop early-abort check and inside the stream iteration loop. This is the correct design because: (1) `armTimeout` sets `output.terminate_reason = SubagentTerminateMode.TIMEOUT` *before* aborting, so abort-reason state is already recorded; (2) the caller in `runNonInteractive` checks `if (abortController.signal.aborted) return;` immediately after the call, resolving `runNonInteractive` as a normal `Promise<void>` (not a rejection); (3) existing TIMEOUT tests assert this resolution behavior and would break if `createAbortError()` were thrown instead. Do not flag the return-empty-on-abort pattern as dropping `finalizeOutput` or treating abort as success — it is intentional and test-validated.

Applied to files:

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

Applied to files:

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

Applied to files:

  • packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.ts
🪛 GitHub Actions: LLxprt Code CI
packages/cli/src/auth/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.test.ts

[error] 1-1: Prettier --write changed formatting in this file; the format check failed due to uncommitted changes.

packages/cli/src/ui/hooks/geminiStream/__tests__/useGeminiStream.turnPreparation.test.ts

[error] 1-1: Prettier --write changed formatting in this file; the format check failed due to uncommitted changes.

🔇 Additional comments (2)
packages/cli/src/auth/__tests__/BucketFailoverHandlerImpl.invalidateAuthCache.test.ts (1)

24-52: Good focused regression coverage for unbucketed cache invalidation.

The test cleanly verifies that handler.invalidateAuthCache() delegates to flushRuntimeAuthScope with the runtime ID, which is the core contract for this fix.

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

18-140: Strong branch and ordering coverage for turn preparation.

These tests validate the critical branch split and ordering guarantees (new turn vs continuation) and include the runtime ID fallback path, matching the intended auth-refresh behavior.

@acoliver
Copy link
Copy Markdown
Collaborator Author

Addressed the remaining PR lint failure.

The latest Lint (Javascript) failure was from the formatter check, not a logic error. CI reformatted three regression-test files and then failed on the resulting diff.

I applied the formatter output locally, rechecked the affected CLI surfaces, and pushed the update.

Rechecked locally:

  • cd packages/cli && npm run build
  • cd packages/cli && npx vitest run src/auth/tests/BucketFailoverHandlerImpl.invalidateAuthCache.test.ts src/ui/hooks/geminiStream/tests/useGeminiStream.turnPreparation.test.ts

Both still pass after the formatting-only update.

@acoliver acoliver merged commit 851e956 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.

unbucketed profiles should check keychain on 401/etc or new turn

1 participant