Skip to content

Run a fleet of agents in your terminal.

claude, codex, anything with a CLI — each in its own virtual terminal, all driven from one place: a TUI, a browser, or the swarm command itself.

The agents get that same command, so they talk to each other — and you can see, shape and pause what they say.

go install github.com/emmanuel-deloget/swarm/cmd/swarm@latest
  • Linux
  • macOS
  • Windows 10 1809+

Requires Go 1.25+ · swarm init writes you a config

swarm run starts the fleet, the TUI and the web remote. The header counts the fleet by state, so a prompt waiting on you is visible without hunting for it.

The bottom row says where your keys are going. Each bar names the door to the other.

attach · ⌨ DIALOGUE — typing goes to dev-1 · esc for a shortcut

The default. What you type goes to the agent on screen, with no i first — esc reaches one shortcut, esc esc gives the keyboard back. and the arrows are not text, so the lock never sees them.

attach · A full · i inject · s send · d dialogue · m mosaic · : cmd · ? help

With the lock off: eighteen letters are shortcuts again, three of which act on an agent’s life. d brings the lock back, and whether it is on is remembered between runs.

ATTACHED — keys go to the agent, ctrl+\ to detach

Attached, the keyboard belongs to the agent whatever the lock says — a bar claiming otherwise would be worse than none. ctrl+g on Windows, whose console cannot produce ctrl+\.

Features

What it gives you#

swarm knows nothing about any particular agent. An agent is a command line — everything below follows from that.

How it works

One hub, one pty per agent#

Everything that drives the fleet — the TUI, the swarm command, a browser — talks to the same hub. The hub owns the fleet, the events and the message bus.

TUIbubbleteaswarm CLIunix socketbrowserHTTP + WShubfleet · events · message busdev-1pty + VTargv: claude, codex, …review-1pty + VTargv: claude, codex, …docs-1pty + VTargv: claude, codex, …
  1. A real terminal per agent

    Not a pipe: an agent gets a terminal — a pty, or a pseudoconsole on Windows — so job control, ^C, terminal queries and the alternate screen all work the way they do when you run it yourself.

  2. A terminal emulator kept in sync

    swarm keeps a virtual terminal in step with each pty, which is what makes a snapshot of any agent possible at any moment — instead of replaying a byte stream that may start mid-sequence. The TUI renders it as ANSI, the web server as HTML lines, and sends only the ones that changed.

  3. One socket, many callers

    The control socket lives in .swarm/<session>.sock. Your other terminals reach it, and so do the agents — which is why an agent can run swarm send with no arguments of its own.

The agents’ guide

swarm writes the fleet’s documentation#

Everything on this page is what swarm does for you. This is what it tells the agents — so they know there is a bus, that a request leaves something outstanding, and how to settle it.

  • swarm run writes .swarm/AGENTS.md from your configuration. Point your agents’ instructions at it and they can coordinate without you.
  • A section appears only when the thing it describes is switched on. A guide that names mechanisms nobody dispatches on is worse than none — an agent told about message kinds in a fleet that ignores them learns to type flags nobody reads.
  • agents_template replaces the built-in one with yours, getting exactly the same data — which is the only way an override can be as informed as what it replaces.
.swarm/AGENTS.md
## When something is asked of you

A `question`, a `request` or a `blocked` addressed to you
leaves something outstanding until you settle it. The message
tells you how, and it is worth doing even when the answer is
"there was nothing to do":

```sh
swarm done                    # everything outstanding is finished
swarm done -thread 7 "note"   # just this one, with a word about it
```

Until then you are counted as owing it.

The CLI

Drive the fleet from any terminal#

Every command talks to a running swarm over a Unix socket — from another terminal, from a script, or from an agent.

Look at what the fleet is doing without stopping it. swarm screen prints what a terminal shows right now; swarm attach hands the window over until you press the detach key.

A target is an agent name, @group, @role, all, or a comma-separated list of those. Every command that acts on agents takes one.

shell
swarm ls                       # state, branch and drift
swarm status @dev              # more detail
swarm screen dev-1             # what that terminal shows right now
swarm attach dev-1             # take it over in this window
swarm logs dev-1 -f            # recorded output, escapes stripped
swarm config check -fix        # a config that has gone stale

Recipes

Fleets that do something#

Each one is a swarm.yaml you can copy, living in the repository — where a test loads them all through the real config loader, so a renamed key breaks the build rather than waiting for you to hit it.

  • tickets — one agent per ticket. swarm spawn worker "take rq-219" makes an instance that is created already owing that task, gets its own branch, and goes away when it says it is done.
  • ssh — an agent is a command line that runs in a terminal, and ssh is a command line that runs in a terminal. So one member of the fleet can be a live session on another machine.
  • nightshift — a fleet woken by a clock. swarm has no scheduler and no reason to have one: the machine already has a good one, and swarm has an HTTP listener for it to talk to.

All seven recipes

Remote control

The same fleet, in a tab#

With web.enabled, swarm run prints a URL carrying a token. The page shows the agent list, the selected terminal — live, and you can type into it — a grid view, the event log, and a composer.

No JavaScript terminal library: swarm already emulates the terminals, so the server sends HTML lines, and only the ones that changed. The grid takes whole screens and picks the arrangement with the biggest cells — one column on a phone.

  • Past localhost, treat that URL as a shell on your machine.
  • Set web.read_only: true if you only want to watch.
  • Put it behind TLS or a tunnel (ssh -R, cloudflared) rather than binding 0.0.0.0 in the open.

Get started

Three commands to a fleet#

Requires Go 1.25+. Linux and macOS are the tested platforms; Windows works and is newer.

  1. Install it

    Or build from a checkout with go build -o swarm ./cmd/swarm.

    go install github.com/emmanuel-deloget/swarm/cmd/swarm@latest
  2. Write a config

    One agent, nothing listening on a port, every other setting present as a commented example — and it offers to add .swarm/ to your .gitignore. Then list your agents.

    swarm init
  3. Start the fleet

    Starts the agents, the TUI and the web remote. --no-tui runs it headless if you would rather drive it from the CLI or the browser.

    swarm run

On Windowssince v0.4.0

Everything works there: the TUI, attaching, the bus, swarm send from inside an agent. Install with go install rather than downloading a binary — none is published signed, and an unsigned Go binary is regularly taken for malware by heuristics.

  • detach_key is ctrl+g: a console makes ctrl+\ arrive as a plain backslash.
  • swarm attach puts its reminder in the window title — the console has no scrolling region to hold a status bar.
  • secret_path is not checked: who may open a file is an ACL, which mode bits cannot express.

MIT licence. Issues and pull requests welcome — CI runs the suite on Linux, macOS and Windows, plus go vet, gofmt, golangci-lint and govulncheck.