Skip to content

feat(ui): window layout model, hash sync and session persistence (RIG-4443) - #1743

Merged
trunk-io[bot] merged 3 commits into
compass-ui/rig-4442-surfaces-use-viewfrom
compass-ui/rig-4443-window-layout
Oct 7, 2026
Merged

trunk-io[bot] merged 3 commits into
compass-ui/rig-4442-surfaces-use-viewfrom
compass-ui/rig-4443-window-layout

Conversation

@rigel-mintaka

@rigel-mintaka rigel-mintaka commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

This PR is part of a stack containing 7 PRs:

  1. main
  2. refactor(ui): extract parseRoute and add ViewScope with useView (RIG-4439) #1652
  3. refactor(ui): move routed surfaces and agent-workspace state onto the view scope (RIG-4442) #1675
  4. "feat(ui): window layout model, hash sync and session persistence (RIG-4443)" (this PR)
  5. feat(ui): view tab strip with keep-alive and open-in-tab links (RIG-4444) #1755
  6. feat(ui): W leader chords and palette commands for tabs and panes (RIG-4445) #1770
  7. feat(ui): two-pane split with a resizable splitter (RIG-4446) #1780
  8. fix(ui): chrome cleanup: drop ADE and usage bar, Session Log naming, pane edges, row re-measure (RIG-4771) #1811

Tabs T3 of docs/designs/ui/compass-in-window-tabs/design.md §T3 (RIG-4443), stacked on T2 #1675. No tab strip yet; that is T4.

  • window-layout.ts: pure reducer per the §T3 interface. It has MAX_TABS = 10, reduceLayout (returns {refused: "tab-cap"}), loadLayout(storage, hashPath), saveLayout, and sessionLayoutStorage(), which returns undefined when sessionStorage throws.
  • store.ts:
    • Layout. A layout signal and dispatchLayout; a refused action leaves the layout as is. There is one ViewScope per view instance, keyed by view id, and focusedView is the layout's focused view.
    • Router binding (bindRouter). It loads the layout from sessionStorage plus the current hash and saves on each change. A hash change applies to the view its history state.viewId names, or to the focused view when that id is missing or closed. A navigation inside one view pushes {viewId}. A focus change replaces, so tab switches never stack. The sync to the hash runs in a microtask, so navigate is never called from inside an effect callback.
  • mount.tsx: stateHashHistory() adds window.history.state to router reads and listens to popstate. Two entries with the same hash but different views fire no hashchange.
  • view-scope.ts: createViewScope takes an optional ViewPathSource, so the layout owns the path.
  • App.tsx: passes navigate options and the location state to the store. ViewHost is keyed on the focused view.

Record readings (§A2/§A8):

  • Boot stamps its entry by a replace and pushes nothing.
  • At the tab cap, a deep-link hash goes to the focused view.
  • layout/dispatchLayout use the names from §T4.

Tests

  • window-layout.test.ts (13): dedupe, close focus order, the last-tab rule, the cap, move bounds, a split that closes back to a single view, resize clamp, restore, corrupt storage falling back to Bridge, and a deep link opening as the focused tab.
  • window-history.test.tsx: the §T3 memory-history scenario as written. It was red first (0/3) before the wiring.
  • moon run compass-ui:test: 1229 pass, 0 fail. Typecheck passes.
  • Playwright visual-smoke + dev-boot: 13 passed, no baseline change. The Solid dev warnings match T2's (53 STRICT_READ_UNTRACKED, 0 FLUSH_IN_EFFECT_CALLBACK).

Review fixes (9d75eb4, bad886a): a restored split keeps its saved focused pane when both panes show the hash. Restored id seeds must be integers in [0, 1e9], so untrusted storage cannot stall the id counter. Both have regression tests that fail on the earlier code. Review is now clean. Full suite: 1231 pass.

CI state

moon (nix) and e2e on the previous run were cancelled with "The job was not acquired by Runner of type hosted even after multiple attempts". That is the fleet-wide hosted-runner shortage since ~19:40Z, which has been routed to the CI owner. Every job that ran passed. The cancelled jobs have been re-run once.

Spec-impact: none.
Ledger-impact: none

Co-authored-by: Matt Wilkinson matt@rigel.build

…-4443)

Adds the pure layout reducer (window-layout.ts) and wires it into the store:
the router mirrors the focused view, history entries carry their view id, and
the layout persists to sessionStorage.

Co-authored-by: Matt Wilkinson <matt@rigel.build>
@linear-code

linear-code Bot commented Oct 5, 2026

Copy link
Copy Markdown

RIG-4443

@github-actions

github-actions Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

Compass engineering docs preview: https://compass-ui-rig-4443-window-l.compass-eng-docs.pages.dev

Deployed from compass-ui/rig-4443-window-layout at bad886a.

rigel-mintaka and others added 2 commits October 5, 2026 16:34
…443)

Co-authored-by: Matt Wilkinson <matt@rigel.build>
…IG-4443)

Co-authored-by: Matt Wilkinson <matt@rigel.build>
@trunk-io

trunk-io Bot commented Oct 7, 2026

Copy link
Copy Markdown

This pull request is queued for merge as part of 1798, which will merge 1652, 1675, 1743, 1755, 1770, 1780, 1787, 1798.

@trunk-io
trunk-io Bot merged commit 26f50c3 into main Oct 7, 2026
42 of 46 checks passed
@trunk-io
trunk-io Bot deleted the compass-ui/rig-4443-window-layout branch October 7, 2026 04:16
@trunk-io

trunk-io Bot commented Oct 7, 2026

Copy link
Copy Markdown

This pull request was merged into main as part of stacked PR 1798.

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.

2 participants