Documentation

How to use the flow

Flow is an IDE, so most of it is somewhere you look: a map of what your project does, the knowledge behind it, a board the work moves across, a workspace per conversation, and your own app running beside the code. Those surfaces come first below.

The work itself runs up a ladder of four stages — find out what you are building, plan it, run the plan, review what landed. Each stage writes a document into your repository, and each one has to leave proof behind before the next will run.

You can type the four commands yourself, or turn on autopilot and have the chain issue them for you. Either way the gate is the same one.

/discovery-plan "usage-based billing"     # what are we building?
/create-plan   @flow/discovery/discovery_usage_billing_v1.md
/execute-plan  @flow/plans/plan_usage_billing_v1.md
/review-code

Start here

Point Flow at a repository. The map derives itself on first open, and a structural pass runs on its own — always, and at no cost to you. A one-time sweep then learns the project into the documents the rest of the app reads, and from then on a module is re-learned when its code drifts away from what was written down.

Nothing needs configuring first. When you want to change how a run behaves — commits, pushes, pull requests, autopilot — that is /flow, and the settings are all optional.

The surfaces

The commands are how work moves through the project. These are the places you look at it.

The feature view

The sheet Flow opens on: your project drawn as the things it does. Three statements, each enforced in code rather than maintained by hand.

  • Area is size — a cell’s area is the lines of code its anchors stand on. A capability built from two hundred files and one built from four cannot draw the same rectangle.
  • Position is adjacency — cells keep the store’s own order. Squarified packing was rejected on purpose: nine neighbours should not relocate because one value changed.
  • A level is a zoom — diving flies one rectangle out to fill the sheet, and popping reverses it. There is no camera on this sheet at all; the map is packed into the measured stage, so it is always already fitted.
  • It nests: countries hold features, a feature holds its parts, a part holds its files.
  • A feature is a capability named in at least two distinct kinds of surface — a route segment and a test suite, say. That rule is what separates a real capability from a lone API route.
  • A change — a plan or an issue that touched a capability — is carried but never drawn, at any depth. The sheet answers one question: what does this project do.
  • The chrome reports its own limits. The title strip carries the understood percentage and an ask-the-brain field, where matches light up and everything else dims; the foot carries a disclosure of what the sheet withheld.
  • The learning lens is a line at the foot of a cell, never a fill — a filled cell would claim the feature is understood, and the line is about its files.

The code map

Behind its own toggle sits the derived graph — the structure rather than the capabilities.

  • Module cells sized by how many files sit under them, with curved wires across modules.
  • A left band of external integrations; a bottom band of datastores and the CLI surface.
  • Components a plan predicts appear inline as dashed ghosts, and turn solid when a later derive finds the real thing in the code. Confirmation is mechanical — an agent cannot claim it built something.
  • This is the one surface with a camera: drag pans, the wheel zooms, and 0 refits.

The knowledge

What your team knows about the code, written beside it as plain markdown and kept honest by content hashes — and, when you share it, learned once for everybody.

  • Learning escalates in four tiers: automatic structure, always on and free; a one-time onboarding sweep; a manual /learn for one module; and a guarded automatic re-learn when the code drifts.
  • Staleness has its own read-only authority that re-hashes the exact files a document was stamped against. Content decides, never a timestamp.
  • Trust is tiered. Code is ground truth, Flow’s own verified store comes next, and a README or a diagram somebody dropped in the repo is an unverified claim until it is corroborated against code.
  • The change brief shows Today and After in one layout with two states. A node the plan introduces is absent in Today but still occupies its box, so the diagram grows into After instead of re-laying itself out — and it is deliberately not ghosted, because Today is the world in which the plan does not exist yet.
  • Sharing is one switch. /flow share=shared commits the knowledge markdown alongside your code, and only the derived layer — everything a rebuild regenerates — stays ignored. The default, share=local, keeps all of it untracked.
  • So the codebase is learned once, by whoever reaches it first. A teammate who pulls already holds those documents: they do not re-learn the same capability, and they do not spend the tokens to do it. Knowledge travels the way the code does, by git, with no service in between.
  • Reading it is bounded too. A capability’s context answer is capped at about 1,500 tokens and never exceeds it, so an agent consults the index rather than crawling the directory — which is what stops a large repository from costing a fortune per turn.
  • Click a file in a module’s popover and it opens read-only beside the board, with a button to promote it to a real tab.

The tasks board

Todo, Doing, Blocked, Review and Done, opened as an editor tab. One rule shapes the whole model: Todo is a window, while Doing, Blocked and Done are records.

  • The list belongs to whoever owns it — a GitHub repo, or Flow’s own ledger — and is read live, storing nothing. The work on that list belongs to Flow, and becomes a local record only when execution starts.
  • An empty backlog and an unreadable one are different answers and never collapse into each other: a queue nobody could read shows the reason it could not, never an empty Todo.
  • Dragging a queue item into Doing performs the exact write a headless loop performs, so a person and an autonomous run can never disagree about who holds an item.
  • A filter may take a card off the board only when nobody has started it and the card itself answers the filter’s question — and the number of cards it hid is reported.
  • One agent thread per task, an auto-generated technical brief, a per-task context folder, and import from Jira, GitHub or Azure DevOps.

Thread worktrees

Every conversation that touches code gets its own git worktree, so nothing an agent does happens in the tree you are working in.

  • The checkout is created on the first message only — a chat-only thread behaves exactly as it did before.
  • A refusal is said out loud. A directory that is not a repository, or a repository with no commits, is refused before anything is created — never a silent fallback into your own working tree.
  • Uncommitted work is offered, never taken. The non-destructive path writes a commit object and touches nothing: your files stay dirty exactly as they were, and the thread starts from a copy.
  • Landing a thread commits what is loose, merges into the branch it was cut from or opens a PR, releases the checkout and keeps the branch. The merge runs inside the thread’s own checkout, so a conflict lands where the merge editor already works.
  • A base that moved is merged, not rebased — a rebase would rewrite the very commits the thread’s Changes list has been showing you.
  • Nothing claims atomicity. A thread spanning two repositories lands them one after another, one row per repository, and one green with one conflicted is a normal result the panel states in words.
  • Where work is published is your answer. An unbound branch is refused, with a suggestion built from a labelled ladder — the configured pattern, then a ticket id, then the shape of the last binding in this repo, then the local name — each labelled with where it came from.

Conflict resolution

Parallel agents produce conflicts, so resolving them is a surface of its own rather than a shell-out.

  • Resolution is per hunk, not per file. The conflicted file opens as an ordinary editor tab with each side tinted and inline actions over every hunk: accept current, accept incoming, accept both, compare, or resolve with AI.
  • Each side is annotated with the branch or ref, the author, and the time it came from — so which side is which is never a guess.
  • The safety invariant is downgrade-only. Structural analysis is the only signal that can call a conflict safe; an AI opinion may confirm that verdict or downgrade it to risky, and can never upgrade a risky one back to safe. A false risky costs you one manual review; a false safe silently applies a broken merge to your codebase.
  • Code an AI synthesised is always held for human review, never auto-applied.
  • A file is badged safe only when every block in it classifies safe — never optimistically.
  • Once the merge is done, the project’s own typecheck, tests, build and lint run, in that order.
  • When two parallel phases each commit an edit to the same file there is no git merge to surface it, so Flow reconstructs both commits and their common base into an ordinary three-way conflict and routes it through the same resolver. No attribution means no clash — never a fabricated one.

The embedded browser

Your app runs inside Flow, next to the code — and so do the terminals running it. Both halves are collected, so what your app did is something you hand over rather than something you describe.

  • A debug drawer sits under the page with Console and Network tabs and live counts. Tag one row, add the recent ones, or add everything.
  • The embedded terminals running your project are collected alongside it — the dev server, a test watcher, whatever else is printing. Each one is captured under its own label, and its output is stamped as it arrives.
  • So a failed request and the server output behind it travel together. You are no longer the thing joining a stack trace in one pane to a request in another.
  • A capture becomes a context chip on the composer carrying the full payload — the response body included, not a screenshot of it.
  • Pick an element and it resolves to the source that rendered it, and attaches a screenshot with it.
  • Secrets are redacted on the way out of both halves, by shape rather than by name: bearer tokens, API keys, and the authorization and cookie headers. Browser captures are cleaned at their own boundary; terminal output gets the same rule applied to it, because server logs print connection strings and environment dumps that headers never do.

Debug sessions

Flow runs both halves of a web application — the app in its embedded browser, the backend in its terminals. A debug session is a window over both at once, on one clock.

  • Press start, reproduce the bug, press finish. Everything in between is collected: browser console, network requests including their response bodies, what you clicked and navigated, and the output of every terminal involved.
  • One clock is what makes it worth anything. Every record carries epoch milliseconds from the host clock — the browser’s own timestamps were measured against it and agree to within 2 ms, and terminal output is stamped as it arrives. So “what did the server print in the 400 ms after I pressed Save” is answered by sorting.
  • Two outputs, deliberately different. The full timeline goes to a file, because one capture can run to megabytes. What reaches the conversation is a summary: what failed, what was slow, what the server said around each failure, and what was clicked just before it.
  • The summary names at most five failures. A real session found twelve, and printing each with its server context filled the whole conversation with a wall nobody reads. The full record is one file away, and the summary says where.
  • Secrets are redacted across both halves — one rule applied twice, not a second implementation. Server logs print connection strings and environment dumps that browser headers never do.
  • A session left running stops itself, and the artifact records that it was capped rather than presenting a window it cannot vouch for.

Agent loops

Work that carries on between your sessions. Two engines: a producer that goes looking, and a consumer that picks things up.

  • A producer hunts inside its scope slice, reproduces what it thinks it found, and files only what survives being reproduced.
  • A consumer claims one filed item, judges it big or small, and either fixes it directly or drives the whole discovery, plan, execute and review pipeline on autopilot.
  • A loop’s direction is a committed file under loops/. Steering it is a commit, so the history of that file is the history of what the loop has been pointed at.
  • Parsing is strict and refuses: an unknown key, a duplicate, a malformed cap. A near miss like max_open_issue is a plausible typo, and ignoring it would run the loop unattended under a cap the file appears to have set.
  • Exactly three things end a run — its cap, its budget, or an empty list. A question is not a stopping condition: a run that genuinely cannot proceed files the question as an item, because a question in a thread nobody opens is not readable tomorrow.
  • Eight open items by default. It stops there so you can look at what it added before it adds more.
  • Every concurrent run slot gets its own worktree, and a run is a thread you can open and watch — not a hidden process.
  • It is a screen, not a dialog: you type the instruction before pressing Run, set the cap, point a consumer at a subject, and the run starts in a chat you can read while it happens.

Finding your way around

Two ways in: one for when you know what you want, one for when you know what it says.

  • The ⌘P palette blends files, threads and commands into one ranked, keyboard-first list. Type > to switch it into command mode.
  • Content search runs across the workspace with line snippets; click a match and the file opens at that line.
  • Search reads the learned documents too, so one query for an invariant finds both the code that implements it and the note recording why it exists.

Runtimes and platforms

Which AI runs your work, and where Flow itself runs.

  • Three runtimes ship: Claude, OpenAI Codex and GitHub Copilot CLI. The choice is per project, and credentials are isolated per runtime and per account.
  • On Claude you pick the model per thread: Opus, Sonnet or Haiku.
  • macOS on Apple Silicon is the reference target: signed, notarized, with an auto-update feed and a one-click update chip in the titlebar.
  • Windows x64 is supported with two caveats stated up front — the build is unsigned, so SmartScreen warns on first launch, and there is no auto-update feed yet, so an update is a manual re-download.
  • The Windows installer is per-user and never asks for elevation. An unsigned installer raising a UAC prompt from an unknown publisher would be a defect, not a step.
  • Linux and Windows on ARM are explicit non-goals.

The four stages

01

/discovery-plan

Work out what you are actually building

Reads every document you point at, finds the related code in your project, and asks you the questions that the request left open. It writes down requirements — functional, non-functional, constraints — and proposes a high-level approach.

It writes no code, and it does not plan. It ends by asking whether you want to continue to /create-plan, and waits.

/discovery-plan "User authentication with OAuth2"
/discovery-plan @docs/feature-spec.md

Writes flow/discovery/discovery_<feature>_v<N>.md

02

/create-plan

Turn the discovery into phases you can approve

Extracts the requirements from the discovery document and lays them out as phases, each with a complexity score from 0 to 10 and its own tasks. A condensed Intent block records the goal, the constraints and what was ruled out, so the reasoning survives the plan.

It then walks you through a Change-Brief Review — the Today vs After shape of the system — before anything runs. The tests phase is always last.

/create-plan @flow/discovery/discovery_user_auth_v1.md
/create-plan "Add dark mode toggle to settings"

Writes flow/plans/plan_<feature>_v<N>.md

03

/execute-plan

Run the plan, phase by phase

Phases are analysed for dependencies and grouped into waves; independent phases in a wave run in parallel sub-agents. You approve each phase before its wave runs. Tasks carrying a <verify> tag are verified the moment they finish, and a failure is diagnosed and repaired in place — up to max_verify_retries attempts.

Build and tests run once, at the end. The finished plan and its discovery document are archived automatically. Database and ORM commands are never run for you: migrations are handed back for you to run yourself.

/execute-plan @flow/plans/plan_user_auth_v1.md

Writes code, commits, and an append-only record in flow/.rounds.jsonl

04

/review-code

Review what actually landed

Reads the diff, loads your project’s own patterns, finds similar implementations already in the codebase, and files the findings as a document. Depth adapts to size: under 50 lines it looks only for security holes, logic bugs and breaking changes; 50–500 lines gets a full review; past 500 it goes multi-pass, grouped by severity, with a summary at the top.

Use /review-pr <url> instead when the changes are already on a pull request — GitHub or Azure DevOps.

/review-code
/review-code --scope staged
/review-code src/services/userService.ts

Writes flow/reviewed-code/review_<feature>.md

The command and the stage are spelled differently on purpose: /discovery-plan is what you type, discovery is the rung — the stage is named for what it produces.

Why a stage can refuse to run

A stage does not ask whether the previous one happened — it looks for what that stage inevitably leaves behind, scoped to the feature you are working on. Ask for /execute-plan with no readable plan for that feature and it refuses, and the refusal names the artifact it looked for.

Two of the four proofs are file presence and two read content, and the difference is reported rather than smoothed over:

Stage
What proves it ran
Strength
discovery
flow/discovery/discovery_<feature>_v<N>.md exists
weak

Presence only — a discovery document has no grammar to check, so an empty file passes.

create-plan
flow/plans/plan_<feature>_v<N>.md parses as a plan
strong

The content is read. A file that calls itself a plan and parses to zero phases proves nothing.

execute-plan
a phase_result entry in flow/.rounds.jsonl
strong

Written by the coordinator itself. Any status counts — a phase that ran and failed still ran.

review-code
flow/reviewed-code/review_<feature>.md exists
weak

Presence only, same as discovery. A review filed under a different name will be asked for again.

The ladder is ordered, not a set. If execution left a trace but no plan parses, the next stage is create-plan — the chain will not step over a missing rung because something further up happened to run.

Autopilot

With autopilot on, you describe the work once and the chain issues each stage from observable state. No command decides for itself whether to keep going, and every hand-off goes through the same gate — a refusal stops the chain rather than advancing past it.

/flow autopilot=true
/flow add usage-based billing to the checkout   # sets autopilot and starts discovery

/flow autopilot=true commit=true push=true pr=true
/flow -status                                   # everything currently set

A chain pauses for exactly three things, and nothing else:

  • a high risk assessment, before anything is published
  • the guard classifier answering ask on an irreversible action — when guarded_autopilot=true
  • a branch nobody has bound, at the moment it would publish

One thing to know if you name things yourself: the chain writes every document under one feature slug, and the proofs are scoped to it. A review filed under a different name — the scope rather than the feature — will not satisfy that rung, and the chain asks for the review again. A repeated review, never a skipped one.

Every command

Any command takes -help and prints its own usage without doing anything.

The workflow

/brainstorm <idea>

Free-form, one-question-at-a-time exploration for an idea too vague for discovery. Pure ideation, no project structure.

flow/brainstorms/brainstorm_<topic>_v<N>.md (optional)

/discovery-plan <doc | description>

Requirements and approach, with the open questions asked. Writes no code.

flow/discovery/discovery_<feature>_v<N>.md

/create-plan <discovery | description>

Phases with complexity scores and tasks, an Intent block, and a Today vs After review.

flow/plans/plan_<feature>_v<N>.md

/execute-plan <plan_file>

Runs the plan in dependency-ordered waves, verifies tagged tasks, archives the plan when done.

code, commits, flow/.rounds.jsonl

/review-code [path] [--scope staged|unstaged]

Reviews local uncommitted changes against your project’s patterns. Depth scales with the diff.

flow/reviewed-code/

/review-pr <pr_url> [--rabbit]

Reviews a pull request on GitHub or Azure DevOps.

flow/reviewed-pr/

/write-tests <coverage_percentage>

Writes and updates tests until the project reaches the coverage target you name.

test files

Knowledge

/learn · /learn <topic>

With no argument, extracts reusable patterns from the current session. With a topic, it teaches — researches, designs a curriculum, and walks you through it step by step.

flow/resources/ · ~/plan-flow/brain/learns/ (global) · flow/brain/learning/

/note <text> · /note -guided

Files a meeting note, an idea or an insight into the project brain by hand, cross-linked with [[wiki-links]].

flow/brain/

/create-contract <source_url> <description>

Builds an integration contract from a documentation URL or a repository, so discovery has something precise to read.

flow/contracts/<service>_contract.md

Session and settings

/resume-work

Reads flow/STATE.md and rebuilds full context after a compaction, a new session or a crash. Creates nothing.

a summary in the chat

/flow <key>=<value> … · -status · -unset <key> · -reset

Every runtime setting, persisted in flow/.flowconfig. Also /flow <prompt>, which turns autopilot on and starts discovery in one move.

flow/.flowconfig

/flow cost [--today|--week|--month] [--detail]

Token usage and spend, by day, project or session.

a report in the chat

Settings

Everything is key=value through /flow, persisted per project in flow/.flowconfig. Settings are independent — commit=true works with autopilot off. /flow -unset <key> puts one back to its default; /flow -reset puts back all of them.

autopilot
true | false
false

Chain the four stages instead of stopping between them.

guarded_autopilot
true | false
false

Classify each dangerous seam of an autonomous run and pause to ask on irreversible actions.

commit
true | false
false

Commit after each completed phase.

push
true | false
false

Push once every phase is done and build and tests pass.

pr
true | false
false

Open a pull request after execution.

pr_draft
true | false
false

Open those PRs as drafts; /review-pr flips one to ready.

branch
<name>
current branch

The base a workspace is cut from and a PR opens against.

remote
<name>
origin

The remote a thread binds its push and PR to.

remote_branch_pattern
<pattern>
unset

Naming convention suggested for a thread’s remote branch, e.g. feature/{ticket}.

thread_worktrees
true | false
true

Give every thread its own workspace, so nothing runs in your tree.

workspace_start
here | trunk | branch:<name>
here

Where a thread’s workspace starts when nobody names a start.

base_refresh
true | false
true

Bring the base up to date before cutting a workspace.

base_refresh_timeout_ms
1000–30000
8000

How long that refresh may take.

wave_execution
true | false
true

Group independent phases into waves and run each wave in parallel.

phase_isolation
true | false
true

Run each phase in a fresh sub-agent with clean context. Turn off to debug inline.

model_routing
true | false
false

Pick the model per phase from its complexity.

max_verify_retries
1–5
2

Repair attempts allowed per failed task verification.

learn_auto
true | false
true

Re-learn a module automatically when its code drifts.

learn_ignore
<globs>
unset

Modules left out of learning, comma-separated.

commands.lint
<cmd>
unset

The lint command the pipeline gates run.

share
local | shared
local

Share this project’s knowledge with the team, or keep it to yourself.

Where everything is written

All of it lives in your repository, as plain markdown. It commits, reviews and merges like code, and a teammate who pulls gets the same picture you have.

flow/discovery/
discovery documents — requirements and approach
flow/plans/
implementation plans, phase by phase
flow/brain/
the learned knowledge: modules, flows, invariants
flow/reviewed-code/
code review findings
flow/reviewed-pr/
pull request review findings
flow/contracts/
integration contracts built from external docs
flow/brainstorms/
raw exploration, before discovery
flow/resources/
patterns extracted from your sessions
flow/references/
the analysis of your stack that indexing produced
flow/archive/
completed plans and their discovery documents
flow/STATE.md
what is in flight — what /resume-work reads
flow/.flowconfig
your settings, as YAML
flow/.rounds.jsonl
the append-only execution record

When you lose the thread

After a compaction, a new session or a crash, /resume-work reads flow/STATE.md, finds the work in flight, reads the plan or discovery behind it, and puts the context back. It creates nothing and changes nothing.

That is the point of writing each stage down as a document: the work survives the session it started in.

Try it on real work.

Download for macOSmacOS on Apple Silicon · Windows x64