Skip to content

Labs: split-pane agent workspace - #42

Closed
sean-brydon wants to merge 6 commits into
mainfrom
labs-workspace
Closed

sean-brydon wants to merge 6 commits into
mainfrom
labs-workspace

Conversation

@sean-brydon

Copy link
Copy Markdown
Collaborator

Labs › Layout › Workspaces: the window becomes a workspace of live agent panes you arrange, like tmux or Zellij for agents. It is not a board: every pane is a live chat or terminal. The sidebar stays the default, and nothing changes unless you pick this layout.

What it is

  • Top bar. Home, then named workspaces as numbered tabs (⌘1–9). A tab gets a warm dot and count when an agent in it needs you. Then +, how the panes tile (side by side, grid, zoom), New task, Search, Review, Automations, ⋯ and Settings.
  • Panes. Up to four agents side by side, from any project on any box; four tile 2×2 by default. Each header shows the agent, its title, the worktree and the box, plus a warm "Needs you" when it waits on you. The focused pane has a blue ring, and the others hide their chat controls. Hover a header for zoom, put away (back to the strip, still running) and the pane menu.
  • Strip. Every agent that isn't on screen. Needs-you agents are pinned first; hover one to see what it asks and answer a permission there. Then working and done agents, as many as fit whole, with "+N more" for the rest; idle agents fold into "N ready". Click brings an agent in (it takes the focused pane's place once four are up), ⌥-click swaps it into the focused pane, or drag it onto a pane edge or its middle.
  • Elsewhere tray. Every box (offline ones too) and each project as a line of state counts, expanding to its worktrees and agents.
  • Keys.
    • ⌘E: a switcher with every agent (needs you first) and every worktree.
    • ⌘J: bring in whoever has waited longest.
    • ⌘⌥ and an arrow: move focus. ⌘⌥⇧ and an arrow: swap panes.
    • ⌘⇧↵: zoom.
    • ⌘1–9: go to a workspace.
  • Opening an agent any other way (a notification, ⌘K, a new task) brings it into the workspace in front.
  • Narrow windows (under 900px) show one pane plus the strip.
  • An empty workspace shows a sheet of the gestures and keys.

How it's built

  • Each workspace is one tab of the existing pane machinery (lib/workspaces.ts, with guest panes for other worktrees). Panes keep their ids, so moving agents in and out never remounts anything.
  • lib/deck.ts keeps each workspace's name, tab and arrangement (berth.decks).
  • tile() in lib/layout.ts is pure and unit-tested.
  • New hooks:
    • WsTab.zoomed, honoured by PaneLayer
    • setSessionOpener in openSession
    • parkPane
    • a session drag source in tab-drag
  • UI is in components/deck/. It uses coss-ui and theme tokens only, with no new dependencies.
  • Pref: layout: "sidebar" | "workspace" (Labs), also ?layout=workspace.

Scores (1–10)

A critic subagent scored each round, and I fixed what it found between rounds. R1 and R2 came from the same critic; R3 and R4 each came from a fresh one, so R4 is the independent final.

R1 R2 R3 (fresh) R4 (fresh, final)
Speed to what needs you 8 8 7 8
Switching 7 8 8 7
Overview of many agents 5 7 5 5
Focus and calm 7 7 6 7
Learnability 6 7 6 6
Visual quality vs today 7 7 7 7

Why the remaining axes are under 8. It's mostly the shape of the idea.

  • Overview (5). At rest you see four panes and a strip of chips. The sidebar showed every project and worktree all the time. The tray brings that back on demand, but pinning it open as a column would make it a sidebar again, which is exactly what this direction replaces.
  • Learnability (6). Gestures (⌥-click, drag to an edge or the middle) and modifier keys are powerful but invisible once panes are up. The empty state, the tooltips and the ask card teach them, but only when you go looking.
  • Calm and visual (7). Four full chat panes is a lot of content by nature. The chrome is quiet, but the chat's own scroll position after a re-tile can leave a half-cut line under a header.
  • Switching (7). One fresh critic wanted ⌃Tab between the last two agents.

Worth taking whatever layout wins: ⌘J to whoever has waited longest, and answering a permission from a hover card.

Checks

  • go vet ./... and go test -race ./...: pass (internal/box passes alone; it timed out once at 10m while builds competed for CPU).
  • cargo check: pass.
  • App: typecheck:plugins, check:titles, check:csp, check:themes, test (299) and build all pass. tsc -p e2e passes.
  • docs-site build: pass.
  • New e2e/workspace-layout.spec.ts (4 tests; passes 3× repeated). It covers two agents side by side, focus and zoom, a worktree from the strip, ⌘E and the tray, a new task into a new pane, a second workspace, ⌘J, the ask card and Settings. Related specs (workspace, keyboard, drop, compare, chat) also pass: 38 tests.

Draft, for review alongside the other layout experiments; not for merging as is.

🤖 Generated with Claude Code

sean-brydon and others added 6 commits October 9, 2026 21:09
…h the rest in a strip

Settings › Labs › Layout › Workspaces trades the sidebar for live panes you
arrange, tmux or Zellij style: named workspaces as tabs across the top
(⌘1–9), up to four agent panes from any project or box side by side, a grid
or zoomed (⌘⇧↵), and every other agent in a strip along the bottom, the
ones that need you first. Click, ⌥-click or drag one in; ⌘E finds any agent
or worktree; ⌘⌥⇧ and an arrow swaps panes. Opening an agent any other way
(a notification, ⌘K, a new task) brings it into the workspace in front.

Each workspace is one tab of the existing pane machinery, so panes keep
their ids and nothing remounts. The sidebar stays the default.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…and four panes tile as a grid

From the critique: the strip's label opens a tray of every box, project,
worktree and agent (the sidebar's tree, on demand, offline boxes said so);
needs-you chips stay pinned at its start and idle agents fold into one;
four panes default to two over two; the focused pane's ring is clear; a
workspace tab counts only who needs you and shows its number; Review and
Automations are labelled; an empty workspace shows its gestures and keys.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…eeps "ready" in sight

The tray has a title and a count of who needs you and who works, boxes
lead it (offline ones last), it fades where it scrolls, and its foot says
how to bring an agent in. "N ready" sits outside the strip's scroll; a
narrow window's other panes read "Here", dashed; the status bar leaves the
agent counts to the strip and tabs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… waited longest

A needs-you chip's hover card says what the agent asks and answers a
permission there (Deny, Allow once). ⌘J brings in the agent that has
waited longest. Panes without the keyboard hide their chat controls, the
focused one has a clear ring, and the status bar names the focused pane's
worktree. The strip shows whole chips and counts the rest in "+N more";
the tray folds each project to a line of counts. "In Main" marks a
narrow window's other panes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ask card says how to bring it in

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@vercel

vercel Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
berth Ready Ready Preview Oct 9, 2026 9:01pm UTC
berth-docs Ready Ready Preview Oct 9, 2026 9:01pm UTC

Request Review

@sean-brydon

Copy link
Copy Markdown
Collaborator Author

Stashed: not going ahead with this layout for now. The branch stays for later.

@sean-brydon sean-brydon closed this Oct 9, 2026

This branch was successfully deployed

2 active deployments
Preview – berth-docs — 189716ed Deployed Oct 9, 2026 by vercel[bot]
Preview – berth — 189716ed Deployed Oct 9, 2026 by vercel[bot]
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