███████╗██╗ ██████╗ ██╗ ██╗ ██╔════╝██║ ██╔═══██╗██║ ██║ █████╗ ██║ ██║ ██║██║ █╗ ██║ ██╔══╝ ██║ ██║ ██║██║███╗██║ ██║ ███████╗╚██████╔╝╚███╔███╔╝ ╚═╝ ╚══════╝ ╚═════╝ ╚══╝╚══╝
🎯 A config-driven SDLC orchestrator over the Claude Code CLI — define a company of role-agents, hand it a brief, and it runs plan → build → review → QA with you approving at every phase gate. Subscription-only; $0 extra API cost.
🪫 One Claude Code session loses the plot on a big build — it plans, half-implements, forgets the plan, and marks itself done. Flow splits the software lifecycle into bounded, single-responsibility phases, runs each as a fresh role-agent, keeps shared state on disk, and stops at human gates so you decide before it moves on. It's not a platform — it's thin, honest glue over
claude -pthat adds the parts that don't exist off-the-shelf: a declarative flow, human gates, a bounded loop, and shared project memory.
Repository map • The pipeline • Architecture • Quick start • Working with it • Security model • Status • License
claude-code-flow-manager/
├── src/ TypeScript engine (v3)
│ ├── index.ts CLI entry: run | roles | phases | status | menu; gate UI + discuss
│ ├── workflow.ts builds the Mastra workflow (one step per phase) + suspend() gates
│ ├── phase.ts per-phase agentic loop (research / spawn / question, with bounds)
│ ├── claude.ts spawns `claude -p`, parses the stream-json NDJSON (cost, session)
│ ├── directive.ts the FLOW protocol: parses the ===FLOW=== JSON block agents emit
│ ├── ledger.ts on-disk state: workspace/state.json + PROGRESS.md
│ ├── projects.ts multi-project registry (projects/<slug>/project.json)
│ ├── config.ts loads team.json / flow.json / conventions.md
│ ├── ui.ts terminal color, spinner, gate prompts
│ └── types.ts shared types (Role, Phase, Directive, …)
├── tools/
│ └── run_capture.py pty terminal emulator — catches TUI layout bugs logic tests miss
├── flow.json the 8 phases: role · instruction · produces · gate
├── team.json the 10 role-agents: model · allowed_tools · system_prompt
├── team.sandbox.json unattended variant (skips tool-permission prompts — see Security)
├── conventions.md common-sense rules injected into every agent, every turn
├── docs/ DESIGN.md · FLOW.md · PRD.md (superseded, historical)
├── projects/ generated — per-project workspaces + state (git-ignored)
└── runs/ generated — timestamped run snapshots (git-ignored)
projects/ and runs/ are produced by running the tool (they hold generated code, run cost, and Anthropic session IDs) and are git-ignored — never committed.
A run walks a brief through 8 sequential phases. Each phase is a single role-agent with a scoped instruction, an artifact it must produce, and an optional human gate.
| # | Phase | Role | Model | Gate | Produces |
|---|---|---|---|---|---|
| 1 | discover |
analyst | opus | ✅ | requirements.md |
| 2 | research |
researcher | sonnet | — | research.md |
| 3 | resource |
architect | opus | ✅ | architecture.md |
| 4 | design |
designer | opus | ✅ | design.md |
| 5 | build |
developer | sonnet | — | implementation-notes.md |
| 6 | review |
senior_engineer | opus | — | review.md |
| 7 | qa |
qa | sonnet | — | qa-report.md |
| 8 | acceptance |
acceptance | sonnet | ✅ | acceptance.md |
Defined entirely in flow.json — reorder phases, move a gate, or swap a role without touching code.
Ten roles live in team.json. Eight drive the phases above; two are spawn-only — pulled in on demand by another agent via a spawn request.
| Role | Purpose | Spawned by |
|---|---|---|
| analyst · researcher · architect · designer | scope, research, stack + system design, UX | phase roles |
| developer · senior_engineer · qa · acceptance | build, code-quality review, automated checks, human handoff | phase roles |
domain_expert |
stack/domain specialist (React, game-design, …) for the build | developer |
security |
security-only review (injection, auth, secrets, deps) | senior_engineer |
Each phase is a loop, not a one-shot. The agent works, writes its artifact, then ends its turn with one machine-readable directive:
===FLOW===
{"status":"in_progress | needs_research | needs_input | done | blocked",
"artifact":"requirements.md",
"requests":[{"type":"research","query":"..."},
{"type":"question","text":"..."},
{"type":"spawn","role":"domain_expert","task":"..."}],
"summary":"what I did, what's next"}
===END===
The orchestrator parses that block (src/directive.ts) and acts on it — runs research, asks you a question, or spawns a specialist — then loops. Hard bounds keep it honest (defaults from flow.json):
max_phase_iters(4) — iterations per phase before it must stop.max_research_per_phase(3) — research fan-outs per phase.max_budget_usd($15) — USD ceiling checked before every iteration.- malformed-directive retry (3) — a turn that forgets the block is re-asked, not trusted.
Four phases carry a gate. At a gate the workflow suspends (durably, via Mastra) and shows you the artifact preview and:
[a]pprove [r]evise [d]iscuss [x]abort
revise sends your feedback back to the same agent; discuss opens a live back-and-forth with that agent (resuming its session) before you decide.
npm run flow run "<brief>"
│
┌─────────▼──────────┐
│ src/index.ts │ CLI · project lifecycle · gate UI · discuss
└────┬───────────┬────┘
projects/<slug>│ │ builds
▼ ▼
┌────────────────┐ ┌──────────────────────────┐
│ src/projects.ts│ │ src/workflow.ts │ one Mastra Step per phase
│ project.json │ │ createWorkflow + suspend()│ gate → suspend/resume
│ registry │ │ LibSQL (.mastra/flow.db) │ durable run-state
└────────────────┘ └────────────┬─────────────┘
│ execute(phase)
┌─────────▼──────────┐
│ src/phase.ts │ agentic loop + bounds
│ research/spawn/ask │
└──┬───────────┬───┬──┘
┌────────────────┘ │ └───────────────┐
▼ ▼ ▼
┌──────────────────┐ ┌──────────────────┐ ┌────────────────┐
│ src/claude.ts │ │ src/directive.ts │ │ src/ledger.ts │
│ execa → `claude -p`│ │ parse ===FLOW=== │ │ state.json + │
│ stream-json parse │ │ inject PROTOCOL │ │ PROGRESS.md │
│ cost · session id │ └──────────────────┘ │ (survives │
└─────────┬─────────┘ │ Mastra reruns)│
│ subprocess, cwd = projects/<slug>/workspace/ │
▼ └────────────────┘
┌──────────────────┐
│ claude (CLI) │ the actual agent: reads/writes files, runs tools,
│ role tools+model │ makes the network calls to Anthropic
└──────────────────┘
Key design choice: all work state (artifacts, cost, decisions, Q&A) lives on disk in the ledger, so Mastra's execute() re-running on resume is always safe. Mastra is used only for durable suspend/resume at gates.
Prerequisites
- Node.js ≥ 22.13 (
node --version). - Claude Code CLI installed and authenticated —
claudemust be on yourPATH. Flow uses your Claude subscription viaclaude -p; noANTHROPIC_API_KEYand no extra API billing.
# 1. Install dependencies
npm install
# ✅ Verify: typecheck is clean
npm run typecheck # → tsc --noEmit, exits 0
# 2. Inspect the team and flow (no cost)
npm run flow roles # list the 10 roles
npm run flow phases # list the 8 phases
# 3. Dry-run first — prints every step, calls nothing, costs nothing
npm run flow run "Build a small Python CLI todo app" --dry-run
# 4. Real run (needs `claude` on PATH). Stops at each gate for your approval.
npm run flow run "Build a small Python CLI todo app"Artifacts land in projects/<slug>/workspace/. Resume the most recent project any time with npm run flow run --resume, or open the picker with a bare npm run flow.
| Command | What it does |
|---|---|
npm run flow |
interactive project menu |
npm run flow run "<brief>" |
start a new project from a brief |
npm run flow run --resume |
resume the most recent active project |
npm run flow roles / phases / status |
list roles · list phases · show all projects |
npm run typecheck |
tsc --noEmit |
npm run build |
compile to dist/ |
| Flag | Effect |
|---|---|
--dry-run |
skip all claude calls; inject a fake done directive — $0 |
--yes |
auto-approve gates and auto-answer questions (unattended) |
--verbose |
stream raw token output from the claude subprocess |
--fresh |
wipe the project workspace and restart from scratch |
--team <path> / --flow <path> |
use an alternate team / flow config |
Everything is data. Add a role, reorder phases, move a gate, or repoint a role's tools by editing team.json and flow.json:
team.json—default_model,max_turns,claude_bin,permission_mode,extra_args, and per-role{ title, model, allowed_tools, system_prompt }.flow.json— orderedphases, each{ id, role, instruction, produces, gate }, plus the loop bounds.conventions.md— common-sense rules ("terminal apps: WASD + arrows, 80×24,\r\nin raw mode", "never silently delete data", …) injected into every agent, every turn. This file is loaded at runtime and must stay at the repo root.
Flow spawns processes and lets agents run tools. Know what that means before an unattended run.
- Subprocess spawning. Each agent turn runs
execa('claude', ['-p', …], { cwd: projects/<slug>/workspace })(src/claude.ts). Theclaudeprocess inherits only the tools its role declares inallowed_tools— planner roles getRead/Grep/Glob;developerandqaalso getEdit/Write/Bash. During QA, agents shell out totools/run_capture.py, which spawns your program in a pseudo-terminal. - No secrets in this tool. Flow reads no
.env, touches noprocess.envsecret, and hardcodes no key. Authentication is entirely the Claude Code CLI's (your subscription). The only external network calls are made by theclaudesubprocess itself. ⚠️ Sandbox mode is dangerous by design.team.sandbox.jsonsetspermission_mode: "bypassPermissions"and passes--dangerously-skip-permissions, so the agent'sBashruns without any confirmation prompts. Combined with--yes(no human gates), a run is fully autonomous with shell access. Only use it in a throwaway VM/container, never on a machine with anything you care about.- Generated output is private.
projects/andruns/capture generated code, per-run USD cost, and Anthropic session UUIDs. They are git-ignored; keep them that way.
Found a vulnerability? See SECURITY.md.
Honest state of the v3 engine:
- ✅ TypeScript, ESM,
strict;npm run typecheckis clean. - ✅ Full 8-phase workflow runs end-to-end in
--dry-run; Mastra suspend/resume at gates works. - Sequential only — one phase at a time. No parallel agents yet (
p-limitis a dependency reserved for that; not yet wired). - Flat roles — no recursive sub-teams; specialists are spawned flat.
- No automated test suite yet — correctness is currently checked via
typecheck+ dry-run + manual real runs. (This is why there is no "tests" or CI badge above — none would be truthful yet.) flow.py(the original Python prototype) has been retired; the TypeScript engine insrc/is the only supported path. Design history lives indocs/DESIGN.md.
Roadmap and design rationale: docs/DESIGN.md · docs/FLOW.md.
MIT © 2026 Akash Varma.
Contributions welcome — see CONTRIBUTING.md · report issues privately via SECURITY.md · be decent per the Code of Conduct.
claude -p — a declarative flow, human gates, a bounded loop, and shared memory. Nothing more, nothing hidden.