refactor: modularize main process, sessions, terminal, app store + cross-window panels & in-app update modal#352
Merged
Anton-Horn merged 4 commits intoJun 9, 2026
Conversation
… add cross-window panels and in-app update modal Breaks up the largest monolith files into focused modules and lands two user-facing features (cross-window panel discovery, in-app update-ready modal). Net -6000 lines with no behavior loss in the refactored paths. Modularization - main/index.ts (1820 lines): extracted lifecycle (openPath, shutdown, telemetry), windows (windowFactory, crashRecovery, dockState, dragGhost, fullscreen, reveal), and IPC handlers (capture, dialogs, dockWindows, dragHandlers, panelWindows, windowControls, windowPanels, batchedDispatcher, handlerError). - terminalRegistry.ts (-1376): split into terminalDom, terminalInput, terminalLifecycle, terminalSearch, terminalSettings, scrollbackCapture, captureAndSaveScrollback, registryState. - workspace/session.ts (-1173): split into sessionLoad, sessionSave, sessionRestore, sessionSerialize, sessionAutosave, sessionStartup. - stores/appStore.ts (-1558): replaced by appStore/ slices (workspace, panel, remote, sync, worktree) plus shared helpers/types. - preload/index.ts trimmed; companion transports share a transport.ts base so SSH/WSL/local only differ at bootstrap. - themes: shared scaffolding pulled into oneDarkShared.ts. Cross-window panels - Main keeps the union of panels across all windows and broadcasts it, so every window's overview and Cmd+K can find and reveal panels living in other windows. New windowPanelStore, windowPanelSync, main windowPanels, and IPC (WINDOW_PANELS_CHANGED/REPORT, FOCUS_WINDOW_PANEL, REVEAL_PANEL_IN_WINDOW). - Removes the separate NodeSwitcher in favor of the unified palette. In-app update modal - UpdateReadyDialog driven by UPDATE_STATUS broadcasts, with UPDATE_QUIT_AND_INSTALL and UPDATE_GET_STATUS for restart and late mounts. Adds tests for window panels, session hydration, panel transfer, detached dock placement, and the new terminal/dom helpers.
…rktree accent on detached rows Detached rows (panels living in another window) now render with the same data as local rows. Agent state/name and listening-port presence are stamped by the owner window on the cross-window union (the owner is the only window that receives a panel's activity scan), and worktreeId rides along too. - WindowPanelInfo/WindowPanelReport carry worktreeId, agentState, agentName, hasPorts. - windowPanelSync stamps agent info + ports per panel, re-reporting on a cheap status signature so the 1s activity poll doesn't trigger needless canvas-map rebuilds. - WorkspaceTab renders terminal/agent detached rows through TerminalPanelRow (shimmer/await/logo/port dot/worktree accent), with a titleHint noting the panel lives in another window.
Consolidate detached panel handling into dock windows, add dock window scrollback sync, extract platform and jsonProjection helpers, slim the preload IPC bridge, and update session restore/save accordingly.
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 free
to 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.
Summary
Large structural cleanup plus two user-facing features. Breaks the biggest monolith files into focused modules (net ~6k lines removed) and lands cross-window panel discovery and an in-app update-ready modal. No behavior loss in the refactored paths.
Modularization
main/index.ts(was 1820 lines) split into:main/lifecycle/—openPath,shutdown,telemetrymain/windows/—windowFactory,crashRecovery,dockState,dragGhost,fullscreen,revealmain/ipc/—capture,dialogs,dockWindows,dragHandlers,panelWindows,windowControls,windowPanels,batchedDispatcher,handlerErrorterminalRegistry.ts(-1376) split intoterminalDom,terminalInput,terminalLifecycle,terminalSearch,terminalSettings,scrollbackCapture,captureAndSaveScrollback,registryStateworkspace/session.ts(-1173) split intosessionLoad,sessionSave,sessionRestore,sessionSerialize,sessionAutosave,sessionStartupstores/appStore.ts(-1558, deleted) replaced bystores/appStore/slices:workspaceSlice,panelSlice,remoteSlice,syncSlice,worktreeSlice+ sharedhelpers/typespreload/index.tstrimmedtransport.tsbase; SSH/WSL/local differ only at bootstrap/launchoneDarkShared.tsCross-window panels
Main now maintains the union of panels across all windows and broadcasts it, so every window's overview and Cmd+K can find and reveal panels that live in other windows.
windowPanelStore,windowPanelSync, main-sidewindowPanelsWINDOW_PANELS_CHANGED,WINDOW_PANELS_REPORT,FOCUS_WINDOW_PANEL,REVEAL_PANEL_IN_WINDOWNodeSwitcherin favor of the unified command paletteIn-app update modal
UpdateReadyDialogdriven byUPDATE_STATUSbroadcastsUPDATE_QUIT_AND_INSTALL(restart + apply) andUPDATE_GET_STATUS(for modals that mount after the download-finished event)Tests
Added coverage for window panels, session hydration, panel transfer, detached dock placement, and the new terminal/dom helpers.
Notes
Mostly mechanical extraction. Worth a focused look at the cross-window panel sync and the appStore slice boundaries.