Skip to content

Latest commit

 

History

History
141 lines (99 loc) · 19.6 KB

layout.md

File metadata and controls

141 lines (99 loc) · 19.6 KB

The repository layout

One clone holds everything Flow is. This page says what is in each folder, and where a new file goes.

Table of contents

The 4 parts

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/, and project-template/
  • 8 entries belong to the repository: CLAUDE.md, README.md, LICENSE, install.sh, CHANGELOG.md, upgrades/, .claude/settings.json, and docs/
  • lab/ is the maintainers' workspace: installed nowhere
  • repos/ and tmp/ 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.

What installs on a machine

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.js is the entry point. It names the commands and hands what was typed to lib/cli.js, the argument layer. Designing a flow command holds the rules every command follows.
  • commands/ holds one file per command or group: init.js is flow init, store.js is flow store, update.js is flow update, and status-line.js is flow status-line.
  • lib/ holds everything the commands, the hooks and the jobs share. A folder groups one subject, and the files loose in lib/ serve every subject:
    • tickets/: the tickets. store.js is the only file that reads or writes a ticket's folder. records.js keeps a project's tickets on its branch flow: the commit, the pull, the push, the renumbering after a clash, and checking the branch out at .flow/. records-place.js keeps 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.js sets a ticket's branch: and words the lines of its history.md. ticket-skills.js writes 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 index flow audit answers from, and permissions.js, which counts the permission log without the index.
    • guard/: the guard's judgment. world.js alone reads the disk, git and the environment. Every other file there turns a command into a decision.
    • setup.js holds the setup sessions flow install, flow init and flow update open. paths.js finds every Flow folder, project.js the project around a folder, git.js runs git and gh, and hook.js reads a hook's event and writes its answer.
  • hooks/ holds one file per hook Claude Code runs. Each reads the event, calls lib/, and writes the answer:
    • guard.js is the PreToolUse hook 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.js holds a case for each kind.
    • changes.js records what each subagent changed, under its agent id, and hands the parent a diff per file when the subagent finishes. lib/changes.js holds the logic.
    • rule-check.js is the PreToolUse hook on Edit and Write. It runs every check in rule-checks/ and records the results.
    • instructions-loaded.js is the InstructionsLoaded hook, recording which rule files entered context.
    • failures.js is the PostToolUseFailure and StopFailure hook. It writes a line into ~/.flow/logs/failures/<month>.jsonl for a failed MCP tool, a failed Flow command or bundled script, and an API error that ended a turn. lib/logs/failures.js holds which calls count.
    • check-ticket.js is the UserPromptExpansion hook that refuses a typed phase skill before it loads on a machine not set up, and a bare /flow:start in a folder with no project.
    • overlays.js is the UserPromptExpansion hook and the PostToolUse hook on Skill. 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.js is the UserPromptSubmit hook that prints references/reminder.md beside every message, unless "reminder": false in ~/.flow/settings.json silences it.
    • compact-check.js is the PreCompact hook on a typed /compact. It refuses with exit 2 and names /flow:handoff, then /clear. "compact": true lets it run.
    • context-check.js is the PostToolBatch and UserPromptSubmit hook 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": false silences it.
    • session-check.js is the SessionStart hook that names what needs attention, reading ~/.flow/run.json, ~/.flow/version and the project's .flow/version, and printing nothing when all 3 are fine. "sessionCheck": false silences it. In a git repository with no .flow/ it suggests flow init through systemMessage, to the user alone. It also makes every skill link match the skills lines, makes every ticket skill match the tickets, and starts jobs/records-sync.js for a project on its branch flow. lib/session-start.js holds the logic.
    • file-suggestion.js builds the list @ opens, named by fileSuggestion in home/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.js saves and sends a project's tickets, and ~/.flow/ with the projects kept in it, where nobody typed flow sync: the Stop hook after a reply once 30 minutes have passed, the SessionEnd hook, a status move and the session check. lib/tickets/records.js holds the logic.
    • skills-pull.js updates every skill repository in ~/.flow/repos/sources/, started by the session check. It pulls each one. With "skillsAutoUpdate": false it only fetches, and writes what is waiting into ~/.flow/skills-update.json. lib/skills/skills-update.js holds the logic.
  • sessions/ holds what the sessions Flow opens follow: machine.md for flow install, project.md for flow init, and migrate.md, instructions and form in one file, for flow update. Not skills: lib/setup.js hands 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, the README.md of ~/.flow/, and the 2 setup forms, setup-machine.md and setup-project.md.
  • record-originals.js copies each path a setup is about to change into the place's original, run by the setup session before its first change. flow restore puts those back, and once --finish closes the original, nothing more is recorded. It is not a flow command, so nobody types it by accident. lib/machine/originals.js holds 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.md states the export contract.
  • package.json and tests/ 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 without paths: frontmatter load every session; rules with paths: load only when the agent reads a matching file. Populated by /flow:file-findings when knowledge is promoted from .flow/findings/.
  • commands/ holds commands, one markdown file each, typed by the file name with no flow: prefix: capture.md is /capture. A command is for a manual trigger only the user types, so each carries disable-model-invocation: true and 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.

What belongs to the repository

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.

The tickets and the research on the branch flow

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 the flow command. The beta checklist is tickets fw-2 to fw-14.
  • research/: the evidence behind the design, one folder per topic holding one file per question, such as workflows/does-any-tool-match-flow.md or claude-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.

The maintainers' workspace under lab/

lab/ ships nowhere. It holds what serves this repository alone:

  • util/: the util CLI, 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 as util/.
  • archive/: code Flow no longer runs, kept readable, with a README.md line 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. Its README.md says what each one draws.
  • scripts/: scripts serving this repository's development, installed nowhere. repos.sh clones the reference repositories, try.sh builds the scratch session, and save-computer.sh saves this computer as a seed for it to start from. test-projects/<name>/ builds each run's practice project: files/ copied in, then build.sh making the tickets, or no build.sh for a project not set up.

What is gitignored

  • 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, and lists/ curated lists for finding more. bash lab/scripts/repos.sh restores 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 from try.sh, kept until try.sh --delete removes it: home/, the pretend computer's home folder with the project in home/code/, remote.git, the stand-in for the repository ~/.flow/ lives in, and sandbox.sh, the line that starts the session. tmp/computers/ holds the seeds, saved computers a run starts from: save-computer.sh saves this one, try.sh --save a 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.

Where a new file goes

  • A decision, with its reason → the file in docs/spec/ for its part, marked V1, next, later or never
  • 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 and build.sh run, picked with try.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, plus upgrades/<number>.md where 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.