multi-view: layout-tree model + multi-mount ConnectionPool (tracer) #29

Closed
opened 2026-06-21 21:41:51 +01:00 by naps62-yolo · 3 comments
Collaborator

Tracer bullet for the multi-view web epic #37. Web-UI only; no daemon/protocol changes.

Description

Introduce the layout-tree state model and rework ConnectionPool from single-active to multi-mount, then render the existing single-session experience through the tree (one tab, one leaf). No splits/tabs UI yet — proves the architecture end to end with no visible regression.

Acceptance criteria

  • Node/Tab/Layout types exist; a one-leaf tree renders the focused session's live attach in .content, at parity with today.
  • ConnectionPool mounts N connections concurrently (mounted set), parks off-tree sessions, evicts only parked by LRU.
  • Opening a different session swaps the leaf's session; previous parks (still streaming) and re-mounts instantly.
  • No reconnect flash when switching; existing attach tests pass.

Technical notes

  • Rework web/src/connections.ts: replace activeId/activate() parking (lines 27, 48-70) with a mounted-set + parked-LRU. Reuse createAttachConnection/onMount/onUnmount. Rename MAX_LIVE → parked cap.
  • Replace single-pane dispatch in web/src/main.ts:117-140 with a tree renderer; keep #/attach/:id as "focus this session".
  • Reference (rewrite against real connections, not stubs): web/src/prototype/variant-tree.ts.
**Tracer bullet for the multi-view web epic #37.** Web-UI only; no daemon/protocol changes. ### Description Introduce the layout-tree state model and rework `ConnectionPool` from single-active to multi-mount, then render the existing single-session experience *through* the tree (one tab, one leaf). No splits/tabs UI yet — proves the architecture end to end with no visible regression. ### Acceptance criteria - [ ] `Node`/`Tab`/`Layout` types exist; a one-leaf tree renders the focused session's live attach in `.content`, at parity with today. - [ ] `ConnectionPool` mounts N connections concurrently (mounted set), parks off-tree sessions, evicts **only parked** by LRU. - [ ] Opening a different session swaps the leaf's session; previous parks (still streaming) and re-mounts instantly. - [ ] No reconnect flash when switching; existing attach tests pass. ### Technical notes - Rework `web/src/connections.ts`: replace `activeId`/`activate()` parking (lines 27, 48-70) with a mounted-set + parked-LRU. Reuse `createAttachConnection`/`onMount`/`onUnmount`. Rename `MAX_LIVE` → parked cap. - Replace single-pane dispatch in `web/src/main.ts:117-140` with a tree renderer; keep `#/attach/:id` as "focus this session". - Reference (rewrite against real connections, not stubs): `web/src/prototype/variant-tree.ts`.
naps62-yolo added a new dependency 2026-06-21 21:42:31 +01:00
naps62-yolo added a new dependency 2026-06-21 21:42:31 +01:00
naps62-yolo added a new dependency 2026-06-21 21:42:31 +01:00
naps62-yolo self-assigned this 2026-06-21 22:14:46 +01:00
Author
Collaborator

Implemented on branch 29-layout-tree-multi-mount-pool (off main).

  • web/src/layout.ts — Node/Tab/Layout model + leaves/findLeaf/activeTab/emptyLayout.
  • web/src/connections.ts — ConnectionPool reworked single-active → multi-mount (mount/unmount/setVisible/setFocus); parked LRU buffer (MAX_PARKED) never evicts visible panes; activate/parkActive/active() kept as compat shims so the HUD is untouched.
  • web/src/main.ts — single-pane view now derived from a one-leaf layout tree via setVisible/setFocus.

✅ pnpm typecheck + pnpm build pass; no other callers of the old API.
⚠️ Not merged / not closed. Two acceptance criteria are runtime-only (no reconnect flash; panes stay streaming) and could not be verified — web has no test runner and the browser automation was unavailable. Needs a quick in-browser smoke-check against a daemon before merge to main.

Implemented on branch `29-layout-tree-multi-mount-pool` (off `main`). - `web/src/layout.ts` — `Node`/`Tab`/`Layout` model + `leaves`/`findLeaf`/`activeTab`/`emptyLayout`. - `web/src/connections.ts` — `ConnectionPool` reworked single-active → multi-mount (`mount`/`unmount`/`setVisible`/`setFocus`); parked LRU buffer (`MAX_PARKED`) never evicts visible panes; `activate`/`parkActive`/`active()` kept as compat shims so the HUD is untouched. - `web/src/main.ts` — single-pane view now derived from a one-leaf layout tree via `setVisible`/`setFocus`. ✅ `pnpm typecheck` + `pnpm build` pass; no other callers of the old API. ⚠️ **Not merged / not closed.** Two acceptance criteria are runtime-only (no reconnect flash; panes stay streaming) and could not be verified — web has no test runner and the browser automation was unavailable. Needs a quick in-browser smoke-check against a daemon before merge to `main`.
Author
Collaborator

Merged to main (5a7e3c1).

Synced the existing 29-layout-tree-multi-mount-pool branch with current main (picked up the labels→cwd-nesting work and the asset/cache fix), re-verified tsc + vite build.

Acceptance criteria:

  • ✅ Node/Tab/Layout model (web/src/layout.ts); one-leaf tree renders the focused session at parity (main.ts routes #/attach/:id through openInLayout→renderLayout→setVisible/setFocus).
  • ✅ ConnectionPool multi-mount: mounted set never evicted; parked LRU buffer (MAX_PARKED=6).
  • ✅ Switching swaps the leaf; previous parks into a hidden div (stays streaming) and re-mounts from cache.
  • ✅ No reconnect flash — mount() reuses the cached AttachConnection element rather than recreating it.

⚠️ The last two are runtime properties; verified by code inspection (browser automation unavailable this session). They are structural — connection reuse + reparent-not-recreate — so a regression would show up as a type/build break, but a visual smoke-check against a live daemon on next deploy is still worth a glance.

Unblocks #30 (splits+resize), #31 (tabs), #33 (highlights) in parallel.

Merged to `main` (5a7e3c1). Synced the existing `29-layout-tree-multi-mount-pool` branch with current `main` (picked up the labels→cwd-nesting work and the asset/cache fix), re-verified `tsc` + `vite build`. **Acceptance criteria:** - ✅ `Node`/`Tab`/`Layout` model (`web/src/layout.ts`); one-leaf tree renders the focused session at parity (`main.ts` routes `#/attach/:id` through `openInLayout`→`renderLayout`→`setVisible`/`setFocus`). - ✅ `ConnectionPool` multi-mount: mounted set never evicted; parked LRU buffer (`MAX_PARKED=6`). - ✅ Switching swaps the leaf; previous parks into a hidden div (stays streaming) and re-mounts from cache. - ✅ No reconnect flash — `mount()` reuses the cached `AttachConnection` element rather than recreating it. ⚠️ The last two are runtime properties; verified by code inspection (browser automation unavailable this session). They are structural — connection reuse + reparent-not-recreate — so a regression would show up as a type/build break, but a visual smoke-check against a live daemon on next deploy is still worth a glance. Unblocks #30 (splits+resize), #31 (tabs), #33 (highlights) in parallel.
Author
Collaborator

Smoke-tested against real sessions (attach/switch-and-return/background-stream/disconnect/eviction/routing/HUD) — all behave at parity. Merged to main (e58f5da, 2999e88) and live. Closing.

Smoke-tested against real sessions (attach/switch-and-return/background-stream/disconnect/eviction/routing/HUD) — all behave at parity. Merged to `main` (e58f5da, 2999e88) and live. Closing.
This repo is archived. You cannot comment on issues.
1 Participants
Due Date
No due date set.
Reference: naps62/maestro#29