feature-flow-cli 0.23.0__tar.gz → 0.25.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {feature_flow_cli-0.23.0/feature_flow_cli.egg-info → feature_flow_cli-0.25.0}/PKG-INFO +59 -12
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/README.md +58 -11
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/adapters/codex/feature-flow/SKILL.md +3 -3
- feature_flow_cli-0.25.0/agents/flow-lens.md +56 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/feature_flow/__init__.py +1 -1
- feature_flow_cli-0.25.0/feature_flow/brainstorm_live.py +386 -0
- feature_flow_cli-0.25.0/feature_flow/brainstorm_page.py +1066 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/feature_flow/command.py +8 -2
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/feature_flow/conductor.py +11 -5
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/feature_flow/prompts.py +6 -1
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/feature_flow/status.py +5 -2
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0/feature_flow_cli.egg-info}/PKG-INFO +59 -12
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/feature_flow_cli.egg-info/SOURCES.txt +11 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/guides/brainstorm.md +32 -4
- feature_flow_cli-0.25.0/guides/lenses/artistic.md +14 -0
- feature_flow_cli-0.25.0/guides/lenses/open-minded.md +14 -0
- feature_flow_cli-0.25.0/guides/lenses/positive.md +14 -0
- feature_flow_cli-0.25.0/guides/lenses/researcher.md +14 -0
- feature_flow_cli-0.25.0/guides/lenses/security.md +14 -0
- feature_flow_cli-0.25.0/guides/lenses/ux.md +14 -0
- feature_flow_cli-0.25.0/guides/styles/blueprint.css +27 -0
- feature_flow_cli-0.25.0/guides/styles/route.css +27 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/guides/templates/brainstorm.md +1 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/scripts/flow-trust.py +6 -1
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/skills/feature-flow/SKILL.md +5 -5
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/LICENSE +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/MANIFEST.in +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/adapters/codex/feature-flow/agents/openai.yaml +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/agents/feature-planner.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/agents/flow-architect.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/agents/flow-designer.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/agents/flow-po.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/agents/flow-scout.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/agents/flow-skeptic.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/agents/flow-tester.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/agents/flow-web.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/agents/plan-reviewer.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/agents/ticket-builder.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/agents/ticket-reviewer.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/feature_flow/__main__.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/feature_flow/checks.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/feature_flow/cli.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/feature_flow/codehash.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/feature_flow/evaluate.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/feature_flow/floorguard.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/feature_flow/gate.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/feature_flow/git.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/feature_flow/importer.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/feature_flow/install.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/feature_flow/lanes.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/feature_flow/proc.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/feature_flow/profiles.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/feature_flow/proof.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/feature_flow/released.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/feature_flow/report.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/feature_flow/scouts.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/feature_flow/state.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/feature_flow/suggest.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/feature_flow/tickets.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/feature_flow/uninstall.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/feature_flow/view.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/feature_flow_cli.egg-info/dependency_links.txt +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/feature_flow_cli.egg-info/entry_points.txt +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/feature_flow_cli.egg-info/top_level.txt +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/guides/brief.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/guides/build.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/guides/debug.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/guides/plan-review.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/guides/plan.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/guides/replan.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/guides/review-feature.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/guides/review-quality.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/guides/review-single.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/guides/review.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/guides/show.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/guides/templates/commands.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/guides/templates/learnings.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/guides/templates/map.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/guides/templates/spec.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/guides/templates/ticket.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/guides/templates/ui-mockup.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/guides/test.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/install.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/install.sh +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/pyproject.toml +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/scripts/floor-guard.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/scripts/flow-status.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/scripts/flow-view.html +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/scripts/flow-view.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/scripts/flow.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/scripts/gate.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/setup.cfg +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/skills/architect-review/SKILL.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.25.0}/skills/automation-design/SKILL.md +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: feature-flow-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.25.0
|
|
4
4
|
Summary: A ticket-graph workflow for coding agents: installs the feature-flow skill into a repo
|
|
5
5
|
License-Expression: MIT
|
|
6
6
|
Project-URL: Homepage, https://github.com/hamilton-sky/feature-flow
|
|
@@ -25,10 +25,25 @@ Dynamic: license-file
|
|
|
25
25
|
|
|
26
26
|
Plan a feature as a graph of small tickets, then build them in the session you are already in. One command, `/feature-flow`, does both. Every ticket is built by one fresh subagent and checked by another that never saw the builder's reasoning. A script, not the agent, decides the order of the steps, runs the build and tests, and watches for work that weakens the checks, and the whole run has limits.
|
|
27
27
|
|
|
28
|
-
One skill,
|
|
28
|
+
One skill, 12 agent roles, a Python conductor, 6 Python scripts (`flow`, `flow-trust`, `flow-status`, `flow-view`, `gate`, `floor-guard`), an installer for both agents, a Claude Code plugin, a PyPI package, a demo and a test suite. All of it is Python (standard library only), so it runs on Linux, macOS and Windows. MIT licensed.
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
### At a glance
|
|
31
|
+
|
|
32
|
+
| | What you get |
|
|
33
|
+
|---|---|
|
|
34
|
+
| **Plan** | A brief you approve, a fresh planner and a fresh plan reviewer, a second yes before anything is written. An optional [brainstorm](#brainstorm-before-planning) first, shown as a review page with diagrams you can edit, or an [import](#starting-from-spec-kit-or-openspec) from Spec Kit or OpenSpec. |
|
|
35
|
+
| **Build** | One fresh builder per ticket, then the [gate, floor guard, footprint, Done when and test-first checks](#how-a-ticket-flows), all run by the script. |
|
|
36
|
+
| **Review** | A fresh reviewer that never saw the builder's reasoning, as much as the ticket's [level](#how-a-ticket-flows) asks for, and [read only](#the-skill-and-the-roles) by hook and by the conductor. |
|
|
37
|
+
| **Prove** | [Acceptance tests](#acceptance-tests-the-tester) written from the spec by a tester before any code, which builders cannot touch. |
|
|
38
|
+
| **Go faster** | [Lanes](#tickets-side-by-side-lanes) build disjoint tickets side by side, the [fast path](#the-fast-path) batches small tickets and reviews the feature once, a [time budget](#a-time-budget) switches to fast mode by itself, and [profiles](#profiles) set all of it with one word. |
|
|
39
|
+
| **Ask, don't guess** | [Scouts](#scouts) read ahead for every role, and [questions](#questions-for-the-architect-designer-or-product-owner) go to an architect, designer or product owner agent before they come to you. |
|
|
40
|
+
| **Measure** | [`feature-flow eval`](#recording-a-run-eval) records what a run cost and what each check caught, and `feature-flow report` shows the log. |
|
|
41
|
+
|
|
42
|
+
[docs/releases.md](docs/releases.md) lists what each release added.
|
|
43
|
+
|
|
44
|
+
- [Quick start](#quick-start) · [How a ticket flows](#how-a-ticket-flows) · [The skill and the roles](#the-skill-and-the-roles) · [Plans and tickets](#plans-and-tickets) · [See the graph](#see-the-graph)
|
|
45
|
+
- [Lanes](#tickets-side-by-side-lanes) · [Scouts](#scouts) · [Questions](#questions-for-the-architect-designer-or-product-owner) · [Acceptance tests](#acceptance-tests-the-tester) · [Fast path](#the-fast-path) · [Time budget](#a-time-budget) · [Eval](#recording-a-run-eval) · [Profiles](#profiles) · [Brainstorm](#brainstorm-before-planning) · [Import](#starting-from-spec-kit-or-openspec)
|
|
46
|
+
- [Long features and handoff](#long-features-and-handoff) · [Commands and settings](#commands-and-settings) · [What is tested](#what-is-tested) · [Limits](#limits) · [Upgrading](#upgrading) · [Caution](#caution)
|
|
32
47
|
|
|
33
48
|
## Quick start
|
|
34
49
|
|
|
@@ -60,7 +75,7 @@ Without a clone, the same installer runs from [PyPI](https://pypi.org/project/fe
|
|
|
60
75
|
uvx feature-flow-cli install /path/to/your/repo --agent all # or: pipx run feature-flow-cli install ...
|
|
61
76
|
```
|
|
62
77
|
|
|
63
|
-
The package puts a `feature-flow` command on your PATH with `install`, `uninstall`, `status <feature>`, `view <feature>`, `reset <feature>`, `report <feature>` and `
|
|
78
|
+
The package puts a `feature-flow` command on your PATH with `install`, `uninstall`, `status <feature>`, `view <feature>`, `reset <feature>`, `report <feature>`, `eval <feature>`, `import <folder> <feature>` and `brainstorm-page <feature>`. It installs the same files, byte for byte, as `install.py` from a clone.
|
|
64
79
|
|
|
65
80
|
The installer lists what it wrote in `.feature-flow/installed.txt`, with each file's hash in `.feature-flow/installed.sha256`. Commit those files (`git add --pathspec-from-file=.feature-flow/installed.txt`); until you do, the flow does not count them as uncommitted changes. Installing a newer version over an older one updates every file nobody edited since it was installed, and keeps (and names) the ones you changed; `--force` replaces those too.
|
|
66
81
|
|
|
@@ -77,6 +92,10 @@ Then, in your repo, in the agent:
|
|
|
77
92
|
| Build its tickets (a plan exists) | `/feature-flow csv-export` | `$feature-flow csv-export` |
|
|
78
93
|
| The same, asking nothing | `/feature-flow csv-export auto` | `$feature-flow csv-export auto` |
|
|
79
94
|
| Watch the graph, animated | `/feature-flow csv-export show` | `$feature-flow csv-export show` |
|
|
95
|
+
| Weigh ways to build it first | `/feature-flow csv-export brainstorm` | `$feature-flow csv-export brainstorm` |
|
|
96
|
+
| Small, low-risk feature: one review at the end | `/feature-flow csv-export fast` | `$feature-flow csv-export fast` |
|
|
97
|
+
| Costly to get wrong: full gate, own review per ticket | `/feature-flow csv-export careful` | `$feature-flow csv-export careful` |
|
|
98
|
+
| Another agent drives the session, no handoffs | `/feature-flow csv-export agent` | `$feature-flow csv-export agent` |
|
|
80
99
|
|
|
81
100
|
The same command plans when `plans/csv-export/` does not exist yet and builds when it does. After your second yes it commits the new plan folder, and only that folder, then goes straight on to building it; say so if you want it to stop after planning.
|
|
82
101
|
|
|
@@ -124,6 +143,9 @@ The Claude Code skill is `skills/feature-flow/`. The Codex skill is written by h
|
|
|
124
143
|
plan touched beyond own Status + Answer + appended lines? │
|
|
125
144
|
│ clean │
|
|
126
145
|
▼ │
|
|
146
|
+
footprint (script): only the paths on the ticket's Touches: fail ─┤
|
|
147
|
+
│ pass │
|
|
148
|
+
▼ │
|
|
127
149
|
Done when checks (script): runs every ```check block fail ─┤
|
|
128
150
|
test-first check (script): Test first: yes needs a test-only │
|
|
129
151
|
commit that failed Test before the code fail ─┤
|
|
@@ -172,13 +194,18 @@ The gate does not depend on the level: it still runs Quick mid-plan and the full
|
|
|
172
194
|
|
|
173
195
|
| Role | Tools | Job |
|
|
174
196
|
|---|---|---|
|
|
175
|
-
| `ticket-builder` | Read, Glob, Grep, Edit, Write, Bash | Builds one ticket by the build guide in its prompt. |
|
|
176
|
-
| `ticket-reviewer` | Read, Glob, Grep, Bash (no Edit, no Write) | Reviews one ticket by the review guide in its prompt and ends with `REVIEW: PASS` or `REVIEW:
|
|
177
|
-
| `feature-planner` | Read, Glob, Grep, Bash, Write,
|
|
197
|
+
| `ticket-builder` | Read, Glob, Grep, Edit, Write, Bash | Builds one ticket (or, in fast mode, a batch of small ones) by the build guide in its prompt. |
|
|
198
|
+
| `ticket-reviewer` | Read, Glob, Grep, Bash (no Edit, no Write) | Reviews one ticket, or the whole feature on the fast path, by the review guide in its prompt and ends with `REVIEW: PASS`, `REVIEW: FAIL` or `REVIEW: ASK <role>`. |
|
|
199
|
+
| `feature-planner` | Read, Glob, Grep, Bash, Write, WebSearch, WebFetch | Plans one feature from the approved brief by the plan guide, writes only the draft, cites outside sources, and ends with `PLAN: READY` or `PLAN: QUESTIONS`. Also folds open tickets on a re-plan. |
|
|
178
200
|
| `plan-reviewer` | Read, Glob, Grep, Bash (no Edit, no Write) | Checks the draft against the brief by the plan review guide and ends with `PLAN-REVIEW: PASS` or `PLAN-REVIEW: FAIL`. |
|
|
179
201
|
| `flow-tester` | Read, Glob, Grep, Edit, Write, Bash | Writes the feature's acceptance tests from `spec.md` alone, before the build, by the test guide. Never reads the tickets. |
|
|
202
|
+
| `flow-scout` | Read, Glob, Grep, Bash (no Edit, no Write), Haiku | Reads the code ahead of a planner, builder, reviewer or consultant and reports what it found. Decides nothing. |
|
|
203
|
+
| `flow-web` | WebSearch, WebFetch, Haiku | Looks up outside facts for the planner or a brainstorm, with sources. |
|
|
204
|
+
| `flow-architect`, `flow-designer`, `flow-po` | Read, Glob, Grep, Bash (no Edit, no Write) | Answer one technical, UI or product question a builder, reviewer or planner asked, or (`flow-po`) rule on a disputed acceptance test. |
|
|
205
|
+
| `flow-skeptic` | Read, Glob, Grep, Bash (no Edit, no Write) | Attacks each option a brainstorm drafted: one objection and one hidden cost each. |
|
|
206
|
+
| `flow-lens` | Read, Glob, Grep, Bash (no Edit, no Write) | Looks at a brainstorm's options through one lens (`positive`, `researcher`, `open-minded`, `artistic`, `ux`, `security`) and reports what it sees. |
|
|
180
207
|
|
|
181
|
-
**Read only roles.** The reviewers, the consultants (`flow-architect`, `flow-designer`, `flow-po`) and `flow-scout` have no Edit or Write tool, and in Claude Code a `PreToolUse` hook in their role file blocks shell commands that change files or the repository: git commands that write (`commit`, `add`, `stash`, `checkout`, `reset` and the like), `sed -i`, `rm`, `mv`, `cp`, `touch`, `tee` and output redirected into a file other than `/dev/null` or `/tmp/`. The hook reads the command's text, so a program that writes files itself (a test runner updating snapshots, a script) still gets through, and Claude Code ignores hooks in a plugin's agents. A Codex subagent cannot be limited at all: Codex gives every child its parent's sandbox. So the conductor is the backstop everywhere: when a reviewer or consultant leaves a tracked file changed, it saves the change as `.feature-flow/state/edit-<feature>-<NN>.patch`, puts the files back, throws that answer away and hands the same review to a fresh reviewer, with a note saying why (`EDIT-UNDONE` in the log). A second edit in a row stops the run, and so does a commit, which it cannot undo safely. A planner's draft reaches `plans/` only through `plan-accept`. On Codex the planner can research the web only if web search is on; otherwise it plans from the code and says so. The Codex planning path has not been run by hand.
|
|
208
|
+
**Read only roles.** The reviewers, the consultants (`flow-architect`, `flow-designer`, `flow-po`), the brainstorm helpers (`flow-skeptic`, `flow-lens`) and `flow-scout` have no Edit or Write tool, and in Claude Code a `PreToolUse` hook in their role file blocks shell commands that change files or the repository: git commands that write (`commit`, `add`, `stash`, `checkout`, `reset` and the like), `sed -i`, `rm`, `mv`, `cp`, `touch`, `tee` and output redirected into a file other than `/dev/null` or `/tmp/`. The hook reads the command's text, so a program that writes files itself (a test runner updating snapshots, a script) still gets through, and Claude Code ignores hooks in a plugin's agents. A Codex subagent cannot be limited at all: Codex gives every child its parent's sandbox. So the conductor is the backstop everywhere: when a reviewer or consultant leaves a tracked file changed, it saves the change as `.feature-flow/state/edit-<feature>-<NN>.patch`, puts the files back, throws that answer away and hands the same review to a fresh reviewer, with a note saying why (`EDIT-UNDONE` in the log). A second edit in a row stops the run, and so does a commit, which it cannot undo safely. A planner's draft reaches `plans/` only through `plan-accept`. On Codex the planner can research the web only if web search is on; otherwise it plans from the code and says so. The Codex planning path has not been run by hand.
|
|
182
209
|
|
|
183
210
|
The guides in `guides/` (installed to `.feature-flow/guides/`) hold the protocol: how to build, review, write the brief, plan, review a plan and show. The skill holds only what differs per agent.
|
|
184
211
|
|
|
@@ -200,6 +227,19 @@ plans/
|
|
|
200
227
|
|
|
201
228
|
`commands.md` and `learnings.md` are separate from the map because they follow different rules. Commands are approved by a human and read by the scripts, so they are frozen. Learnings grow with every ticket, so they are append only and a human prunes them (`--check` warns past 40 lines). The map stays short.
|
|
202
229
|
|
|
230
|
+
The lines `commands.md` can hold ([template](guides/templates/commands.md)); delete the ones you do not need:
|
|
231
|
+
|
|
232
|
+
| Line | Needed | What reads it |
|
|
233
|
+
|---|---|---|
|
|
234
|
+
| `Build:`, `Test:`, `Lint:` | yes (`Test:` at least) | the gate, after every ticket |
|
|
235
|
+
| `Smoke:` | yes | run before every ticket; the run stops if it fails |
|
|
236
|
+
| `Quick:` | no | a fast subset of Test for the tickets in the middle of a plan |
|
|
237
|
+
| `Run:` | no | how to start what the feature builds |
|
|
238
|
+
| `Acceptance:` | no | turns on the [tester](#acceptance-tests-the-tester); runs only `plans/<feature>/acceptance/` |
|
|
239
|
+
| `Sensitive:` | no | paths that make any ticket touching them level 3 |
|
|
240
|
+
| `Shared:`, `Setup:` | no | for [lanes](#tickets-side-by-side-lanes): paths that keep a ticket alone, and what a fresh worktree needs |
|
|
241
|
+
| `Profile:` | no | `careful`, `normal` or `fast` for this plan ([profiles](#profiles)) |
|
|
242
|
+
|
|
203
243
|
One markdown file per ticket in `plans/<feature>/tasks/NN-slug.md`:
|
|
204
244
|
|
|
205
245
|
````
|
|
@@ -360,7 +400,11 @@ The long `python3 -I -c ...` line the skill uses to call the conductor stays as
|
|
|
360
400
|
|
|
361
401
|
When an idea is still fuzzy, the session can brainstorm it with you before it writes the brief: `/feature-flow <feature> brainstorm`, always in `careful`, and offered on its own when there is no bar yet or there are two real ways to build it. It asks you up to three questions, one at a time, sends a scout to see how the code does the nearest thing today, then lays out two or three options, each with a mermaid diagram, its pros and cons, its size and its risky areas, and recommends one. Your pick and the brief share one yes.
|
|
362
402
|
|
|
363
|
-
|
|
403
|
+
Read only helpers work for the session during a brainstorm: a code scout, a web scout, the architect, designer and product owner, `flow-skeptic`, who attacks each finished option so the session that wrote the options is not the one that judges them, and `flow-lens`, who looks at the options through one lens the session picks for the idea: `positive`, `researcher`, `open-minded`, `artistic`, `ux` or `security` ([guides/lenses/](guides/lenses/)). Each gets its prompt from `brainstorm-prompt <helper> <question file>`, which counts them: `normal` allows 2 scouts, 1 web, 2 consultants, 1 skeptic and 2 lenses per brainstorm, `careful` 3, 2, 3, 1 and 3, and `FLOW_SCOUTS=off` no scouts. Helpers never write the brainstorm and never ask you anything; the session does both.
|
|
404
|
+
|
|
405
|
+
Before you pick, the session shows the brainstorm as a review page: `feature-flow brainstorm-page <feature>` (or `flow-status.py <feature> --brainstorm-page`) writes it beside the brainstorm as one HTML file. It has a sidebar that routes between the sections and shows how far you read, a system, light or dark switch, flowchart diagrams you can edit (drag, add boxes of seven kinds, colour them from 12 colours, rename and delete them, connect them with arrows, undo and redo, with the keyboard too), reset, and copy back as mermaid (the edited diagram once you change it; edits are kept only in that browser), and an arrow animation that stays off until you turn it on. Its look is a style from [guides/styles/](guides/styles/): `route` (the default) or `blueprint`, picked with `--style`, the brainstorm's `Style:` line or `FLOW_STYLE`. A style is one CSS file of colour and font tokens, so adding one is adding a file. `--fragment` leaves out the html and body tags, for publishing the page as an artifact.
|
|
406
|
+
|
|
407
|
+
**The live page (Claude only).** When the session can publish artifacts, it publishes the page live instead (`--live <folder>` writes `index.html` and a `state.json` beside it). Everyone you share it with (a claude.ai sign-in and edit access, no Claude Code needed) can save their own version of each diagram, pick between the original and anyone's version, turn on **Compare with original** to see added, removed and renamed boxes and arrows marked, ask Claude in the page to change a diagram (it uses that person's own Claude), and send the session questions from **Talk to Claude**. A save wakes the session: it reads the page's `state.json`, lists the open asks (`--asks`), answers each one (`--answer`), puts a version into the brainstorm when asked (`--apply <folder> <figure> <version>`), and publishes the next round to the same link. `/feature-flow <feature> brainstorm sketch` starts from your own drawing: the page opens with a small sketch of the idea, you draw yours and send it, and the options build on it. Without an Artifact tool (or on Codex) you get the plain page.
|
|
364
408
|
|
|
365
409
|
The result is `brainstorm.md` ([template](guides/templates/brainstorm.md)), committed with the plan. The planner follows its chosen option and copies its diagram into `spec.md`, the plan reviewer fails a plan that builds a rejected option or leaves a risky area below level 3, and a re-plan keeps the choice. It is skipped in `fast`, for an import, and with `auto`; with `agent`, the driving agent picks, the file says `Picked by: agent`, and the eval records it.
|
|
366
410
|
|
|
@@ -453,7 +497,8 @@ The run also stops on its own after a number of phases (`BUILD` and `REVIEW` han
|
|
|
453
497
|
|
|
454
498
|
| Path | Tested |
|
|
455
499
|
|---|---|
|
|
456
|
-
|
|
|
500
|
+
| Real repos | Used by its author on several repos besides its own. In a field run on a separate application repo (two features), all 7 issues the reviews caught were confirmed real. That run shaped 0.19.0 to 0.23.0: read only reviewers, agent-driven runs, follow-ups, batches, and the single level 3 review (the 19 separate spec reviews it ran caught nothing the quality review missed). |
|
|
501
|
+
| Claude Code | The offline suite, and **one real run of the bar** on the demo project: the two-ticket demo in two `/feature-flow hello auto` sessions with one `HANDOFF` between them, each ticket built by a builder subagent and passed by a reviewer subagent, with all 16 acceptance checks ok. It used about 23k output tokens and 2M cached input tokens on Sonnet. |
|
|
457
502
|
| Codex | The install, offline, in CI on Linux and macOS. A probe in the Codex app showed that subagents with separate contexts work and that a reviewer's verdict reaches the session. The full flow is **not yet tested with a real run**. |
|
|
458
503
|
| Claude Code on the web | Documented, untested: commit `.claude/`, `scripts/` and `.feature-flow/` into the repo, because cloud sessions read only the repo's `.claude/`. |
|
|
459
504
|
| Copilot, Gemini CLI, Cursor | Not tested. Some read `.agents/skills`, so `--agent codex` may already work. |
|
|
@@ -488,7 +533,7 @@ feature-flow's layers are tripwires, not a security boundary. They catch acciden
|
|
|
488
533
|
- **The floor guard reads diffs with patterns.** It does not see a test made trivially true by other means (a mock that returns the expected answer, an `assert` on something that is always set, a test that no longer exercises the code), or an assertion weakened without being deleted. It does catch assertions that cannot fail (`trivial-assert`) and warns the reviewer when a test file loses assertions. A new test with no assertion at all is not caught. The red-first proof only covers tickets with `Test first: yes`.
|
|
489
534
|
- **A plan can be wrong and still pass.** The plan lint checks that every ticket has a way to be proven and that `commands.md` has a Test command. It cannot tell whether the plan builds the right thing; the second yes is yours.
|
|
490
535
|
- **The trust runner stops accidents, not the session.** It catches a builder editing the conductor mid-run. The session that runs it is the thing it cannot check; a hand-run `flow-trust.py` is unprotected (see above).
|
|
491
|
-
- **
|
|
536
|
+
- **Some paths are newer than the field runs.** The Codex skill and the Codex planner have not been run by hand, the plugin install and the brainstorm have not had a real run, and the Quick gate has only been run by tests. See [docs/field-run.md](docs/field-run.md) for how to try it on your own repo and what to send back.
|
|
492
537
|
- **One ticket at a time**, with a handoff to a new session every few tickets, unless you turn on lanes.
|
|
493
538
|
- **Lanes share one disk.** A builder in one lane can still write into another lane's folder or the main worktree. The conductor sees that as a dirty tree and stops, but only afterwards. Overlap of `Touches:` is judged from the patterns, so two tickets that could never meet may still run one after the other.
|
|
494
539
|
|
|
@@ -503,6 +548,8 @@ Earlier versions had seven skills and an unattended loop. The five flow skills a
|
|
|
503
548
|
|
|
504
549
|
The installer never deletes the old skill folders, but it names any it finds. Delete them from `.claude/skills/` or `.agents/skills/` yourself.
|
|
505
550
|
|
|
551
|
+
**Between versions, upgrade between features, not in the middle of a run.** The skill pins the sha256 of `scripts/flow-trust.py`, so a session started with the old skill stops with `flow-trust.py does not match this skill` once the new runner is installed. Finish the feature (or reach a `HANDOFF`), install the new version, commit it, and start the next session. Plans keep working across versions: a ticket with no `Level:` line keeps the pre-0.9.0 review rules, a plan with no `Touches:` lines runs one ticket at a time, and a plan with no `Acceptance:` line runs without a tester. [docs/releases.md](docs/releases.md) lists what changed in each version.
|
|
552
|
+
|
|
506
553
|
## Releasing to PyPI
|
|
507
554
|
|
|
508
555
|
The package is [`feature-flow-cli`](https://pypi.org/project/feature-flow-cli/) (the shorter `feature-flow` is likely refused by PyPI as too close to the existing `featureflow`). Its version is `__version__` in `feature_flow/__init__.py`.
|
|
@@ -6,10 +6,25 @@
|
|
|
6
6
|
|
|
7
7
|
Plan a feature as a graph of small tickets, then build them in the session you are already in. One command, `/feature-flow`, does both. Every ticket is built by one fresh subagent and checked by another that never saw the builder's reasoning. A script, not the agent, decides the order of the steps, runs the build and tests, and watches for work that weakens the checks, and the whole run has limits.
|
|
8
8
|
|
|
9
|
-
One skill,
|
|
9
|
+
One skill, 12 agent roles, a Python conductor, 6 Python scripts (`flow`, `flow-trust`, `flow-status`, `flow-view`, `gate`, `floor-guard`), an installer for both agents, a Claude Code plugin, a PyPI package, a demo and a test suite. All of it is Python (standard library only), so it runs on Linux, macOS and Windows. MIT licensed.
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
### At a glance
|
|
12
|
+
|
|
13
|
+
| | What you get |
|
|
14
|
+
|---|---|
|
|
15
|
+
| **Plan** | A brief you approve, a fresh planner and a fresh plan reviewer, a second yes before anything is written. An optional [brainstorm](#brainstorm-before-planning) first, shown as a review page with diagrams you can edit, or an [import](#starting-from-spec-kit-or-openspec) from Spec Kit or OpenSpec. |
|
|
16
|
+
| **Build** | One fresh builder per ticket, then the [gate, floor guard, footprint, Done when and test-first checks](#how-a-ticket-flows), all run by the script. |
|
|
17
|
+
| **Review** | A fresh reviewer that never saw the builder's reasoning, as much as the ticket's [level](#how-a-ticket-flows) asks for, and [read only](#the-skill-and-the-roles) by hook and by the conductor. |
|
|
18
|
+
| **Prove** | [Acceptance tests](#acceptance-tests-the-tester) written from the spec by a tester before any code, which builders cannot touch. |
|
|
19
|
+
| **Go faster** | [Lanes](#tickets-side-by-side-lanes) build disjoint tickets side by side, the [fast path](#the-fast-path) batches small tickets and reviews the feature once, a [time budget](#a-time-budget) switches to fast mode by itself, and [profiles](#profiles) set all of it with one word. |
|
|
20
|
+
| **Ask, don't guess** | [Scouts](#scouts) read ahead for every role, and [questions](#questions-for-the-architect-designer-or-product-owner) go to an architect, designer or product owner agent before they come to you. |
|
|
21
|
+
| **Measure** | [`feature-flow eval`](#recording-a-run-eval) records what a run cost and what each check caught, and `feature-flow report` shows the log. |
|
|
22
|
+
|
|
23
|
+
[docs/releases.md](docs/releases.md) lists what each release added.
|
|
24
|
+
|
|
25
|
+
- [Quick start](#quick-start) · [How a ticket flows](#how-a-ticket-flows) · [The skill and the roles](#the-skill-and-the-roles) · [Plans and tickets](#plans-and-tickets) · [See the graph](#see-the-graph)
|
|
26
|
+
- [Lanes](#tickets-side-by-side-lanes) · [Scouts](#scouts) · [Questions](#questions-for-the-architect-designer-or-product-owner) · [Acceptance tests](#acceptance-tests-the-tester) · [Fast path](#the-fast-path) · [Time budget](#a-time-budget) · [Eval](#recording-a-run-eval) · [Profiles](#profiles) · [Brainstorm](#brainstorm-before-planning) · [Import](#starting-from-spec-kit-or-openspec)
|
|
27
|
+
- [Long features and handoff](#long-features-and-handoff) · [Commands and settings](#commands-and-settings) · [What is tested](#what-is-tested) · [Limits](#limits) · [Upgrading](#upgrading) · [Caution](#caution)
|
|
13
28
|
|
|
14
29
|
## Quick start
|
|
15
30
|
|
|
@@ -41,7 +56,7 @@ Without a clone, the same installer runs from [PyPI](https://pypi.org/project/fe
|
|
|
41
56
|
uvx feature-flow-cli install /path/to/your/repo --agent all # or: pipx run feature-flow-cli install ...
|
|
42
57
|
```
|
|
43
58
|
|
|
44
|
-
The package puts a `feature-flow` command on your PATH with `install`, `uninstall`, `status <feature>`, `view <feature>`, `reset <feature>`, `report <feature>` and `
|
|
59
|
+
The package puts a `feature-flow` command on your PATH with `install`, `uninstall`, `status <feature>`, `view <feature>`, `reset <feature>`, `report <feature>`, `eval <feature>`, `import <folder> <feature>` and `brainstorm-page <feature>`. It installs the same files, byte for byte, as `install.py` from a clone.
|
|
45
60
|
|
|
46
61
|
The installer lists what it wrote in `.feature-flow/installed.txt`, with each file's hash in `.feature-flow/installed.sha256`. Commit those files (`git add --pathspec-from-file=.feature-flow/installed.txt`); until you do, the flow does not count them as uncommitted changes. Installing a newer version over an older one updates every file nobody edited since it was installed, and keeps (and names) the ones you changed; `--force` replaces those too.
|
|
47
62
|
|
|
@@ -58,6 +73,10 @@ Then, in your repo, in the agent:
|
|
|
58
73
|
| Build its tickets (a plan exists) | `/feature-flow csv-export` | `$feature-flow csv-export` |
|
|
59
74
|
| The same, asking nothing | `/feature-flow csv-export auto` | `$feature-flow csv-export auto` |
|
|
60
75
|
| Watch the graph, animated | `/feature-flow csv-export show` | `$feature-flow csv-export show` |
|
|
76
|
+
| Weigh ways to build it first | `/feature-flow csv-export brainstorm` | `$feature-flow csv-export brainstorm` |
|
|
77
|
+
| Small, low-risk feature: one review at the end | `/feature-flow csv-export fast` | `$feature-flow csv-export fast` |
|
|
78
|
+
| Costly to get wrong: full gate, own review per ticket | `/feature-flow csv-export careful` | `$feature-flow csv-export careful` |
|
|
79
|
+
| Another agent drives the session, no handoffs | `/feature-flow csv-export agent` | `$feature-flow csv-export agent` |
|
|
61
80
|
|
|
62
81
|
The same command plans when `plans/csv-export/` does not exist yet and builds when it does. After your second yes it commits the new plan folder, and only that folder, then goes straight on to building it; say so if you want it to stop after planning.
|
|
63
82
|
|
|
@@ -105,6 +124,9 @@ The Claude Code skill is `skills/feature-flow/`. The Codex skill is written by h
|
|
|
105
124
|
plan touched beyond own Status + Answer + appended lines? │
|
|
106
125
|
│ clean │
|
|
107
126
|
▼ │
|
|
127
|
+
footprint (script): only the paths on the ticket's Touches: fail ─┤
|
|
128
|
+
│ pass │
|
|
129
|
+
▼ │
|
|
108
130
|
Done when checks (script): runs every ```check block fail ─┤
|
|
109
131
|
test-first check (script): Test first: yes needs a test-only │
|
|
110
132
|
commit that failed Test before the code fail ─┤
|
|
@@ -153,13 +175,18 @@ The gate does not depend on the level: it still runs Quick mid-plan and the full
|
|
|
153
175
|
|
|
154
176
|
| Role | Tools | Job |
|
|
155
177
|
|---|---|---|
|
|
156
|
-
| `ticket-builder` | Read, Glob, Grep, Edit, Write, Bash | Builds one ticket by the build guide in its prompt. |
|
|
157
|
-
| `ticket-reviewer` | Read, Glob, Grep, Bash (no Edit, no Write) | Reviews one ticket by the review guide in its prompt and ends with `REVIEW: PASS` or `REVIEW:
|
|
158
|
-
| `feature-planner` | Read, Glob, Grep, Bash, Write,
|
|
178
|
+
| `ticket-builder` | Read, Glob, Grep, Edit, Write, Bash | Builds one ticket (or, in fast mode, a batch of small ones) by the build guide in its prompt. |
|
|
179
|
+
| `ticket-reviewer` | Read, Glob, Grep, Bash (no Edit, no Write) | Reviews one ticket, or the whole feature on the fast path, by the review guide in its prompt and ends with `REVIEW: PASS`, `REVIEW: FAIL` or `REVIEW: ASK <role>`. |
|
|
180
|
+
| `feature-planner` | Read, Glob, Grep, Bash, Write, WebSearch, WebFetch | Plans one feature from the approved brief by the plan guide, writes only the draft, cites outside sources, and ends with `PLAN: READY` or `PLAN: QUESTIONS`. Also folds open tickets on a re-plan. |
|
|
159
181
|
| `plan-reviewer` | Read, Glob, Grep, Bash (no Edit, no Write) | Checks the draft against the brief by the plan review guide and ends with `PLAN-REVIEW: PASS` or `PLAN-REVIEW: FAIL`. |
|
|
160
182
|
| `flow-tester` | Read, Glob, Grep, Edit, Write, Bash | Writes the feature's acceptance tests from `spec.md` alone, before the build, by the test guide. Never reads the tickets. |
|
|
183
|
+
| `flow-scout` | Read, Glob, Grep, Bash (no Edit, no Write), Haiku | Reads the code ahead of a planner, builder, reviewer or consultant and reports what it found. Decides nothing. |
|
|
184
|
+
| `flow-web` | WebSearch, WebFetch, Haiku | Looks up outside facts for the planner or a brainstorm, with sources. |
|
|
185
|
+
| `flow-architect`, `flow-designer`, `flow-po` | Read, Glob, Grep, Bash (no Edit, no Write) | Answer one technical, UI or product question a builder, reviewer or planner asked, or (`flow-po`) rule on a disputed acceptance test. |
|
|
186
|
+
| `flow-skeptic` | Read, Glob, Grep, Bash (no Edit, no Write) | Attacks each option a brainstorm drafted: one objection and one hidden cost each. |
|
|
187
|
+
| `flow-lens` | Read, Glob, Grep, Bash (no Edit, no Write) | Looks at a brainstorm's options through one lens (`positive`, `researcher`, `open-minded`, `artistic`, `ux`, `security`) and reports what it sees. |
|
|
161
188
|
|
|
162
|
-
**Read only roles.** The reviewers, the consultants (`flow-architect`, `flow-designer`, `flow-po`) and `flow-scout` have no Edit or Write tool, and in Claude Code a `PreToolUse` hook in their role file blocks shell commands that change files or the repository: git commands that write (`commit`, `add`, `stash`, `checkout`, `reset` and the like), `sed -i`, `rm`, `mv`, `cp`, `touch`, `tee` and output redirected into a file other than `/dev/null` or `/tmp/`. The hook reads the command's text, so a program that writes files itself (a test runner updating snapshots, a script) still gets through, and Claude Code ignores hooks in a plugin's agents. A Codex subagent cannot be limited at all: Codex gives every child its parent's sandbox. So the conductor is the backstop everywhere: when a reviewer or consultant leaves a tracked file changed, it saves the change as `.feature-flow/state/edit-<feature>-<NN>.patch`, puts the files back, throws that answer away and hands the same review to a fresh reviewer, with a note saying why (`EDIT-UNDONE` in the log). A second edit in a row stops the run, and so does a commit, which it cannot undo safely. A planner's draft reaches `plans/` only through `plan-accept`. On Codex the planner can research the web only if web search is on; otherwise it plans from the code and says so. The Codex planning path has not been run by hand.
|
|
189
|
+
**Read only roles.** The reviewers, the consultants (`flow-architect`, `flow-designer`, `flow-po`), the brainstorm helpers (`flow-skeptic`, `flow-lens`) and `flow-scout` have no Edit or Write tool, and in Claude Code a `PreToolUse` hook in their role file blocks shell commands that change files or the repository: git commands that write (`commit`, `add`, `stash`, `checkout`, `reset` and the like), `sed -i`, `rm`, `mv`, `cp`, `touch`, `tee` and output redirected into a file other than `/dev/null` or `/tmp/`. The hook reads the command's text, so a program that writes files itself (a test runner updating snapshots, a script) still gets through, and Claude Code ignores hooks in a plugin's agents. A Codex subagent cannot be limited at all: Codex gives every child its parent's sandbox. So the conductor is the backstop everywhere: when a reviewer or consultant leaves a tracked file changed, it saves the change as `.feature-flow/state/edit-<feature>-<NN>.patch`, puts the files back, throws that answer away and hands the same review to a fresh reviewer, with a note saying why (`EDIT-UNDONE` in the log). A second edit in a row stops the run, and so does a commit, which it cannot undo safely. A planner's draft reaches `plans/` only through `plan-accept`. On Codex the planner can research the web only if web search is on; otherwise it plans from the code and says so. The Codex planning path has not been run by hand.
|
|
163
190
|
|
|
164
191
|
The guides in `guides/` (installed to `.feature-flow/guides/`) hold the protocol: how to build, review, write the brief, plan, review a plan and show. The skill holds only what differs per agent.
|
|
165
192
|
|
|
@@ -181,6 +208,19 @@ plans/
|
|
|
181
208
|
|
|
182
209
|
`commands.md` and `learnings.md` are separate from the map because they follow different rules. Commands are approved by a human and read by the scripts, so they are frozen. Learnings grow with every ticket, so they are append only and a human prunes them (`--check` warns past 40 lines). The map stays short.
|
|
183
210
|
|
|
211
|
+
The lines `commands.md` can hold ([template](guides/templates/commands.md)); delete the ones you do not need:
|
|
212
|
+
|
|
213
|
+
| Line | Needed | What reads it |
|
|
214
|
+
|---|---|---|
|
|
215
|
+
| `Build:`, `Test:`, `Lint:` | yes (`Test:` at least) | the gate, after every ticket |
|
|
216
|
+
| `Smoke:` | yes | run before every ticket; the run stops if it fails |
|
|
217
|
+
| `Quick:` | no | a fast subset of Test for the tickets in the middle of a plan |
|
|
218
|
+
| `Run:` | no | how to start what the feature builds |
|
|
219
|
+
| `Acceptance:` | no | turns on the [tester](#acceptance-tests-the-tester); runs only `plans/<feature>/acceptance/` |
|
|
220
|
+
| `Sensitive:` | no | paths that make any ticket touching them level 3 |
|
|
221
|
+
| `Shared:`, `Setup:` | no | for [lanes](#tickets-side-by-side-lanes): paths that keep a ticket alone, and what a fresh worktree needs |
|
|
222
|
+
| `Profile:` | no | `careful`, `normal` or `fast` for this plan ([profiles](#profiles)) |
|
|
223
|
+
|
|
184
224
|
One markdown file per ticket in `plans/<feature>/tasks/NN-slug.md`:
|
|
185
225
|
|
|
186
226
|
````
|
|
@@ -341,7 +381,11 @@ The long `python3 -I -c ...` line the skill uses to call the conductor stays as
|
|
|
341
381
|
|
|
342
382
|
When an idea is still fuzzy, the session can brainstorm it with you before it writes the brief: `/feature-flow <feature> brainstorm`, always in `careful`, and offered on its own when there is no bar yet or there are two real ways to build it. It asks you up to three questions, one at a time, sends a scout to see how the code does the nearest thing today, then lays out two or three options, each with a mermaid diagram, its pros and cons, its size and its risky areas, and recommends one. Your pick and the brief share one yes.
|
|
343
383
|
|
|
344
|
-
|
|
384
|
+
Read only helpers work for the session during a brainstorm: a code scout, a web scout, the architect, designer and product owner, `flow-skeptic`, who attacks each finished option so the session that wrote the options is not the one that judges them, and `flow-lens`, who looks at the options through one lens the session picks for the idea: `positive`, `researcher`, `open-minded`, `artistic`, `ux` or `security` ([guides/lenses/](guides/lenses/)). Each gets its prompt from `brainstorm-prompt <helper> <question file>`, which counts them: `normal` allows 2 scouts, 1 web, 2 consultants, 1 skeptic and 2 lenses per brainstorm, `careful` 3, 2, 3, 1 and 3, and `FLOW_SCOUTS=off` no scouts. Helpers never write the brainstorm and never ask you anything; the session does both.
|
|
385
|
+
|
|
386
|
+
Before you pick, the session shows the brainstorm as a review page: `feature-flow brainstorm-page <feature>` (or `flow-status.py <feature> --brainstorm-page`) writes it beside the brainstorm as one HTML file. It has a sidebar that routes between the sections and shows how far you read, a system, light or dark switch, flowchart diagrams you can edit (drag, add boxes of seven kinds, colour them from 12 colours, rename and delete them, connect them with arrows, undo and redo, with the keyboard too), reset, and copy back as mermaid (the edited diagram once you change it; edits are kept only in that browser), and an arrow animation that stays off until you turn it on. Its look is a style from [guides/styles/](guides/styles/): `route` (the default) or `blueprint`, picked with `--style`, the brainstorm's `Style:` line or `FLOW_STYLE`. A style is one CSS file of colour and font tokens, so adding one is adding a file. `--fragment` leaves out the html and body tags, for publishing the page as an artifact.
|
|
387
|
+
|
|
388
|
+
**The live page (Claude only).** When the session can publish artifacts, it publishes the page live instead (`--live <folder>` writes `index.html` and a `state.json` beside it). Everyone you share it with (a claude.ai sign-in and edit access, no Claude Code needed) can save their own version of each diagram, pick between the original and anyone's version, turn on **Compare with original** to see added, removed and renamed boxes and arrows marked, ask Claude in the page to change a diagram (it uses that person's own Claude), and send the session questions from **Talk to Claude**. A save wakes the session: it reads the page's `state.json`, lists the open asks (`--asks`), answers each one (`--answer`), puts a version into the brainstorm when asked (`--apply <folder> <figure> <version>`), and publishes the next round to the same link. `/feature-flow <feature> brainstorm sketch` starts from your own drawing: the page opens with a small sketch of the idea, you draw yours and send it, and the options build on it. Without an Artifact tool (or on Codex) you get the plain page.
|
|
345
389
|
|
|
346
390
|
The result is `brainstorm.md` ([template](guides/templates/brainstorm.md)), committed with the plan. The planner follows its chosen option and copies its diagram into `spec.md`, the plan reviewer fails a plan that builds a rejected option or leaves a risky area below level 3, and a re-plan keeps the choice. It is skipped in `fast`, for an import, and with `auto`; with `agent`, the driving agent picks, the file says `Picked by: agent`, and the eval records it.
|
|
347
391
|
|
|
@@ -434,7 +478,8 @@ The run also stops on its own after a number of phases (`BUILD` and `REVIEW` han
|
|
|
434
478
|
|
|
435
479
|
| Path | Tested |
|
|
436
480
|
|---|---|
|
|
437
|
-
|
|
|
481
|
+
| Real repos | Used by its author on several repos besides its own. In a field run on a separate application repo (two features), all 7 issues the reviews caught were confirmed real. That run shaped 0.19.0 to 0.23.0: read only reviewers, agent-driven runs, follow-ups, batches, and the single level 3 review (the 19 separate spec reviews it ran caught nothing the quality review missed). |
|
|
482
|
+
| Claude Code | The offline suite, and **one real run of the bar** on the demo project: the two-ticket demo in two `/feature-flow hello auto` sessions with one `HANDOFF` between them, each ticket built by a builder subagent and passed by a reviewer subagent, with all 16 acceptance checks ok. It used about 23k output tokens and 2M cached input tokens on Sonnet. |
|
|
438
483
|
| Codex | The install, offline, in CI on Linux and macOS. A probe in the Codex app showed that subagents with separate contexts work and that a reviewer's verdict reaches the session. The full flow is **not yet tested with a real run**. |
|
|
439
484
|
| Claude Code on the web | Documented, untested: commit `.claude/`, `scripts/` and `.feature-flow/` into the repo, because cloud sessions read only the repo's `.claude/`. |
|
|
440
485
|
| Copilot, Gemini CLI, Cursor | Not tested. Some read `.agents/skills`, so `--agent codex` may already work. |
|
|
@@ -469,7 +514,7 @@ feature-flow's layers are tripwires, not a security boundary. They catch acciden
|
|
|
469
514
|
- **The floor guard reads diffs with patterns.** It does not see a test made trivially true by other means (a mock that returns the expected answer, an `assert` on something that is always set, a test that no longer exercises the code), or an assertion weakened without being deleted. It does catch assertions that cannot fail (`trivial-assert`) and warns the reviewer when a test file loses assertions. A new test with no assertion at all is not caught. The red-first proof only covers tickets with `Test first: yes`.
|
|
470
515
|
- **A plan can be wrong and still pass.** The plan lint checks that every ticket has a way to be proven and that `commands.md` has a Test command. It cannot tell whether the plan builds the right thing; the second yes is yours.
|
|
471
516
|
- **The trust runner stops accidents, not the session.** It catches a builder editing the conductor mid-run. The session that runs it is the thing it cannot check; a hand-run `flow-trust.py` is unprotected (see above).
|
|
472
|
-
- **
|
|
517
|
+
- **Some paths are newer than the field runs.** The Codex skill and the Codex planner have not been run by hand, the plugin install and the brainstorm have not had a real run, and the Quick gate has only been run by tests. See [docs/field-run.md](docs/field-run.md) for how to try it on your own repo and what to send back.
|
|
473
518
|
- **One ticket at a time**, with a handoff to a new session every few tickets, unless you turn on lanes.
|
|
474
519
|
- **Lanes share one disk.** A builder in one lane can still write into another lane's folder or the main worktree. The conductor sees that as a dirty tree and stops, but only afterwards. Overlap of `Touches:` is judged from the patterns, so two tickets that could never meet may still run one after the other.
|
|
475
520
|
|
|
@@ -484,6 +529,8 @@ Earlier versions had seven skills and an unattended loop. The five flow skills a
|
|
|
484
529
|
|
|
485
530
|
The installer never deletes the old skill folders, but it names any it finds. Delete them from `.claude/skills/` or `.agents/skills/` yourself.
|
|
486
531
|
|
|
532
|
+
**Between versions, upgrade between features, not in the middle of a run.** The skill pins the sha256 of `scripts/flow-trust.py`, so a session started with the old skill stops with `flow-trust.py does not match this skill` once the new runner is installed. Finish the feature (or reach a `HANDOFF`), install the new version, commit it, and start the next session. Plans keep working across versions: a ticket with no `Level:` line keeps the pre-0.9.0 review rules, a plan with no `Touches:` lines runs one ticket at a time, and a plan with no `Acceptance:` line runs without a tester. [docs/releases.md](docs/releases.md) lists what changed in each version.
|
|
533
|
+
|
|
487
534
|
## Releasing to PyPI
|
|
488
535
|
|
|
489
536
|
The package is [`feature-flow-cli`](https://pypi.org/project/feature-flow-cli/) (the shorter `feature-flow` is likely refused by PyPI as too close to the existing `featureflow`). Its version is `__version__` in `feature_flow/__init__.py`.
|
|
@@ -15,15 +15,15 @@ The conductor is `python3 scripts/flow.py <feature> <command>`. If `scripts/flow
|
|
|
15
15
|
|
|
16
16
|
Every conductor command (`start`, `next`, `prompt`, `verdict`, `fast`, `scouts`, `scout-prompt`, `reset`, `plan-prompt`, `plan-review-prompt`, `plan-accept`, `plan-scouts`, `plan-scout-prompt`, `consult-prompt`, `brainstorm-prompt`, `budget`, `replan-prompt`) runs through `flow-trust.py`, never `flow.py` itself. `<S>` below is the folder of the `flow.py` picked above: `scripts` for the repo's own install, else `"${FEATURE_FLOW_HOME:-$HOME/.feature-flow}/scripts"`. `flow-trust.py` is started by this loader line, which checks the file against the sha256 pinned here and runs those same bytes. Copy it exactly, replacing only `<S>`:
|
|
17
17
|
|
|
18
|
-
python3 -I -c "import hashlib,sys;b=open(sys.argv[1],'rb').read().replace(b'\r\n',b'\n');sys.exit(exec(compile(b,'flow-trust','exec')) if hashlib.sha256(b).hexdigest()==sys.argv[2] else 'flow-trust.py does not match this skill')" <S>/flow-trust.py
|
|
18
|
+
python3 -I -c "import hashlib,sys;b=open(sys.argv[1],'rb').read().replace(b'\r\n',b'\n');sys.exit(exec(compile(b,'flow-trust','exec')) if hashlib.sha256(b).hexdigest()==sys.argv[2] else 'flow-trust.py does not match this skill')" <S>/flow-trust.py 9532117f7d6cb0fff2b8d9886de79f727641bc02399e8922a67346bdc229c04b
|
|
19
19
|
|
|
20
20
|
A full conductor command, here `next` (any other command and its arguments go where `next` is):
|
|
21
21
|
|
|
22
|
-
FLOW_TRUST=<digest> FLOW_SESSION=<token> FLOW_INVOKE='$feature-flow' python3 -I -c "import hashlib,sys;b=open(sys.argv[1],'rb').read().replace(b'\r\n',b'\n');sys.exit(exec(compile(b,'flow-trust','exec')) if hashlib.sha256(b).hexdigest()==sys.argv[2] else 'flow-trust.py does not match this skill')" <S>/flow-trust.py
|
|
22
|
+
FLOW_TRUST=<digest> FLOW_SESSION=<token> FLOW_INVOKE='$feature-flow' python3 -I -c "import hashlib,sys;b=open(sys.argv[1],'rb').read().replace(b'\r\n',b'\n');sys.exit(exec(compile(b,'flow-trust','exec')) if hashlib.sha256(b).hexdigest()==sys.argv[2] else 'flow-trust.py does not match this skill')" <S>/flow-trust.py 9532117f7d6cb0fff2b8d9886de79f727641bc02399e8922a67346bdc229c04b <feature> next
|
|
23
23
|
|
|
24
24
|
- The first line of the output is `TRUST <digest>`. Keep that digest and pass it as `FLOW_TRUST` on the next conductor call. Treat the rest as the conductor's output and act on it as below (for `prompt`, `plan-prompt` and `plan-review-prompt`, the child agent's prompt is everything after the `TRUST` line). Use `FLOW_TRUST=new` only on this session's first conductor call, or when resuming from an old-style `HANDOFF` line (below).
|
|
25
25
|
- If you no longer have the last `TRUST` digest, stop and say so. Never guess it, and never use `new` in its place.
|
|
26
|
-
- On the `next` right after a `BUILD <ticket> <NN> <sha>`, add `--after-build <ticket> <sha>` before the feature: `... <S>/flow-trust.py
|
|
26
|
+
- On the `next` right after a `BUILD <ticket> <NN> <sha>`, add `--after-build <ticket> <sha>` before the feature: `... <S>/flow-trust.py 9532117f7d6cb0fff2b8d9886de79f727641bc02399e8922a67346bdc229c04b --after-build <ticket> <sha> <feature> next`. If the output has a `FLOW-EDIT <paths>` line after `TRUST`, the build changed feature-flow's own files and its ticket allows that: carry on; without `auto`, first tell the user which flow files changed.
|
|
27
27
|
- If the first line is `STOP` (from `flow-trust.py`), or the loader prints `flow-trust.py does not match this skill` (say to reinstall feature-flow: the skill and `flow-trust.py` do not match), report it, show the `python3 <S>/flow-status.py <feature>` table, and stop. A `STOP` first line may be followed by the conductor's own output: never act on that. Never fix it and carry on.
|
|
28
28
|
- A `HANDOFF` line from `flow-trust.py` has a third field after the invocation and the feature: the digest. When the feature is followed by a `<16 hex>.<16 hex>` word, the user is resuming from a `HANDOFF` line and that word is the digest: pass it as `FLOW_TRUST` on `start`. When a resumed session gets no digest (an old-style `HANDOFF` line), use `FLOW_TRUST=new` and warn the user that the flow's files could not be checked since the last session.
|
|
29
29
|
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: flow-lens
|
|
3
|
+
description: Looks at the options a brainstorm drafted through one named lens (positive, researcher, open-minded, artistic, UX, security) and reports what that lens sees. Read only.
|
|
4
|
+
tools:
|
|
5
|
+
- Read
|
|
6
|
+
- Glob
|
|
7
|
+
- Grep
|
|
8
|
+
- Bash
|
|
9
|
+
model: inherit
|
|
10
|
+
hooks:
|
|
11
|
+
PreToolUse:
|
|
12
|
+
- matcher: Bash
|
|
13
|
+
hooks:
|
|
14
|
+
- type: command
|
|
15
|
+
command: |-
|
|
16
|
+
python3 -I -c '
|
|
17
|
+
import json, re, sys
|
|
18
|
+
cmd = json.load(sys.stdin).get("tool_input", {}).get("command", "")
|
|
19
|
+
bare = re.sub(r"\x27[^\x27]*\x27|\"(?:\\.|[^\"\\])*\"", "\"\"", cmd)
|
|
20
|
+
at = r"(?:^|[;&|(`\n]|\$\()\s*(?:\w+=\S*\s+|sudo\s+|env\s+|command\s+|xargs\s+(?:-\S+\s+)*)*"
|
|
21
|
+
rules = (
|
|
22
|
+
(at + r"(?:rm|rmdir|mv|cp|touch|mkdir|ln|chmod|chown|truncate|dd|tee|install|patch|unlink|shred)\b", "it changes files"),
|
|
23
|
+
(r"\b(?:sed|perl|ruby)\b[^;&|\n]*\s(?:-[a-zA-Z]*i|--in-place)", "it edits a file in place"),
|
|
24
|
+
(r"\s-(?:delete|exec\s+(?:rm|mv|cp|sed))\b", "it changes files"),
|
|
25
|
+
(r"\bgit(?:\s+-[Cc]\s+\S+|\s+--?[\w-]+(?:=\S+)?)*\s+(?:add|am|apply|checkout|cherry-pick|clean|clone|commit|config|fetch|gc|init|merge|mv|notes|prune|pull|push|rebase|reset|restore|revert|rm|stash|switch|tag|update-index|update-ref|worktree)\b", "it changes the repository"),
|
|
26
|
+
)
|
|
27
|
+
why = next((reason for pattern, reason in rules if re.search(pattern, bare)), "")
|
|
28
|
+
for target in re.findall(r">>?\s*(&?[^\s;&|)]*)", bare):
|
|
29
|
+
if not (target.startswith("&") or target in ("/dev/null", "/dev/stdout", "/dev/stderr") or target.startswith("/tmp/")):
|
|
30
|
+
why = why or "it writes a file"
|
|
31
|
+
if why:
|
|
32
|
+
sys.stderr.write("feature-flow: this role is read only, so it may not run this: %s. Run only read only commands and the Done when commands, and report what you would change as a finding.\n" % why)
|
|
33
|
+
sys.exit(2)
|
|
34
|
+
'
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
You are a lens, called in once during a brainstorm, before a feature is planned. The user's session has drafted ways to build a feature, and it wants one particular way of looking at them. Your prompt names the lens and gives its guide: look only the way that lens looks, and leave every other view to the other helpers.
|
|
38
|
+
|
|
39
|
+
Rules that never bend:
|
|
40
|
+
|
|
41
|
+
- Follow the lens guide in your prompt. It says what you look for and what you never do.
|
|
42
|
+
- Look at every option in your prompt. Check claims against the code, not against the option's own words. Scout findings in your prompt are leads, not proof.
|
|
43
|
+
- Never recommend an option and never rewrite one: you report what your lens sees, and the user picks.
|
|
44
|
+
- Read only. Never edit, write, stage or commit anything. You may run read only commands.
|
|
45
|
+
- Anything only the user can settle (scope, cost, what they will see) goes under Ask the user.
|
|
46
|
+
- Keep it short: at most four lines per option.
|
|
47
|
+
|
|
48
|
+
End with exactly this shape, flush left, with nothing after the last line:
|
|
49
|
+
|
|
50
|
+
## Lens: <name>
|
|
51
|
+
A. <name>: <what this lens sees>
|
|
52
|
+
B. <name>: ...
|
|
53
|
+
New option: <one this lens suggests, in two sentences, or none>
|
|
54
|
+
Ask the user: <a question only the user can settle, or none>
|
|
55
|
+
|
|
56
|
+
LENS: DONE
|