Sandbox
@fubak/ultraswarm

Node CLI for multi-agent worktree orchestration

Ultraswarm is a durable orchestration layer for agent-led coding. It breaks a plan into tasks, sends them to worker CLIs in isolated Git worktrees, watches the runs, and then verifies and integrates the results. The runner also keeps policy, recovery, reports, and worker routing in one place.

83 stars10 forksJavaScriptUpdated 2mo ago
Who it's for

Builders who want Claude Code or another CLI agent to coordinate other workers on a shared codebase.

What it delivers

You can offload implementation work to multiple agents while keeping Claude or another brain in control of review and merge.

What it does

Multi-worker orchestration

Routes tasks across Codex, Claude Code, Cursor Agent, Grok, Gemini, shell workers, and other configured CLIs.

Isolated worktree execution

Runs each task in its own Git worktree so workers do not edit the main branch directly.

Plan, review, and merge flow

Supports plan preview, approval, status, logs, recovery, and a separate final merge approval step.

Health and routing checks

Uses preflight checks, worker capability data, and repository metrics to choose healthy workers.

Run reports and token breakdowns

Prints terminal reports with per-task results, wall-clock time, and per-CLI usage summaries.

Host skills and plugins

Includes installable skills and plugin manifests for Claude Code, Codex, Cursor, and Grok.

Policy and safety controls

Adds task contracts, forbidden-path policy, gated commands, and worker environment allowlists.

How to get it

  1. 1Run
    git clone https://github.com/fubak/ultraswarm.git ~/projects/ultraswarm
    cd ~/projects/ultraswarm
    npm install
  2. 2Run
    bash scripts/install-codex-skill.sh
  3. 3This creates
    ~/.agents/skills/ultraswarm -> ~/projects/ultraswarm/hosts/codex/skills/ultraswarm
  4. 4Install the plugin
    /plugin marketplace add fubak/ultraswarm
    /plugin install ultraswarm@ultraswarm
  5. 5For direct/shell or non-Grok use
    node ~/projects/ultraswarm/bin/ultraswarm.mjs run ...
    # or the installed bin after `npm install -g` equivalent
  6. 6Run
    bash scripts/install-cursor-skill.sh

README

ultraswarm

Ultraswarm is a durable multi-worker coding orchestrator for Codex, Claude Code, Cursor Agent, Grok, and shell usage. One standalone Node runner owns decomposition, worker routing, process supervision, isolated Git worktrees, adaptive review, transactional integration, approvals, recovery, and reporting.

What's New In v3.6.0

The run report now ends with an estimated-vs-used token breakdown by CLI, model, and effort, and the CLI gained onboarding/recovery commands:

  • TOKENS BY CLI / MODEL / EFFORT table closes every reportCLI | model | effort | est. | used | Δ | attempts, plus a total row. est. is a calibration-informed heuristic: ultraswarm prefers the measured per-(CLI, model, effort) average persisted in .ultraswarm/state.sqlite (route_calibration, self-correcting across runs) and falls back to a static tier curve (simple 10k / moderate 30k / complex 75k / expert 150k tokens) until enough runs accumulate. used is ONLY structured usage summed across attempts — when a CLI reports none, never backfilled from the estimate (the v3.5.13 honesty invariant still holds).
  • Attempts now record the resolved model id, tier, and effort, not just the tier where "model" used to live (schema migration v3, additive — existing v2 databases upgrade in place). Failed attempts record their burned tokens too, so a rejected retry still counts toward the table above. When a CLI doesn't self-report cost, worker spend is now priced from config.intelligence.pricing[model] (USD per million tokens; falls back to built-in Claude rates, else 0 for an unpriced model) so maxCostUsd can actually bound external worker spend.
  • Declarative usage capture widens real token reporting from 2 built-ins to 3. Each registry entry can now declare a usage array of { input, output, cost? } dot-path descriptors (with a * wildcard for keyed maps), evaluated against structured worker output; overrides.<cli>.usage and aliases.<name>.usage let you add or override a descriptor for a CLI without a built-in parser. Gemini now runs with --output-format json and its stats.models.*.tokens.* usage is captured, joining codex and opencode as real-usage CLIs.
  • Routing feedback--decompose planning and doctor now show each worker's measured track record (codex (backend…; 12 runs, 92% pass)) pulled from worker_metrics, so the brain and the operator both see what has actually been working, not just declared specialties.
  • doctor --models prints the resolved model per CLI per tier (registry + overrides + aliases), so a stale model pin is visible without reading config files; an optional modelListCmd per registry entry/alias warns when a resolved model is missing from the CLI's own model list.
  • ultraswarm replan <runId> emits a plan JSON of a run's failed/blocked tasks, ready to feed straight back into run --plan-file - — a partially-failed run's surviving tasks never need to be retyped by hand.
  • ultraswarm add-cli <name> --binary <bin> [--extends <builtin>] [--model <id>] onboards a new CLI in one command: probes the binary, builds a valid alias skeleton, and merges + validates it into ultraswarm.config.json, refusing to clobber an existing alias.
  • Prompt efficiency — worker prompts are hard-capped at 64k chars with a loud [ultraswarm: truncated N chars] marker instead of silently growing; retry feedback is bounded to the last 10 rejected attempts (500 chars each) and now names the files the rejected attempt changed, so a retry converges instead of re-exploring from scratch.
  • Ledger guard — the report now prints a loud ⚠ LEDGER MISMATCH line if the merged/failed/ blocked task rows don't add up to the plan's task count, instead of printing plausible-looking numbers that quietly don't reconcile.

What's New In v3.5.18

Run-output polish:

  • Plain terminal report by default (no markdown #/**/_ showing as literal chars); pass --markdown to keep GitHub-markdown for pasting into a PR.
  • Color — the live stream and report verdict are color-coded (green pass / red fail / yellow retry); auto-off when piped, honors NO_COLOR / --no-color.
  • Run wall-clock in the Summary, and short 8-char run-ids (merge/status/logs/… accept an unambiguous prefix).

What's New In v3.5.17

  • Every table in the run report is now a clean aligned terminal table — the per-task list was the last markdown table; it now matches the per-CLI / PLAN PREVIEW / WORKER ROSTER fixed-width style.

What's New In v3.5.16

  • Per-CLI token table now renders as a clean aligned terminal table (the 3.5.15 version was a markdown table whose pipes didn't line up in a raw CLI) — fixed-width columns with a separator and right-aligned numbers, matching the PLAN PREVIEW / WORKER ROSTER style.

What's New In v3.5.15

Per-CLI token breakdown (see the CHANGELOG):

  • "Work offloaded" now breaks usage down by CLI — a table of landed (tokens that produced integrated work) vs spent (all attempts, incl. rejected retries and competition losers) vs overhead, with a reconciling total. You can see at a glance which worker burned tokens and how much went to retries/competition (e.g. Workers used ≈ 383,578 tokens — ≈ 274,485 landed, ≈ 109,093 on retries + competition).

What's New In v3.5.14

Real token-usage capture (see the CHANGELOG):

  • codex and opencode now report real usage. Their default invocations use exec --json / run --format json, and ultraswarm parses the structured JSONL usage events — so the report's "Work offloaded" section shows the actual token count (e.g. Workers reported ≈ 238,656 tokens) instead of "not reported". No more scraped guesswork (removed in 3.5.13), and no fabrication when a CLI doesn't report — a custom invocation without the JSON flag honestly shows "not reported".

What's New In v3.5.13

Honest run-report value section (see the CHANGELOG):

  • No more scraped token noise — the old "Tokens saved" number was regex-scraped from worker stdout and matched incidental digits (e.g. "≈ 62 tokens" for a run that used thousands). The free-text scrape is gone; token/cost now come only from a worker's structured usage, else nothing is claimed.
  • "Work offloaded" reports what's measured — tasks, worker-attempt count, and total external wall-clock. A token figure shows only when a worker actually reported one; otherwise the report says "Token/cost usage: not reported by these CLIs" rather than inventing a misleading count.

What's New In v3.5.12

Live-stream readability follow-up to v3.5.11 (see the CHANGELOG):

  • No more git chatter in the streamgit worktree add / merge --squash output is captured instead of inherited, so a big swarm's progress lines aren't buried under "Preparing worktree …".
  • Consistent glyphs everywhere — routine-path escalation/rejection/blocked lines now carry the same // glyphs as the high-risk competition path, so the whole stream scans uniformly.

What's New In v3.5.11

Readability + accuracy pass on the two human-facing output surfaces (see the CHANGELOG for detail):

  • Accurate run-end report — reports "integrated" (not "merged") while a run awaits merge approval, with a staging line making clear nothing lands on your branch until you approve; the headline counts every task (including post-merge regressions) so the numbers reconcile.
  • Honest token offload — the offload headline no longer leads with a misleading ≈ N/≈ 0; it shows the exact figure on full coverage, an explicit floor (x of y tasks reported) on partial, and "not measurable here" when no worker reports usage. Retried-but-integrated tasks are named.
  • Visible competition retries — when a high-risk competition winner is rejected by adversarial QA, the live stream now logs the judged winner and ✗ … rejected by QA — retrying instead of silently jumping to the next attempt.

What's New In v3.5.1–v3.5.10

Hardening from a full audit of the orchestrator (each fix shipped as its own patch release; see the CHANGELOG for per-version detail):

  • Concurrency — fixed a re-entrant limiter deadlock that could hang an entire run, and froze runs deterministically on ≤3-core hosts (CI), whenever a high-risk task fanned out competition/QA work.
  • Security — plan contract.commands now reject shell metacharacters (no more npm test; rm -rf ~ reaching the shell); worker env passthrough narrowed from the whole XDG_* namespace to named vars.
  • Integration — a no-op squash records a clean skip instead of throwing and blocking the whole wave; a failed per-task commit fails loud instead of reporting ok; post-run cleanup deletes only the current run's branches.
  • Recoveryresume judges liveness on a persisted orchestrator identity (pid + boot id), so it can't reap a still-running run or be fooled by PID reuse after a reboot; terminal runs are immutable.
  • Brain — Anthropic schema calls extract JSON defensively and fall back to raw text so the validate-and-retry loop works; malformed --plan-file / package.json fail with a clear USAGE error.
  • Alias workers in competition — user-defined alias workers can now participate in (and be retried within) high-risk competition; they previously tombstoned as "only N usable worker(s)".

What's New In v3.5

  • Functional preflightpreflight runs a cached exec smoke test per CLI (write a file in an isolated temp dir) and excludes workers that pass --version but can't actually run (dead auth, no-op). Routing keys off the functional verdict. See Prerequisites.
  • Human-readable outputpreflight, plan previews, status, and doctor render aligned tables by default; add --json for the old machine output.
  • Live progress + every-agent heartbeat — runs stream per-agent dispatch lines, gate results, and a periodic active/idle heartbeat to stderr so every worker stays visible.
  • Tokens-saved summary — the final report estimates the implementation tokens that ran on external CLIs off your Claude context (an honest best-effort floor).
  • Repo-local worktrees with deps installed — per-task and integration worktrees default to <repo>/.ultraswarm/worktrees and have dependencies installed before gates run (detected from the lockfile: pnpm/npm/yarn), so build/test gates resolve node_modules even on pnpm workspaces.

What's New In v3.4

  • agent worker — the Cursor CLI (agent -p --force) as a headless shell worker for isolated worktree execution. See Cursor Agent Worker.
  • Cursor agent host skill — install with scripts/install-cursor-skill.sh so Cursor sessions can orchestrate via the standalone runner. See Cursor Agent.

What's New In v3.3

What's New In v3.2

  • User-defined harness aliases — register your own CLI entries under a new top-level aliases config key. Each alias extends a built-in (inheriting its binary, timeout, effort flags, and capabilities), overrides only its specialty / models / invocation, and can cap routing with maxTier. Generalizes the previously hardcoded pi-local; strictly opt-in. See Harness Aliases.

What's New In v3.1

  • pi worker — the provider-agnostic pi coding CLI (Anthropic Claude spread by default). See Local / Private Models.
  • pi-local worker — an always-on local/private worker that drives Ollama models through the same pi binary for fully offline-capable runs.
  • Per-task effort levels — the decomposition brain assigns reasoning effort per task, independent of model tier, defaulting to low, with effort-first QA escalation. See Effort Levels.

What Changed In v3

  • SQLite state and append-only events under .ultraswarm/state.sqlite
  • Capability and repository-metric worker routing with explanations
  • Supervised worker process groups, timeouts, cancellation, redacted bounded logs
  • Executable task contracts and forbidden-path policy
  • Integration branches that do not modify the checked-out branch
  • Separate plan and merge approvals
  • Crash/status/log/export commands and stale-base recovery
  • Generated Claude, Codex, Grok, and Cursor agent skills from one provenance-locked contract

Node 22 or newer is required because ultraswarm uses the built-in node:sqlite API.

Install

git clone https://github.com/fubak/ultraswarm.git ~/projects/ultraswarm
cd ~/projects/ultraswarm
npm install

Codex

bash scripts/install-codex-skill.sh

This creates:

~/.agents/skills/ultraswarm -> ~/projects/ultraswarm/hosts/codex/skills/ultraswarm

Restart Codex and invoke $ultraswarm.

Claude Code

Install the plugin:

/plugin marketplace add fubak/ultraswarm
/plugin install ultraswarm@ultraswarm

Invoke /ultraswarm.

Grok Build (xAI Plugin Marketplace)

Ultraswarm is published in the official xAI Grok plugin marketplace.

  • Grok Build can proactively suggest the skill for complex multi-step coding tasks.
  • Install directly from the Grok marketplace / plugin browser (searches for "ultraswarm").
  • Invocation inside Grok: follow the skill (typically ultraswarm or /ultraswarm).

The skill delegates to the standalone runner (do not re-implement orchestration inside the host).

For direct/shell or non-Grok use:

node ~/projects/ultraswarm/bin/ultraswarm.mjs run ...
# or the installed bin after `npm install -g` equivalent

See the generated Grok host contract: hosts/grok/skills/ultraswarm/SKILL.md.

Plugin source + details: https://github.com/fubak/ultraswarm (manifests in .grok-plugin/ + .claude-plugin/).

Maintaining the plugin after publication

  1. Bump the version in every manifest so they agree (validate Check 3): package.json, package-lock.json (run npm install --package-lock-only), .claude-plugin/plugin.json and .grok-plugin/plugin.json (keep byte-identical — cp one to the other), and both version fields in .claude-plugin/marketplace.json (metadata.version + plugins[0].version).
  2. Update docs + CHANGELOG (move [Unreleased] to the new version + date).
  3. npm run validate and npm test must pass.
  4. Push to main.
  5. Capture the new commit SHA (git rev-parse HEAD).
  6. In the plugin-marketplace repo, update the sha for ultraswarm, re-run python3 scripts/generate-plugin-index.py, then validate + open PR.
  7. scripts/validate.sh now also validates .grok-plugin/plugin.json (parse + version match) and enforces that the two manifests are byte-identical.

This addresses review feedback on packaging validation and sync risk.

Cursor Agent

bash scripts/install-cursor-skill.sh

This creates:

~/.cursor/skills/ultraswarm -> ~/projects/ultraswarm/hosts/agent/skills/ultraswarm

Restart Cursor and invoke the ultraswarm skill. The host prepares plans and delegates execution to bin/ultraswarm.mjs; it does not implement feature work directly.

Install the Cursor CLI separately if you also want agent as a worker:

curl https://cursor.com/install -fsS | bash
agent --version

Grok Or Shell (non-Grok hosts)

See the full Grok Build (xAI Plugin Marketplace) section (and the maintenance subsection) above. For direct execution outside Grok:

node ~/projects/ultraswarm/bin/ultraswarm.mjs ...

The generated Grok host contract is at hosts/grok/skills/ultraswarm/SKILL.md.

Prerequisites

  • A Git repository
  • Node 22+
  • At least two authenticated worker CLIs from codex, gemini, grok, agy, droid, opencode, pi, pi-local, small-harness, and agent
  • An authenticated claude CLI for the default QA/decomposition brain, or ANTHROPIC_API_KEY with ULTRASWARM_BRAIN=anthropic-api

Check readiness:

# Functionally verify each CLI (cached smoke test — proves a worker can actually write a file,
# not just that `--version` succeeds). Workers shown UNUSABLE are excluded from routing.
node ~/projects/ultraswarm/bin/ultraswarm.mjs preflight

# Policy, gates, and worker capabilities (add --json for machine-readable output):
node ~/projects/ultraswarm/bin/ultraswarm.mjs doctor
node ~/projects/ultraswarm/bin/ultraswarm.mjs workers

preflight is the recommended first step: a CLI can pass --version yet fail every real run (dead auth, no-op output). The smoke test catches that and routing skips non-functional workers automatically. Verdicts are cached in .ultraswarm/functional-probe.json (24h TTL, keyed by binary version); preflight --smoke forces a re-probe.

Run

Create a plan:

{
  "tasks": [
    {
      "id": "api-tests",
      "description": "Add regression coverage for the API",
      "files": ["test/api.test.mjs"],
      "complexity_score": 25,
      "risk": "routine",
      "effort": "low",
      "dependencies": [],
      "prompt": "Add focused regression tests for invalid request handling.",
      "contract": {
        "commands": ["npm test"],
        "assertions": ["Invalid requests return 400"],
        "allowed_paths": ["test"]
      }
    }
  ]
}

cli, model_tier, and effort are optional. When cli/model_tier are omitted, ultraswarm ranks healthy workers using capability fit and repository-local pass, latency, and cost history. When effort is omitted it defaults to low (see Effort Levels).

Preview without executing:

node ~/projects/ultraswarm/bin/ultraswarm.mjs run \
  --plan-file .ultraswarm-plan.json

Approve the plan and execute:

node ~/projects/ultraswarm/bin/ultraswarm.mjs run \
  --plan-file .ultraswarm-plan.json \
  --approve-plan

While a run executes, it streams colour-coded progress to stderr — wave headers, a per-agent dispatch line for every worker the moment it starts (▶ task → cli@tier attempt N [pid …]), gate results (/), review verdicts ( approved; ✗ … rejected by QA — retrying), escalations (), and a periodic active/idle heartbeat (⏱ active: … · idle: …) so every worker's state stays visible. Colour auto-disables when output is not a TTY (piped/CI), honours the NO_COLOR convention, and is suppressed by --no-color.

When it finishes it prints a run report (plain terminal text by default; pass --markdown to emit GitHub-markdown for pasting into a PR/issue): a per-task table showing which worker landed each task, a Summary with the run wall-clock, and a Work offloaded section — how many tasks/worker-attempts ran on external CLIs, their total compute time, and a per-CLI token breakdown (landed vs spent vs retry/competition overhead) read from each CLI's structured usage. The headline value: the implementation ran on external CLIs, off your Claude context; Claude only orchestrated and reviewed (see token reporting).

The report ends with an estimated-vs-used breakdown by CLI, model, and effort level:

Tokens by CLI / model / effort

CLI     model           effort     est.    used    Δ  attempts
──────  ──────────────  ──────  ───────  ──────  ───  ────────
codex   gpt-5.4-mini    low      45,200  41,830  -7%         6
gemini  gemini-2.5-pro  medium   62,000       —    —         2
Total                           107,200  41,830  -7%         8

est. is a calibration-informed heuristic and used is only structured usage — see State And Safety for how each is derived.

Per-task and integration worktrees are created under <repo>/.ultraswarm/worktrees (gitignored). Because a fresh worktree checks out tracked files only (no node_modules), the runner installs dependencies in each worktree before gates run — inferred from the lockfile (pnpm-lock.yamlpnpm install --frozen-lockfile, package-lock.jsonnpm ci, yarn.lockyarn install --immutable); repos without a lockfile are left untouched. This is what makes gates resolve node_modules on pnpm workspaces, where upward module resolution from a sibling worktree does not reach the symlinked deps. Override the worktree location with --worktree-root <dir>.

Gates are auto-detected from your package.json scripts (build, test, lint). Override which scripts gate with --gates <names> (e.g. --gates test,lint to drop a worktree-unsafe build) or a "gates" array in ultraswarm.config.json; an empty list disables gates. The same selection applies to the integration gate at merge time, so run and merge stay consistent.

The run finishes in awaiting_merge. Your checked-out branch has not changed. After reviewing status and logs, provide the separate merge approval:

node ~/projects/ultraswarm/bin/ultraswarm.mjs status <run-id>
node ~/projects/ultraswarm/bin/ultraswarm.mjs logs <run-id>
node ~/projects/ultraswarm/bin/ultraswarm.mjs merge <run-id> --approve

The final merge is fast-forward only. If the target branch moved, the run enters stale_base; recover it with:

node ~/projects/ultraswarm/bin/ultraswarm.mjs resume <run-id>

Commands

CommandPurpose
preflightFunctionally verify enabled CLIs (cached smoke test); --smoke forces a re-probe
runPreview or execute a plan
merge <id> --approveApprove and fast-forward integrated work
status [id]List runs or inspect durable state
logs <id>Read append-only events
cancel <id>Terminate worker process trees
resume <id>Recover awaiting-merge or stale-base state
doctorValidate policy, gates, and worker health; --models shows resolved model per CLI per tier
workersShow worker health and capabilities
explain-routing <task>Explain worker rankings
export <id>Export run provenance as JSON
replan <runId>Emit a plan JSON of a run's failed/blocked tasks, for run --plan-file -
add-cli <name> --binary <bin>Probe, validate, and write a new CLI alias into ultraswarm.config.json

preflight, run (plan preview), status, doctor, and workers print human-readable tables by default; add --json for machine-readable output. By default run functionally verifies the pool (cached smoke test) before assigning; pass --smoke to force a fresh probe or --no-smoke to fall back to a --version-only check.

The run report renders as plain terminal text by default; pass --markdown to emit GitHub-markdown (for pasting into a PR or issue). Colour is enabled for interactive terminals and disabled when output is piped/redirected; turn it off explicitly with --no-color (or NO_COLOR=1). Any command that takes a run id also accepts an unambiguous prefix — e.g. the 8-character id printed in the report's Approve merge with: line — in place of the full id (merge/status/logs/cancel/resume/export).

Legacy --plan-file ... --yes syntax remains as a v2 compatibility shim. --yes maps only to plan approval; it never approves the final merge.

Exit codes are 0 success, 1 runtime failure, 2 usage error, 3 approval required, and 4 blocked or stale state.

Policy

Add policy to ultraswarm.config.json:

{
  "enabled": ["codex", "gemini"],
  "workerEnvAllowlist": ["OPENAI_API_KEY"],
  "policy": {
    "minimumHealthyWorkers": 2,
    "maxParallelWorkers": 4,
    "requireCompetitionForRisk": ["high"],

Files in the repo

Repository payload20 top-level entries
  • .claude-plugin
  • .githooks
  • .github
  • .grok-plugin
  • bin
  • docs
  • fixtures
  • hosts
  • lib
  • maintenance
  • scripts
  • skills
  • .gitignore
  • CHANGELOG.md
  • LICENSE
  • package-lock.json
  • package.json
  • README.md
  • ultraswarm.config.advanced.json
  • ultraswarm.config.example.json

Discussion (0)

Ask about usage, or say what you built with it

Sign in to join the discussion.

No comments yet. Be the first to say what this is good for.

More tools

JuliusBrussee/
caveman

🪨 why use many token when few token do trick — Claude Code skill that cuts 65% of tokens by talking like caveman

105k
1 add
MemPalace/
mempalace

The best-benchmarked open-source AI memory system. And it's free.

59k
stablyai/
orca

Orca is the ADE for working with a fleet of parallel agents. Run any coding agent with your own subscription. Available on desktop, mobile and remote runtime.

66k

A cross-platform desktop All-in-One assistant for Claude Code, Codex, OpenCode, OpenClaw, Grok Build & Hermes Agent. Only official website: ccswitch.io

132k

Never stop coding. Free MIT AI gateway: one endpoint, 352 providers (150+ free), 1200+ models Kimi, Claude, GPT, Gemini, GLM, DeepSeek, MiniMax. Works with Claude Code, Codex, Cursor, OpenCode, Cline & Copilot. Quota-aware auto-fallback, RTK+Caveman compression saves 15-95% tokens, MCP/A2A, Desktop/PWA. Built by 550+ contributors

64k
headroomlabs-ai/
headroom

Compress tool outputs, logs, files, and RAG chunks before they reach the LLM. 20% fewer tokens for coding agents, 60-95% fewer tokens for JSON, same answers. Library, proxy, MCP server.

71k