One clone holds everything Flow is. This page says what is in each folder, and where a new file goes.
- The 4 parts: what installs, what stays in the repository, the maintainers' workspace, and scratch
- What installs on a machine: the 6 folders and every file in
scripts/ - What belongs to the repository: the files that install nowhere, the docs and the spec among them
- The tickets and the research on the branch flow: open work, and the evidence behind the design
- The maintainers' workspace under lab: the submodules and the scripts serving this repository
- What is gitignored: other people's clones, and scratch
- Where a new file goes: one line per kind of file
Installing creates symlinks from your machine into this clone, so most files are reachable from 2 paths at once: one in the repository, one on the machine. Trying a change says how to edit a dev copy while your sessions run the release.
When you first open the repository, the split that matters has 4 parts:
- 6 folders install:
home/,scripts/,references/,skills/,claude/, andproject-template/ - 8 entries belong to the repository:
CLAUDE.md,README.md,LICENSE,install.sh,CHANGELOG.md,upgrades/,.claude/settings.json, anddocs/ lab/is the maintainers' workspace: installed nowhererepos/andtmp/are gitignored: either can be thrown away at any moment
.gitignore, .gitmodules, and .vscode/ belong to git and the editor. Flow reads none of them. .vscode/ is gitignored, since it holds one person's editor settings.
home/CLAUDE.md is the rules that apply in every directory, project or not. The machine's setup session writes it to ~/.flow/CLAUDE.md once the user has checked its form, and links ~/.claude/CLAUDE.md to that file, so Claude Code loads it. It is personalized there. The copy here is the template: placeholders and rules, never personal content. A project's rules sit in its own CLAUDE.md. docs/spec/rules.md → ### The rule files says why Flow writes no AGENTS.md anywhere.
home/settings.json is the permissions, the hooks, feature flags, and skillOverrides (the off list, which reaches outside skills only). Settings explains every key. The setup session flow install opens merges it into ~/.claude/settings.json key by key. The links flow install makes before that session write none of the 3 above: a rule file copied before the interview holds nothing of the user.
scripts/ holds the CLI, the hooks, and the script that carries out a migration. Symlinked as ~/.flow/scripts. flow.js gets 2 more symlinks in ~/.local/bin/ named flow and fw.
flow.jsis the entry point. It names the commands and hands what was typed tolib/cli.js, the argument layer. Designing a flow command holds the rules every command follows.commands/holds one file per command or group:init.jsisflow init,store.jsisflow store,update.jsisflow update, andstatus-line.jsisflow status-line.lib/holds everything the commands, the hooks and the jobs share. A folder groups one subject, and the files loose inlib/serve every subject:tickets/: the tickets.store.jsis the only file that reads or writes a ticket's folder.records.jskeeps a project's tickets on its branchflow: the commit, the pull, the push, the renumbering after a clash, and checking the branch out at.flow/.records-place.jskeeps them in the Flow home instead: the folder under~/.flow/projects/, the link.flow/to it, and the repository's address that finds it from another clone.ticket-history.jssets a ticket'sbranch:and words the lines of itshistory.md.ticket-skills.jswrites one user-only skill per open ticket, after every command that writes a ticket.machine/: this machine. What Flow installed, its links, the originals a restore puts back, the migrations, the version stamp, and~/.flow/as a private git repository.skills/: the skill links, the skill repositories, and their updates.logs/: the one file per month every log under~/.flow/logs/uses, and which failed calls count.checks/: the rule checks and their scorecard.audit/: Claude Code's transcripts, read into the indexflow auditanswers from, andpermissions.js, which counts the permission log without the index.guard/: the guard's judgment.world.jsalone reads the disk, git and the environment. Every other file there turns a command into a decision.setup.jsholds the setup sessionsflow install,flow initandflow updateopen.paths.jsfinds every Flow folder,project.jsthe project around a folder,git.jsruns git andgh, andhook.jsreads a hook's event and writes its answer.
hooks/holds one file per hook Claude Code runs. Each reads the event, callslib/, and writes the answer:guard.jsis thePreToolUsehook on Edit, Write, Bash and Read. It reads each command the way bash splits it, asks before 7 kinds of harm, and never allows anything. On Edit and Write it asks only for a file that can switch the guard off or for~/.ssh, and on Read it checks the path for a private key or a login alone. A throw anywhere answers ask.scripts/tests/guard.test.jsholds a case for each kind.changes.jsrecords what each subagent changed, under its agent id, and hands the parent a diff per file when the subagent finishes.lib/changes.jsholds the logic.rule-check.jsis thePreToolUsehook on Edit and Write. It runs every check inrule-checks/and records the results.instructions-loaded.jsis theInstructionsLoadedhook, recording which rule files entered context.failures.jsis thePostToolUseFailureandStopFailurehook. It writes a line into~/.flow/logs/failures/<month>.jsonlfor a failed MCP tool, a failed Flow command or bundled script, and an API error that ended a turn.lib/logs/failures.jsholds which calls count.check-ticket.jsis theUserPromptExpansionhook that refuses a typed phase skill before it loads on a machine not set up, and a bare/flow:startin a folder with no project.overlays.jsis theUserPromptExpansionhook and thePostToolUsehook onSkill. Each time a skill loads, typed or loaded by the agent, it hands the agent~/.flow/skill-overlays/<name>.md, for every skill, Flow's or not, in every project.reminder.jsis theUserPromptSubmithook that printsreferences/reminder.mdbeside every message, unless"reminder": falsein~/.flow/settings.jsonsilences it.compact-check.jsis thePreCompacthook on a typed/compact. It refuses with exit 2 and names/flow:handoff, then/clear."compact": truelets it run.context-check.jsis thePostToolBatchandUserPromptSubmithook that tells the agent to hand off once the conversation passes"wrapUpAt"tokens, 150,000 by default, and again every 20,000 past it. It reads the size off the session file."wrapUp": falsesilences it.session-check.jsis theSessionStarthook that names what needs attention, reading~/.flow/run.json,~/.flow/versionand the project's.flow/version, and printing nothing when all 3 are fine."sessionCheck": falsesilences it. In a git repository with no.flow/it suggestsflow initthroughsystemMessage, to the user alone. It also makes every skill link match theskillslines, makes every ticket skill match the tickets, and startsjobs/records-sync.jsfor a project on its branchflow.lib/session-start.jsholds the logic.file-suggestion.jsbuilds the list@opens, named byfileSuggestioninhome/settings.json. It saves each project's walk in the system's temp folder and answers every keystroke from it.
jobs/holds the 2 scripts that run in the background, never typed:records-sync.jssaves and sends a project's tickets, and~/.flow/with the projects kept in it, where nobody typedflow sync: theStophook after a reply once 30 minutes have passed, theSessionEndhook, a status move and the session check.lib/tickets/records.jsholds the logic.skills-pull.jsupdates every skill repository in~/.flow/repos/sources/, started by the session check. It pulls each one. With"skillsAutoUpdate": falseit only fetches, and writes what is waiting into~/.flow/skills-update.json.lib/skills/skills-update.jsholds the logic.
sessions/holds what the sessions Flow opens follow:machine.mdforflow install,project.mdforflow init, andmigrate.md, instructions and form in one file, forflow update. Not skills:lib/setup.jshands the text over as a system prompt, and the machine's setup runs in safe mode, which loads no skill.templates/holds what Flow writes a new file from: a ticket, a map, a study case, theREADME.mdof~/.flow/, and the 2 setup forms,setup-machine.mdandsetup-project.md.record-originals.jscopies each path a setup is about to change into the place's original, run by the setup session before its first change.flow restoreputs those back, and once--finishcloses the original, nothing more is recorded. It is not aflowcommand, so nobody types it by accident.lib/machine/originals.jsholds the logic.rule-checks/holds one file per rule check, named after the rule id it enforces. The folder is the whole registry, and/flow:file-findings'references/write-checks.mdstates the export contract.package.jsonandtests/sit here: this is the Node package root.
references/ holds files Flow ships and rarely loads: style.md is the house style, with cut-loaded-files.md beside it for a file an agent loads, write-rules.md for a rule file and write-docs.md for a documentation page, workflow.md describes how the pieces fit, knowledge.md maps how skills, plugins, MCP servers and findings arrive and grow, study-cases.md says how to record a failure, reminder.md is the line the UserPromptSubmit hook prints beside every message, and harnesses/<name>.md says where one harness keeps its own files, Claude Code's first. Symlinked as ~/.flow/references.
skills/ holds every skill, one folder each, filed under a group: phases/, tools/, dev/, or drafts/. Adding a skill covers the groups. The symlinks flow install builds are flat and named for the skill, inside ~/.agents/skills/flow/skills/, so the only group names read outside this tree are drafts/, which never installs, and dev/, whose skills switch.
skills/.claude-plugin/plugin.json names Flow, describes it, and lists the 4 group folders under skills. The name is what makes every skill typed /flow:groundwork instead of /groundwork. The list lets claude --plugin-dir skills load this tree as it stands, for a session on the dev copy. Codex reads the file here, because it follows each skill's link into this tree and looks above the real folder. flow install copies it without the list into ~/.agents/skills/flow/.claude-plugin/, where Claude Code reads it. Copied rather than linked, because Codex ignores a symlinked manifest. That copy and ~/.flow/settings.local.json are the only things flow install writes that are not symlinks.
claude/ holds what Claude Code alone reads, each file symlinked into the folder of the same name under ~/.claude/:
agents/holds subagent definitions, one markdown file each: a system prompt, a tool allowlist, and a model.rules/holds prescriptive rules, one markdown file per topic. Rules withoutpaths:frontmatter load every session; rules withpaths:load only when the agent reads a matching file. Populated by/flow:file-findingswhen knowledge is promoted from.flow/findings/.commands/holds commands, one markdown file each, typed by the file name with noflow:prefix:capture.mdis/capture. A command is for a manual trigger only the user types, so each carriesdisable-model-invocation: trueand costs no context until typed.
project-template/ is what a new project starts with: a CLAUDE.md with 2 sections (## Project, ## Rules), each holding a placeholder comment, an empty .claude/settings.json, a .gitignore and a .uncommitted-include. Nothing else. It is copied into a project as-is. A directory that is not a project deletes ## Project. .uncommitted-include ships empty, with a comment explaining that it names the gitignored files that travel with util git uncommitted send.
CLAUDE.md holds the rules for working on Flow itself, and installs nowhere. While Flow is not installed on a machine, these are the only rules any session here loads.
README.md introduces Flow and links to everything else.
LICENSE is the MIT license: anyone may use, change, share and sell Flow, as long as the license text goes with every copy.
install.sh is what the one pasted install line runs, curl -fsSL <address>/install.sh | bash. It checks for git, node, claude and gh, clones Flow into ~/.flow/repos/flow/, then hands over to flow install, which does every other step. A clone that exists is never cloned again, so running it twice changes nothing. --use <folder> skips the clone and uses that folder as Flow.
CHANGELOG.md holds one entry per change in how Flow behaves, numbered from 1, newest first. An entry's number is Flow's version, and ~/.flow/version holds the number a machine last applied. Nothing is written into it until Flow is installed on a machine, since a migration is the only reader an entry has.
upgrades/ holds one guide per entry, 12.md being the step from 11 to 12. The session flow update opens reads every guide above the machine's number and writes one migration from them, and upgrades/README.md says what a guide holds. Nothing here is symlinked: the session reads the guides out of this clone, through ~/.flow/repos/flow.
.claude/settings.json is this repository's own Claude Code settings, committed. It carries claudeMdExcludes, which stops every CLAUDE.md under lab/, repos/, and project-template/ from loading when a file beside one is read.
docs/ holds Flow's published documentation. The pages at its top are guides for whoever uses Flow, one per subject, such as tickets.md or safety.md. reference/ holds the 4 lookup pages: commands, settings, skills and files. dev/ is this folder, for whoever changes Flow. spec/ is Flow's own product spec: product.md says what Flow is and indexes one file per part, each holding what the part does and how it is built, every behavior marked V1, next, later or never. docs/README.md and dev/README.md each index their own pages. Nothing in dev/ restates what the user pages cover, and nothing in the user pages names a hidden command or flag. Symlinked as ~/.flow/docs, so /flow:help names a page by a path that is the same on every machine.
Flow works on itself the way it works on any project. Its records live on the orphan branch flow, checked out at .flow/, which no code branch carries:
tickets/: every open piece of work, one folder each, read and moved through theflowcommand. The beta checklist is ticketsfw-2tofw-14.research/: the evidence behind the design, one folder per topic holding one file per question, such asworkflows/does-any-tool-match-flow.mdorclaude-code-mods/.inbox.md: raw notes waiting for/flow:file-findings.
A decision belongs in docs/spec/, never here. Git holds the history of how each one was reached.
lab/ ships nowhere. It holds what serves this repository alone:
util/: theutilCLI, a submodule: Adrian333Dev/util. Edited here, committed from inside the folder, and the new pointer committed here afterwards.domain-skills/: the shared skills about one field or tool each, a submodule: Adrian333Dev/domain-skills. Committed the same way asutil/.archive/: code Flow no longer runs, kept readable, with aREADME.mdline per file saying what replaced it.mockups/: drawings from design work, and the scripts that build them row by row, kept as samples for the ASCII engine. ItsREADME.mdsays what each one draws.scripts/: scripts serving this repository's development, installed nowhere.repos.shclones the reference repositories,try.shbuilds the scratch session, andsave-computer.shsaves this computer as a seed for it to start from.test-projects/<name>/builds each run's practice project:files/copied in, thenbuild.shmaking the tickets, or nobuild.shfor a project not set up.
repos/: clones of other people's repositories, in 5 folders by what they are read for:workflows/holds the workflows Flow is compared against,skills/skill sets and the skill format,tools/single tools around a session such as guards and checkers,harnesses/the agents' own source, andlists/curated lists for finding more.bash lab/scripts/repos.shrestores them, and its list says what Flow takes from each. Nothing here is yours and nothing here is ever edited.tmp/: scratch.tmp/try/<name>/is one run of the scratch session fromtry.sh, kept untiltry.sh --deleteremoves it:home/, the pretend computer's home folder with the project inhome/code/,remote.git, the stand-in for the repository~/.flow/lives in, andsandbox.sh, the line that starts the session.tmp/computers/holds the seeds, saved computers a run starts from:save-computer.shsaves this one,try.sh --savea run's. None is ever rewritten.tmp/tests/is where both test suites write.
Neither survives a fresh clone, and nothing at runtime reads either.
Copies of other people's docs never enter this repository, since publishing them would republish someone else's pages. They sit in the wiki on each machine, in ~/.flow/wiki/claude-code/downloads/ and ~/.flow/wiki/agentskills/downloads/, which flow sync never carries.
- A decision, with its reason → the file in
docs/spec/for its part, markedV1,next,laterornever - An open item → a ticket, through
flow new - Research behind a decision →
.flow/research/<topic>/, one file per question - A shipped script →
scripts/, once. A script that serves only this repository →lab/scripts/.lab/scripts/test-projects/<name>/is a board for the practice project,files/copied in andbuild.shrun, picked withtry.sh --project <name> - A rule check →
scripts/rule-checks/<rule-id>.js, named after the rule it enforces. Nothing registers it - A change in how Flow behaves, once Flow is installed somewhere → one entry in
CHANGELOG.md, plusupgrades/<number>.mdwhere the change moves a path on a machine - A scratch file →
tmp/, never the repository root - A skill →
skills/<group>/<name>/SKILL.md. Adding a skill covers the rest.
Two rules bind lab/. Nothing under lab/ is a Flow skill, even where a folder there holds a SKILL.md: Flow's own skills live in skills/ alone, and domain-skills/ is another repository's. And no path inside lab/ may appear in a skill, in home/, or in project-template/, because none of those can see lab/ once installed.