refactor(dashboard): extract ProviderDetailPageClient — #3501 Phase 0 - #3633
Conversation
Strangler-fig decomposition of the 12,882-LOC providers/[id]/page.tsx god-component (the single largest file in the repo). Phase 0 establishes the foundation: - page.tsx becomes a thin 9-line route wrapper delegating to ProviderDetailPageClient, matching the repo convention (EndpointPageClient/ApiManagerPageClient). - ProviderDetailPageClient.tsx holds the (unchanged) component body; the client reads the route id via useParams() so no props are threaded. - First-ever smoke render test for the page (Hard Rule #8): mounts the client, asserts the loading shell renders and on-mount data loading fires. This is the safety net every later extraction phase (1-6) is diffed against. - file-size ratchet now tracks ProviderDetailPageClient.tsx; vitest include globs the providers __tests__ dir. Behavior unchanged. Foundation for Phases 1-6 per the approved plan in #3501. Co-authored-by: oyi77 <oyi77@users.noreply.github.com>
There was a problem hiding this comment.
Code Review
This pull request initiates Phase 0 of the provider-detail god-component decomposition by extracting ProviderDetailPageClient.tsx and introducing its first smoke render test. Feedback focuses on aligning with the repository's style guide by moving the newly added test file from the src/ directory into the tests/ directory, updating the Vitest configuration accordingly, and refactoring the test's asynchronous wait logic to use vi.waitFor for improved robustness.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| // @vitest-environment jsdom | ||
| // | ||
| // Phase 0 smoke test for Issue #3501 (strangler-fig decomposition of the | ||
| // 12.8K-LOC providers/[id] god-component). Before any code is moved out of the | ||
| // component, this proves the freshly-extracted ProviderDetailPageClient still | ||
| // mounts and renders its loading shell without throwing — the safety net that | ||
| // every later extraction phase (1..6) is diffed against. Hard Rule #8: the page | ||
| // had ZERO tests before this; this is the first. |
There was a problem hiding this comment.
According to the Repository Style Guide (Rule 1: File Placement & Organization), all unit tests, integration tests, ecosystem tests, or Vitest files must strictly be placed within the tests/ directory (e.g., tests/unit/). They should not be created inside the src/ directory or other non-test directories.
Please move this test file to the tests/ directory (for example, tests/unit/dashboard/providers/ProviderDetailPageClient.test.tsx).
References
- All unit tests, integration tests, ecosystem tests, or Vitest files must strictly be placed within the
tests/directory. (link)
| include: [ | ||
| "src/app/**/dashboard/cache/__tests__/**/*.test.tsx", | ||
| "src/app/**/dashboard/endpoint/__tests__/**/*.test.tsx", | ||
| "src/app/**/dashboard/providers/**/__tests__/**/*.test.tsx", |
There was a problem hiding this comment.
Since the test file should be moved to the tests/ directory per the Repository Style Guide, this glob pattern targeting src/app/**/dashboard/providers/**/__tests__/**/*.test.tsx should not be added. Instead, ensure the tests/ directory is covered by the Vitest configuration.
References
- All unit tests, integration tests, ecosystem tests, or Vitest files must strictly be placed within the
tests/directory. (link)
| // Let the mount effects schedule their fetches. | ||
| await act(async () => { | ||
| await Promise.resolve(); | ||
| }); | ||
| expect(fetchMock).toHaveBeenCalled(); |
There was a problem hiding this comment.
Using await act(async () => { await Promise.resolve(); }) to flush microtasks can be fragile and prone to flakiness if the component's initialization involves multiple nested promises or asynchronous steps.
Using Vitest's vi.waitFor is a more robust and idiomatic way to wait for asynchronous side effects (like API calls) to occur.
| // Let the mount effects schedule their fetches. | |
| await act(async () => { | |
| await Promise.resolve(); | |
| }); | |
| expect(fetchMock).toHaveBeenCalled(); | |
| // Wait for the mount effects to schedule and trigger their fetches. | |
| await vi.waitFor(() => { | |
| expect(fetchMock).toHaveBeenCalled(); | |
| }); |
* chore(release): open v3.8.22 development cycle * refactor(dashboard): extract ProviderDetailPageClient — #3501 Phase 0 (#3633) #3501 Phase 0: extract ProviderDetailPageClient + smoke test. Co-authored-by: oyi77 <oyi77@users.noreply.github.com> * refactor(dashboard): extract auth-import modals — #3501 Phase 1a (#3634) #3501 Phase 1a: extract 3 auth-import modal clusters. Co-authored-by: oyi77 <oyi77@users.noreply.github.com> * fix(db): reclassify localDb unexported modules as intentionally-internal (#3499) (#3635) Closes #3499 — reclassify localDb unexported modules as intentionally-internal (audit + honest gate framing). * refactor(db): move call_logs aggregations into callLogStats db module (#3500) (#3636) #3500 slice 1: call_logs aggregations → src/lib/db/callLogStats.ts (Rule #5). Byte-identical queries; TDD 6/6. * refactor(dashboard): extract EditCompatibleNodeModal — #3501 Phase 1b (#3638) #3501 Phase 1b: extract EditCompatibleNodeModal (cycle-safe via leaf constants module). Co-authored-by: oyi77 <oyi77@users.noreply.github.com> * refactor(db): move community_servers SQL into gamification db module (#3500 slice 3) (#3639) #3500 slice 3: community_servers SQL → gamification db module. * refactor(db): move usage_history SQL into usageAnalytics module (#3500 slice 2) (#3644) #3500 slice 2: usage_history/daily_usage_summary SQL → usageAnalytics db module. * refactor(db): move skills UPDATE + db-backups SQL into db modules (#3500 slice 5) (#3647) #3500 slice 5: skills UPDATE (allowlist) + db-backups SQL → db modules. * refactor(db): move usage_logs/semantic_cache/proxy_logs SQL into db modules (#3500 slice 4) (#3648) #3500 slice 4: usage_logs/semantic_cache/proxy_logs SQL → db modules. All internal routes done (2 external by-design remain). * chore(db-gate): reclassify external-DB reads, fully close #3500 (#3649) Closes #3500: reclassify external-DB reads; all internal raw-SQL migrated to db/ modules. * refactor(dashboard): extract pure helpers to providerPageHelpers — #3501 Phase 2 (#3653) #3501 Phase 2: extract pure helpers to providerPageHelpers (leaf, cycle-safe). Co-authored-by: oyi77 <oyi77@users.noreply.github.com> * refactor(dashboard): extract remaining shared helpers to providerPageHelpers — #3501 Phase 2b (#3658) #3501 Phase 2b: extract remaining shared helpers to providerPageHelpers (leaf, cycle-safe). Heavy modals unblocked. Co-authored-by: oyi77 <oyi77@users.noreply.github.com> * fix(reasoning): replay reasoning_content on plain DeepSeek turns (#1682) (#3632) Integrated into release/v3.8.22 * fix(kiro): route enterprise IAM Identity Center accounts to their regional endpoint (#3631) Integrated into release/v3.8.22 * refactor: small code cleanup (#3523) Integrated into release/v3.8.22 * fix(combo): skip same-provider targets on 408/500/502/503/504/524 errors (#3637) Integrated into release/v3.8.22 — circuit-breaker guard added in review (#1731v2) * feat(providers): add MiMoCode free-tier provider with bootstrap JWT auth (#3659) Integrated into release/v3.8.22 — page.tsx conflict resolved + NoAuthAccountCard re-applied to ProviderDetailPageClient in review. MiMoCode endpoint validated live. * Log Responses WebSocket calls in history (#3616) Integrated into release/v3.8.22 — Codex Responses WebSocket call history logging. * Add Claude Code routing preference for unprefixed Claude models (#3540) Integrated into release/v3.8.22 — page.tsx conflict resolved (re-applied toggle to ProviderDetailPageClient) + disable-test updated for catalog drift in review. * docs(changelog): credit #3632/#3631/#3637/#3659/#3540/#3616/#3523 (v3.8.22 targeted review round) * fix(mimocode): add required authHeader:"none" to registry entry (#3659 follow-up) The mimocode RegistryEntry omitted the required authHeader field, which broke typecheck:core (TS2741). Match the no-auth convention (authType:"none" + authHeader:"none") used by veoaifree-web and other free providers. Follow-up to #3659 (@pizzav-xyz). * fix(responses): detect stream readiness for tool-call-only and object-less chunks (#3612) (#3661) Closes #3612 * fix(mitm): remove duplicated 'Command failed:' error prefix (#3641) (#3662) Closes #3641 * fix(cli): honor HERMES_HOME for Hermes Agent config path (#3628) (#3663) Closes #3628 * fix(api): fetch live OpenCode model catalog for no-auth model picker (#3611) (#3664) Closes #3611 * fix(api): flag provider topology error state by current status, not stale history (#3619) (#3666) Closes #3619 * fix(electron): launch peer-stamping server-ws.mjs entrypoint to avoid 403 LOCAL_ONLY (#3386) (#3665) Closes #3386 * fix(dashboard): restore home topology live in-flight pulse (#3507) (#3667) Closes #3507 * fix(oauth): name Kiro/AWS auto-imported accounts and dedupe by profileArn (#3615) (#3671) Closes #3615 * fix(resilience): clear stale transient connection cooldowns on startup (#3625) (#3672) Closes #3625 * fix(i18n): use logical CSS direction utilities for sidebar and key overlays (RTL #3541) (#3670) Closes #3541 * fix(dashboard): honor auto-hide and switch to visible filter on passthrough Test-all (#3610) (#3669) Closes #3610 * refactor(dashboard): extract AddApiKeyModal + EditConnectionModal — #3501 Phase 1c (#3674) #3501 Phase 1c: extract AddApiKeyModal, EditConnectionModal, WebSessionCredentialGuide into components/; god-component 10,166->8,092 LOC. Reconciles the v3.8.22 file-size drift for this file. Co-authored-by: oyi77 <oyi77@users.noreply.github.com> * docs(changelog): reconcile v3.8.22 — credit #3621/#3622 + MiMoCode follow-up roll-up * refactor(dashboard): extract ConnectionRow + ModelCompatPopover + SiliconFlowEndpointModal — #3501 Phase 1d (#3676) #3501 Phase 1d: god-component 8,092->6,838 LOC. Co-authored-by: oyi77 <oyi77@users.noreply.github.com> * feat(obsidian): add WebDAV config route + encrypt creds at rest (#3485 part 1) (#3677) Part 1 of #3485. Adds /api/settings/obsidian/webdav (GET/POST/DELETE) wiring the ready obsidianSync lib, encrypts webdav password + obsidian token at rest, removes the duplicate UI block, drops the KNOWN_MISSING entry. WebDAV file server is part 2. * feat(obsidian): add /api/v1/webdav file server for Obsidian vault sync (#3485 part 2) (#3678) Part 2 of #3485. WebDAV server (PROPFIND/GET/PUT/DELETE/MKCOL/MOVE/OPTIONS) handled in the custom server layer (standalone-server-ws.mjs) since the App Router cannot export WebDAV methods. Basic-Auth (constant-time), path-traversal hardened, password decrypt ported from encryption.ts (parity-tested), DATA_DIR resolution parity-tested against dataPaths.ts. End-to-end Obsidian-over-Tailscale validation is a live VPS step (Rule #18). * fix(combo): stop premature context compaction — real auto-combo windows + per-target compression limit (#3680) Integrated into release/v3.8.22 * feat(dashboard): deactivate/activate accounts from the quota overview (#3675) Integrated into release/v3.8.22 * fix(dashboard): close review gaps in bulk provider connection actions (#3271 follow-up) (#3673) Integrated into release/v3.8.22 — page.tsx conflict (god-component split #3501) resolved by re-applying the bulk-action deltas to ProviderDetailPageClient.tsx * refactor(dashboard): extract useModelCompatState hook + model sections — #3501 Phase 1e (#3683) #3501 Phase 1e: extract useModelCompatState hook (unblocks the model sections) + ModelRow/PassthroughModelsSection/PassthroughModelRow/CustomModelsSection/CompatibleModelsSection. god-component 6,838->4,921 LOC. Co-authored-by: oyi77 <oyi77@users.noreply.github.com> * refactor(dashboard): extract useProviderConnections/Settings/Models hooks — #3501 Phase 1f (#3684) #3501 Phase 1f: god-component 4,948->4,062 LOC. Connection state+handlers, settings, and model metadata moved into hooks/. Co-authored-by: oyi77 <oyi77@users.noreply.github.com> * chore(release): v3.8.22 CHANGELOG + env-doc sync - Set release date in CHANGELOG [3.8.22] to 2026-06-11 - Add HERMES_HOME to .env.example (from #3628/#3663) - Add HERMES_HOME + OMNIROUTE_PREFER_CLAUDE_CODE_FOR_UNPREFIXED_CLAUDE_MODELS to ENVIRONMENT.md (#3628/#3540) * docs(changelog): credit #3673 + #3675 — leninejunior bulk-actions + quota-toggle --------- Co-authored-by: oyi77 <oyi77@users.noreply.github.com> Co-authored-by: Abhishek Divekar <adivekar@utexas.edu> Co-authored-by: NOXX - Commiter <artur1992123@mail.ru> Co-authored-by: Nicolas Lorin <androw95220@gmail.com> Co-authored-by: Hernan Javier Ardila Sanchez <hjasgr@gmail.com> Co-authored-by: PizzaV <103120356+pizzav-xyz@users.noreply.github.com> Co-authored-by: kkkayye <98376609+kkkayye@users.noreply.github.com> Co-authored-by: Witroch4 <witalo_rocha@hotmail.com> Co-authored-by: Lenine Júnior <lenine@engrene.com.br>
…3501 Phase 0 (diegosouzapw#3633) Co-authored-by: oyi77 <oyi77@users.noreply.github.com>
…3501 Phase 0 (diegosouzapw#3633) Co-authored-by: oyi77 <oyi77@users.noreply.github.com>
* chore(release): open v3.8.22 development cycle * refactor(dashboard): extract ProviderDetailPageClient — diegosouzapw#3501 Phase 0 (diegosouzapw#3633) diegosouzapw#3501 Phase 0: extract ProviderDetailPageClient + smoke test. Co-authored-by: oyi77 <oyi77@users.noreply.github.com> * refactor(dashboard): extract auth-import modals — diegosouzapw#3501 Phase 1a (diegosouzapw#3634) diegosouzapw#3501 Phase 1a: extract 3 auth-import modal clusters. Co-authored-by: oyi77 <oyi77@users.noreply.github.com> * fix(db): reclassify localDb unexported modules as intentionally-internal (diegosouzapw#3499) (diegosouzapw#3635) Closes diegosouzapw#3499 — reclassify localDb unexported modules as intentionally-internal (audit + honest gate framing). * refactor(db): move call_logs aggregations into callLogStats db module (diegosouzapw#3500) (diegosouzapw#3636) diegosouzapw#3500 slice 1: call_logs aggregations → src/lib/db/callLogStats.ts (Rule diegosouzapw#5). Byte-identical queries; TDD 6/6. * refactor(dashboard): extract EditCompatibleNodeModal — diegosouzapw#3501 Phase 1b (diegosouzapw#3638) diegosouzapw#3501 Phase 1b: extract EditCompatibleNodeModal (cycle-safe via leaf constants module). Co-authored-by: oyi77 <oyi77@users.noreply.github.com> * refactor(db): move community_servers SQL into gamification db module (diegosouzapw#3500 slice 3) (diegosouzapw#3639) diegosouzapw#3500 slice 3: community_servers SQL → gamification db module. * refactor(db): move usage_history SQL into usageAnalytics module (diegosouzapw#3500 slice 2) (diegosouzapw#3644) diegosouzapw#3500 slice 2: usage_history/daily_usage_summary SQL → usageAnalytics db module. * refactor(db): move skills UPDATE + db-backups SQL into db modules (diegosouzapw#3500 slice 5) (diegosouzapw#3647) diegosouzapw#3500 slice 5: skills UPDATE (allowlist) + db-backups SQL → db modules. * refactor(db): move usage_logs/semantic_cache/proxy_logs SQL into db modules (diegosouzapw#3500 slice 4) (diegosouzapw#3648) diegosouzapw#3500 slice 4: usage_logs/semantic_cache/proxy_logs SQL → db modules. All internal routes done (2 external by-design remain). * chore(db-gate): reclassify external-DB reads, fully close diegosouzapw#3500 (diegosouzapw#3649) Closes diegosouzapw#3500: reclassify external-DB reads; all internal raw-SQL migrated to db/ modules. * refactor(dashboard): extract pure helpers to providerPageHelpers — diegosouzapw#3501 Phase 2 (diegosouzapw#3653) diegosouzapw#3501 Phase 2: extract pure helpers to providerPageHelpers (leaf, cycle-safe). Co-authored-by: oyi77 <oyi77@users.noreply.github.com> * refactor(dashboard): extract remaining shared helpers to providerPageHelpers — diegosouzapw#3501 Phase 2b (diegosouzapw#3658) diegosouzapw#3501 Phase 2b: extract remaining shared helpers to providerPageHelpers (leaf, cycle-safe). Heavy modals unblocked. Co-authored-by: oyi77 <oyi77@users.noreply.github.com> * fix(reasoning): replay reasoning_content on plain DeepSeek turns (diegosouzapw#1682) (diegosouzapw#3632) Integrated into release/v3.8.22 * fix(kiro): route enterprise IAM Identity Center accounts to their regional endpoint (diegosouzapw#3631) Integrated into release/v3.8.22 * refactor: small code cleanup (diegosouzapw#3523) Integrated into release/v3.8.22 * fix(combo): skip same-provider targets on 408/500/502/503/504/524 errors (diegosouzapw#3637) Integrated into release/v3.8.22 — circuit-breaker guard added in review (#1731v2) * feat(providers): add MiMoCode free-tier provider with bootstrap JWT auth (diegosouzapw#3659) Integrated into release/v3.8.22 — page.tsx conflict resolved + NoAuthAccountCard re-applied to ProviderDetailPageClient in review. MiMoCode endpoint validated live. * Log Responses WebSocket calls in history (diegosouzapw#3616) Integrated into release/v3.8.22 — Codex Responses WebSocket call history logging. * Add Claude Code routing preference for unprefixed Claude models (diegosouzapw#3540) Integrated into release/v3.8.22 — page.tsx conflict resolved (re-applied toggle to ProviderDetailPageClient) + disable-test updated for catalog drift in review. * docs(changelog): credit diegosouzapw#3632/diegosouzapw#3631/diegosouzapw#3637/diegosouzapw#3659/diegosouzapw#3540/diegosouzapw#3616/diegosouzapw#3523 (v3.8.22 targeted review round) * fix(mimocode): add required authHeader:"none" to registry entry (diegosouzapw#3659 follow-up) The mimocode RegistryEntry omitted the required authHeader field, which broke typecheck:core (TS2741). Match the no-auth convention (authType:"none" + authHeader:"none") used by veoaifree-web and other free providers. Follow-up to diegosouzapw#3659 (@pizzav-xyz). * fix(responses): detect stream readiness for tool-call-only and object-less chunks (diegosouzapw#3612) (diegosouzapw#3661) Closes diegosouzapw#3612 * fix(mitm): remove duplicated 'Command failed:' error prefix (diegosouzapw#3641) (diegosouzapw#3662) Closes diegosouzapw#3641 * fix(cli): honor HERMES_HOME for Hermes Agent config path (diegosouzapw#3628) (diegosouzapw#3663) Closes diegosouzapw#3628 * fix(api): fetch live OpenCode model catalog for no-auth model picker (diegosouzapw#3611) (diegosouzapw#3664) Closes diegosouzapw#3611 * fix(api): flag provider topology error state by current status, not stale history (diegosouzapw#3619) (diegosouzapw#3666) Closes diegosouzapw#3619 * fix(electron): launch peer-stamping server-ws.mjs entrypoint to avoid 403 LOCAL_ONLY (diegosouzapw#3386) (diegosouzapw#3665) Closes diegosouzapw#3386 * fix(dashboard): restore home topology live in-flight pulse (diegosouzapw#3507) (diegosouzapw#3667) Closes diegosouzapw#3507 * fix(oauth): name Kiro/AWS auto-imported accounts and dedupe by profileArn (diegosouzapw#3615) (diegosouzapw#3671) Closes diegosouzapw#3615 * fix(resilience): clear stale transient connection cooldowns on startup (diegosouzapw#3625) (diegosouzapw#3672) Closes diegosouzapw#3625 * fix(i18n): use logical CSS direction utilities for sidebar and key overlays (RTL diegosouzapw#3541) (diegosouzapw#3670) Closes diegosouzapw#3541 * fix(dashboard): honor auto-hide and switch to visible filter on passthrough Test-all (diegosouzapw#3610) (diegosouzapw#3669) Closes diegosouzapw#3610 * refactor(dashboard): extract AddApiKeyModal + EditConnectionModal — diegosouzapw#3501 Phase 1c (diegosouzapw#3674) diegosouzapw#3501 Phase 1c: extract AddApiKeyModal, EditConnectionModal, WebSessionCredentialGuide into components/; god-component 10,166->8,092 LOC. Reconciles the v3.8.22 file-size drift for this file. Co-authored-by: oyi77 <oyi77@users.noreply.github.com> * docs(changelog): reconcile v3.8.22 — credit diegosouzapw#3621/diegosouzapw#3622 + MiMoCode follow-up roll-up * refactor(dashboard): extract ConnectionRow + ModelCompatPopover + SiliconFlowEndpointModal — diegosouzapw#3501 Phase 1d (diegosouzapw#3676) diegosouzapw#3501 Phase 1d: god-component 8,092->6,838 LOC. Co-authored-by: oyi77 <oyi77@users.noreply.github.com> * feat(obsidian): add WebDAV config route + encrypt creds at rest (diegosouzapw#3485 part 1) (diegosouzapw#3677) Part 1 of diegosouzapw#3485. Adds /api/settings/obsidian/webdav (GET/POST/DELETE) wiring the ready obsidianSync lib, encrypts webdav password + obsidian token at rest, removes the duplicate UI block, drops the KNOWN_MISSING entry. WebDAV file server is part 2. * feat(obsidian): add /api/v1/webdav file server for Obsidian vault sync (diegosouzapw#3485 part 2) (diegosouzapw#3678) Part 2 of diegosouzapw#3485. WebDAV server (PROPFIND/GET/PUT/DELETE/MKCOL/MOVE/OPTIONS) handled in the custom server layer (standalone-server-ws.mjs) since the App Router cannot export WebDAV methods. Basic-Auth (constant-time), path-traversal hardened, password decrypt ported from encryption.ts (parity-tested), DATA_DIR resolution parity-tested against dataPaths.ts. End-to-end Obsidian-over-Tailscale validation is a live VPS step (Rule diegosouzapw#18). * fix(combo): stop premature context compaction — real auto-combo windows + per-target compression limit (diegosouzapw#3680) Integrated into release/v3.8.22 * feat(dashboard): deactivate/activate accounts from the quota overview (diegosouzapw#3675) Integrated into release/v3.8.22 * fix(dashboard): close review gaps in bulk provider connection actions (diegosouzapw#3271 follow-up) (diegosouzapw#3673) Integrated into release/v3.8.22 — page.tsx conflict (god-component split diegosouzapw#3501) resolved by re-applying the bulk-action deltas to ProviderDetailPageClient.tsx * refactor(dashboard): extract useModelCompatState hook + model sections — diegosouzapw#3501 Phase 1e (diegosouzapw#3683) diegosouzapw#3501 Phase 1e: extract useModelCompatState hook (unblocks the model sections) + ModelRow/PassthroughModelsSection/PassthroughModelRow/CustomModelsSection/CompatibleModelsSection. god-component 6,838->4,921 LOC. Co-authored-by: oyi77 <oyi77@users.noreply.github.com> * refactor(dashboard): extract useProviderConnections/Settings/Models hooks — diegosouzapw#3501 Phase 1f (diegosouzapw#3684) diegosouzapw#3501 Phase 1f: god-component 4,948->4,062 LOC. Connection state+handlers, settings, and model metadata moved into hooks/. Co-authored-by: oyi77 <oyi77@users.noreply.github.com> * chore(release): v3.8.22 CHANGELOG + env-doc sync - Set release date in CHANGELOG [3.8.22] to 2026-06-11 - Add HERMES_HOME to .env.example (from diegosouzapw#3628/diegosouzapw#3663) - Add HERMES_HOME + OMNIROUTE_PREFER_CLAUDE_CODE_FOR_UNPREFIXED_CLAUDE_MODELS to ENVIRONMENT.md (diegosouzapw#3628/diegosouzapw#3540) * docs(changelog): credit diegosouzapw#3673 + diegosouzapw#3675 — leninejunior bulk-actions + quota-toggle --------- Co-authored-by: oyi77 <oyi77@users.noreply.github.com> Co-authored-by: Abhishek Divekar <adivekar@utexas.edu> Co-authored-by: NOXX - Commiter <artur1992123@mail.ru> Co-authored-by: Nicolas Lorin <androw95220@gmail.com> Co-authored-by: Hernan Javier Ardila Sanchez <hjasgr@gmail.com> Co-authored-by: PizzaV <103120356+pizzav-xyz@users.noreply.github.com> Co-authored-by: kkkayye <98376609+kkkayye@users.noreply.github.com> Co-authored-by: Witroch4 <witalo_rocha@hotmail.com> Co-authored-by: Lenine Júnior <lenine@engrene.com.br>
* chore(release): open v3.8.22 development cycle * refactor(dashboard): extract ProviderDetailPageClient — diegosouzapw#3501 Phase 0 (diegosouzapw#3633) diegosouzapw#3501 Phase 0: extract ProviderDetailPageClient + smoke test. Co-authored-by: oyi77 <oyi77@users.noreply.github.com> * refactor(dashboard): extract auth-import modals — diegosouzapw#3501 Phase 1a (diegosouzapw#3634) diegosouzapw#3501 Phase 1a: extract 3 auth-import modal clusters. Co-authored-by: oyi77 <oyi77@users.noreply.github.com> * fix(db): reclassify localDb unexported modules as intentionally-internal (diegosouzapw#3499) (diegosouzapw#3635) Closes diegosouzapw#3499 — reclassify localDb unexported modules as intentionally-internal (audit + honest gate framing). * refactor(db): move call_logs aggregations into callLogStats db module (diegosouzapw#3500) (diegosouzapw#3636) diegosouzapw#3500 slice 1: call_logs aggregations → src/lib/db/callLogStats.ts (Rule diegosouzapw#5). Byte-identical queries; TDD 6/6. * refactor(dashboard): extract EditCompatibleNodeModal — diegosouzapw#3501 Phase 1b (diegosouzapw#3638) diegosouzapw#3501 Phase 1b: extract EditCompatibleNodeModal (cycle-safe via leaf constants module). Co-authored-by: oyi77 <oyi77@users.noreply.github.com> * refactor(db): move community_servers SQL into gamification db module (diegosouzapw#3500 slice 3) (diegosouzapw#3639) diegosouzapw#3500 slice 3: community_servers SQL → gamification db module. * refactor(db): move usage_history SQL into usageAnalytics module (diegosouzapw#3500 slice 2) (diegosouzapw#3644) diegosouzapw#3500 slice 2: usage_history/daily_usage_summary SQL → usageAnalytics db module. * refactor(db): move skills UPDATE + db-backups SQL into db modules (diegosouzapw#3500 slice 5) (diegosouzapw#3647) diegosouzapw#3500 slice 5: skills UPDATE (allowlist) + db-backups SQL → db modules. * refactor(db): move usage_logs/semantic_cache/proxy_logs SQL into db modules (diegosouzapw#3500 slice 4) (diegosouzapw#3648) diegosouzapw#3500 slice 4: usage_logs/semantic_cache/proxy_logs SQL → db modules. All internal routes done (2 external by-design remain). * chore(db-gate): reclassify external-DB reads, fully close diegosouzapw#3500 (diegosouzapw#3649) Closes diegosouzapw#3500: reclassify external-DB reads; all internal raw-SQL migrated to db/ modules. * refactor(dashboard): extract pure helpers to providerPageHelpers — diegosouzapw#3501 Phase 2 (diegosouzapw#3653) diegosouzapw#3501 Phase 2: extract pure helpers to providerPageHelpers (leaf, cycle-safe). Co-authored-by: oyi77 <oyi77@users.noreply.github.com> * refactor(dashboard): extract remaining shared helpers to providerPageHelpers — diegosouzapw#3501 Phase 2b (diegosouzapw#3658) diegosouzapw#3501 Phase 2b: extract remaining shared helpers to providerPageHelpers (leaf, cycle-safe). Heavy modals unblocked. Co-authored-by: oyi77 <oyi77@users.noreply.github.com> * fix(reasoning): replay reasoning_content on plain DeepSeek turns (diegosouzapw#1682) (diegosouzapw#3632) Integrated into release/v3.8.22 * fix(kiro): route enterprise IAM Identity Center accounts to their regional endpoint (diegosouzapw#3631) Integrated into release/v3.8.22 * refactor: small code cleanup (diegosouzapw#3523) Integrated into release/v3.8.22 * fix(combo): skip same-provider targets on 408/500/502/503/504/524 errors (diegosouzapw#3637) Integrated into release/v3.8.22 — circuit-breaker guard added in review (#1731v2) * feat(providers): add MiMoCode free-tier provider with bootstrap JWT auth (diegosouzapw#3659) Integrated into release/v3.8.22 — page.tsx conflict resolved + NoAuthAccountCard re-applied to ProviderDetailPageClient in review. MiMoCode endpoint validated live. * Log Responses WebSocket calls in history (diegosouzapw#3616) Integrated into release/v3.8.22 — Codex Responses WebSocket call history logging. * Add Claude Code routing preference for unprefixed Claude models (diegosouzapw#3540) Integrated into release/v3.8.22 — page.tsx conflict resolved (re-applied toggle to ProviderDetailPageClient) + disable-test updated for catalog drift in review. * docs(changelog): credit diegosouzapw#3632/diegosouzapw#3631/diegosouzapw#3637/diegosouzapw#3659/diegosouzapw#3540/diegosouzapw#3616/diegosouzapw#3523 (v3.8.22 targeted review round) * fix(mimocode): add required authHeader:"none" to registry entry (diegosouzapw#3659 follow-up) The mimocode RegistryEntry omitted the required authHeader field, which broke typecheck:core (TS2741). Match the no-auth convention (authType:"none" + authHeader:"none") used by veoaifree-web and other free providers. Follow-up to diegosouzapw#3659 (@pizzav-xyz). * fix(responses): detect stream readiness for tool-call-only and object-less chunks (diegosouzapw#3612) (diegosouzapw#3661) Closes diegosouzapw#3612 * fix(mitm): remove duplicated 'Command failed:' error prefix (diegosouzapw#3641) (diegosouzapw#3662) Closes diegosouzapw#3641 * fix(cli): honor HERMES_HOME for Hermes Agent config path (diegosouzapw#3628) (diegosouzapw#3663) Closes diegosouzapw#3628 * fix(api): fetch live OpenCode model catalog for no-auth model picker (diegosouzapw#3611) (diegosouzapw#3664) Closes diegosouzapw#3611 * fix(api): flag provider topology error state by current status, not stale history (diegosouzapw#3619) (diegosouzapw#3666) Closes diegosouzapw#3619 * fix(electron): launch peer-stamping server-ws.mjs entrypoint to avoid 403 LOCAL_ONLY (diegosouzapw#3386) (diegosouzapw#3665) Closes diegosouzapw#3386 * fix(dashboard): restore home topology live in-flight pulse (diegosouzapw#3507) (diegosouzapw#3667) Closes diegosouzapw#3507 * fix(oauth): name Kiro/AWS auto-imported accounts and dedupe by profileArn (diegosouzapw#3615) (diegosouzapw#3671) Closes diegosouzapw#3615 * fix(resilience): clear stale transient connection cooldowns on startup (diegosouzapw#3625) (diegosouzapw#3672) Closes diegosouzapw#3625 * fix(i18n): use logical CSS direction utilities for sidebar and key overlays (RTL diegosouzapw#3541) (diegosouzapw#3670) Closes diegosouzapw#3541 * fix(dashboard): honor auto-hide and switch to visible filter on passthrough Test-all (diegosouzapw#3610) (diegosouzapw#3669) Closes diegosouzapw#3610 * refactor(dashboard): extract AddApiKeyModal + EditConnectionModal — diegosouzapw#3501 Phase 1c (diegosouzapw#3674) diegosouzapw#3501 Phase 1c: extract AddApiKeyModal, EditConnectionModal, WebSessionCredentialGuide into components/; god-component 10,166->8,092 LOC. Reconciles the v3.8.22 file-size drift for this file. Co-authored-by: oyi77 <oyi77@users.noreply.github.com> * docs(changelog): reconcile v3.8.22 — credit diegosouzapw#3621/diegosouzapw#3622 + MiMoCode follow-up roll-up * refactor(dashboard): extract ConnectionRow + ModelCompatPopover + SiliconFlowEndpointModal — diegosouzapw#3501 Phase 1d (diegosouzapw#3676) diegosouzapw#3501 Phase 1d: god-component 8,092->6,838 LOC. Co-authored-by: oyi77 <oyi77@users.noreply.github.com> * feat(obsidian): add WebDAV config route + encrypt creds at rest (diegosouzapw#3485 part 1) (diegosouzapw#3677) Part 1 of diegosouzapw#3485. Adds /api/settings/obsidian/webdav (GET/POST/DELETE) wiring the ready obsidianSync lib, encrypts webdav password + obsidian token at rest, removes the duplicate UI block, drops the KNOWN_MISSING entry. WebDAV file server is part 2. * feat(obsidian): add /api/v1/webdav file server for Obsidian vault sync (diegosouzapw#3485 part 2) (diegosouzapw#3678) Part 2 of diegosouzapw#3485. WebDAV server (PROPFIND/GET/PUT/DELETE/MKCOL/MOVE/OPTIONS) handled in the custom server layer (standalone-server-ws.mjs) since the App Router cannot export WebDAV methods. Basic-Auth (constant-time), path-traversal hardened, password decrypt ported from encryption.ts (parity-tested), DATA_DIR resolution parity-tested against dataPaths.ts. End-to-end Obsidian-over-Tailscale validation is a live VPS step (Rule diegosouzapw#18). * fix(combo): stop premature context compaction — real auto-combo windows + per-target compression limit (diegosouzapw#3680) Integrated into release/v3.8.22 * feat(dashboard): deactivate/activate accounts from the quota overview (diegosouzapw#3675) Integrated into release/v3.8.22 * fix(dashboard): close review gaps in bulk provider connection actions (diegosouzapw#3271 follow-up) (diegosouzapw#3673) Integrated into release/v3.8.22 — page.tsx conflict (god-component split diegosouzapw#3501) resolved by re-applying the bulk-action deltas to ProviderDetailPageClient.tsx * refactor(dashboard): extract useModelCompatState hook + model sections — diegosouzapw#3501 Phase 1e (diegosouzapw#3683) diegosouzapw#3501 Phase 1e: extract useModelCompatState hook (unblocks the model sections) + ModelRow/PassthroughModelsSection/PassthroughModelRow/CustomModelsSection/CompatibleModelsSection. god-component 6,838->4,921 LOC. Co-authored-by: oyi77 <oyi77@users.noreply.github.com> * refactor(dashboard): extract useProviderConnections/Settings/Models hooks — diegosouzapw#3501 Phase 1f (diegosouzapw#3684) diegosouzapw#3501 Phase 1f: god-component 4,948->4,062 LOC. Connection state+handlers, settings, and model metadata moved into hooks/. Co-authored-by: oyi77 <oyi77@users.noreply.github.com> * chore(release): v3.8.22 CHANGELOG + env-doc sync - Set release date in CHANGELOG [3.8.22] to 2026-06-11 - Add HERMES_HOME to .env.example (from diegosouzapw#3628/diegosouzapw#3663) - Add HERMES_HOME + OMNIROUTE_PREFER_CLAUDE_CODE_FOR_UNPREFIXED_CLAUDE_MODELS to ENVIRONMENT.md (diegosouzapw#3628/diegosouzapw#3540) * docs(changelog): credit diegosouzapw#3673 + diegosouzapw#3675 — leninejunior bulk-actions + quota-toggle --------- Co-authored-by: oyi77 <oyi77@users.noreply.github.com> Co-authored-by: Abhishek Divekar <adivekar@utexas.edu> Co-authored-by: NOXX - Commiter <artur1992123@mail.ru> Co-authored-by: Nicolas Lorin <androw95220@gmail.com> Co-authored-by: Hernan Javier Ardila Sanchez <hjasgr@gmail.com> Co-authored-by: PizzaV <103120356+pizzav-xyz@users.noreply.github.com> Co-authored-by: kkkayye <98376609+kkkayye@users.noreply.github.com> Co-authored-by: Witroch4 <witalo_rocha@hotmail.com> Co-authored-by: Lenine Júnior <lenine@engrene.com.br>
…3501 Phase 0 (diegosouzapw#3633) diegosouzapw#3501 Phase 0: extract ProviderDetailPageClient + smoke test. Co-authored-by: oyi77 <oyi77@users.noreply.github.com>
* chore(release): open v3.8.22 development cycle * refactor(dashboard): extract ProviderDetailPageClient — diegosouzapw#3501 Phase 0 (diegosouzapw#3633) diegosouzapw#3501 Phase 0: extract ProviderDetailPageClient + smoke test. Co-authored-by: oyi77 <oyi77@users.noreply.github.com> * refactor(dashboard): extract auth-import modals — diegosouzapw#3501 Phase 1a (diegosouzapw#3634) diegosouzapw#3501 Phase 1a: extract 3 auth-import modal clusters. Co-authored-by: oyi77 <oyi77@users.noreply.github.com> * fix(db): reclassify localDb unexported modules as intentionally-internal (diegosouzapw#3499) (diegosouzapw#3635) Closes diegosouzapw#3499 — reclassify localDb unexported modules as intentionally-internal (audit + honest gate framing). * refactor(db): move call_logs aggregations into callLogStats db module (diegosouzapw#3500) (diegosouzapw#3636) diegosouzapw#3500 slice 1: call_logs aggregations → src/lib/db/callLogStats.ts (Rule diegosouzapw#5). Byte-identical queries; TDD 6/6. * refactor(dashboard): extract EditCompatibleNodeModal — diegosouzapw#3501 Phase 1b (diegosouzapw#3638) diegosouzapw#3501 Phase 1b: extract EditCompatibleNodeModal (cycle-safe via leaf constants module). Co-authored-by: oyi77 <oyi77@users.noreply.github.com> * refactor(db): move community_servers SQL into gamification db module (diegosouzapw#3500 slice 3) (diegosouzapw#3639) diegosouzapw#3500 slice 3: community_servers SQL → gamification db module. * refactor(db): move usage_history SQL into usageAnalytics module (diegosouzapw#3500 slice 2) (diegosouzapw#3644) diegosouzapw#3500 slice 2: usage_history/daily_usage_summary SQL → usageAnalytics db module. * refactor(db): move skills UPDATE + db-backups SQL into db modules (diegosouzapw#3500 slice 5) (diegosouzapw#3647) diegosouzapw#3500 slice 5: skills UPDATE (allowlist) + db-backups SQL → db modules. * refactor(db): move usage_logs/semantic_cache/proxy_logs SQL into db modules (diegosouzapw#3500 slice 4) (diegosouzapw#3648) diegosouzapw#3500 slice 4: usage_logs/semantic_cache/proxy_logs SQL → db modules. All internal routes done (2 external by-design remain). * chore(db-gate): reclassify external-DB reads, fully close diegosouzapw#3500 (diegosouzapw#3649) Closes diegosouzapw#3500: reclassify external-DB reads; all internal raw-SQL migrated to db/ modules. * refactor(dashboard): extract pure helpers to providerPageHelpers — diegosouzapw#3501 Phase 2 (diegosouzapw#3653) diegosouzapw#3501 Phase 2: extract pure helpers to providerPageHelpers (leaf, cycle-safe). Co-authored-by: oyi77 <oyi77@users.noreply.github.com> * refactor(dashboard): extract remaining shared helpers to providerPageHelpers — diegosouzapw#3501 Phase 2b (diegosouzapw#3658) diegosouzapw#3501 Phase 2b: extract remaining shared helpers to providerPageHelpers (leaf, cycle-safe). Heavy modals unblocked. Co-authored-by: oyi77 <oyi77@users.noreply.github.com> * fix(reasoning): replay reasoning_content on plain DeepSeek turns (diegosouzapw#1682) (diegosouzapw#3632) Integrated into release/v3.8.22 * fix(kiro): route enterprise IAM Identity Center accounts to their regional endpoint (diegosouzapw#3631) Integrated into release/v3.8.22 * refactor: small code cleanup (diegosouzapw#3523) Integrated into release/v3.8.22 * fix(combo): skip same-provider targets on 408/500/502/503/504/524 errors (diegosouzapw#3637) Integrated into release/v3.8.22 — circuit-breaker guard added in review (#1731v2) * feat(providers): add MiMoCode free-tier provider with bootstrap JWT auth (diegosouzapw#3659) Integrated into release/v3.8.22 — page.tsx conflict resolved + NoAuthAccountCard re-applied to ProviderDetailPageClient in review. MiMoCode endpoint validated live. * Log Responses WebSocket calls in history (diegosouzapw#3616) Integrated into release/v3.8.22 — Codex Responses WebSocket call history logging. * Add Claude Code routing preference for unprefixed Claude models (diegosouzapw#3540) Integrated into release/v3.8.22 — page.tsx conflict resolved (re-applied toggle to ProviderDetailPageClient) + disable-test updated for catalog drift in review. * docs(changelog): credit diegosouzapw#3632/diegosouzapw#3631/diegosouzapw#3637/diegosouzapw#3659/diegosouzapw#3540/diegosouzapw#3616/diegosouzapw#3523 (v3.8.22 targeted review round) * fix(mimocode): add required authHeader:"none" to registry entry (diegosouzapw#3659 follow-up) The mimocode RegistryEntry omitted the required authHeader field, which broke typecheck:core (TS2741). Match the no-auth convention (authType:"none" + authHeader:"none") used by veoaifree-web and other free providers. Follow-up to diegosouzapw#3659 (@pizzav-xyz). * fix(responses): detect stream readiness for tool-call-only and object-less chunks (diegosouzapw#3612) (diegosouzapw#3661) Closes diegosouzapw#3612 * fix(mitm): remove duplicated 'Command failed:' error prefix (diegosouzapw#3641) (diegosouzapw#3662) Closes diegosouzapw#3641 * fix(cli): honor HERMES_HOME for Hermes Agent config path (diegosouzapw#3628) (diegosouzapw#3663) Closes diegosouzapw#3628 * fix(api): fetch live OpenCode model catalog for no-auth model picker (diegosouzapw#3611) (diegosouzapw#3664) Closes diegosouzapw#3611 * fix(api): flag provider topology error state by current status, not stale history (diegosouzapw#3619) (diegosouzapw#3666) Closes diegosouzapw#3619 * fix(electron): launch peer-stamping server-ws.mjs entrypoint to avoid 403 LOCAL_ONLY (diegosouzapw#3386) (diegosouzapw#3665) Closes diegosouzapw#3386 * fix(dashboard): restore home topology live in-flight pulse (diegosouzapw#3507) (diegosouzapw#3667) Closes diegosouzapw#3507 * fix(oauth): name Kiro/AWS auto-imported accounts and dedupe by profileArn (diegosouzapw#3615) (diegosouzapw#3671) Closes diegosouzapw#3615 * fix(resilience): clear stale transient connection cooldowns on startup (diegosouzapw#3625) (diegosouzapw#3672) Closes diegosouzapw#3625 * fix(i18n): use logical CSS direction utilities for sidebar and key overlays (RTL diegosouzapw#3541) (diegosouzapw#3670) Closes diegosouzapw#3541 * fix(dashboard): honor auto-hide and switch to visible filter on passthrough Test-all (diegosouzapw#3610) (diegosouzapw#3669) Closes diegosouzapw#3610 * refactor(dashboard): extract AddApiKeyModal + EditConnectionModal — diegosouzapw#3501 Phase 1c (diegosouzapw#3674) diegosouzapw#3501 Phase 1c: extract AddApiKeyModal, EditConnectionModal, WebSessionCredentialGuide into components/; god-component 10,166->8,092 LOC. Reconciles the v3.8.22 file-size drift for this file. Co-authored-by: oyi77 <oyi77@users.noreply.github.com> * docs(changelog): reconcile v3.8.22 — credit diegosouzapw#3621/diegosouzapw#3622 + MiMoCode follow-up roll-up * refactor(dashboard): extract ConnectionRow + ModelCompatPopover + SiliconFlowEndpointModal — diegosouzapw#3501 Phase 1d (diegosouzapw#3676) diegosouzapw#3501 Phase 1d: god-component 8,092->6,838 LOC. Co-authored-by: oyi77 <oyi77@users.noreply.github.com> * feat(obsidian): add WebDAV config route + encrypt creds at rest (diegosouzapw#3485 part 1) (diegosouzapw#3677) Part 1 of diegosouzapw#3485. Adds /api/settings/obsidian/webdav (GET/POST/DELETE) wiring the ready obsidianSync lib, encrypts webdav password + obsidian token at rest, removes the duplicate UI block, drops the KNOWN_MISSING entry. WebDAV file server is part 2. * feat(obsidian): add /api/v1/webdav file server for Obsidian vault sync (diegosouzapw#3485 part 2) (diegosouzapw#3678) Part 2 of diegosouzapw#3485. WebDAV server (PROPFIND/GET/PUT/DELETE/MKCOL/MOVE/OPTIONS) handled in the custom server layer (standalone-server-ws.mjs) since the App Router cannot export WebDAV methods. Basic-Auth (constant-time), path-traversal hardened, password decrypt ported from encryption.ts (parity-tested), DATA_DIR resolution parity-tested against dataPaths.ts. End-to-end Obsidian-over-Tailscale validation is a live VPS step (Rule diegosouzapw#18). * fix(combo): stop premature context compaction — real auto-combo windows + per-target compression limit (diegosouzapw#3680) Integrated into release/v3.8.22 * feat(dashboard): deactivate/activate accounts from the quota overview (diegosouzapw#3675) Integrated into release/v3.8.22 * fix(dashboard): close review gaps in bulk provider connection actions (diegosouzapw#3271 follow-up) (diegosouzapw#3673) Integrated into release/v3.8.22 — page.tsx conflict (god-component split diegosouzapw#3501) resolved by re-applying the bulk-action deltas to ProviderDetailPageClient.tsx * refactor(dashboard): extract useModelCompatState hook + model sections — diegosouzapw#3501 Phase 1e (diegosouzapw#3683) diegosouzapw#3501 Phase 1e: extract useModelCompatState hook (unblocks the model sections) + ModelRow/PassthroughModelsSection/PassthroughModelRow/CustomModelsSection/CompatibleModelsSection. god-component 6,838->4,921 LOC. Co-authored-by: oyi77 <oyi77@users.noreply.github.com> * refactor(dashboard): extract useProviderConnections/Settings/Models hooks — diegosouzapw#3501 Phase 1f (diegosouzapw#3684) diegosouzapw#3501 Phase 1f: god-component 4,948->4,062 LOC. Connection state+handlers, settings, and model metadata moved into hooks/. Co-authored-by: oyi77 <oyi77@users.noreply.github.com> * chore(release): v3.8.22 CHANGELOG + env-doc sync - Set release date in CHANGELOG [3.8.22] to 2026-06-11 - Add HERMES_HOME to .env.example (from diegosouzapw#3628/diegosouzapw#3663) - Add HERMES_HOME + OMNIROUTE_PREFER_CLAUDE_CODE_FOR_UNPREFIXED_CLAUDE_MODELS to ENVIRONMENT.md (diegosouzapw#3628/diegosouzapw#3540) * docs(changelog): credit diegosouzapw#3673 + diegosouzapw#3675 — leninejunior bulk-actions + quota-toggle --------- Co-authored-by: oyi77 <oyi77@users.noreply.github.com> Co-authored-by: Abhishek Divekar <adivekar@utexas.edu> Co-authored-by: NOXX - Commiter <artur1992123@mail.ru> Co-authored-by: Nicolas Lorin <androw95220@gmail.com> Co-authored-by: Hernan Javier Ardila Sanchez <hjasgr@gmail.com> Co-authored-by: PizzaV <103120356+pizzav-xyz@users.noreply.github.com> Co-authored-by: kkkayye <98376609+kkkayye@users.noreply.github.com> Co-authored-by: Witroch4 <witalo_rocha@hotmail.com> Co-authored-by: Lenine Júnior <lenine@engrene.com.br>
#3501 Phase 0 — Strangler-fig decomposition of the providers/[id] god-component
First phase of the approved 6-phase plan in #3501 to drive
providers/[id]/page.tsx(the repo's single largest file, 12,882 LOC) under the 800-LOC cap incrementally.What changed (behavior unchanged)
page.tsx→ thin 9-line route wrapper delegating toProviderDetailPageClient, matching the repo's*PageClientconvention (EndpointPageClient / ApiManagerPageClient).ProviderDetailPageClient.tsxholds the unchanged component body. The client reads the route id viauseParams(), so no props are threaded through the wrapper.check-file-sizebaseline now tracksProviderDetailPageClient.tsx; vitestincludeglobs the providers__tests__dir.Validation
typecheck:core: cleancheck:cycles: no cyclescheck-file-size: this change is clean; 4 unrelated pre-existing violations (usage.ts/combo.ts/accountFallback.ts/openai-to-gemini.ts) are v3.8.22-cycle drift to be re-baselined at release time — not introduced here.Context
A contributor (@oyi77) opened #3627 attempting the same decomposition; that PR diverges from the approved plan (no PageClient wrapper, flat file layout, no hook extraction, no tests, big-bang) and is base-contaminated, so it's not merged here — but credited as co-author for the parallel effort. This PR follows the registered plan.
Part of #3501.