flowdeck
v0.4.0
Published
Human↔AI collaboration via TODO.md files and git commits
Maintainers
Readme
flowdeck
Human↔AI collaboration via TODO.md files and git commits.
You write tasks. Claude does them. Git tracks the conversation.
Install
npm install -g flowdeckRequires Node.js ≥ 18 and Claude Code.
Canonical home: flowdeck.ruco.dev — docs, changelog, and release notes live there. The old scoped package
@ruco-ai/flowdeckis deprecated. Installflowdeckinstead.
Why flowdeck
Flowdeck is the only agent harness that is natively frontend-agnostic. The same card deck runs in a terminal, a CI pipeline, a chat interface, or an IDE. You don't migrate your workflow when you change your tooling.
lowdeck gives you the LangSmith feedback loop without LangSmith. Your git log is your trace. Your TODO.md is your eval. Your AGENT.md is your memory. The loop runs in plain text."
Quick start
cd your-project
flowdeck initThis creates a .flowdeck/ scaffold and a FLOWDECK.md at the project root:
FLOWDECK.md ← living project document injected into every play/turn (edit this)
.flowdeck/
AGENT.md ← project context Claude reads on every play (edit this)
TODO.md.template ← card format reference
start/
TODO.md ← your first work area
_energy/ ← mdblu templates (SPEC, MISSION, ADR, …)
.flowdeckignoreAdd a task for Claude in .flowdeck/start/TODO.md:
## BOT
- [ ] Add a README to this projectThen hand off:
flowdeck play start
# plays the "start" card — Claude reads it, completes the BOT tasks, marks them done, commits
flowdeck turn
# passes the full deck to Claude — Claude decides what to play, discard, or combineHow it works
TODO.md is the shared board
Every folder under .flowdeck/ is a column. Each column has a TODO.md card with two sections:
## BOT
- [ ] Task for Claude to do
- [x] Completed task
> short note on what was done
## HUMAN
- [ ] Something Claude needs from you
> why it's needed## BOT— Claude's inbox. Claude completes these and marks them[x]with a one-line note.## HUMAN— Your inbox. Claude adds items here when it needs you to act.#### COMMENTS(under## HUMAN) — Notable findings from execution: unexpected behaviour, real validations, non-obvious decisions. Added by Claude when there's something worth preserving beyond the task notes.
flowdeck play <slug> — single card
flowdeck play payments
# plays .flowdeck/payments/TODO.md exactly — no scanningClaude reads the card, works through the ## BOT tasks, marks them done, and commits.
flowdeck flash <slug> — review without executing
flowdeck flash payments
# annotates the card with analysis, questions, and risks — no tasks executedClaude reads the card and writes observations into ## HUMAN → #### COMMENTS. Anything requiring a decision becomes a - [ ] item under ## HUMAN. BOT tasks are left untouched. Useful before starting a card to surface unknowns.
flowdeck deal <slug> — write concrete tasks without executing
flowdeck deal payments
# reads COMMENTS and context, then fills in concrete BOT tasks — no tasks executedClaude reads the card's #### COMMENTS, HUMAN questions/answers, and any existing BOT items, then replaces placeholder or vague - [ ] items with concrete, actionable tasks (specific file paths, what to change, expected outcome). Nothing is executed. Useful after flash to translate analysis into a ready-to-play card.
flowdeck kemps <slug> — suggest answers to HUMAN questions
flowdeck kemps payments
# suggests answers for all unanswered > _answer:_ stubs under ## HUMANClaude reads each unanswered - [ ] item under ## HUMAN — specifically those followed by an empty > _answer:_ stub — and replaces the stub with > _kemps:_ <suggested answer>. The - [ ] item stays unchecked; the human reviews the suggestion and either accepts it (changing _kemps:_ to _answer:_) or edits as needed. Useful when HUMAN questions are blocking deal or play and you want the AI to propose answers rather than waiting for manual input.
flowdeck turn — full hand
flowdeck turnPasses every card with open ## BOT items to Claude in one call. Claude:
- Assesses the hand — decides play order, flags duplicates, identifies cards that can be combined
- Discards obsolete or redundant cards (moves items to
## DISCARDED, keeps the file) - Combines complementary cards into a single efficient pass
- Executes — works through all cards in chosen order, committing after each
- Docs pass — updates
FLOWDECK.md,README.md(unlessdocs: flowdeck-only), AGENT.md insights, and cross-card notes holistically
FLOWDECK.md is the living project document
FLOWDECK.md at the project root is injected into every play and turn prompt after AGENT.md. It carries the current project state so Claude can make consistent decisions across sessions without re-reading the codebase. Update it at meld time to reflect what shipped.
Structure: ## Vision (one paragraph), ## Current state (shipped capabilities), ## Known gaps (open issues).
AGENT.md is the project context
.flowdeck/AGENT.md is the first thing Claude reads on every play and turn. Keep it updated with architecture notes, preferences, and current priorities. It's yours to maintain — flowdeck never overwrites it after init.
docs: mode — add a plain line docs: flowdeck-only anywhere in AGENT.md to restrict all doc updates to FLOWDECK.md only (no README edits). The default (docs: readme) lets Claude update both.
Templates
.flowdeck/_energy/ contains a curated set of mdblu templates (SPEC, MISSION, OPEN-QUESTIONS, ADR, GENERALINSIGHTS, PROJECTINSIGHTS, CLAUDE). Claude can use these when creating structured documents during a session.
To get more templates:
mdblu get --all --output .flowdeck/_energy/Commands
| Command | What it does |
|---------|-------------|
| flowdeck init | Create .flowdeck/ scaffold in the current directory (idempotent for pile setup) |
| flowdeck play <slug> | Play a single card — Claude executes all BOT tasks |
| flowdeck flash <slug> | Review a card — Claude annotates without executing |
| flowdeck deal <slug> | Write concrete BOT tasks from context — no execution |
| flowdeck kemps <slug> | Suggest answers to unanswered HUMAN questions — writes > _kemps:_ stubs |
| flowdeck turn | Pass the full hand to Claude — orchestrates cards in parallel, executes, documents |
| flowdeck turn --serial | Run cards sequentially using the legacy single-agent path |
| flowdeck add <column> [title] | Create a new column and card — auto-slugifies name, errors if card already exists anywhere in the deck |
| flowdeck append <column> <task> | Append a task to a card (ends with ? → goes to HUMAN) — resolves cards in piles too, not just the table |
| flowdeck meld <card> | Move a completed card to _meld/ — bot writes delivery summary |
| flowdeck discard <card> | Move a cancelled card to _discard/ — warns if open tasks remain |
| flowdeck frozen <card> [-m note] | Park a blocked card in _frozen/ — bot writes blocking condition and unfreeze signal |
| flowdeck stock <card> | Move a card to _stock/ backlog |
| flowdeck bring <card> | Return a card from any pile back to the table |
| flowdeck list | List card slugs on the table (one per line); --discard, --meld, --stock, --frozen to list a pile instead |
| flowdeck lint | Check all table and _stock/ cards for structural issues |
| flowdeck gh-sync <card-file> | Sync card state to a linked GitHub Issue |
| flowdeck serve [--port 7331] | Start the HTTP API server on localhost |
Slash commands
After flowdeck init, your project gets slash commands in .claude/commands/:
| Slash command | What it does |
|---------------|-------------|
| /play-card <slug> | Play a single card by name |
| /turn | Play the full hand (assess, discard, combine, execute, document) |
| /add-card <column> [tasks] | Create a new column and card |
| /append-card <column> <task> | Append a task or note to an existing card |
flowdeck gh-sync — GitHub Issues integration
Link a card to a GitHub Issue and keep them in sync across the human↔AI lifecycle.
Step 1 — add github_issue frontmatter to a card:
---
github_issue: owner/repo
github_labels: [feature, backend]
---
# paymentsStep 2 — run gh-sync at each lifecycle phase:
# Create the GitHub Issue (writes issue number back to the card)
flowdeck gh-sync .flowdeck/payments/TODO.md
# After Claude completes BOT tasks — posts a completion report as a comment
flowdeck gh-sync .flowdeck/payments/TODO.md --phase bot-done
# After human review — closes the issue
flowdeck gh-sync .flowdeck/payments/TODO.md --phase human-doneOmitting --phase auto-detects: if all ## HUMAN checkboxes are checked → human-done, otherwise → bot-done.
Lifecycle labels applied automatically:
| Phase | Label applied | Labels removed |
|-------|--------------|----------------|
| created | flowdeck:draft | — |
| bot-done | flowdeck:review | flowdeck:draft, flowdeck:bot |
| human-done | flowdeck:done | flowdeck:draft, flowdeck:bot, flowdeck:review |
Labels are auto-created in the repo on first use.
Options:
| Flag | Effect |
|------|--------|
| --phase <created\|bot-done\|human-done> | Force a specific phase |
| --dry-run | Print what would happen without making API calls |
| --no-create | Error instead of auto-creating a new issue |
| --token <token> | GitHub token (default: $GITHUB_TOKEN) |
| --verbose | Log API requests to stderr |
Requires a GitHub token with repo scope (issues read/write). Set GITHUB_TOKEN or pass --token.
flowdeck serve — HTTP API
Expose flowdeck over a local HTTP API so any tool — GitHub Actions, VS Code extensions, Codex CLI, web dashboards — can drive the same workflow without coupling to Claude Code.
flowdeck serve # start on port 7331 (default)
flowdeck serve --port 9000 # custom port
flowdeck serve --no-auth # disable token check
flowdeck serve --agent codex # override default agentThe server binds to 127.0.0.1 only. Set FLOWDECK_API_TOKEN to enable bearer token auth (all endpoints except /flowdeck/health require the header when set).
Endpoints:
| Method | Path | What it does |
|--------|------|-------------|
| GET | /flowdeck/health | Liveness check — no auth required |
| GET | /flowdeck/status | Server state, active card, git status |
| GET | /flowdeck/cards | All cards with current states |
| GET | /flowdeck/cards/:id | Single card |
| POST | /flowdeck/run | Start a card's BOT section ({ card_id }) |
| POST | /flowdeck/run/:id/cancel | Cancel a running card |
| POST | /flowdeck/turn | Run a full deck turn |
| POST | /flowdeck/cards/:id/human-done | Mark HUMAN section complete, commit |
| GET | /flowdeck/deck | Full deck as JSON (raw + cards + agent context) |
| POST | /flowdeck/deck/sync | git pull --rebase and re-parse deck |
| GET | /flowdeck/events | SSE stream — real-time BOT output and state changes |
Card states: idle → bot-running → bot-done → human-pending → human-done → archived
SSE events: bot:output (streaming text), bot:done, state:change, error. Clients reconnect with Last-Event-ID to replay from the ring buffer (last 100 events).
Nested card slugs use -- as separator in URLs: .flowdeck/payments/stripe-webhook/TODO.md → card id payments--stripe-webhook.
Environment variables:
| Variable | Default | Effect |
|----------|---------|--------|
| FLOWDECK_API_TOKEN | — | Enable bearer auth |
| FLOWDECK_PORT | 7331 | Default port |
| FLOWDECK_AGENT | claude-code | Default agent |
Pile management — card lifecycle
Cards have a full lifecycle beyond the active table. Four piles handle different terminal and parked states:
.flowdeck/
_meld/ ← shipped — all tasks done
_discard/ ← cancelled or abandoned
_frozen/ ← blocked on an external condition
_stock/ ← backlog, not yet readyflowdeck init creates these directories (idempotent — safe to run on an existing project). Existing done/ contents are migrated to _meld/ automatically.
flowdeck meld <card> — mark a card as successfully shipped. Claude reads the completed TODO.md and writes a delivery summary to _meld/<card>/MELD.md. The CLI appends a row to _meld/MELD.md index.
flowdeck discard <card> — cancel a card. If open tasks exist, you'll be prompted to confirm. The CLI writes a DISCARD.md listing any dropped tasks. No index — discard is a graveyard.
flowdeck frozen <card> [-m "note"] — park a blocked card. The CLI moves it and writes a FREEZE.md stub. Claude then fills in the Blocking Condition and Unfreeze Signal — concrete, observable text so turn can auto-check whether the block has lifted. The card is added to _frozen/FROZEN.md.
flowdeck stock <card> — defer a card to the backlog. The CLI adds a row to _stock/STOCK.md with a description derived from the card's first task.
flowdeck bring <card> — return any card from any pile back to the active table. The CLI finds it, moves it, and removes it from the relevant index.
During flowdeck turn, Claude reads _frozen/FROZEN.md and evaluates each card's Unfreeze Signal against the current codebase. Cards whose conditions are met are brought back automatically (or surfaced in ## HUMAN for your approval).
Folder structure
New subject → new folder under .flowdeck/:
.flowdeck/
payments/
TODO.md
stripe-webhook/ ← subtask
TODO.md
auth/
TODO.mdflowdeck add payments "Stripe integration"
flowdeck add payments/stripe-webhookLicense
MIT
