Run a whole team of Claude Code sessions from one seat. claude-fleet is a multi-session manager and orchestration layer for Claude Code: one manager session spawns, steers, and hands off multiple Claude Code agents running in parallel across every project on your machine β an agent fleet for long-running autonomous coding work, without babysitting a terminal.
Workers aren't fire-and-forget processes β they're durable Claude Code sessions on disk. They survive crashes, reboots, and the manager's own death. You can steer one mid-turn, drop into any of them interactively through Claude Code's agents menu, reset one's context while keeping its work journal, or park one that hit a usage limit and resume it later. It's a single-file, stdlib-only Python CLI plus a few hooks β no daemon of its own, no framework, no dependencies.
π How it works Β· π Getting started Β· πΊοΈ Roadmap Β· π All docs Β· π Spec
$ fleet spawn migrate-users --dir C:\proga\billing-service --mode bypass \
--task "Port the users table migration from Knex to raw SQL, see MIGRATION.md" \
--token-ceiling 200000
migrate-users a1b2c3d4-... (native bg, short id a1b2c3d4)
$ fleet status
NAME STATUS TURNS COST AGE MAIL FLAGS
migrate-users working 1 0.00 2m 0 -
$ fleet send migrate-users "also add a down-migration, I forgot to ask"
migrate-users: turn running -- message queued to mailbox
$ fleet peek migrate-users
[tool] Read MIGRATION.md
[tool] Write migrations/0042_users.sql
[mail] delivered: "also add a down-migration, I forgot to ask"
[tool] Write migrations/0042_users.down.sql
[assistant] Added the down-migration and re-ran the local suite; both pass.
$ fleet result migrate-users
Migrated 0042_users to raw SQL with a matching down-migration. Ran
`npm test -- migrations` locally: 14 passed. Diff is 2 files, no schema drift.One task, one worker, one budget cap, mid-turn steering β and never once attached a terminal. That's the whole loop.
Claude Code ships its own background agents (claude --bg, claude agents) β spawn, list, monitor. Great primitives. What they don't give you is the operator layer on top:
- a named registry with per-task permission modes,
- mid-turn mailbox steering without attaching,
- journals + respawn so a worker's context can reset without losing its work,
- budget and token ceilings enforced before every turn,
- a durable manager identity that survives restarts and hands off cleanly,
- and a knowledge base that gets smarter every campaign.
claude-fleet is exactly that layer β riding on top of Claude Code's native background-agent substrate, not reinventing it.
State is plain files + a CLI. Every surface is a disposable view.
The registry, mailboxes, journals, and knowledge live on disk. The statusline, the /fleet:* slash commands, the manager session β all just read the same files. Add or drop a surface without touching the core. No surface owns data; no view ever probes a PID, takes a lock, or writes. And nothing is pushed: fleet injects no context into any session, so installing it does not change how a session in an unrelated project starts.
flowchart TB
M["π§ββοΈ Manager session<br/>(you, or a Claude Code session)"]
R["π Registry Β· state/fleet.json<br/>single writer Β· lock-guarded"]
W["π€ Workers Β· durable claude --bg sessions<br/>(worker A Β· worker B Β· worker C Β· β¦)"]
F["ποΈ state files<br/>mailbox Β· journals Β· outcomes"]
K["π knowledge/ Β· git-tracked<br/>INDEX Β· lessons Β· playbooks"]
M -->|"fleet CLI"| R
R -->|"dispatch Β· steer"| W
W -->|"hooks each turn"| F
F -.->|"status derived"| R
M <-.->|"read at start Β· write after each campaign"| K
Every fleet command is a short-lived CLI invocation. The registry is the single source of truth every view derives from β never independent state. See it all explained with diagrams: How claude-fleet works β
| Mid-turn steering | fleet send drops a message into a running worker's mailbox; injected at the next tool boundary, no attach required. |
| Token caps | --token-ceiling is enforced fleet-side before every resume turn β a worker that would blow its cap refuses to continue. |
| Respawn with journal continuity | fleet respawn gives a worker a fresh session (new context, same name/cwd/mode) while carrying its journal and drained mailbox forward β the context-reset lever for long campaigns. |
| Usage-limit park/resume | A worker that hits a Claude plan usage limit parks itself (limited status, recorded reset horizon) instead of dying silently; fleet resume-limited relaunches it once the window passes. |
| Durable manager identity | A boot-claim + heartbeat + hand-off protocol (fleet sup-boot / sup-handoff-*) so exactly one manager owns the fleet across restarts β and can pass the baton to a successor without dropping a campaign. |
| Knowledge loop | knowledge/ is git-tracked: an index, playbooks, per-project quirks, and append-only lessons that every manager session reads at startup and writes back to after every campaign. The fleet gets better at running the fleet. |
fleet doctor |
25 health checks in one command β registry readability, hook wiring, stale sessions, orphaned mailboxes, stale attaches, version pins, how long since the last autoclean sweep, supervisor claim, and more. Report-only: --repair is the one flag that mutates, and it only quarantines a corrupt state/fleet.json. |
| Terminal surface | Statusline + /fleet:* slash commands, shipped as a normal Claude Code plugin. The statusline is opt-in (fleet init --statusline) and is the only ambient surface; the plugin itself registers no hooks and injects nothing. |
| Interactive hand-off | A worker is a real Claude Code session, so you drop into it through Claude Code β the agents menu (Ctrl+T) or claude attach <session-id>. fleet release hands a stale attached record back to headless. (fleet attach itself currently refuses and redirects there; native attach integration is a later milestone.) |
| Crash-safe by design | A worker is a durable Claude Code session addressed by --session-id/--resume, not a process fleet has to keep alive. Fleet runs no persistent process of its own β every fleet command is a short-lived CLI invocation. |
Runs today on: Windows 10+ (PowerShell + Git Bash) and Linux, both verified by the test suite; macOS shares the POSIX backend but has no receipt yet. Python 3.10+ β this repo's reference box uses py -3.13, but the floor is declared once as fleet.MIN_PYTHON_VERSION and the suite runs green at it. Claude Code CLI 2.1.202+ (pin-tested at 2.1.217).
# 1. Clone, add bin\ to PATH (bin\ holds fleet.cmd)
git clone https://github.com/exPardus/fleet.git
# 2. Render machine-local hook wiring
fleet init
# 3. Install the plugin (manager skill + /fleet:* commands; registers no hooks)
claude plugin marketplace add <path-or-github-repo-of-this-clone>
claude plugin install fleet@claude-fleet
# restart Claude Code, verify: claude plugin details fleet
# 4. Optional: the always-on statusline (a plugin can't ship one)
fleet init --statuslineThen open a Claude Code session, say "become the fleet manager", and spawn your first worker. Full install detail β collaborator/multi-machine setup, the --statusline --chain composition flag β is in docs/SPEC.md.
| Command | Purpose |
|---|---|
fleet init |
Render machine-local worker-settings.json from the template |
fleet spawn |
Spawn a new worker session |
fleet status |
Show the worker status table |
fleet peek |
Digest of the last few substantive transcript records (works mid-turn) |
fleet result |
Final result text of the last completed turn |
fleet wait |
Block until turn(s) end |
fleet send |
Steer a worker (mailbox mid-turn, or a new turn if idle) |
fleet interrupt |
Stop a worker's running turn |
fleet attach / release |
attach refuses and points at claude attach / the agents menu; release returns a stale attached record to idle |
fleet respawn |
Fresh session for a worker (the context-reset lever) |
fleet resume-limited |
Relaunch workers parked on a usage limit past their reset horizon |
fleet kill |
Interrupt (if running) and mark a worker dead |
fleet clean / archive / autoclean |
Tiered cleanup: remove dead workers, archive terminal ones, staleness sweep run by the supervisor's beat and the interface's startup ritual |
fleet doctor [--repair] |
Run the 25 fleet health checks. Report-only unless --repair is passed, which quarantines a corrupt state/fleet.json by renaming it aside |
fleet sup-* |
Supervisor identity: boot, spawn, heartbeat, checkpoint, status, handoff-{begin,complete,abort} |
Shipped: core lifecycle (spawn/steer/respawn/knowledge), the terminal surface (statusline, slash commands, plugin), native background-agent dispatch, a durable supervisor identity with hand-off, and a POSIX platform backend (Linux verified, macOS unreceipted). Specced and unbuilt: SDD drift-control (M-F) and the fleet index. Ahead: a watchtower for continuous monitoring, a Telegram bridge, a local web UI, and a "trust ledger" intelligence layer. Full detail: docs/ROADMAP.md.
This repo attacks its own work before it ships. Every spec and code change runs an adversarial-review pass with receipts β real bugs caught past green tests, five-hostile-pass spec reviews, live-repro authority. It's all public in docs/reviews/ and the accumulated postmortems in knowledge/lessons.md. If you want to see the process actually work, start with docs/reviews/c2-review-adversarial.md (a HIGH-severity double-launch bug found behind a passing suite).
It's also battle-proven on itself β fleet's own development runs on fleet. Mid-campaign, a ~10-hour host outage was absorbed with zero loss (durable sessions resumed by session id), and workers that hit Claude plan usage limits have parked and been resumed live in production, more than once. The receipts, failures included, are in knowledge/lessons.md.
Under the hood: the native-substrate pivot
Fleet originally hosted worker processes itself (detached launch + PID/ctime liveness probes). It now hands process hosting and liveness to Claude Code's own background-agent daemon (claude --bg, the agents menu) and keeps only the semantic layer β mailbox steering, budgets, journals, the supervisor, the knowledge loop β on top. This shipped end-to-end and is pin-verified against the live daemon:
FLEET_LIVE=1 pytest tests/integration/test_native_pin.py
Design: docs/superpowers/specs/2026-07-13-native-agents-pivot-design.md.
Contract: docs/specs/native-substrate.md.
Because the daemon is a moving target, the pin suite re-runs on every claude version bump β see the pin gate in fleet doctor.
| Doc | For |
|---|---|
| How claude-fleet works | The idea, the problem, and the mechanics β with diagrams. Start here. |
| Getting started | Install β become the manager β run your first campaign. |
| Roadmap | What's shipped, what's next, and the soak-gate discipline behind each phase. |
| SPEC.md | The architecture of record: registry schema, load-bearing invariants, every command's contract. |
| Docs index | Every doc in the repo, tagged by audience (users / contributors / internal). |
Not sure where to look? The docs index tags every file by audience.
See CONTRIBUTING.md.
MIT Β© exPardus