Repository navigation
refactor(desktop): take the overlays review follow-ups - #5364
Conversation
Astro-Han
left a comment
There was a problem hiding this comment.
Reviewed against gh pr diff plus the PR head (414ae07e6). All four P3s from the #4997 approval and the destination note are addressed, and I could not find a behavior change. Notes and two nits below.
Verified
The rename is mechanical. Normalizing the identifier renames, model/settings-surface.ts (main) and model/settings-modal-state.ts (PR head) are byte-identical, so the state machine — the request merge/replace rules, the sub-surface resets, closeSettingsModal's early return — is untouched. The use-overlays-controller.ts, overlays-projection.ts, and testing.ts hunks are identifier-only. No dangling references at the PR head: SettingsSurface* / openSettingsSurface / settings-surface.js now resolve only to the unrelated settings/settings-surface.tsx component, so the name collision with the 1264-line component is genuinely gone.
renderer-architecture.json regeneration is exact. I re-parsed both versions of app-shell-command-actions.ts with the checker's own parser config (explicitResourceManagement, importAttributes, jsx, typescript, tokens: true): 2299 → 2298 tokens, matching the committed nonTriviaTokens and nothing else in that entry. The renamed model file needs no ledger update — legacyAppShell.files only inventories shell/legacy paths, and features/overlays is not in legacyRendererFiles, legacyFeatureImports, or the Astryx surface inventory.
The reworded comment is accurate. openHelp in the shell really is overlays.commands.openHelp (app-shell.tsx:360-371 destructures the projection's commands and openHelp is passed down into the command-list options), and the foot-gun it names is real: the controller registers a bare ? hotkey (use-overlays-controller.ts, { keys: '?', onPress: … }), so a synthetic KeyboardEvent for ? would have gone through the global listener.
Dropping the boundary test loses no coverage. scripts/check-app-shell-hooks.mjs fails closed on any use* call in AppShell/AppShellContent (unknown names → added, above budget → grown, below → stale), and app-shell.tsx defines only those two components, so the deleted assertion — six specific overlay hook names anywhere in the file — is subsumed by a strictly name-agnostic gate. Nothing in the repo referenced the deleted test by name.
The README's Destination section checks out. commands-and-overlays did move application/overlays → features/overlays (in #4997, f875dc8f3), and the two reasons given are the real ones: check-renderer-architecture.mjs forbids legacy targets from both the application and feature source zones, and it requires production consumers to reach an owner through the slice's public entry. The two files left on the legacy list (app-shell-overlays.tsx, app-shell-command-actions.ts) are exactly the ledger's legacyPaths.
Keeping OverlayFocusService is defensible and matches "either way is fine": ports.ts:39-45 already records why the port exists (macOS menu commands open Settings without moving DOM focus), and overlays-provider-scope.test.ts:117-145 asserts the blur-once-per-closed→open rule through an injected fake — which inlining into the controller would put back behind a document.
For a pure rename + comment + doc change there is nothing meaningful to test; typecheck plus the existing model tests cover the symbol moves.
Nits
features/overlays/README.md:56— the new "Model" line is 84 columns, while the rest of the file wraps near 80 (only the pre-existingOwnershipbullet at line 33 is longer). Biome doesn't format markdown, soformat:checkwon't flag it; rewrapping keeps the file's rhythm.features/overlays/README.md(Destination) — "thecontrollerOwnersguard registers owners only underfeatures/<slice>/index.ts" is a hair off: the ledger'sownerfield isfeatures/overlays/ui/overlays-root.tsx. What the guard ties toindex.tsis that production consumers must import the owner through the public entry, and thatindex.tsmust not expose the controller itself. Worth saying precisely, since this paragraph is the record of why the destination isfeatures/overlays.
Not an issue, just noting: main is 30 commits ahead of the merge-base and touched app-shell.tsx and renderer-architecture.json; a git merge-tree dry run merges cleanly, so no rebase friction expected.
Reword the `onOpenShortcuts` comment that still cited the removed `useKeyboardHelp`, rename the Settings modal state model so nothing in the overlays slice shares a name with the `SettingsSurface` component, drop the boundary test that repeated the hook gate, and record in the slice README why the ledger's `commands-and-overlays` destination moved from `application/overlays` to `features/overlays`.
Generated-by: Codex
68d096a to
4bfb65c
Compare
Astro-Han
left a comment
There was a problem hiding this comment.
Clean follow-up — every claim verified against the code.
- Rename is complete and the disambiguation is real: all five consumers updated, remaining
SettingsSurfacereferences belong to the component that deliberately keeps its name, andfeatures/overlays/index.tsnever re-exported the model so nothing leaks through the barrel. - No behavior change: the renamed model is byte-identical modulo identifiers;
setSettings(closeSettingsModal)keeps the same updater shape. - The dropped boundary test is genuinely redundant —
check-app-shell-hooks.mjscounts every hook in both render bodies against an exactALLOWEDinventory that fails on growth AND shrinkage, so it covers the same scope with a broader net, and it runs in CI. - The README destination note matches the actual guard rules (controller ownership, index-barrel enforcement, legacy import budgets) as wired in
check-renderer-architecture.mjs. OverlayFocusServicestaying is the right call — the port keeps the controller DOM-free and is what makes the blur-once-per-closed-to-open rule testable without a document.
Summary
The four non-blocking P3s from the #4997 approval, plus the destination note it asked for.
app-shell-command-actions.ts: the comment ononOpenShortcutsno longer cites the deleteduseKeyboardHelp; it now says the shell hands in the overlays owner'sopenHelpcommand and why that beats a syntheticKeyboardEvent.features/overlays/model/settings-surface.tsis nowmodel/settings-modal-state.ts, and its symbols follow (SettingsModalState,SettingsModalIntent,openSettingsModal,closeSettingsModal,CLOSED_SETTINGS_MODAL), so nothing in the slice shares a name with theSettingsSurfacecomponent insettings/settings-surface.tsx. The only importers are the controller, the projection type, the testing entry, and the model test.overlays-boundary.test.tsdrops the case that asserted no overlay hook is left inapp-shell.tsx;check-app-shell-hooks.mjsalready rejects exactly that.commands-and-overlaysdestination moved fromapplication/overlaystofeatures/overlays: the owner guard registers owners only underfeatures/<slice>/index.ts, and neither the application nor the feature zone may import legacy code, so the two legacy files stay on the entry's list until the Settings modal and the command builders can follow.Kept as is:
OverlayFocusService. The review called inlining the singleblur()legal either way; the port keeps the controller free of DOM access and letsoverlays-provider-scope.test.tsassert the blur-once-per-closed-to-open rule without a document.No runtime behavior changes. Refs #4582
Verification
test:dist2675/2675, typecheck (stories included), lint, format:checkcheck:renderer-architecture --base upstream/main,check:app-shell-hooks, Astryx inventory (regenerated for the renamed file), Knip (apps/desktop), ASF headers,git diff --checkAI use
Select exactly one:
Tool(s) and scope: Claude Code applied the rename, the comment and README edits, and ran the verification; the human contributor reviewed the work and chose to submit it.
Checklist
Does this PR entail a change in behavior?