Repository navigation
refactor(dashboard): #3501 Phase 1c — extract AddApiKey + EditConnection modals - #3674
Conversation
|
Warning You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again! |
| import EditCompatibleNodeModal from "./components/modals/EditCompatibleNodeModal"; | ||
| import AddApiKeyModal from "./components/modals/AddApiKeyModal"; | ||
| import EditConnectionModal from "./components/modals/EditConnectionModal"; | ||
| import WebSessionCredentialGuide from "./components/WebSessionCredentialGuide"; |
There was a problem hiding this comment.
WARNING: Unused import - WebSessionCredentialGuide is imported here but not referenced elsewhere in this file.
This should fail lint under the usual no-unused-imports rule. Remove the import or use the component in the rendered tree.
| runtime_error: { labelKey: "errorTypeRuntime", variant: "warning" }, | ||
| upstream_auth_error: { labelKey: "errorTypeUpstreamAuth", variant: "error" }, | ||
| account_deactivated: { labelKey: "Account Deactivated", variant: "error" }, | ||
| auth_missing: { labelKey: "errorTypeMissingCredential", variant: "warning" }, |
There was a problem hiding this comment.
WARNING: ERROR_TYPE_LABELS.variant is widened to string, which can break Badge prop typing.
Badge only accepts keyof typeof variants, so this shared map should use a narrowed variant union to keep testErrorMeta.variant type-safe.
| token_refresh_failed: { labelKey: "errorTypeRefreshFailed", variant: "warning" }, | ||
| token_expired: { labelKey: "errorTypeTokenExpired", variant: "warning" }, | ||
| upstream_rate_limited: { labelKey: "errorTypeRateLimited", variant: "warning" }, | ||
| upstream_unavailable: { labelKey: "errorTypeUpstreamUnavailable", variant: "error" }, |
There was a problem hiding this comment.
SUGGESTION: account_deactivated.labelKey is not an i18n key in most locales.
The repo only has a literal "Account Deactivated" translation in en.json; other locales do not. Use a real translation key or a fallback path so localized UI does not render the key text.
| // --------------------------------------------------------------------------- | ||
| export function formatTimeAgo(dateStr: string): string { | ||
| const now = Date.now(); | ||
| const date = new Date(dateStr).getTime(); |
There was a problem hiding this comment.
SUGGESTION: formatTimeAgo can render NaNm ago for malformed health timestamps.
If lastFailure is ever absent, empty, or invalid, new Date(dateStr).getTime() becomes NaN and the existing comparisons do not catch it. Guard with Number.isNaN(date) before computing the delta.
|
|
||
| const handleBulkSubmit = async () => { | ||
| if (!provider) return; | ||
| const parsed = parseBulkApiKeys(bulkText); |
There was a problem hiding this comment.
SUGGESTION: Bulk-add stale results are not cleared when parsed input has no entries.
setBulkWarnings(parsed.warnings) runs before the empty-entries return, but bulkResult remains visible from a previous successful bulk add. Clear bulkResult before returning for zero parsed entries.
| } | ||
| validatedBaseUrl = checked.value; | ||
| } | ||
|
|
There was a problem hiding this comment.
WARNING: Edit save can skip re-validation after validation inputs change.
validationResult === "success" is treated as sufficient even if the user changes baseUrl, cx, region, or customUserAgent after clicking Check. That can persist an API key as validated for a different target configuration. Clear validationResult on relevant input changes or force re-validation during save.
| extraApiKeys: extraApiKeys.filter((k) => k.trim().length > 0), | ||
| tag: formData.tag.trim() || undefined, | ||
| tags: parseRoutingTagsInput(formData.routingTags), | ||
| excludedModels: parseExcludedModelsInput(formData.excludedModels), |
There was a problem hiding this comment.
WARNING: passthroughModels cannot be disabled once enabled.
When the toggle is off, the field is omitted and the existing true value is preserved by the spread. Persist an explicit undefined/delete path when disabled so users can turn this setting off.
| updates.providerSpecificData.consoleApiKey = undefined; | ||
| } | ||
| } | ||
| if (formData.validationModelId) { |
There was a problem hiding this comment.
WARNING: validationModelId cannot be cleared from the edit modal.
The code only writes the field when formData.validationModelId is truthy, so clearing the input preserves the old providerSpecificData value. Write formData.validationModelId.trim() || undefined instead.
| if (usesBaseUrl) { | ||
| updates.providerSpecificData.baseUrl = validatedBaseUrl; | ||
| } else if (showsRegion) { | ||
| updates.providerSpecificData.region = formData.region.trim() || defaultRegion; |
There was a problem hiding this comment.
WARNING: Cloudflare accountId cannot be cleared from the edit modal.
The field is only written when non-empty, so deleting the input preserves the previous accountId via the existing providerSpecificData spread. Handle the empty case explicitly with undefined.
Code Review SummaryStatus: 9 Issues Found | Recommendation: Address before merge Overview
Issue Details (click to expand)CRITICAL
WARNING
SUGGESTION
Other Observations (not in diff)No additional unchanged-code issues identified. Files Reviewed (8 files)
Fix these issues in Kilo Cloud Reviewed by nex-n2-pro:free · 6,810,221 tokens |
* 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>
* chore(release): open v3.8.22 development cycle * refactor(dashboard): extract ProviderDetailPageClient — cheaper-inference#3501 Phase 0 (cheaper-inference#3633) cheaper-inference#3501 Phase 0: extract ProviderDetailPageClient + smoke test. Co-authored-by: oyi77 <oyi77@users.noreply.github.com> * refactor(dashboard): extract auth-import modals — cheaper-inference#3501 Phase 1a (cheaper-inference#3634) cheaper-inference#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 (cheaper-inference#3499) (cheaper-inference#3635) Closes cheaper-inference#3499 — reclassify localDb unexported modules as intentionally-internal (audit + honest gate framing). * refactor(db): move call_logs aggregations into callLogStats db module (cheaper-inference#3500) (cheaper-inference#3636) cheaper-inference#3500 slice 1: call_logs aggregations → src/lib/db/callLogStats.ts (Rule cheaper-inference#5). Byte-identical queries; TDD 6/6. * refactor(dashboard): extract EditCompatibleNodeModal — cheaper-inference#3501 Phase 1b (cheaper-inference#3638) cheaper-inference#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 (cheaper-inference#3500 slice 3) (cheaper-inference#3639) cheaper-inference#3500 slice 3: community_servers SQL → gamification db module. * refactor(db): move usage_history SQL into usageAnalytics module (cheaper-inference#3500 slice 2) (cheaper-inference#3644) cheaper-inference#3500 slice 2: usage_history/daily_usage_summary SQL → usageAnalytics db module. * refactor(db): move skills UPDATE + db-backups SQL into db modules (cheaper-inference#3500 slice 5) (cheaper-inference#3647) cheaper-inference#3500 slice 5: skills UPDATE (allowlist) + db-backups SQL → db modules. * refactor(db): move usage_logs/semantic_cache/proxy_logs SQL into db modules (cheaper-inference#3500 slice 4) (cheaper-inference#3648) cheaper-inference#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 cheaper-inference#3500 (cheaper-inference#3649) Closes cheaper-inference#3500: reclassify external-DB reads; all internal raw-SQL migrated to db/ modules. * refactor(dashboard): extract pure helpers to providerPageHelpers — cheaper-inference#3501 Phase 2 (cheaper-inference#3653) cheaper-inference#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 — cheaper-inference#3501 Phase 2b (cheaper-inference#3658) cheaper-inference#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 (cheaper-inference#1682) (cheaper-inference#3632) Integrated into release/v3.8.22 * fix(kiro): route enterprise IAM Identity Center accounts to their regional endpoint (cheaper-inference#3631) Integrated into release/v3.8.22 * refactor: small code cleanup (cheaper-inference#3523) Integrated into release/v3.8.22 * fix(combo): skip same-provider targets on 408/500/502/503/504/524 errors (cheaper-inference#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 (cheaper-inference#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 (cheaper-inference#3616) Integrated into release/v3.8.22 — Codex Responses WebSocket call history logging. * Add Claude Code routing preference for unprefixed Claude models (cheaper-inference#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 cheaper-inference#3632/cheaper-inference#3631/cheaper-inference#3637/cheaper-inference#3659/cheaper-inference#3540/cheaper-inference#3616/cheaper-inference#3523 (v3.8.22 targeted review round) * fix(mimocode): add required authHeader:"none" to registry entry (cheaper-inference#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 cheaper-inference#3659 (@pizzav-xyz). * fix(responses): detect stream readiness for tool-call-only and object-less chunks (cheaper-inference#3612) (cheaper-inference#3661) Closes cheaper-inference#3612 * fix(mitm): remove duplicated 'Command failed:' error prefix (cheaper-inference#3641) (cheaper-inference#3662) Closes cheaper-inference#3641 * fix(cli): honor HERMES_HOME for Hermes Agent config path (cheaper-inference#3628) (cheaper-inference#3663) Closes cheaper-inference#3628 * fix(api): fetch live OpenCode model catalog for no-auth model picker (cheaper-inference#3611) (cheaper-inference#3664) Closes cheaper-inference#3611 * fix(api): flag provider topology error state by current status, not stale history (cheaper-inference#3619) (cheaper-inference#3666) Closes cheaper-inference#3619 * fix(electron): launch peer-stamping server-ws.mjs entrypoint to avoid 403 LOCAL_ONLY (cheaper-inference#3386) (cheaper-inference#3665) Closes cheaper-inference#3386 * fix(dashboard): restore home topology live in-flight pulse (cheaper-inference#3507) (cheaper-inference#3667) Closes cheaper-inference#3507 * fix(oauth): name Kiro/AWS auto-imported accounts and dedupe by profileArn (cheaper-inference#3615) (cheaper-inference#3671) Closes cheaper-inference#3615 * fix(resilience): clear stale transient connection cooldowns on startup (cheaper-inference#3625) (cheaper-inference#3672) Closes cheaper-inference#3625 * fix(i18n): use logical CSS direction utilities for sidebar and key overlays (RTL cheaper-inference#3541) (cheaper-inference#3670) Closes cheaper-inference#3541 * fix(dashboard): honor auto-hide and switch to visible filter on passthrough Test-all (cheaper-inference#3610) (cheaper-inference#3669) Closes cheaper-inference#3610 * refactor(dashboard): extract AddApiKeyModal + EditConnectionModal — cheaper-inference#3501 Phase 1c (cheaper-inference#3674) cheaper-inference#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 cheaper-inference#3621/cheaper-inference#3622 + MiMoCode follow-up roll-up * refactor(dashboard): extract ConnectionRow + ModelCompatPopover + SiliconFlowEndpointModal — cheaper-inference#3501 Phase 1d (cheaper-inference#3676) cheaper-inference#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 (cheaper-inference#3485 part 1) (cheaper-inference#3677) Part 1 of cheaper-inference#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 (cheaper-inference#3485 part 2) (cheaper-inference#3678) Part 2 of cheaper-inference#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 cheaper-inference#18). * fix(combo): stop premature context compaction — real auto-combo windows + per-target compression limit (cheaper-inference#3680) Integrated into release/v3.8.22 * feat(dashboard): deactivate/activate accounts from the quota overview (cheaper-inference#3675) Integrated into release/v3.8.22 * fix(dashboard): close review gaps in bulk provider connection actions (cheaper-inference#3271 follow-up) (cheaper-inference#3673) Integrated into release/v3.8.22 — page.tsx conflict (god-component split cheaper-inference#3501) resolved by re-applying the bulk-action deltas to ProviderDetailPageClient.tsx * refactor(dashboard): extract useModelCompatState hook + model sections — cheaper-inference#3501 Phase 1e (cheaper-inference#3683) cheaper-inference#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 — cheaper-inference#3501 Phase 1f (cheaper-inference#3684) cheaper-inference#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 cheaper-inference#3628/cheaper-inference#3663) - Add HERMES_HOME + OMNIROUTE_PREFER_CLAUDE_CODE_FOR_UNPREFIXED_CLAUDE_MODELS to ENVIRONMENT.md (cheaper-inference#3628/cheaper-inference#3540) * docs(changelog): credit cheaper-inference#3673 + cheaper-inference#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 — cheaper-inference#3501 Phase 0 (cheaper-inference#3633) cheaper-inference#3501 Phase 0: extract ProviderDetailPageClient + smoke test. Co-authored-by: oyi77 <oyi77@users.noreply.github.com> * refactor(dashboard): extract auth-import modals — cheaper-inference#3501 Phase 1a (cheaper-inference#3634) cheaper-inference#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 (cheaper-inference#3499) (cheaper-inference#3635) Closes cheaper-inference#3499 — reclassify localDb unexported modules as intentionally-internal (audit + honest gate framing). * refactor(db): move call_logs aggregations into callLogStats db module (cheaper-inference#3500) (cheaper-inference#3636) cheaper-inference#3500 slice 1: call_logs aggregations → src/lib/db/callLogStats.ts (Rule cheaper-inference#5). Byte-identical queries; TDD 6/6. * refactor(dashboard): extract EditCompatibleNodeModal — cheaper-inference#3501 Phase 1b (cheaper-inference#3638) cheaper-inference#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 (cheaper-inference#3500 slice 3) (cheaper-inference#3639) cheaper-inference#3500 slice 3: community_servers SQL → gamification db module. * refactor(db): move usage_history SQL into usageAnalytics module (cheaper-inference#3500 slice 2) (cheaper-inference#3644) cheaper-inference#3500 slice 2: usage_history/daily_usage_summary SQL → usageAnalytics db module. * refactor(db): move skills UPDATE + db-backups SQL into db modules (cheaper-inference#3500 slice 5) (cheaper-inference#3647) cheaper-inference#3500 slice 5: skills UPDATE (allowlist) + db-backups SQL → db modules. * refactor(db): move usage_logs/semantic_cache/proxy_logs SQL into db modules (cheaper-inference#3500 slice 4) (cheaper-inference#3648) cheaper-inference#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 cheaper-inference#3500 (cheaper-inference#3649) Closes cheaper-inference#3500: reclassify external-DB reads; all internal raw-SQL migrated to db/ modules. * refactor(dashboard): extract pure helpers to providerPageHelpers — cheaper-inference#3501 Phase 2 (cheaper-inference#3653) cheaper-inference#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 — cheaper-inference#3501 Phase 2b (cheaper-inference#3658) cheaper-inference#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 (cheaper-inference#1682) (cheaper-inference#3632) Integrated into release/v3.8.22 * fix(kiro): route enterprise IAM Identity Center accounts to their regional endpoint (cheaper-inference#3631) Integrated into release/v3.8.22 * refactor: small code cleanup (cheaper-inference#3523) Integrated into release/v3.8.22 * fix(combo): skip same-provider targets on 408/500/502/503/504/524 errors (cheaper-inference#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 (cheaper-inference#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 (cheaper-inference#3616) Integrated into release/v3.8.22 — Codex Responses WebSocket call history logging. * Add Claude Code routing preference for unprefixed Claude models (cheaper-inference#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 cheaper-inference#3632/cheaper-inference#3631/cheaper-inference#3637/cheaper-inference#3659/cheaper-inference#3540/cheaper-inference#3616/cheaper-inference#3523 (v3.8.22 targeted review round) * fix(mimocode): add required authHeader:"none" to registry entry (cheaper-inference#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 cheaper-inference#3659 (@pizzav-xyz). * fix(responses): detect stream readiness for tool-call-only and object-less chunks (cheaper-inference#3612) (cheaper-inference#3661) Closes cheaper-inference#3612 * fix(mitm): remove duplicated 'Command failed:' error prefix (cheaper-inference#3641) (cheaper-inference#3662) Closes cheaper-inference#3641 * fix(cli): honor HERMES_HOME for Hermes Agent config path (cheaper-inference#3628) (cheaper-inference#3663) Closes cheaper-inference#3628 * fix(api): fetch live OpenCode model catalog for no-auth model picker (cheaper-inference#3611) (cheaper-inference#3664) Closes cheaper-inference#3611 * fix(api): flag provider topology error state by current status, not stale history (cheaper-inference#3619) (cheaper-inference#3666) Closes cheaper-inference#3619 * fix(electron): launch peer-stamping server-ws.mjs entrypoint to avoid 403 LOCAL_ONLY (cheaper-inference#3386) (cheaper-inference#3665) Closes cheaper-inference#3386 * fix(dashboard): restore home topology live in-flight pulse (cheaper-inference#3507) (cheaper-inference#3667) Closes cheaper-inference#3507 * fix(oauth): name Kiro/AWS auto-imported accounts and dedupe by profileArn (cheaper-inference#3615) (cheaper-inference#3671) Closes cheaper-inference#3615 * fix(resilience): clear stale transient connection cooldowns on startup (cheaper-inference#3625) (cheaper-inference#3672) Closes cheaper-inference#3625 * fix(i18n): use logical CSS direction utilities for sidebar and key overlays (RTL cheaper-inference#3541) (cheaper-inference#3670) Closes cheaper-inference#3541 * fix(dashboard): honor auto-hide and switch to visible filter on passthrough Test-all (cheaper-inference#3610) (cheaper-inference#3669) Closes cheaper-inference#3610 * refactor(dashboard): extract AddApiKeyModal + EditConnectionModal — cheaper-inference#3501 Phase 1c (cheaper-inference#3674) cheaper-inference#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 cheaper-inference#3621/cheaper-inference#3622 + MiMoCode follow-up roll-up * refactor(dashboard): extract ConnectionRow + ModelCompatPopover + SiliconFlowEndpointModal — cheaper-inference#3501 Phase 1d (cheaper-inference#3676) cheaper-inference#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 (cheaper-inference#3485 part 1) (cheaper-inference#3677) Part 1 of cheaper-inference#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 (cheaper-inference#3485 part 2) (cheaper-inference#3678) Part 2 of cheaper-inference#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 cheaper-inference#18). * fix(combo): stop premature context compaction — real auto-combo windows + per-target compression limit (cheaper-inference#3680) Integrated into release/v3.8.22 * feat(dashboard): deactivate/activate accounts from the quota overview (cheaper-inference#3675) Integrated into release/v3.8.22 * fix(dashboard): close review gaps in bulk provider connection actions (cheaper-inference#3271 follow-up) (cheaper-inference#3673) Integrated into release/v3.8.22 — page.tsx conflict (god-component split cheaper-inference#3501) resolved by re-applying the bulk-action deltas to ProviderDetailPageClient.tsx * refactor(dashboard): extract useModelCompatState hook + model sections — cheaper-inference#3501 Phase 1e (cheaper-inference#3683) cheaper-inference#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 — cheaper-inference#3501 Phase 1f (cheaper-inference#3684) cheaper-inference#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 cheaper-inference#3628/cheaper-inference#3663) - Add HERMES_HOME + OMNIROUTE_PREFER_CLAUDE_CODE_FOR_UNPREFIXED_CLAUDE_MODELS to ENVIRONMENT.md (cheaper-inference#3628/cheaper-inference#3540) * docs(changelog): credit cheaper-inference#3673 + cheaper-inference#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>
…heaper-inference#3501 Phase 1c (cheaper-inference#3674) cheaper-inference#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>
* chore(release): open v3.8.22 development cycle * refactor(dashboard): extract ProviderDetailPageClient — cheaper-inference#3501 Phase 0 (cheaper-inference#3633) cheaper-inference#3501 Phase 0: extract ProviderDetailPageClient + smoke test. Co-authored-by: oyi77 <oyi77@users.noreply.github.com> * refactor(dashboard): extract auth-import modals — cheaper-inference#3501 Phase 1a (cheaper-inference#3634) cheaper-inference#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 (cheaper-inference#3499) (cheaper-inference#3635) Closes cheaper-inference#3499 — reclassify localDb unexported modules as intentionally-internal (audit + honest gate framing). * refactor(db): move call_logs aggregations into callLogStats db module (cheaper-inference#3500) (cheaper-inference#3636) cheaper-inference#3500 slice 1: call_logs aggregations → src/lib/db/callLogStats.ts (Rule cheaper-inference#5). Byte-identical queries; TDD 6/6. * refactor(dashboard): extract EditCompatibleNodeModal — cheaper-inference#3501 Phase 1b (cheaper-inference#3638) cheaper-inference#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 (cheaper-inference#3500 slice 3) (cheaper-inference#3639) cheaper-inference#3500 slice 3: community_servers SQL → gamification db module. * refactor(db): move usage_history SQL into usageAnalytics module (cheaper-inference#3500 slice 2) (cheaper-inference#3644) cheaper-inference#3500 slice 2: usage_history/daily_usage_summary SQL → usageAnalytics db module. * refactor(db): move skills UPDATE + db-backups SQL into db modules (cheaper-inference#3500 slice 5) (cheaper-inference#3647) cheaper-inference#3500 slice 5: skills UPDATE (allowlist) + db-backups SQL → db modules. * refactor(db): move usage_logs/semantic_cache/proxy_logs SQL into db modules (cheaper-inference#3500 slice 4) (cheaper-inference#3648) cheaper-inference#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 cheaper-inference#3500 (cheaper-inference#3649) Closes cheaper-inference#3500: reclassify external-DB reads; all internal raw-SQL migrated to db/ modules. * refactor(dashboard): extract pure helpers to providerPageHelpers — cheaper-inference#3501 Phase 2 (cheaper-inference#3653) cheaper-inference#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 — cheaper-inference#3501 Phase 2b (cheaper-inference#3658) cheaper-inference#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 (cheaper-inference#1682) (cheaper-inference#3632) Integrated into release/v3.8.22 * fix(kiro): route enterprise IAM Identity Center accounts to their regional endpoint (cheaper-inference#3631) Integrated into release/v3.8.22 * refactor: small code cleanup (cheaper-inference#3523) Integrated into release/v3.8.22 * fix(combo): skip same-provider targets on 408/500/502/503/504/524 errors (cheaper-inference#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 (cheaper-inference#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 (cheaper-inference#3616) Integrated into release/v3.8.22 — Codex Responses WebSocket call history logging. * Add Claude Code routing preference for unprefixed Claude models (cheaper-inference#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 cheaper-inference#3632/cheaper-inference#3631/cheaper-inference#3637/cheaper-inference#3659/cheaper-inference#3540/cheaper-inference#3616/cheaper-inference#3523 (v3.8.22 targeted review round) * fix(mimocode): add required authHeader:"none" to registry entry (cheaper-inference#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 cheaper-inference#3659 (@pizzav-xyz). * fix(responses): detect stream readiness for tool-call-only and object-less chunks (cheaper-inference#3612) (cheaper-inference#3661) Closes cheaper-inference#3612 * fix(mitm): remove duplicated 'Command failed:' error prefix (cheaper-inference#3641) (cheaper-inference#3662) Closes cheaper-inference#3641 * fix(cli): honor HERMES_HOME for Hermes Agent config path (cheaper-inference#3628) (cheaper-inference#3663) Closes cheaper-inference#3628 * fix(api): fetch live OpenCode model catalog for no-auth model picker (cheaper-inference#3611) (cheaper-inference#3664) Closes cheaper-inference#3611 * fix(api): flag provider topology error state by current status, not stale history (cheaper-inference#3619) (cheaper-inference#3666) Closes cheaper-inference#3619 * fix(electron): launch peer-stamping server-ws.mjs entrypoint to avoid 403 LOCAL_ONLY (cheaper-inference#3386) (cheaper-inference#3665) Closes cheaper-inference#3386 * fix(dashboard): restore home topology live in-flight pulse (cheaper-inference#3507) (cheaper-inference#3667) Closes cheaper-inference#3507 * fix(oauth): name Kiro/AWS auto-imported accounts and dedupe by profileArn (cheaper-inference#3615) (cheaper-inference#3671) Closes cheaper-inference#3615 * fix(resilience): clear stale transient connection cooldowns on startup (cheaper-inference#3625) (cheaper-inference#3672) Closes cheaper-inference#3625 * fix(i18n): use logical CSS direction utilities for sidebar and key overlays (RTL cheaper-inference#3541) (cheaper-inference#3670) Closes cheaper-inference#3541 * fix(dashboard): honor auto-hide and switch to visible filter on passthrough Test-all (cheaper-inference#3610) (cheaper-inference#3669) Closes cheaper-inference#3610 * refactor(dashboard): extract AddApiKeyModal + EditConnectionModal — cheaper-inference#3501 Phase 1c (cheaper-inference#3674) cheaper-inference#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 cheaper-inference#3621/cheaper-inference#3622 + MiMoCode follow-up roll-up * refactor(dashboard): extract ConnectionRow + ModelCompatPopover + SiliconFlowEndpointModal — cheaper-inference#3501 Phase 1d (cheaper-inference#3676) cheaper-inference#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 (cheaper-inference#3485 part 1) (cheaper-inference#3677) Part 1 of cheaper-inference#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 (cheaper-inference#3485 part 2) (cheaper-inference#3678) Part 2 of cheaper-inference#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 cheaper-inference#18). * fix(combo): stop premature context compaction — real auto-combo windows + per-target compression limit (cheaper-inference#3680) Integrated into release/v3.8.22 * feat(dashboard): deactivate/activate accounts from the quota overview (cheaper-inference#3675) Integrated into release/v3.8.22 * fix(dashboard): close review gaps in bulk provider connection actions (cheaper-inference#3271 follow-up) (cheaper-inference#3673) Integrated into release/v3.8.22 — page.tsx conflict (god-component split cheaper-inference#3501) resolved by re-applying the bulk-action deltas to ProviderDetailPageClient.tsx * refactor(dashboard): extract useModelCompatState hook + model sections — cheaper-inference#3501 Phase 1e (cheaper-inference#3683) cheaper-inference#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 — cheaper-inference#3501 Phase 1f (cheaper-inference#3684) cheaper-inference#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 cheaper-inference#3628/cheaper-inference#3663) - Add HERMES_HOME + OMNIROUTE_PREFER_CLAUDE_CODE_FOR_UNPREFIXED_CLAUDE_MODELS to ENVIRONMENT.md (cheaper-inference#3628/cheaper-inference#3540) * docs(changelog): credit cheaper-inference#3673 + cheaper-inference#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>
Part of #3501 (god-component decomposition). Phase 1c.
Co-authored-by: oyi77 oyi77@users.noreply.github.com