Skip to content
← Tools

cmux

Running several agents at once

A macOS terminal built for running several AI coding agents at once. Each agent gets its own pane, organised into workspaces, with notifications when one needs you.

I usually have four or five agent sessions running. Not because it is impressive, but because most of what they do is waiting: for an import to settle, for a build, for an API to page through a workspace. cmux is what makes that many sessions legible instead of chaotic, because it tells me which one is asking for something.

How I use it

One workspace per piece of work, colour coded. An orchestrating session and the workers it spawned all carry the same colour, so the relationship is visible without reading a single title. When a notification arrives, the colour says which job it belongs to before I have read a word.

Small fleets share a workspace. Under about four workers, they go into panes next to the session that started them rather than into a new workspace of their own. I want to watch a worker and take over its keyboard, and a worker parked somewhere I never look is the same as no worker.

Agents talk to each other directly. Sessions can send a line into another session’s input, so a worker can ask its coordinator a question instead of stalling. It has to be one line, because a newline submits, and a multi line message arrives as its first fragment with the rest lost.

Handoffs are files, not chat. Every worker writes its result to a known path and drops a flag when it is done. Chat gets summarised away and a pane can be closed. A file on disk survives both, and it is the only thing I let a worker claim credit for.

What I have learned the hard way

Session handles do not survive a restart, and nothing tells you. New identifiers are minted while every session still remembers its old one. Sending to a stale handle reports success, so messages vanish into nowhere and the channel looks healthy. I lost a couple of hours to exactly that. Now a handle is re-checked against the live list before it is used, and an absent one is treated as dead rather than slow.

Ghost handles invent conflicts that do not exist. Two sessions self reporting old identifiers looked like two different agents claiming the same job, when they were one agent under two names. Any roster built from what sessions remember about themselves is fiction. Build it from the live list.

The text and the Enter are two separate sends. Combine them and the Enter races ahead of a long paste, so the message sits in the peer’s input box unsent. It looks identical to a session that is ignoring you.

Never close a worker before its output exists. The order that works is: the worker saves its notes, the result is checked by someone other than the worker, and only then does the pane close. Reversing the last two steps means trusting a self declared success, which is the one report that is never evidence.

Resources

This is one part of a stack. The rest is on the tools page, and what I build with it is on work.

tools/cmux.md
---
tool: cmux
role: Running several agents at once
category: Building
url: https://mihajlomaiga.com/tools/cmux
---

# cmux
A macOS terminal built for running several AI coding agents at once. Each agent gets its own pane, organised into workspaces, with notifications when one needs you.
I usually have four or five agent sessions running. Not because it is impressive,
but because most of what they do is waiting: for an import to settle, for a build,
for an API to page through a workspace. cmux is what makes that many sessions
legible instead of chaotic, because it tells me which one is asking for something.

## How I use it

**One workspace per piece of work, colour coded.** An orchestrating session and
the workers it spawned all carry the same colour, so the relationship is visible
without reading a single title. When a notification arrives, the colour says which
job it belongs to before I have read a word.

**Small fleets share a workspace.** Under about four workers, they go into panes
next to the session that started them rather than into a new workspace of their
own. I want to watch a worker and take over its keyboard, and a worker parked
somewhere I never look is the same as no worker.

**Agents talk to each other directly.** Sessions can send a line into another
session's input, so a worker can ask its coordinator a question instead of
stalling. It has to be one line, because a newline submits, and a multi line
message arrives as its first fragment with the rest lost.

**Handoffs are files, not chat.** Every worker writes its result to a known path
and drops a flag when it is done. Chat gets summarised away and a pane can be
closed. A file on disk survives both, and it is the only thing I let a worker
claim credit for.

## What I have learned the hard way

**Session handles do not survive a restart, and nothing tells you.** New identifiers
are minted while every session still remembers its old one. Sending to a stale
handle reports success, so messages vanish into nowhere and the channel looks
healthy. I lost a couple of hours to exactly that. Now a handle is re-checked
against the live list before it is used, and an absent one is treated as dead
rather than slow.

**Ghost handles invent conflicts that do not exist.** Two sessions self reporting
old identifiers looked like two different agents claiming the same job, when they
were one agent under two names. Any roster built from what sessions remember about
themselves is fiction. Build it from the live list.

**The text and the Enter are two separate sends.** Combine them and the Enter races
ahead of a long paste, so the message sits in the peer's input box unsent. It looks
identical to a session that is ignoring you.

**Never close a worker before its output exists.** The order that works is: the
worker saves its notes, the result is checked by someone other than the worker, and
only then does the pane close. Reversing the last two steps means trusting a
self declared success, which is the one report that is never evidence.
## Resources
- [cmux](https://cmux.com)
- [Documentation](https://cmux.com/docs)
- [Source](https://github.com/manaflow-ai/cmux)