Uh oh!
There was an error while loading. Please reload this page.
refactor(renderer): app-shell state-cluster decomposition — 4/5 blades (Round B) - #876
Merged
Merged
Conversation
…ding-action sets Replace the four hand-rolled keyed de-dup registries (turn-footer actions with state+timers, session-row actions, per-session permission-mode and model changes) with one generic useKeyedPendingRegistry. Only the turn-footer instance opts into the React-visible state mirror + 5s auto-clear timers; the other three stay ref-only and keep clearing in their action factories' finally blocks. keysRef stays a stable Set so the action factories and the unmount cleanup effect operate on the same object — zero behavior change. Re-pin the source-slice contracts (sticky-model, permission-mode presentation, row-actions fail-soft) to the registry form. Blade 1 of Round B app-shell decomposition.
Move the workspace / project-picker cluster (appInfo + git status, branch list + pending flag, recent-workspace history, project-picker pending state and its dedup refs) plus the createAppShellProjectActions wiring into a dedicated hook. Seeds still come from the persisted composer defaults; the picker refs are returned for the bootstrap unmount cleanup. Pure move, zero behavior change. Add the two new hook files to the renderer shell source allowlist so combined-source contracts keep seeing the moved decls. Blade 3 of Round B app-shell decomposition.
Move the two sidebar-module data clusters — skills / managed sources / bundled catalog and plan reminders — plus their createAppShellSkillActions and createAppShellPlanActions wiring into one hook. The surface-active predicates are injected so mutation error toasts stay scoped to the foreground module, and the plan getter still reads the latest reminders per call. Pure move, zero behavior change. Blade 4 of Round B app-shell decomposition.
Move the LLM-connection cluster — the connection list, default-connection slug, connectionsEqual dedup, refreshConnections, and handleConnectionEvent — into a dedicated hook. setConnections/setDefaultConnection are returned so the onboarding-snapshot seed (which stays in AppShell to also seed sessions) can prime them. Pure move, zero behavior change. Partial vs the map's blade 5: themePref/themePalette, userLabel and defaultPermissionMode stay in app-shell.tsx — the default-permission-mode contract pins the defaultPermissionMode useState + refreshShellSettings + closeSettings mirror to app-shell.tsx specifically, and the theme setters have multiple app-shell writers (visual-smoke, settings-overlay onChange), so moving them would require setter injection with no net simplification. Blade 5 of Round B app-shell decomposition.
…pped app-shell.tsx 1733 → 1666; blades 1/3/4/5 extracted (pending-registry, project-context, module-data, shell-connections); blade 2 (navigation) skipped as disproportionately risky (anchors pinned to app-shell, bridge callbacks carry untested runtime identity semantics). Documents why the < 900 target is unreachable through state-cluster blades alone.
# Conflicts: # notes/frontend-simplification-map-2026-07-13.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Round B (flagship) of notes/frontend-simplification-map-2026-07-13.md. app-shell.tsx 1733 → 1666 lines, 31 → 19 useState, zero behavior change; one extraction per commit, full gate between each.
Blades
useKeyedPendingRegistryreplaces the four hand-rolled keyed pending sets (turn actions + timers, session-row actions, permission-mode changes, session-model changes). keysRef stays a stable Set so factories and unmount cleanup are byte-identical. Contracts sticky-model / status-presentation / row-actions-fail-soft re-pinned to the registry form.The map's <900 target is recorded as structurally unreachable via state-cluster blades alone (remaining bulk = ~210 L derived-value memos + ~340 L JSX return; separate scope).
Gates
Every commit + post-merge-with-main (this branch includes merged Round C/D-1): desktop 2397/2397 · ui 125/125 · typecheck · check-dead-css · knip ×2 = 0 · alignment auditor clean on all 9 fixtures · CDP branch-vs-baseline pixel captures: module-skills byte-identical; two known-environmental diffs (live git-branch label in composer; overlay-scrollbar fade ≤25/255) verified non-regressions. Implemented by an opus worktree agent; map conflict with Rounds C/D-1 resolved keeping both records.