A tmux wall to watch every agent
One Ghostty window with a split per running agent, each one more tmux client on its session, so I can read every chat at once.
In 30 seconds
- Every agent runs in its own tmux session; a wall is one window with a split per running agent on its list.
- Each split is one more client on that session, next to its normal tab; closing it only detaches.
- Cells sit side by side in one row, in a fixed order, at a smaller font.
- Each session follows the client last typed in, so a zoomed cell prints full width.
Problem
On 2026-10-14 at 09:51 I asked for all my agents’ chats side by side on my big monitor. Each agent runs in its own tmux server, on my Mac laptop or a Linux box, with one Ghostty tab each. A first wall ran live at 10:17.
What I tried
| Attempt | What happened |
|---|---|
| A three-by-two grid of cells | Cells came out uneven widths; I asked for one row, side by side. |
| Sizing each session to its smallest client | A zoomed cell’s history stayed wrapped at the narrow cell’s width. |
| Finding the wall by its titles and cell count | Rejected in review: the tab window would match too. |
| Rebuilding walls by hand after restarts | After agent restarts the walls went stale; starts now rebuild them. |
What worked
Never starts an agent. Each cell is one more tmux client on an agent’s session, local or over SSH, next to its tab; typing in it reaches the agent like the tab. Closing a cell only detaches.
Only live agents. A cell needs the assistant actually running in the session; a leftover shell or an agent still being set up is skipped, with the reason printed.
One row, fixed order. Cells sit side by side, with an override to wrap. Ghostty can’t move a split, so order comes from a list at build time: to rearrange, I edit it and rebuild. The font is smaller than in tabs; I drag the window to the big monitor and maximize it.
Size follows the last client typed in. Claude Code wraps output at the width current when it prints and never reflows history. Sized to the smallest client, even the tabs printed at cell width. Now a zoomed cell or the tab prints full width once I type in it.
Recorded after each step. The script drives Ghostty through its AppleScript interface, never simulated keystrokes. It records the window id after the first cell, then which cell holds which agent after each split. If a record can’t be written, it closes what it just made and checks it is gone; if that fails, it tells me to close it by hand.
Heal after a start. A re-run brings an open wall to the front. After my start or restart command, a wall whose cells are gone is closed by its recorded id and rebuilt; a failed heal is only a warning.
Numbers
| Wall font size | 11configured |
|---|---|
| Agents on one wall (2026-10-24) | 5measured |
The wall’s narrow cells are why each session follows its last-typed client, not its smallest.
When it stops being true
A wall Ghostty restores after a laptop restart has new ids, so I close it by hand. A wall cell counts as an attached client, so my start script skips that agent’s tab. A cell I haven’t typed in may show a clipped view of a wider session.
Agent brief
You are helping me watch all my coding agents in one terminal window.
First ask me:
- Which machines my agents run on, and how sessions start.
- My terminal app and its version.
- My agent list and order, or build one with me.
Constraints:
- Never start, stop or restart an agent; typing in a cell reaches it like its tab.
- Each cell is another tmux client on the agent's own session; closing detaches.
- Script splits via the terminal's interface (Ghostty: AppleScript), not keystrokes; check its dictionary and minimum version.
- Cells only for agents whose assistant process runs; print skip reasons.
Steps:
- Call tools by full path; the terminal may lack my PATH.
- Remote cells: prompt-free SSH; a common terminal type if the remote lacks mine.
- One row in my order, optionally wrapped.
- Size by the last-typed client (tmux's default since 3.1; drop any smallest setting); it's server-wide.
- Record the window id, then each cell's id and agent; if a write fails, close what you made.
- Re-run: bring the wall forward; if a recorded cell is gone, close by id and rebuild all.
Pitfalls:
- Smallest-client sizing leaves history wrapped at cell width, even in the tab.
- A same-title or same-count window may be another of mine.
- An unrecorded wall gets a twin next run.
- A leftover shell looks like a live session.
- A reboot-restored wall has new ids; close it by hand.
- Anything treating attached sessions as in use sees one more client.
- Cells share the session's current window; switching it moves the tab too.
- Closing the wall may ask to confirm.
Done when:
- A dry run lists cells and skip reasons, changing nothing.
- Each running agent's session lists one more client; its tab still types.
- A second run opens nothing new; with a cell closed, it rebuilds.
- Typing in a zoomed cell makes new output full width.