{"id":49048045,"url":"https://github.com/sds-mode/pitboss","last_synced_at":"2026-04-19T19:01:07.668Z","repository":{"id":352221759,"uuid":"1213058794","full_name":"SDS-Mode/pitboss","owner":"SDS-Mode","description":"Rust headless dispatcher for parallel Claude Code agent sessions","archived":false,"fork":false,"pushed_at":"2026-04-18T14:25:43.000Z","size":718,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-18T14:40:27.791Z","etag":null,"topics":["agent-orchestration","ai-agents","anthropic","claude","claude-code","cli","dispatcher","llm-agents","llm-orchestration","mcp","model-context-protocol","parallel-execution","ratatui","rust","tui"],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SDS-Mode.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE-APACHE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":"ROADMAP.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-04-17T02:14:08.000Z","updated_at":"2026-04-18T08:44:37.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/SDS-Mode/pitboss","commit_stats":null,"previous_names":["sds-mode/pitboss"],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/SDS-Mode/pitboss","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SDS-Mode%2Fpitboss","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SDS-Mode%2Fpitboss/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SDS-Mode%2Fpitboss/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SDS-Mode%2Fpitboss/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SDS-Mode","download_url":"https://codeload.github.com/SDS-Mode/pitboss/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SDS-Mode%2Fpitboss/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32018764,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-18T20:23:30.271Z","status":"online","status_checked_at":"2026-04-19T02:00:07.110Z","response_time":55,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agent-orchestration","ai-agents","anthropic","claude","claude-code","cli","dispatcher","llm-agents","llm-orchestration","mcp","model-context-protocol","parallel-execution","ratatui","rust","tui"],"created_at":"2026-04-19T19:00:48.365Z","updated_at":"2026-04-19T19:01:07.649Z","avatar_url":"https://github.com/SDS-Mode.png","language":"Rust","readme":"# Pitboss\n\n\u003e You deal the cards; the pit watches the chips.\n\n\u003e **Operating pitboss from an AI agent?** See [`AGENTS.md`](AGENTS.md) —\n\u003e schema reference, decision tree, canonical examples, and the rules for\n\u003e translating natural-language requests into valid manifests.\n\n**v0.5.0** ships the flagship operator-control bucket: `pitboss attach\n\u003crun-id\u003e \u003ctask-id\u003e` for a follow-mode log viewer on a single worker;\nSIGSTOP freeze-pause as an opt-in alternative to cancel-with-resume;\nstructured `ApprovalPlan` (rationale / resources / risks / rollback)\nrendered as labeled sections in the TUI modal; a new `propose_plan`\nMCP tool + `[run].require_plan_approval` flag that gates `spawn_worker`\non operator pre-flight approval; and `fake-claude` end-to-end test\ncoverage through `pitboss mcp-bridge` that closes the v0.3 Task 26\nplaceholder. 455 tests, zero flakes, full flagship bucket delivered.\nSee `CHANGELOG.md` for the per-version history and `AGENTS.md` for\nMCP tool reference, keybindings, and manifest schema.\n\nRust toolkit for running and observing parallel Claude Code sessions. A\ndispatcher (`pitboss`) fans out `claude` subprocesses under a concurrency\ncap, captures structured artifacts per run, and — in hierarchical mode —\nlets a **lead** dynamically spawn more workers via MCP. The TUI\n(`pitboss-tui`) gives the floor view: tile grid, live log tailing, budget +\ntoken counters.\n\nLanguage models are stochastic. A well-run pit is not. Give the house a\nclear manifest, a budget, and a prompt — the pit turns variance into\nconsistently usable output.\n\n## Vocabulary\n\n| Term | Meaning |\n|---|---|\n| **Pitboss** | The `pitboss` dispatcher binary. Runs manifests, manages worktrees, persists run state. |\n| **Lead** | The coordinating `claude` subprocess in a hierarchical run — receives the operator's prompt + MCP tools, decides how many workers to spawn. |\n| **Run** | One invocation of `pitboss dispatch`. Produces `~/.local/share/pitboss/runs/\u003crun-id\u003e/` with manifest snapshot, resolved config, per-task logs, and a summary. |\n| **House rules** | The hierarchical-run guardrails: `max_workers`, `budget_usd`, `lead_timeout_secs`. |\n\n## Install\n\n### Via shell installer (recommended)\n\nPitboss releases ship through [`cargo-dist`][cargo-dist], which\nproduces two `curl | sh` installers per release (one per binary):\n\n```bash\ncurl -LsSf https://github.com/SDS-Mode/pitboss/releases/latest/download/pitboss-cli-installer.sh | sh\ncurl -LsSf https://github.com/SDS-Mode/pitboss/releases/latest/download/pitboss-tui-installer.sh | sh\n\npitboss version\npitboss-tui --version\n```\n\nEach installer detects your platform, downloads the matching `tar.xz`\ntarball, verifies its SHA-256, and drops the binary into `~/.cargo/bin`.\nCurrent target matrix: `x86_64-unknown-linux-gnu`,\n`aarch64-unknown-linux-gnu`, `aarch64-apple-darwin`.\n\n### Via Homebrew\n\n```bash\nbrew install SDS-Mode/pitboss/pitboss-cli\nbrew install SDS-Mode/pitboss/pitboss-tui\n```\n\nFormulae are auto-published to the [`SDS-Mode/homebrew-pitboss`][tap] tap\non every release.\n\n### Via container image\n\nPublished to GitHub Container Registry on every push to `main` and\nevery release tag (`linux/amd64` + `linux/arm64`):\n\n```bash\npodman pull ghcr.io/sds-mode/pitboss:latest\npodman run --rm -v $(pwd)/pitboss.toml:/run/pitboss.toml \\\n    ghcr.io/sds-mode/pitboss:latest \\\n    pitboss validate /run/pitboss.toml\n```\n\nThe image carries `git` (needed for worktree isolation) but NOT the\n`claude` binary — mount your host's Claude Code install or build a\nderived image that layers it in.\n\n### Direct tarball download\n\nPrefer the tarball? Grab `pitboss-cli-\u003ctarget\u003e.tar.xz` or\n`pitboss-tui-\u003ctarget\u003e.tar.xz` from the [latest release][releases]:\n\n```bash\ncurl -L https://github.com/SDS-Mode/pitboss/releases/latest/download/pitboss-cli-x86_64-unknown-linux-gnu.tar.xz \\\n  | tar xJ -C ~/.local/bin\n```\n\n[cargo-dist]: https://github.com/astral-sh/cargo-dist\n[tap]: https://github.com/SDS-Mode/homebrew-pitboss\n[releases]: https://github.com/SDS-Mode/pitboss/releases/latest\n\n### From source\n\n```bash\ngit clone https://github.com/SDS-Mode/pitboss.git\ncd pitboss\ncargo install --path crates/pitboss-cli\ncargo install --path crates/pitboss-tui\n```\n\n## Subcommands\n\n```\npitboss validate \u003cmanifest\u003e          parse + resolve + validate, exit non-zero on error\npitboss dispatch \u003cmanifest\u003e          deal a run\npitboss resume \u003crun-id\u003e              re-deal a prior run, reusing claude_session_id\npitboss attach \u003crun-id\u003e \u003ctask-id\u003e    follow-mode log viewer for a single worker\npitboss diff \u003crun-a\u003e \u003crun-b\u003e         compare two runs side-by-side\npitboss completions \u003cshell\u003e          print shell completion script\npitboss version                      print version\n```\n\n`pitboss attach` accepts a run-id prefix (first 8 chars are plenty when\nit's unique). `--raw` streams the raw stream-json jsonl; without it,\nlines render like the TUI focus pane. Exits on Ctrl-C or when the\nworker emits its terminal `Event::Result`.\n\n### Shell completions\n\nBoth binaries emit completion scripts for bash, zsh, fish, elvish, and\npowershell:\n\n```bash\n# bash\npitboss completions bash       \u003e ~/.local/share/bash-completion/completions/pitboss\npitboss-tui completions bash   \u003e ~/.local/share/bash-completion/completions/pitboss-tui\n\n# zsh (adjust for your $fpath)\npitboss completions zsh        \u003e ~/.zsh/completions/_pitboss\npitboss-tui completions zsh    \u003e ~/.zsh/completions/_pitboss-tui\n```\n\n## Quick start — flat dispatch\n\nDeal N independent hands at once. Each `[[task]]` becomes a worker; results\nland in `~/.local/share/pitboss/runs/\u003crun-id\u003e/`.\n\n```toml\n[run]\nmax_parallel = 2\n\n[[task]]\nid = \"hello\"\ndirectory = \"/path/to/repo\"\nprompt = \"Say hello in a file called hello.txt\"\nbranch = \"feat/hello\"\n```\n\n```bash\npitboss validate pitboss.toml\npitboss dispatch pitboss.toml\n```\n\nEach run produces: `manifest.snapshot.toml`, `resolved.json`, `meta.json`,\n`summary.json`, `summary.jsonl`, and per-task `tasks/\u003cid\u003e/{stdout.log,stderr.log}`.\n\n## Quick start — watch the floor\n\n```bash\npitboss-tui                # open the most recent run (500ms polling)\npitboss-tui list           # table of runs to stdout\npitboss-tui 019d99         # open a run by UUID prefix\n```\n\nSee [`crates/pitboss-tui/README.md`](crates/pitboss-tui/README.md) for\nkeybindings.\n\n## Quick start — hierarchical\n\nFlat dispatch is fixed-seat blackjack: N tables, N hands, all at once.\nHierarchical dispatch hands the lead a deck and a stake and says *deal as\nmany hands as you need to finish the job, within house rules*.\n\n```toml\n[run]\nmax_workers = 4\nbudget_usd = 5.00\nlead_timeout_secs = 900\n\n[[lead]]\nid = \"triage\"\ndirectory = \"/path/to/repo\"\nprompt = \"\"\"\nInspect recent PRs, spawn one worker per unique author, ask each to summarize\nthat author's work in summary-\u003cid\u003e.md, then write a combined digest.\n\"\"\"\nbranch = \"feat/triage-lead\"\n```\n\n```bash\npitboss validate pitboss.toml    # prints a hierarchical summary when [[lead]] is set\npitboss dispatch pitboss.toml\n```\n\nThe lead has these MCP tools, auto-allowed in its `--allowedTools`:\n\n| Tool | Purpose |\n|---|---|\n| `mcp__pitboss__spawn_worker` | Deal a new worker with a prompt + optional directory/model/tools |\n| `mcp__pitboss__worker_status` | Non-blocking peek at a worker's state |\n| `mcp__pitboss__wait_for_worker` | Block until a specific worker settles |\n| `mcp__pitboss__wait_for_any` | Block until any of a list of workers settles |\n| `mcp__pitboss__list_workers` | Snapshot of active + completed workers |\n| `mcp__pitboss__cancel_worker` | Signal a per-worker `CancelToken` |\n| `mcp__pitboss__pause_worker` | Pause a worker — `mode=\"cancel\"` (default, terminates + snapshots session) or `mode=\"freeze\"` (SIGSTOPs the subprocess in place) |\n| `mcp__pitboss__continue_worker` | Resume a paused/frozen worker (`claude --resume` or SIGCONT respectively) |\n| `mcp__pitboss__reprompt_worker` | Mid-flight redirect: kill + `claude --resume \u003csid\u003e` with a new prompt |\n| `mcp__pitboss__request_approval` | Gate a single in-flight action on operator approval; accepts an optional typed `ApprovalPlan` |\n| `mcp__pitboss__propose_plan` | Pre-flight gate: submit an execution plan for approval; required before `spawn_worker` when `[run].require_plan_approval = true` |\n\nWorkers additionally get the 7 shared-store tools (`kv_get`, `kv_set`,\n`kv_cas`, `kv_list`, `kv_wait`, `lease_acquire`, `lease_release`) for\nhub-mediated coordination without breaking the depth-1 invariant. See\n`AGENTS.md` for full schemas.\n\n### House rules\n\n- **`max_workers`** — hard cap on concurrent + queued workers (1–16, default unset).\n- **`budget_usd`** — the chip stack. Each spawn reserves a model-aware estimate\n  up front; the reservation releases and the actual cost books in when the\n  worker settles. Once `spent + reserved + next_estimate` would exceed the\n  stack, `spawn_worker` returns `budget exceeded` and the lead decides what to\n  do with partial results.\n- **`lead_timeout_secs`** — wall-clock cap on the lead. The pit always clears.\n- Depth is 1. Workers don't spawn sub-workers; no re-raise, no chaining.\n\n### The bridge\n\nClaude Code's MCP client only speaks stdio. The pitboss MCP server listens on\na unix socket. Between them is `pitboss mcp-bridge \u003csocket\u003e` — a stdio↔socket\nproxy that pitboss auto-launches via the lead's generated `--mcp-config`. You\nnever invoke it directly.\n\n### On the floor\n\nIn the TUI, leads render with `[LEAD] \u003cid\u003e` in a cyan border; workers show\n`← \u003clead-id\u003e` on their bottom border. The status bar reads\n`— N workers spawned`. As workers complete, their tiles mark done without\nclearing — full history stays visible for the run.\n\n### Resume\n\n`pitboss resume \u003crun-id\u003e` re-deals any prior run.\n\n- **Flat**: each task respawns with its original `claude_session_id`.\n- **Hierarchical**: only the lead resumes (`--resume \u003csession-id\u003e`); the lead\n  decides whether to deal fresh workers. `resolved.json` in the new run\n  records the `resume_session_id` for audit.\n\n## Concurrency\n\nDefault `max_parallel` is 4. Override priority: `[run].max_parallel` beats\n`ANTHROPIC_MAX_CONCURRENT` env beats the default.\n\nIn hierarchical mode, `max_workers` is independent of `max_parallel` — it\ncaps the lead's fanout, not the overall process count.\n\n## Philosophy\n\nThe model is stochastic. The pit is not.\n\nYou cannot guarantee any single hand. You can guarantee:\n\n- **Isolation.** Every worker runs in its own git worktree on its own branch.\n  One bad hand doesn't contaminate the next.\n- **Observability.** Every token, every cache hit, every session id is\n  persisted. When you want to know what happened, the artifacts are on the\n  table.\n- **Bounded risk.** Workers, budget, and timeouts are explicit. The house\n  knows its exposure before the first card is dealt.\n- **Determinism where it's free.** Stream-JSON parsing, cancellation protocol,\n  SQL schema migrations, UTF-8 boundary safety. If we can make it reliable\n  without sacrificing capability, we do.\n- **A visible floor.** The TUI never editorializes. It shows you what's\n  happening; you decide what it means.\n\nPlay enough hands under these rules and the edge shows up. The pit does not\nguarantee any single hand — it guarantees you can inspect it.\n\n## Status\n\n`v0.5.0` — the flagship operator-control bucket shipped:\n`pitboss attach` follow-mode viewer, SIGSTOP freeze-pause, structured\n`ApprovalPlan`, pre-flight `propose_plan` gate, and a full\nfake-claude-through-`mcp-bridge` e2e test harness. Builds on v0.4.4's\nshared-store + resume polish, v0.4.3's worker shared store, and\nv0.4.1's control plane (cancel/pause/continue/reprompt, operator\napprovals, notification sinks). 455 tests pass under `cargo test\n--workspace --features pitboss-core/test-support`. See\n[`CHANGELOG.md`](CHANGELOG.md) for the per-version history.\n\n## Manual smoke testing\n\nOffline scripts are in `scripts/` (see Development below). For live\nverification against real `claude`: validate a hierarchical manifest,\ndispatch a 2–4 worker triage, watch the TUI annotations, tighten `budget_usd`\nto force mid-run rejections, Ctrl-C a running dispatch, resume a completed\nrun. Budget: ~$0.50–$1.50 on Haiku for a full sweep.\n\nRequires `claude` authenticated via its normal subscription config (no\n`ANTHROPIC_API_KEY` needed on Claude Code login systems).\n\n## Development\n\n```bash\ncargo build --workspace\ncargo test --workspace --features pitboss-core/test-support    # 455 tests\ncargo lint                                                     # clippy -D warnings\ncargo fmt --all -- --check\n```\n\nAutomated smoke scripts (no API calls):\n\n```bash\nscripts/smoke-part1.sh          # 10 offline flat-mode tests\nscripts/smoke-part3-tui.sh      # 7 non-interactive TUI tests\n```\n\n### Continuous integration\n\n`.github/workflows/ci.yml` runs on every push or PR to `main`:\n`cargo fmt --check`, `cargo clippy -D warnings`, `cargo test`, and\n`scripts/smoke-part1.sh`. Commits that change only `CHANGELOG.md` or\n`README.md` skip CI.\n\n### Cutting a release\n\n1. Move `[Unreleased]` items in `CHANGELOG.md` into a new\n   `[X.Y.Z] — YYYY-MM-DD` section. Add the compare-link at the bottom.\n2. Bump `version` in the root `Cargo.toml` `[workspace.package]` block.\n3. Commit to `main`.\n4. Tag and push:\n   ```bash\n   git tag -a vX.Y.Z -m \"vX.Y.Z — \u003cshort summary\u003e\"\n   git push origin vX.Y.Z\n   ```\n\nThe tag push triggers two workflows in parallel:\n\n- **`.github/workflows/release.yml`** (cargo-dist generated). Builds\n  `pitboss-cli-\u003ctarget\u003e.tar.xz` and `pitboss-tui-\u003ctarget\u003e.tar.xz` for\n  every target in the `dist-workspace.toml` matrix\n  (`x86_64-unknown-linux-gnu`, `aarch64-unknown-linux-gnu`,\n  `aarch64-apple-darwin`), produces shell installers + Homebrew\n  formulae, and publishes to the\n  [`SDS-Mode/homebrew-pitboss`][tap] tap via the\n  `HOMEBREW_TAP_TOKEN` repo secret. Attaches everything to the\n  auto-created GitHub release. Adding or removing a target triple is\n  a one-line change to `dist-workspace.toml` followed by `dist\n  generate`.\n- **`.github/workflows/container.yml`**. Builds the multi-arch image\n  (`linux/amd64` + `linux/arm64`) and pushes to\n  `ghcr.io/sds-mode/pitboss:{version, major.minor, major, latest}`.\n\n### Regenerating the release workflow\n\n`dist-workspace.toml` is the source of truth for the cargo-dist matrix.\nAfter editing it, regenerate the workflow:\n\n```bash\ncargo install cargo-dist --version 0.28.7    # one-time\ndist generate\ngit diff .github/workflows/release.yml       # review\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsds-mode%2Fpitboss","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsds-mode%2Fpitboss","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsds-mode%2Fpitboss/lists"}