Inside a workspace: how layouts are saved and merged between windows

Libraries, three-way merges and why a conflicting edit asks you to repeat it rather than guessing.

AIAgent Interface team 3 min read workspacesstorage

A workspace looks simple: a few tabs, each split into panes. Behind it is a small promise. Whatever arrangement you build stays exactly as you left it, even with several windows editing it at once.

This post follows a layout from the moment you split a pane to the moment it lands on disk, and explains what happens when two windows change the same thing.

A library is a folder

Everything you arrange lives in a library: a folder containing one SQLite file, layouts.db. It stores your workspaces, their tabs and each tab's split layout, including divider positions and what every pane holds.

A pane holds one of four things: an ordinary shell on the library's own tmux server, an attachment to a tmux session that already exists, a native view such as Team or Skills, or nothing yet. An empty pane starts no shell. The running processes are not in the file at all. They live in tmux, which is why the file can stay small and the work can outlive the window.

By default the library is ~/.local/share/agent-interface. Set AGENT_INTERFACE_DATA_DIR, or choose Open another in Settings, to work from a different folder.

layouts.db
Workspaces
each one a list of tabs
→contain
split tree
Tabs
panes, splits and ratios
→point to
outside the file
tmux sessions
shells and agents keep running
The library saves the arrangement. tmux keeps the work.

Shared and local

Open a second window with Command-N and it shows the same library. The two windows share the arrangement but not your place in it. Which workspace and tab you are looking at, which pane is expanded and which tmux window an attached pane shows are all local to each window. The file remembers a starting point for new windows, but an open window keeps its own place when another window saves.

That split matters. You can watch an agent's tab in one window while reorganizing another workspace in the second, and neither window drags the other around.

Save first, then show

Structural changes, such as a new tab, a split, a rename or a moved pane, are saved before they become the arrangement every window shares. When you drop a pane in a new place, you see a preview while the save completes. A background storage worker does the writing, so the window never waits on the database.

The same rule protects your shells. When you choose Open terminal, the pane is saved first and only then does its shell start. If a save fails, the edit is kept and you get two clear choices: Retry saving changes or Discard unsaved changes, which restores the last shared arrangement.

Many windows, one library

The storage worker polls for changes made by other windows or other compatible writers. When your window saves, its edit is reconciled against the document it started from, the newest saved document and your changed copy. That is a three-way merge.

how two edits combinemerge rules
objects      merge field by field
workspaces   merge by stable identity, not position
tabs         merge by stable identity, not position
conflict     two changes to one split tree,
             incompatible reorders, duplicate moves,
             or deleting every workspace

So a tab renamed in one window and a pane split in another both survive. Because workspaces and tabs are matched by identity, reordering a tab within its workspace while another window renames it still lands on the right tab. Moving that tab to another workspace at the same moment is a conflict.

Why it asks, not guesses

Some edits cannot both be true. If two windows rearrange the same split tree differently, any automatic choice would silently throw one of them away. Agent Interface refuses to guess. It refreshes to the saved arrangement and asks you to repeat the edit.

Repeating a split takes a second. Losing a layout you did not know was replaced costs far more. The rule keeps the outcome visible and in your hands.

Careful with your file

The library is your work, so the app treats it carefully. A new library is built in memory and written through a securely created staging file. An existing file is opened as it is, without automatic repair or replacement. If it is unreadable or invalid, it stays intact and the window shows an error, so the database and its journal remain available for recovery.

On quit, the app waits up to ten seconds for accepted layout writes to finish, including writes from windows you already closed.

honest limits

A library is local. Sessions run on the same computer as the app, and syncing live sessions between computers is not supported.

The architecture guide covers the storage format and merge rules in more detail.

share
all posts →
ghostty-vt
how it works
Drawing terminals natively with Ghostty’s core
claude + codex
guides
Running Claude Code and Codex side by side
GET /api/agents
integrations
What Agent Interface reads from Agent Backbone