Repository navigation
refactor(desktop): move the overlay surfaces below AppShell - #4997
Conversation
ceaf524 to
6c7b6d5
Compare
|
Rebased onto Posted by Claude Code on behalf of the PR author. |
6c7b6d5 to
4b2b3d1
Compare
|
Rebased onto Posted by Claude Code on behalf of the PR author. |
|
@Astro-Han this one is ready for your look when you have time: the Commands / overlays slice claimed on #4582, sitting on Posted by Claude Code on behalf of the PR author. |
372e1f1 to
96340b4
Compare
|
For the record: the one red run on this PR (at Posted by Claude Code on behalf of the PR author. |
96340b4 to
02f5542
Compare
|
The Desktop E2E step is red again at
I am not going to keep force-pushing to re-roll the E2E; the next rebase (which Posted by Claude Code on behalf of the PR author. |
Give keyboard help, the Command Palette, Search and Settings one owner in features/overlays. OverlaysRoot owns useOverlaysController and hands a stable command projection to AppShellContent; the legacy overlay layer keeps the lazy Settings chunk and shell command list. Preserve the current main search lifecycle: pass request IDs and cancellation through the modal, controller and Desktop adapter, and let the transcript reading-position owner clear navigation targets. Retain SettingsOverlay as the single Escape owner across lazy chunk loading. Register OverlaysRoot in controllerOwners and regenerate architecture and Astryx inventories against main. Cover search cancellation through the real overlay provider, modal and Desktop adapter. Generated-by: Claude Code Generated-by: Codex
02f5542 to
649319e
Compare
Astro-Han
left a comment
There was a problem hiding this comment.
Approving at 649319e37 — reviewed along two angles (architecture/ownership and behavior/test integrity); both came back clean on the mechanics that matter.
The move is sanctioned: commands-and-overlays already listed these legacy paths and the ledger records the retarget to features/overlays; the slice mirrors task-entry (index/ports/services-context/controller/model/ui/testing), useOverlaysController is registered with OverlaysRoot as its single owner, and nothing lands outside approved zones. Ownership stays single — visibility state lives once in the controller, the shell reads the projection, overlay UI reads the context. No parallel path.
Behavior holds on every path traced: the four moved hotkeys, all six Settings openers (intent→section, persist key, blur-once), the #5256 debounce/cancellation contract — now with a real regression test through SearchModal — anyModalOpen/shellObscured, the e2e fixture seam, and the search scroll-target wiring. No surface was dropped; features/search/ leaves no dangling references.
Net prod +939/−707 — the shell sheds ~80 lines and a whole overlay concern; real entropy reduction, not churn.
P3s, none blocking:
app-shell-command-actions.ts:150still cites the deleteduseKeyboardHelp— reword tooverlays.commands.openHelpor drop it.model/settings-surface.tsshares its name with the 1264-linesettings/settings-surface.tsxcomponent; consider renaming or accept it.OverlayFocusServiceis a port for a singledocument.activeElement.blur()— legal to inline in the controller; either way is fine.- In
overlays-boundary.test.ts, the "leaves the shell with no overlay hook" test duplicates whatcheck-app-shell-hooks.mjsalready rejects — safe to delete.
One ask: the ledger retargets commands-and-overlays from application/overlays to features/overlays — a change to the declared migration plan, not just execution. Worth one line in the PR body so the destination change is on record.
中文版
两路评审(架构归属、行为/测试)在 649319e37 干净通过。迁移在账本计划内(commands-and-overlays 已列这些 legacy 路径),新 feature slice 结构对齐 task-entry,useOverlaysController 唯一 owner 已注册,无并行路径。行为逐条核实保持:热键、六个 Settings 开启路径、#5256 的 debounce/取消契约(且新增了走 SearchModal 的回归测试)、anyModalOpen、e2e fixture、search scroll-target 接线。净生产 +939/−707,真实减负。P3:过时注释引用已删 hook、model/settings-surface.ts 与现有组件重名、OverlayFocusService port 可内联、boundary 测试里一条与 check-app-shell-hooks 重复可删。另请正文补一句账本 destination 从 application/overlays 改为 features/overlays 的说明。
AI assistance: I used Devin with two delegated review passes (architecture and behavior/test integrity) over the checked-out head; findings were cross-verified by me.
…ined The "Transitional feature exports outside Conversation" table scheduled OverlaysConsumer and ManualDiagnosticReportConsumer for M5, with the legacy command actions. Neither can leave the root within R2. app-shell-overlays.tsx composes the legacy Settings surface, which it imports lazily, and the palette command list that apache#4997 deliberately kept as a shell injection point; feature zones may not import legacy code. The manual report is the diagnostics owner's command handed to the shell-built palette options. Both rows now record why they stay. Refs apache#4582 Generated-by: Claude Opus 5.5
Summary
Move the shell's overlay surfaces below
AppShell: the keyboard help, the Command Palette, the Search modal, and the Settings modal now have one owner,features/overlays, withOverlaysRootregistered incontrollerOwnersas the only caller ofuseOverlaysController.OverlaysRootowns the four open flags, the Settings request with its three sub-surfaces (provider catalog, connection detail, provider create), the Search scroll target, and the global shortcuts (mod+k,mod+/,mod+?, bare?). It hands the shell frame the overlays through a render prop the wayTaskEntryRoothands overtaskEntry, soAppShellandAppShellContentcall none of the four hooks: the gate inventory goes from 40 hooks / 65 call sites to 36 / 61.openSettingsSurfaceapplies it, and the section an intent lands on is what the adapter persists; the transitions are unit-tested without React.openProjectSettingsstill replaces the whole request, and closing still keeps the connection slug and create type for the next open, as before.OverlaysConsumer; its props drop from 34 to 17, and the 15 pass-through values the shell used to thread into it are gone.keyboard-help.tsx,command-palette.tsx,command-palette-types.ts,use-settings-modal.ts, 233 → 229 legacy files). The search hook and service seam fromfeatures/searchmove into this slice. The ledger'scommands-and-overlaysownership entry now namesfeatures/overlaysas the home of the two files that stay.SettingsOverlayEscape owner for the lazy Settings chunk, and the one-identitysearchThreadthe Search modal's debounce depends on.useSessionCollaborationDialog, the fifth modal inhasModalOpen, which needsopenSettingsSectionfrom this slice and follows separately; and the palette's command list, which stays a shell concern because its rows are shell actions.Refs #4582
Verification
Validated on Node 24.19.0 / npm 11.19.0 against
main3f297e9aa:test:dist2673/2673 and UItest:dist496/496.git diff --check.check:renderer-architecture --base upstream/main;OverlaysRootremains the registered controller owner. AppShell hook gate: 36 hooks / 61 call sites.settings.spec.ts,sidebar-project-reload.spec.ts, andworkhub-layout.spec.ts.OverlaysRoot,SearchModalHost, and Desktop adapter to verify request identity, supersession, dismissal, reopening, and unmount cancellation. Search navigation retains main's transcript-owned target clearing.Review focus
The hand-off and the nesting.
OverlaysRootsits insideTaskEntryRoot's frame and aroundAppShellContent, so an overlay change re-renders the shell frame exactly as the shell's ownuseStatedid before, and nothing above it. The only remaining injection point iscommandOptions.AI use
Select exactly one:
Tool(s) and scope: Claude Code designed and implemented the original slice. Codex resolved the conflicts with current main, preserved search cancellation and Settings dismissal, updated the regression coverage, and ran the verification above. The human contributor owns final review and submission.
Checklist
Does this PR entail a change in behavior?