perf(workspaces): switch projects without re-running startup or reloading beads - #2
Draft
andreiverdes wants to merge 1 commit into
Draft
perf(workspaces): switch projects without re-running startup or reloading beads#2andreiverdes wants to merge 1 commit into
andreiverdes wants to merge 1 commit into
Conversation
…ding beads Every workspace switch re-ran the startup health check — which unmounts the route and shows "Starting up..." — and then refetched the epic tree from bd, so a project that had been on screen seconds earlier came back as a full-screen spinner followed by a skeleton. - StartupGate remembers which workspaces passed a check this session and adopts a switch to one of them silently: no re-check, children stay mounted. A workspace's first visit still runs the check (that is the one that can fail) and a workspace that later fails loses its pass. The id recorded is the one the check covered, not the live cookie, so a switch that lands mid-check gets its own check instead of inheriting the previous workspace's verdict. - Routes now resolve the active workspace from the cookie through a subscription (hooks/use-active-workspace.ts, and the equivalent listener in useWorkspaceLifecycle) since they are no longer remounted. A cookie pointing at an unknown id keeps the current workspace instead of silently jumping to the first one. - lib/epics-session-cache.ts keeps the last tree per databasePath (LRU, 6 entries) so a switch back paints immediately and refreshes in the background. It mirrors rendered state, so beads closed or deleted locally do not reappear. A switch also bumps the load generation and raises isLoading, so the previous project's beads cannot render under the new project's name. - lib/workspace-actions.ts extracts the activate/unregister sequences the dashboard and the lifecycle hook each had their own copy of, and useWorkspaceLifecycle drops its dead handleWorkspaceChange (the cookie listener is the single switch path), calls rpc handlers through the proxy instead of capturing them at module load, and no longer writes the cookie from inside a setState updater.
This was referenced Sep 3, 2026
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.
Layer 2 of 3. Base:
pr1-registry-durability(#1).Switching to a project already verified this session re-ran the whole startup sequence: health check, then a fresh
bdload. Now a workspace that passed its health check keeps that pass for the session, and each workspace's view state (epic tree, activity feed, pipeline) is held in a per-workspace cache, so switching back paints immediately.On not duplicating
bdstate — the constraint CONTRIBUTING sets:bdchange signal, so a CLI-side edit still lands.bdstays authoritative; this only avoids re-asking for an answer we already have and have not been told is stale.Verified by hand against
tauri:dev, sincetest:e2ecollects nothing today (playwright.config.tsignores every spec) and the client throwsRpcUnavailableErrorwithout a Tauri runtime:bd epicsper switch.