Skip to content

perf(workstation): release idle content hosts when the tab pool empties - #848

Open
Harry19081 wants to merge 1 commit into
developfrom
perf/offload-idle-workstation-hosts
Open

perf(workstation): release idle content hosts when the tab pool empties#848
Harry19081 wants to merge 1 commit into
developfrom
perf/offload-idle-workstation-hosts

Conversation

@Harry19081

Copy link
Copy Markdown
Member

Summary

Bounds the AppShell's host keep-alive so an idle WorkStation stops holding every previously-visited surface in memory. With no real tabs (Launchpad only), the code / browser / project hosts and the hidden Agent Station simulator all unmount; while real tabs exist, visited hosts stay mounted-but-hidden exactly as before so tab switches remain instant.

Problem

The keep-alive in AppShellContent was monotonic: once a host mounted it never unmounted (visitedModes only ever grew), the code host was mounted from launch even on the empty Launchpad (file-tree autoload, git/diff/diagnostics/output hooks all live), the Browser host was unconditionally pre-mounted one frame after startup, and the Agent Station simulator stayed mounted forever after one visit — even back in My Station with no session. An idle window paid RAM and background-work costs for surfaces showing nothing.

Solution

  • New pure policy module AppShell/hostMountPolicy.ts + unit tests covering the mount matrix.
  • New derived booleans mainPaneHasRealTabsAtom / mainPaneHasBrowserHostTabsAtom in store/workstation/tabHost.ts (Launchpad start tabs never count as real work; subscribers only re-render when the boolean flips).
  • useAppShellDock clears the visited set when the pool empties and drops the deferred Browser pre-mount; the active host still mounts synchronously via the is*Mode branch, so first-tab-open latency is unchanged.
  • Browser host mounts on any of: active/visited (with real tabs), background browser-session tabs, live engine sessions, or a pending New-Browser request — the request consumer in BrowserLayout was already remount-safe via the module-scoped consumed-tick atom, and the engine-sessions trigger bridges the gap between request consumption and the sessions ↔ tab-strip sync creating the tab.
  • Agent Station simulator: mounted while visible; kept warm while hidden only when a session is attached (workstationActiveSessionIdAtom), so mid-session My Station ↔ Agent Station toggles stay instant but an idle simulator releases its subtree.
  • The Launchpad itself now unmounts while real tabs are shown (it was previously kept hidden in the DOM).

Potential risks

  • Opening the first real tab from the Launchpad now cold-mounts its host: one file-tree reload IPC and the known one-frame blank in the 40px header strip (same as the current very first launch frame). No grace delay was added for close-last-tab → reopen churn; can be added later if it's noticeable.
  • The Browser host's lifecycle has the most triggers; the launchpad New-Browser flow, restored localStorage sessions, and background browser-session tabs are each covered by an explicit mount trigger, but this is the area to watch in manual testing.
  • Component-local state inside a host (e.g. editor right-panel width) resets after a full pool-empty cycle; persisted atom state (sidebar widths, layout mode) is unaffected.
  • RAM savings are unmeasured in this PR (heap snapshot on the idle Launchpad before/after is the right check); the structural claim — fewer mounted subtrees and no idle file-tree autoload with zero tabs — holds by construction.

Validation / Test plan

  • tsc --noEmit clean; eslint clean on touched files.
  • vitest run src/modules/WorkStation/AppShell/ src/store/workstation/ — 23 files, 228 tests passed, including the new hostMountPolicy.test.ts matrix (empty-pool release, pending-request mount, session-bridge gap, agent-station session gating).
  • Manual checks recommended before merge: New Browser from empty Launchpad; restart with restored browser sessions; close last tab → Launchpad → reopen file tab; Agent Station toggle with and without a live session.

Bound the AppShell keep-alive instead of keeping every visited host
mounted forever: with no real tabs (Launchpad only) the code, browser,
and project hosts all unmount, the hidden Launchpad unmounts behind real
tabs, and the Agent Station simulator is kept warm while hidden only as
long as a session is attached.

The Browser host's unconditional deferred pre-mount is replaced by
explicit mount triggers (pending new-session request via the remount-safe
consumed-tick atom, live engine sessions, background browser-session
tabs), so the Launchpad "New Browser" flow and restored sessions keep
working without a permanently mounted host.

Pre-commit hook ran. Total eslint: 5, total circular: 0
@Harry19081

Copy link
Copy Markdown
Member Author

orgii://cloud/session/ref?v=1&org=bfa7b134-2486-45fa-81ad-a369441fafb4&owner=e17cf230-b78f-4b1b-8480-6005832983b7&session=claudecodeapp-fc51ef5d-d978-4309-88ae-f69b15f534b4

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.

1 participant