Tabs, lanes, and stacked panes: a layout system built for humans *and* agents
tmux layouts were designed for shells. rysh's tab → lane → group → stack hierarchy is designed for a screen full of long-running agent conversations.
tmux gives you a binary tree of splits. Split horizontal, split vertical, repeat until every pane is a ribbon four lines tall. That was fine when a pane was a shell you glanced at.
It stops being fine when a pane is a conversation.
Agents changed the unit of terminal work. You're no longer juggling six shells — you're juggling six ongoing dialogues: a refactoring agent, a test runner, an ops shell, a chat with a reviewer agent. Conversations need readable width and a persistent identity. Ribbons four lines tall give you neither.
The rysh hierarchy
Rysh structures a workspace in four layers:
Tab
└── Lane (a column; flex weight for width)
└── Pane group (can split down; RowFlex for height)
└── Panes (stacked like a deck of cards)
- Tabs are contexts: one per project, per incident, per experiment.
- Lanes are columns. Each lane has a flex weight, so "editor lane wide, worker lane narrow" is layout policy, not pixel-nudging.
- Pane groups live inside a lane. A lane holds one group by default; split down and you get a second group stacked below it in the same column, with its own share of vertical space.
- Panes stack within a group like cards. Only the top pane is visible and takes input; the rest show as title bars. (Stacking gets its own article — it's the density trick that makes many agents livable.)
The result: layouts stay columnar and readable no matter how many agents you spawn. You physically can't shred your screen into confetti.
Driving it from the keyboard
Everything is modal, Zellij-style:
Tab mode — Ctrl+T:
n— new tab1–9— jump straight to a tabAlt+Left/Alt+Right— previous / next tab (these also work globally, no mode needed)
Pane mode — Ctrl+P:
n— new pane, split right (a new column)v— split down (a new group below, same column)s— new stacked pane, on top of the active group's deckx— close the active paner— rename the pane (a given-name, unique per lane — this is the name other panes and commands refer to)d— detach the whole session
Layout mode — Ctrl+L:
- arrow keys resize the active pane —
Left/Rightadjust column width,Up/Downadjust height
Stack mode — Ctrl+S: rotate the deck (j/k).
Plus the ambient shortcuts: Tab cycles panes, [ and ] cycle tabs, Alt+Up/Alt+Down move between panes, Alt+P f toggles fullscreen for the active pane when one conversation deserves the whole screen. Every mode exits with Esc or ..
Ten minutes of muscle memory, and you stop thinking about layout entirely.
Why the structure is opinionated
The three-decisions design:
1. Columns, not arbitrary bisection. Agent output is prose and diffs, not just status lines. Prose has a readable measure. Lanes keep every conversation at column width — the same reason your editor doesn't let text run 400 characters wide.
2. Splitting down creates a group, not just a pane. The vertical split inherits the column. Your "tests below the editor" layout stays aligned as you resize, because both groups belong to the same lane and split its height by flex weight.
3. Density goes into stacks, not smaller panes. More agents shouldn't mean smaller everything. It means deeper decks.
The part that makes it reliable
Here's the architectural bit, because it's why the layout never lies to you.
Every layer is an actor: workspace → tab → lane → group → pane, each with its own mailbox over an embedded NATS bus. Layout state is authoritative in the tab actor — not in the renderer. Creating a lane, closing a pane, moving focus, resizing: each is a message processed sequentially by the owning actor.
The TUI never reaches into that state. It asks for a snapshot (a NATS request/reply that cascades down the hierarchy) and renders exactly what comes back. No shared mutable state, no mutexes, no "the UI thinks the pane is closed but it isn't." If the snapshot says three lanes at 2:1:1 flex, that is the layout.
And because workspace structure is persisted in JetStream KV on every change, the layout — tabs, lanes, groups, stacks, flex weights, focus — survives detach, reattach, even a machine reboot. You build your working environment once. It's still there tomorrow.
A layout that agents can live in
The quiet payoff: panes in rysh aren't just displays, they're addressable workspaces. A pane has a name; agents can inspect and message other panes; one pane can listen to another's output stream. The layout hierarchy is also the coordination hierarchy.
So "my screen" stops being decoration and starts being an org chart: editor lane, worker stack, ops column, a reviewer pane listening in. Layout as infrastructure.
tmux never needed that. Your agents do.
Rysh is early, and we're building it with design partners — teams who want agents in their real workflow and a direct line to the founders. → rysh.ai/design-partner
Related: Stacked panes: why your agents should behave like a deck of cards · Double-Escape: one keystroke between your shell and your AI