* chore(lint): batch 4 of #12146 — resolve the react-hooks compiler violations in shared/components
Real refactors (no suppressions, no eslint-disable) for the 21 react-hooks/*
violations across the 11 src/shared/components files of this batch:
- set-state-in-effect (prop/state mirror or modal open/close reset):
replaced with guarded render-time adjustments (react.dev "You Might Not
Need an Effect" prev-tracking pattern) — KiroAuthModal,
ModelSelectModal, ProxyConfigModal, OAuthModal (provider-change, close
and open resets; ref invalidation split into ref-only effects),
RequestLoggerDetail.sections (liveDetail mirror),
ComboCompressionModeSelect (initialCompressionMode mirror).
- set-state-in-effect (fetch+set effects calling component-scope
functions): moved the async loader inside the effect (ModelSelectModal
fetchCombos/fetchProviderNodes/fetchCustomModels, PricingModal
loadPricing, useProviderDailyUsage fetchRows — now with a cancelled
guard) or wrapped the call in an effect-local async runner
(ReasoningRoutingRules load, UsageStats fetchStats, OAuthModal
startOAuthFlow) with every setState on the async path.
- OAuthModal device-code countdown: deviceCodeSecondsRemaining state
deleted and derived from deviceCodeExpiresAt plus a `now` tick state
updated by the interval (re-anchored when polling starts).
- Sidebar localStorage hydration: reads moved into useSyncExternalStore
snapshots (server snapshot null) applied via render-time adjustment;
skipInitialActiveExpansion ref converted to state; the active-section
expansion effect became a render-time adjustment keyed on the old
effect deps; persistence consolidated into one saveToStorage effect
(removes the saves that ran inside setState updaters and drops a
pre-existing eslint-disable for exhaustive-deps).
- immutability (use-before-declare): PricingModal loadPricing inlined
into its effect; ProxyConfigModal resetFields hoisted above the load
effect as a dependency-free useCallback.
- exhaustive-deps (ProxyConfigModal): effect now depends on the stable
resetFields and on hoisted translated strings (socks5HiddenError,
levelGlobalLabel) instead of the `t` identity.
- preserve-manual-memoization (UsageStats sortedAccounts): optional
chains destructured into locals so the memo deps match the usage.
config/quality/eslint-suppressions.json: removed every react-hooks/*
entry for the 11 files (other-rule entries preserved).
Validation: eslint gate (--suppressions-location, --max-warnings 0) green
on all 11 files; typecheck:core clean; node unit sweep 373/373; vitest
sweep 547/550 with the 3 fails being 5s-timeout flakes under parallel
load (all pass isolated 8/8, one in an untouched file).
Refs #12146
* test(mutation): register search-432-plan-limit-cooldown in tap.testFiles
The test (merged with the DuckDuckGo cooldown fix) covers accountFallback.ts and
auth.ts but was not listed, so check:mutation-test-coverage --strict reds any PR
whose merge ref includes it. Base also merged in.
* feat(routing): add reasoning-based model and effort routing
* refactor(routing): modularize reasoning and auto-routing pipeline
* fix(routing): remove redundant DB re-export and prevent SQL scan false positives
* fix(routing): resolve reasoning routing review blockers
* fix(i18n): keep release ranking fallbacks outside reasoning
* fix(db): renumber reasoning-routing migration past release tip (124→125)
124_generic_session_affinity_ttl.sql (#7274) has since landed on
release/v3.8.49 at version 124, colliding with this PR's own
124_reasoning_routing_rules.sql. Renumbers to 125 (the next free slot
past the current release tip) and updates the one filename reference
in docs/routing/REASONING_ROUTING.md.
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
* chore(db): renumber reasoning-routing migration 125→126 (slot taken by #7360)
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
* refactor(api): compact temp-path decls in exportAll GET (complexity-ratchet lines budget)
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
* refactor(api): single-statement auth guard in exportAll GET (function under 80-line cap)
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
---------
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>