Workspaces step 2b: Window container, dormant behind a flag#190
Merged
Conversation
…, store, flag
Pure additive lib core for the Workspace container. No app wiring yet (that is
2b part 2, in the standalone adapter), so this is fully dormant and changes no
behavior.
- session-types: PersistedWorkspace, PersistedWindow, WorkspaceId, and
readPersistedWindow() — reads a canonical/JSON window or migrates a bare
PersistedSession (any version) to a single "Workspace 1" window; drops
unreadable inner sessions; repairs a dangling activeWorkspaceId. Plus
wrapSessionInWindow() and activeWorkspaceSession() helpers.
- feature-flags: isWorkspacesEnabled() / setWorkspacesEnabled(), a localStorage
flag (dormouse.flags.workspaces) off by default — gates the whole container
(stage 2b) and the UI built on it (3/4).
- workspace-union: computeWorkspaceUnion(surfaceIds, activitySnapshot) →
{ ringing, todo, count }, the display-only projection. Only terminals ring;
any surface may carry TODO; each attention-owing surface counts once.
- workspace-store: in-memory model (list + activeId) with the container verbs
(create/close/rename/switch), default single Workspace, subscribable for the
stage-3 strip. closeWorkspace refuses the last; reactivates a neighbor.
Tests: +35 across the four units. Full lib suite green (710), tsc -b clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…s (flag-gated) The standalone now persists a PersistedWindow when the workspaces flag is on, and a bare PersistedSession when off — so with the flag off (the default) the stored blob and all behavior are byte-identical to today. Dormant. - window-persistence (lib): activeSessionFromStored / storedValueForSession — flag-gated, pure translators between the host's stored top-level blob and the bare PersistedSession the shared restore/save code (reconnect, session-save) operates on. Flag off = identity passthrough. Flag on: load returns the active Workspace's session; save merges back into the active slot, preserving the other Workspaces. Migrates a pre-workspace bare session transparently on load. - session-types: replaceActiveSession(window, session) helper. - tauri-adapter + browser-sidecar-adapter: getState/saveState route through the helpers. No change to shared lib persistence (no session-save.ts touch). The Window container is standalone-only; VS Code keeps one bare PersistedSession per webview, untouched. Tests: +8 (window-persistence, both flag states + multi-Workspace merge/load). Full lib suite green (718); standalone tsc --noEmit clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…g/VS Code = 3/4 Now that the Workspace/Window container, migration, model, union projection, and standalone persistence wiring are in place behind `dormouse.flags.workspaces`, update the spec status markers to match reality: - glossary Implementation status: three buckets — live (2a), implemented-but- dormant-behind-flag (2b container/migration/model/union/persistence), and not yet built (strip + union surfacing = 3, Wall mount/unmount on switch + >1 Workspace = 4) - transport: container/migration paragraphs flip to implemented; document that the wrapping lives at the standalone adapter boundary (window-persistence.ts), flag off = byte-identical bare PersistedSession - layout: Workspaces section is partially implemented (model behind flag; strip + switch-rerender still 3/4) - alert: union projection implemented (computeWorkspaceUnion); surfacing still 3 - vscode: union primitive exists but VS Code does not yet feed/reflect it; the Window container is standalone-only and doesn't touch VS Code Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…guards/id Cleanup pass over the stage-2b diff (4 review angles). Quality only, no behavior change. - window-persistence: add storage-level loadSessionState/saveSessionState that own the JSON parse/stringify + localStorage access, so both standalone adapters collapse to a one-liner instead of re-implementing the identical read-merge-write dance. saveSessionState skips reading the existing blob when the flag is off (the default) — previously every debounced save needlessly re-parsed the scrollback-bearing snapshot on the hot path. - session-types: isPersistedWindowShape is now a structural gate only; per- Workspace validation (id/name/readable session) moved into readPersistedWindow so malformed elements are dropped uniformly instead of a single bad element rejecting the whole Window. Deletes the now-redundant isPersistedWorkspaceShape. - workspace-store: generateWorkspaceId uses the random suffix only (drops the belt-and-suspenders monotonic counter); the suffix never equals "workspace-1". Skipped (intentional, noted): the hand-rolled subscribe/snapshot store and localStorage-guard patterns (codebase convention, no shared helper exists), the flags-module reader and dormant createWorkspace option, and the multi-validation cost at N>1 (proportionate for dormant N=1). Tests: +5 (storage round trip incl. flag-off no-read). Full lib suite green (729); lib + standalone tsc clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Deploying mouseterm with
|
| Latest commit: |
9d28cc8
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://21bc69f0.mouseterm.pages.dev |
| Branch Preview URL: | https://workspaces-2b.mouseterm.pages.dev |
dormouse-bot
approved these changes
Jun 30, 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.
Stage 2b of the Workspace effort: introduce the Workspace / Window container and its supporting model, dormant behind a feature flag. Builds on the spec + stage-2a work already on
main(#189).Dormant by default
Everything here is gated on
dormouse.flags.workspaces(localStorage, off by default). With the flag off, the standalone persists a barePersistedSessionand the app runs exactly one implicit Workspace — byte-identical to today (a test locks the flag-off save path doing no extra read). The flag gates the container so stages 3 (switch UI) and 4 (real multi-Workspace) can build on a structure that's already in place and exercised by daily use at N=1.What's included
session-types.ts):PersistedWorkspace/PersistedWindowandreadPersistedWindow(), which migrates a pre-workspace barePersistedSession(any version) to a singleWorkspace 1, drops unreadable inner sessions, and repairs a danglingactiveWorkspaceId.feature-flags.ts):isWorkspacesEnabled()/setWorkspacesEnabled().workspace-union.ts):computeWorkspaceUnion()→{ ringing, todo, count }(only terminals ring; any surface may carry TODO; each attention-owing surface counts once).workspace-store.ts): the list + active id with the container verbs (create/close/rename/setActive), subscribable for the stage-3 strip. Default single Workspace.window-persistence.ts+ the Tauri / browser-dev adapters):getState/saveStateroute through flag-gated helpers. Standalone-only — VS Code keeps one barePersistedSessionper webview, untouched.Deliberately deferred (not in this PR)
switchWorkspace(today the model switches the active id but does not re-render the Wall) and lifting the one-Workspace cap.Spec status markers (
glossaryImplementation status,transport,layout,alert,vscode) are updated to reflect implemented-but-dormant vs. stages 3/4.Verification
pnpm test— all packages green (dor, lib 729, standalone, website).pnpm build— vscode-ext + website build clean.tsc --noEmitclean. No Rust changes (cargo checkunaffected).🤖 Generated with Claude Code