Wingman is a long-lived Claude Code session that orchestrates a crew of agents for you. You (the pilot) give it high-level directives - "implement this feature," "investigate this issue," "what's my crew doing?" - and it delegates the real work, tracks status, and surfaces only real decisions to you. It orchestrates; it never does the heavy lifting itself.
Each crew member is an independent claude session in its own tmux window, launched in your target project - so you can watch it, type into it, or take it over live, and it survives even if wingman is killed.
A subagent is a function call: it runs in your context and vanishes when it returns. That fits a single bounded task, not work that outlives one turn - a PR sitting through CI, a plan awaiting your sign-off, a multi-step effort. Wingman fills that gap:
- Survives restarts - state lives on disk (
~/.wingman/), not in a transcript, so it outlasts compaction and restarts. - Zero-token supervision - the wake loop is event-driven; nothing burns tokens asking "done yet?"
- One status contract - every crew type reports through a shared contract, never transcript scraping.
- Cost-disciplined - spawning is deliberate and the org is depth-capped, never an unbounded swarm.
- Enforced by hooks, not prompt discipline alone.
Crew members can still spin off their own subagents for bounded lookups - wingman is the coordination layer above that.
See docs/architecture.md for how each piece works.
git clone https://github.com/greerviau/wingman.git
cd wingman
bin/wingman # recommended; plain `claude` also works
On first launch wingman runs bin/doctor (installs any missing dependencies with your consent), discovers your sibling repos with zero config, and starts the supervisor.
Then give it a directive. All you need up front is claude and git.
bin/wingmanis a thin launcher: it pre-adds sibling repos (--add-dir), mints a run id so preferences are asked once per run, and wires up Remote Control disconnect detection. Plainclaudeworks too, with less - see the launcher docs.
Talk in plain language, or use the slash commands:
| You say | Wingman does |
|---|---|
"Implement feature X in <repo>" |
software-analyst plans it → you review → developer ships a PR and shepherds it to merge |
| "Investigate issue Y" | software-analyst investigates in report mode (bugs reproduced end-to-end first) |
| "Take the lead on X" | a lead hires and runs its own crew, rolling one status line up to you |
/spawn <type> <repo|global> <objective> |
launch any crew type; bin/spawn-crew --list-types shows them all |
/status |
compact roster: who's on what, blocked, stalled, or ready |
/blocked |
each blocked member and the decision it needs |
| "Take over X" | prints the exact command to attach to a crew member's window |
/standdown <id> |
wrap up a member and close its window |
/prune |
drop fully-closed records (archived first) |
Fleet-wide events are handled for you: a mass crew death offers a one-command resume, and a detected API outage or an approaching usage-quota pauses new spawns and resumes automatically - already-running crew are never touched. See fleet resilience.
A crew member isn't spun down the moment its deliverable appears.
A developer that opens a PR parks in a review state and keeps running - watching CI, fixing breakage, and addressing feedback (dropping back to working while it does) - and reports done only when the PR merges or closes.
Your feedback routes back to that same session, so it keeps full context.
It stops early only if you /standdown it.
- Attach to any crew member's tmux window to type or take over; detach (
Ctrl-b d) to hand back. - Killing wingman leaves the crew running; relaunching rebuilds the roster.
- Every crew member is also reachable from
claude.ai/codeand the Claude desktop/mobile apps via Remote Control, with dropped connections auto-recovered - see Remote Control.
Crew launch with --permission-mode bypassPermissions, so gated tool calls auto-approve instead of hanging with no human at the terminal.
Two one-time gates (Claude Code's Bypass-Permissions acceptance and each repo's first-time trust dialog) are detected before a window opens, refusing the spawn with the exact remedy rather than freezing; once cleared, crew in that repo run unattended.
Model: most specific wins - an explicit --model on the spawn, then a per-crew-type entry in the settings file, then its default, then the agent CLI's own.
Optional, and gitignored so a git pull never touches it. Copy the template and edit what you want:
cp config.example.toml config.local.toml[prefs] # answered here = never asked again
remote = false
verbosity = "detailed"
[models]
default = "opus"
developer = "sonnet" # per crew type
[projects]
roots = ["~/dev"] # where to look for your reposIt also holds [effort] (same shape as [models]), [projects.pins]/ignore, [harness] (agent, permission mode, Remote Control, tmux session), and [env] — a raw WM_* passthrough for the ~100 internal tuning knobs the typed settings don't model.
An explicit flag beats the file, and the file beats wingman's defaults. bin/config prints every setting as resolved with the source it came from; bin/config --check (and bin/doctor) rejects a typo rather than ignoring it. Full details in configuration.md.
A crew type is just a playbook - plain prose in playbooks/<category>/<role>.md. The software-development category reads as an org:
| Role | Purpose |
|---|---|
software-analyst |
requirements / plan or report |
architect |
detailed technical design from an approved spec |
developer |
worktree → implement → commit → push → PR |
reviewer |
review a plan or PR and report findings |
lead and research live in the domain-neutral common category; more categories ship too (ai-research, data-science, scientific-research, business-development, business-operations, infrastructure).
bin/spawn-crew --list-types lists every role.
- Customize: drop a
<type>.local.mdbeside the default; if present it wins. - Add: create
<type>.mdand spawn with--type <name>. A type exists iff its playbook does; a bare name works when it's unique, and a category-qualified name (software-development/developer) breaks a collision.
*.local.md is gitignored, so your customizations can't be committed by accident and survive git pull.
Your crew is a tree with you at the top. Small directives take lean direct paths; a large, end-to-end effort gets a lead that decomposes it, sequences the phases (software-analyst → architect → developer(s) → reviewer), integrates the results, and rolls a single status line up to you.
- Each layer sees only its direct reports. A worker's blocker surfaces to its lead; only a decision the lead can't make escalates to you, and your answer flows back down.
- Peers collaborate directly - two developers on an interface, or a developer and a reviewer, without routing through the lead.
- Drill down any time:
/status --treefor the whole org,/status --owner <lead-id>for one team.
The tree is domain-neutral - swap playbooks and the same machinery runs a science lab or a business team. Depth is capped at two crew layers (a lead does not spawn leads).
bash tests/run.sh runs the bash E2E suites - no real claude/tmux fleet needed, just bash, git, tmux, and uv.
GitHub Actions runs the same suite on every push and PR to main.
- architecture.md - the core model: the wake loop, the deliverable lifecycle, and the crew hierarchy.
- configuration.md - the settings file, the launcher, the spawn recipe, model selection, and state in
~/.wingman/. - reporting.md - report altitude, self-report vs verified state, and the visibility preferences.
- guards.md - the mechanical guards, the preferences gate, checkout freshness, and autonomous mode.
- runbooks/incidents.md - what to do on a stalled, mass-death, outage, or usage-limit fire.
- fleet-resilience.md - correlated fleet events, API-outage and usage-limit detection.
- playbooks.md - crew types, categories, and local overrides.
