Skip to content

Settings split pass 9: hoist AI settings logic into a hook (SettingsView 5.2k) - #156

Merged
AdamXweb merged 1 commit into
mainfrom
refactor/settings-ai-summaries
Aug 3, 2026
Merged

Settings split pass 9: hoist AI settings logic into a hook (SettingsView 5.2k)#156
AdamXweb merged 1 commit into
mainfrom
refactor/settings-ai-summaries

Conversation

@adamXbot

@adamXbot adamXbot commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator

Pass 9 — AI Summaries, stage 1 (logic)

SettingsView.tsx 5,643 → 5,204 (−439), with zero JSX changes. Branched from a clean main — passes 6–8 are all merged.

What moved

The AI Summaries card's whole state machine: provider / base-URL / model / key form state, the connection test, model discovery against a custom endpoint, the sample-policy dry run, the three per-phase request timeouts, and the debounced blob auto-save. That's ~480 lines spread across six regions of SettingsView.

The JSX is deliberately untouched — hook fields are renamed back on destructure, so all nine diff hunks land above the first return ( at line 3037. This reviews as "did the logic move intact?" without a markup diff. The 791-line markup move is the next pass.

Inputs are five: showToast, three translators used by the auto-save toast labels, the task-center handle, and loadSettings. Three more that the identifier sweep suggested — base, schedule, toast — turned out to be matches inside comments, checked before threading them.

Deliberate leaks, returned rather than kept private:

  • aiProvider — the timeouts panel disables its inputs when AI is off
  • saveAiSettings + debugLogging — the Developer Options debug toggle round-trips through this same blob
  • the three aiTimeout* values and their auto-savers, which the timeouts panel owns visually but which belong to this blob

hydrate() is the seam for the shared settings loader: it reads every settings key in one request, so it hands the AI slice over in one call rather than this hook mounting a duplicate fetch.

StoredAiSettings and AiSamplePolicyResult move to settings/types.ts — both sides need them now.

The hook call sits below showToast and loadSettings rather than where the state block was; both are const arrows, so the original position was a TDZ error. Same fix as use-import-history.

Verification

tsc, biome, 441 unit tests, full Playwright suite 45 passed.

⚠️ Local installs are currently broken on main (not caused by this PR)

pnpm install fails with:

ERR_PNPM_MINIMUM_RELEASE_AGE_VIOLATION
ultracite@7.10.0 was published at 2026-08-02T09:14:16Z, within the minimumReleaseAge cutoff

It arrived via the Renovate bump in #154. CI is unaffected#154 merged green, so the policy is local, not in the repo config. It resolves itself as the package ages.

Worth knowing because it fails confusingly: pnpm typecheck exits 0 while never running tsc, so a broken tree can look clean. Worse, the aborted install had already removed 83 packages from node_modules, which then surfaced as an unrelated "cannot find @axe-core/playwright" error.

Until it ages out:

pnpm install --frozen-lockfile --config.minimumReleaseAge=0

and --config.verifyDepsBeforeRun=false on pnpm test / build / test:e2e.

Phase 3 running total

SettingsView
Start 11,460
Passes 1–8 (main) 5,643
Pass 9 (this) 5,204

−55%. Stage 2 moves the remaining 791-line AI markup, and that completes the section extraction.

🤖 Generated with Claude Code

Stage 1 of the last section. The AI Summaries card's state machine —
provider/base-URL/model/key form state, the connection test, model
discovery against a custom endpoint, the sample-policy dry run, the three
per-phase request timeouts, and the debounced blob auto-save — moves to
lib/use-ai-settings.ts. That is ~480 lines spread across six regions of
SettingsView.

The JSX is untouched: hook fields are renamed back on destructure, so all
nine diff hunks land above the first `return (` at line 3037. The
791-line markup move is the next pass.

Inputs are five: showToast, three translators used by the auto-save toast
labels, the task-center handle, and loadSettings. Nothing else crossed
the boundary. Three more candidates the identifier sweep suggested —
`base`, `schedule`, `toast` — turned out to be matches inside comments.

Several bindings leak deliberately and are returned rather than kept
private: `aiProvider` (the timeouts panel disables its inputs when AI is
off), `saveAiSettings` + `debugLogging` (the Developer Options debug
toggle round-trips through this same blob), and the three `aiTimeout*`
values with their auto-savers.

`hydrate()` is the seam for the shared settings loader: it reads every
settings key in one request, so it hands the AI slice over in a single
call rather than this hook mounting a duplicate fetch.

Four types move to ./settings/types.ts — StoredAiSettings and
AiSamplePolicyResult, which both sides now need.

The hook call sits below `showToast` and `loadSettings` rather than where
the state block was, for the same TDZ reason as use-import-history: both
are const arrows.

SettingsView 5,643 -> 5,204.

Verified with tsc, biome, 441 unit tests and the full Playwright suite
(45 passed).

Note for anyone verifying locally: `pnpm install` currently fails on this
repo with ERR_PNPM_MINIMUM_RELEASE_AGE_VIOLATION for ultracite@7.10.0,
which arrived via the Renovate bump in #154 and is newer than pnpm's
release-age cutoff. It is a local policy, not a CI one (#154 merged
green), and it resolves itself as the package ages. Until then,
`--config.minimumReleaseAge=0` on install and
`--config.verifyDepsBeforeRun=false` on run get you moving.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@adamXbot
adamXbot requested a review from AdamXweb as a code owner August 3, 2026 02:33
aiTimeoutMergeMs,
setAiTimeoutMergeMs,
aiTestStatus,
setAiTestStatus,
aiTestStatus,
setAiTestStatus,
aiTestMessage,
setAiTestMessage,
aiTestMessage,
setAiTestMessage,
aiTestLatency,
setAiTestLatency,
aiTestLatency,
setAiTestLatency,
aiSampleStatus,
setAiSampleStatus,
aiSampleStatus,
setAiSampleStatus,
aiSampleMessage,
setAiSampleMessage,
aiSampleMessage,
setAiSampleMessage,
aiSampleResult,
setAiSampleResult,
aiSampleResult,
setAiSampleResult,
discoveredModels,
setDiscoveredModels,
discoveredModels,
setDiscoveredModels,
modelsStatus,
setModelsStatus,
modelsStatus,
setModelsStatus,
modelsError,
setModelsError,
Comment thread lib/use-ai-settings.ts
import { useSettingsAutoSave } from "@/lib/use-settings-auto-save";
import { fmtDuration } from "@/app/components/settings/format";
import type { useTaskCenter } from "@/app/components/TaskCenter";
import { pushSettingsToast } from "@/app/components/SettingsAutoSaveToast";
@AdamXweb
AdamXweb merged commit c862bd3 into main Aug 3, 2026
8 of 13 checks passed
@AdamXweb
AdamXweb deleted the refactor/settings-ai-summaries branch August 3, 2026 07:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants