opencode-fleet
Run and coordinate a fleet of OpenCode agents from the command line. One agent spawns and messages others, and you can watch any worker in a real terminal when you want to.
fleet spawn reviewer --pane # a watchable terminal
fleet spawn auditor --headless # quiet, no terminal
fleet ask auditor "check the READMEs"
fleet list
Install
pipx install opencode-fleet # or: uv tool install opencode-fleet
fleet install # write the agent profiles
fleet doctor # check the environment
fleet install writes three agent profiles and one slash command into your
OpenCode config. That step is not optional decoration: without the profiles,
nothing tells OpenCode an orchestrator exists, and the CLI has nothing to
orchestrate.
Requires Python 3.9 or newer. fleet itself imports only the standard library. It
shells out to opencode, and to herdr if you want pane mode.
The three agents
orchestrator splits a request into independent parts, spawns a worker for each,
collects the replies, and synthesizes one answer. It can only run fleet and
write to /tmp, so it coordinates rather than doing the work itself.
worker takes one delegated task and reports a complete answer. It can message
peers in the fleet, so two workers can talk to each other.
analyst investigates and reports without changing any file.
Switch a session over with /orchestrate, or select orchestrator as the
session's agent.
Commands
| Command | What it does |
|---|---|
fleet spawn <name> |
Start an agent. --pane for a watchable terminal, --headless (default) for quiet |
fleet ask <name> <text> |
Send work, wait for the turn to settle, print the reply |
fleet send <name> <text> |
Send work without waiting |
fleet wait <name> |
Block until an agent is free again |
fleet collect <name> |
Print an agent's latest reply |
fleet broadcast <text> --to a b |
Send the same message to several agents |
fleet list |
Every agent, its mode, status, and cost |
fleet status <name> |
One agent in detail, as JSON |
fleet kill <name>... |
Delete one or more agents |
fleet prune |
Forget agents whose session or pane died |
fleet install / uninstall / upgrade |
Manage the bundled agent profiles |
fleet doctor |
Check the environment |
fleet templates |
Show the bundled profiles |
fleet config [key [value]] |
Read or change settings |
Long messages belong in a file, which keeps quoting sane:
fleet ask reviewer --file /tmp/brief.md
cat brief.md | fleet ask reviewer
fleet ask waits for a real settle rather than for the server's wait
endpoint, which returns immediately for a session that has not picked the work
up yet. When a wait times out, fleet prints the partial reply and names any tool
calls that started and never returned, which is usually a blocked permission
prompt.
Agents talking to each other
Any agent in the fleet can reach any other by name:
fleet send bob "check the schema first"
fleet collect bob
The orchestrator uses this to fan work out. Give workers the worker or
analyst profile and they can message each other, so a two-step conversation
between workers is just a fleet send followed by a fleet collect.
Pane mode
fleet spawn <name> --pane splits your current pane and starts a real agent in
it. You get a terminal you can watch, scroll back through, and take over. The
session id is discovered from Herdr, so the rest of the commands work exactly as
they do for a headless agent.
Pane mode needs to run from inside a Herdr-managed pane. Herdr classifies agent lifecycle states and can see approval prompts that the message log cannot, so pane agents take their status from Herdr.
Your edits are safe
The agent profiles are plain Markdown that you are entitled to edit. So fleet install records a hash of what it wrote, and fleet upgrade leaves any file
that no longer matches alone rather than overwriting your work. It tells you
which files it kept, and --force overrides.
fleet upgrade
# unchanged agents/analyst.md
# kept, you modified it agents/worker.md
fleet uninstall follows the same rule: it removes what it wrote and keeps what
you changed.
Configuration
fleet config # show everything
fleet config default_agent worker # profile new sessions get
fleet config default_model opencode/longcat-2.5-preview-free
Settings live in ~/.config/fleet/config.json. The agent registry lives in
~/.local/state/fleet/registry.json.
| Variable | Purpose |
|---|---|
FLEET_STATE_DIR |
Where the registry lives |
FLEET_CONFIG_DIR |
Where settings and the install record live |
FLEET_OPENCODE_CONFIG_DIR |
Where agent profiles are written |
FLEET_OPENCODE_BIN |
Full path to the opencode CLI, overriding PATH |
FLEET_DEBUG |
Re-raise unexpected exceptions instead of printing a message |
Design notes
No effect: ask in a bundled profile. An agent with ask in its permission
rules blocks forever when nobody answers the approval prompt, which is what an
unattended worker always is. All three profiles override the inherited ask
rules on .env reads and outside-workspace paths, replacing them with allow or
deny so a blocked call fails fast and can be reported.
Status comes from the message log. The server leaves Session.Info.time.idle
unpopulated, so that field cannot say whether a session is busy. fleet reads the
message log instead: a streaming assistant message means working, an idle
marker after the last assistant message means settled.
The registry lock is per operation, not per process. A coordinator holds a
long fleet ask while the worker it is waiting on may itself call fleet spawn.
A process-lifetime lock deadlocks that pair.
Nothing is a runtime dependency. fleet shells out to opencode api rather
than speaking HTTP, so it inherits the same service discovery and authentication
the TUI uses and works with a remote server without knowing anything about it.
Development
uv venv && uv pip install -e ".[dev]"
uv run pytest
The suite runs offline against a stub opencode binary, so it costs no model
calls. tests/test_messaging.py covers the message-log logic, which is where the
subtle bugs have been.
Licence
MIT.
Release files for opencode-fleet 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| opencode_fleet-0.2.0.tar.gz | 37.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| opencode_fleet-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 69.7 kB
Release files / opencode_fleet-0.2.0.tar.gz
| Download URL | opencode_fleet-0.2.0.tar.gz |
|---|---|
| Size | 37.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a0aaa2371b50c3089ba6afc14c3469c1fce06333c5bdee5dca48fb583d491723
|
|
BLAKE2b-256 checksum How to use checksums |
4a5f502550f64f77995d47806720f0adacfd87c9d94312519f0f17e734c2f828
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.19 {"installer":{"name":"uv","version":"0.12.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / opencode_fleet-0.2.0-py3-none-any.whl
| Download URL | opencode_fleet-0.2.0-py3-none-any.whl |
|---|---|
| Size | 32.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
49d51c7c646ea455022d13d0f3fd16bbe2c11eb55eb15a622341efb48fcc8e1b
|
|
BLAKE2b-256 checksum How to use checksums |
534ff4d013ecbb7a733da9ea28e81dbb8e4b000283cf0ac5d9938021163fcc38
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.19 {"installer":{"name":"uv","version":"0.12.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|