> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stateset.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Get started with StateSet Swarm

> Run a first swarm of Claude Code agents in StateSet sandboxes from Ghostty and Herdr: install, plan a goal, run it with review, watch it, and take the branch.

Run a swarm of Claude Code agents in StateSet sandboxes, toward one goal, from a terminal you
can leave: [Ghostty](https://ghostty.org) as the terminal, [Herdr](https://herdr.dev) as the
workspace that keeps your panes and lists your agents, and Claude Code as the agent you talk to.

You write a goal. A planner agent splits it into tasks. A coordinator starts one sandbox per
task, a reviewer agent checks each result, and accepted work is merged onto one branch on your
machine. Sandboxes hold no GitHub credentials: work comes back as patches, and nothing is pushed
or merged for you.

> [!NOTE]
>
> Every command on this page was checked against the tools' own help and the Sandbox source
> (CLI 3.4.0, MCP server 0.5.0, Herdr 0.9.3). The sequence as a whole has not yet been run end
> to end on a clean machine.

## What runs where

| Piece | Where it runs | What it is for |
| - | - | - |
| Ghostty | Your machine | The terminal window |
| Herdr | Your machine, in Ghostty | Persistent panes and tabs, and one list of every agent and its state |
| Claude Code | A Herdr pane | The agent you talk to: writes the goal with you, reads the swarm through MCP |
| Planner, coordinator, dispatcher | A Herdr pane, from a checkout of the Sandbox repository | Split the goal, launch tasks, merge accepted work |
| Coding agents and reviewers | StateSet sandboxes | The work itself: model loop, builds, tests |
| The swarm record | The StateSet service | What the CLI, the MCP tools and the dashboard read |

The work happens in the sandboxes, so a swarm costs the workstation almost nothing. Closing
Ghostty does not stop it: Herdr's session and the sandboxes go on.

## Before you start

* A StateSet Sandbox account, an API key and a card on file. Without a card, creating a sandbox
  answers `402 PAYMENT_METHOD_REQUIRED`.
* Node.js 20.19 or later in the 20 line, or 22.12 or later, and git.
* Ghostty, Herdr and Claude Code, installed from their own sites.
* A git repository for the swarm to work on, with the base branch committed. Uncommitted work is
  not uploaded.
* Model access for the agents in the sandboxes: a provider key or a Claude subscription token
  stored as an organization secret. Model charges are separate from sandbox compute.

## 1. Install

```bash theme={null}
npm install -g @stateset/sandbox-cli        # the `stateset` command, 3.4.0 or later
stateset config setup                       # asks for your API key and keeps it in a profile
stateset swarm list                         # a table, or "No swarms found": the key works
```

The planner and the coordinator are not in the npm package. They run from a checkout of the
Sandbox repository, with the SDK and the CLI built:

```bash theme={null}
cd ~/src/stateset-sandbox                   # your checkout
npm ci
npm run build -w sdk && npm run build -w cli
```

## 2. Open Ghostty and start Herdr

Open Ghostty and run:

```bash theme={null}
herdr                                # starts, or re-attaches to, the persistent session
herdr integration install claude     # once: Claude Code reports working / waiting / done to Herdr
herdr integration status             # "claude: current"
```

Make three panes: one for Claude Code, one for the swarm, one to watch it.

```bash theme={null}
herdr pane split --current --direction right --cwd ~/src/widgets           # your repository
herdr pane split --current --direction down  --cwd ~/src/stateset-sandbox  # the checkout
```

`herdr tab create --label swarm --cwd PATH` makes a tab where a split is too narrow, for example
on a phone.

## 3. Start Claude Code and give it the swarm tools

In the first pane, in your repository:

```bash theme={null}
claude mcp add stateset-sandbox -e STATESET_API_KEY=YOUR_API_KEY -- npx -y @stateset/sandbox-mcp
claude
```

Claude Code now has the sandbox tools, among them `swarm_list`, `swarm_get`, `swarm_create` and
`swarm_cancel`. `swarm_create` stores a plan and `swarm_cancel` marks a swarm cancelled at the
service; neither starts or stops a sandbox. Herdr lists this session as an agent, with its state.

## 4. Write the goal

A goal is a short text file: what to build, where in the repository, and how you will know it is
done. Ask Claude Code to draft it with you, then read it. The goal is the one thing the planner
sees.

```markdown theme={null}
# Goal: export the report as CSV

`src/report.ts` builds the monthly report as JSON. Add `GET /report.csv`
(src/routes/report.ts) that returns the same rows as CSV, with a header row and
RFC 4180 quoting. Add tests for a value containing a comma, a quote and a line
break. `npm test` passes.
```

## 5. Plan it

In the second pane, in the checkout:

```bash theme={null}
node examples/claude-agent/swarm-plan.mjs ~/src/widgets/goal.md ~/swarms/csv/plan.json \
  --repo ~/src/widgets --base main --max-tasks 4
```

One planner agent, in one sandbox, writes `plan.json`: tasks with an `id`, an `objective` and
`depends_on`. It starts none of them and never replaces an existing plan. Read the plan before
you run it, and edit it if a task is wrong.

## 6. Run it

```bash theme={null}
node examples/claude-agent/swarm.mjs run ~/swarms/csv/plan.json ~/swarms/csv/run-1 \
  --check 'npm test' --review --publish --union CHANGELOG.md
```

| Option | What it does |
| - | - |
| `--check 'COMMAND'` | Runs on the merged tree after each merge, in a fresh worktree; a failure undoes that merge |
| `--review` | A reviewer agent, in its own sandbox, reads each result before it is merged: accepted, fixed or rejected. Work it lists as sensitive (authentication, billing, secrets, deleted data) is held for you |
| `--publish` | Keeps the swarm at the service, so the CLI, the MCP tools and the dashboard can read it |
| `--union PATH` | Lets several tasks each add a line to that file without a merge conflict |
| `--max-parallel N`, `--launch-gap SECONDS` | At most 4 tasks at once, 60 seconds apart, by default: this keeps a swarm clear of the rate limit |

The run stays in the foreground and prints a table as tasks move. It exits 0 only if every task
was accepted. Run the same command again on the same state directory and it resumes.

## 7. Watch it

In the third pane:

```bash theme={null}
node examples/claude-agent/swarm.mjs status ~/swarms/csv/run-1   # the table; ends with "Published as swarm SWARM_ID."
stateset swarm watch SWARM_ID                                    # follows the swarm until it has ended
stateset swarm get SWARM_ID                                      # one look: each task and its phase
```

Or ask Claude Code in the first pane: "List the running swarms and show the tasks of the newest
one." It answers through `swarm_list` and `swarm_get`. The dashboard shows the same record at
`/dashboard/swarms`.

`herdr agent list` shows every agent Herdr knows and which are waiting for you.

## 8. Take the result

Accepted work is on the branch `swarm/run-1` in your repository, named after the state
directory. Nothing was pushed.

```bash theme={null}
cd ~/src/widgets
git log --oneline main..swarm/run-1        # one merge per accepted task
git diff main...swarm/run-1                # read it
npm test                                   # run your own checks on the merged tree
git push -u origin swarm/run-1             # when you are satisfied; then open the pull request
```

Read the table before the diff. Only one outcome means the work was judged good:

| Phase | Meaning | What to do |
| - | - | - |
| accepted | The reviewer found it ready, it merged, and the check passed | Read the diff |
| rejected | The reviewer read it and found it not ready | Read the verdict; fix the plan and pass `--retry TASK_ID` |
| not reviewed | The review itself did not happen: it could not start, crashed or timed out | The work is unjudged, not bad. Fix the cause and run again |
| held | The reviewer listed it as sensitive | Read it yourself; `--release TASK_ID` merges it |
| blocked | A task it depends on was not accepted | It did not start. Resolve the task it waits for |

## Leaving it running

* **Closing the window.** Herdr's session is persistent: open Ghostty again, run `herdr`, and
  the panes are where you left them.
* **A backlog of goals.** `swarm-dispatch.mjs` takes goal files from a directory one after
  another, under a daily budget and a budget per goal. It never pushes or merges.

## What goes wrong on the first day

* **`429` when several sandboxes start at once.** Keep the default `--max-parallel` and
  `--launch-gap`; do not start swarms in a loop.
* **An agent killed during an install.** A sandbox that is not given a size has 2Gi. Set
  `"sandbox": { "memory": "4Gi", "cpus": "2" }` in the plan (8Gi for a large monorepo).
* **Tests that fail only in the sandbox.** Sandboxes set `NODE_ENV=production`. Tell the agent
  to run `npm ci --include=dev`, and to run a React test suite as `NODE_ENV=test npm test` until
  the project's own test set-up does that.
* **The model refuses every agent.** An exhausted model account stops the work; nothing is
  wrong with the goal. Add `--preflight` and `--wait-for-model` so the run checks the model
  first and waits when it is refused.
* **Work lost with a sandbox.** Work an agent had not finished is lost if its sandbox ends
  first. Give tasks a size that fits, and resume with the same `run` command.

## Related pages

* [Sandbox terminal workbench](https://docs.stateset.com/stateset-sandbox/workbench.md): the terminal dashboard and JSON
  commands.
* [Prepared agent tasks and teams](https://docs.stateset.com/stateset-sandbox/agent-tasks.md): the task records behind a
  fleet.
* [Sandbox MCP server](https://docs.stateset.com/stateset-sandbox/stateset-sandbox-mcp.md): the tools Claude Code uses in
  step 3.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.