specs/041-layout-export-apply/spec.md
Specification: layout.export / layout.apply
Created: 2026-10-10. Status: clarified.
herdr can export a tab's layout as a portable tree and start a new tab from
one (layout.export / layout.apply), so a grid of agents can be saved and
recreated. signaltty only has tab.set_layout, which rearranges panes that
already exist.
Acceptance
layout.export {tab_id}returns{workspace_id, tab_id, title, root}.roothas thetab.set_layoutshape, and eachpaneleaf adds the pane'scwd,argvandname. An empty tab givesroot: null. An unknown tab →NO_SUCH_TAB.layout.apply {workspace_id, title?, root}starts a new, active tab (default titlelayout) with one new pane per leaf:- the leaf's
argv, defaulting to the user shell; - the leaf's
cwd, defaulting to the workspace folder; - the leaf's
name, if set.
Split directions and ratios are kept, with ratios clamped. Leaf
pane_idis ignored, so export output applies as is. The method returns{tab, panes}and emitstab.created, thenpane.createdfor each pane.- the leaf's
All or nothing: every leaf is validated before anything starts. A bad
cwd, an emptyargv, an invalid or taken name, a name repeated in the tree, a non-finite ratio, or more than 32 panes →BAD_PARAMS. If a spawn fails, the panes already started are stopped →SPAWN_FAILED, and nothing is created.Documented in
docs/08andmethod::ALL, exposed in the CLI (tab export,tab apply), and covered by an integration test.
Scope and clarification
- herdr's
tab_id(replace a tab in place),focusand per-leafenvare left out. To replace a tab, apply the new layout, thentab.closethe old one. Both are visible to clients. - Names stay unique: applying an export while the named source panes live fails, so the caller drops or changes the names.
- New panes start at 80×24, and the GUI resizes them when it shows the tab.