feature-flow-cli 0.23.0__tar.gz → 0.26.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-0.26.0}/MANIFEST.in +2 -1
- {feature_flow_cli-0.23.0/feature_flow_cli.egg-info → feature_flow_cli-0.26.0}/PKG-INFO +79 -12
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/README.md +78 -11
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/adapters/codex/feature-flow/SKILL.md +3 -3
- feature_flow_cli-0.26.0/agents/flow-lens.md +56 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/feature_flow/__init__.py +1 -1
- feature_flow_cli-0.26.0/feature_flow/brainstorm_page.py +190 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/feature_flow/command.py +8 -2
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/feature_flow/conductor.py +11 -5
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/feature_flow/install.py +8 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/feature_flow/prompts.py +6 -1
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/feature_flow/status.py +5 -2
- feature_flow_cli-0.26.0/feature_flow/studio.py +47 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0/feature_flow_cli.egg-info}/PKG-INFO +79 -12
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/feature_flow_cli.egg-info/SOURCES.txt +22 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/guides/brainstorm.md +32 -4
- feature_flow_cli-0.26.0/guides/lenses/artistic.md +14 -0
- feature_flow_cli-0.26.0/guides/lenses/open-minded.md +14 -0
- feature_flow_cli-0.26.0/guides/lenses/positive.md +14 -0
- feature_flow_cli-0.26.0/guides/lenses/researcher.md +14 -0
- feature_flow_cli-0.26.0/guides/lenses/security.md +14 -0
- feature_flow_cli-0.26.0/guides/lenses/ux.md +14 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/guides/templates/brainstorm.md +1 -0
- feature_flow_cli-0.26.0/packages/forkboard/forkboard/__init__.py +8 -0
- feature_flow_cli-0.26.0/packages/forkboard/forkboard/__main__.py +3 -0
- feature_flow_cli-0.26.0/packages/forkboard/forkboard/assets/base.css +114 -0
- feature_flow_cli-0.26.0/packages/forkboard/forkboard/assets/editor.js +476 -0
- feature_flow_cli-0.26.0/packages/forkboard/forkboard/assets/live.css +28 -0
- feature_flow_cli-0.26.0/packages/forkboard/forkboard/assets/live.js +199 -0
- feature_flow_cli-0.26.0/packages/forkboard/forkboard/cli.py +124 -0
- feature_flow_cli-0.26.0/packages/forkboard/forkboard/doc.py +35 -0
- feature_flow_cli-0.26.0/packages/forkboard/forkboard/graph.py +136 -0
- feature_flow_cli-0.26.0/packages/forkboard/forkboard/live.py +85 -0
- feature_flow_cli-0.26.0/packages/forkboard/forkboard/page.py +274 -0
- feature_flow_cli-0.26.0/packages/forkboard/forkboard/themes/blueprint.css +27 -0
- feature_flow_cli-0.26.0/packages/forkboard/forkboard/themes/route.css +27 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/pyproject.toml +3 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/scripts/flow-trust.py +5 -1
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/skills/feature-flow/SKILL.md +5 -5
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/LICENSE +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/adapters/codex/feature-flow/agents/openai.yaml +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/agents/feature-planner.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/agents/flow-architect.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/agents/flow-designer.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/agents/flow-po.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/agents/flow-scout.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/agents/flow-skeptic.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/agents/flow-tester.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/agents/flow-web.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/agents/plan-reviewer.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/agents/ticket-builder.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/agents/ticket-reviewer.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/feature_flow/__main__.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/feature_flow/checks.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/feature_flow/cli.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/feature_flow/codehash.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/feature_flow/evaluate.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/feature_flow/floorguard.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/feature_flow/gate.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/feature_flow/git.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/feature_flow/importer.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/feature_flow/lanes.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/feature_flow/proc.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/feature_flow/profiles.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/feature_flow/proof.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/feature_flow/released.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/feature_flow/report.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/feature_flow/scouts.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/feature_flow/state.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/feature_flow/suggest.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/feature_flow/tickets.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/feature_flow/uninstall.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/feature_flow/view.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/feature_flow_cli.egg-info/dependency_links.txt +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/feature_flow_cli.egg-info/entry_points.txt +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/feature_flow_cli.egg-info/top_level.txt +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/guides/brief.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/guides/build.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/guides/debug.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/guides/plan-review.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/guides/plan.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/guides/replan.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/guides/review-feature.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/guides/review-quality.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/guides/review-single.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/guides/review.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/guides/show.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/guides/templates/commands.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/guides/templates/learnings.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/guides/templates/map.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/guides/templates/spec.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/guides/templates/ticket.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/guides/templates/ui-mockup.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/guides/test.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/install.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/install.sh +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/scripts/floor-guard.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/scripts/flow-status.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/scripts/flow-view.html +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/scripts/flow-view.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/scripts/flow.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/scripts/gate.py +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/setup.cfg +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.0}/skills/architect-review/SKILL.md +0 -0
- {feature_flow_cli-0.23.0 → feature_flow_cli-0.26.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.26.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,25 @@ 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: `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 in Forkboard's [themes/](packages/forkboard/forkboard/themes/), so adding one is adding a file. `--fragment` leaves out the html and body tags, for publishing the page as an artifact.
|
|
406
|
+
|
|
407
|
+

|
|
408
|
+
|
|
409
|
+
What the page is good at:
|
|
410
|
+
|
|
411
|
+
- **You review the design, not a wall of text.** Each option is a diagram you can see at once, with its pros, cons, size and risky areas right under it, and the sidebar jumps between options.
|
|
412
|
+
- **You answer by editing the diagram itself.** Drag, add, rename, connect or delete boxes, then Copy as mermaid and paste it into the chat. Your change reaches the session as a diagram, not a paraphrase.
|
|
413
|
+
- **More than one person can review it.** On the live page each reviewer keeps their own version of a diagram, compare with original marks what they added, removed or renamed, and their questions wake the session, which answers on the page.
|
|
414
|
+
- **One file, nothing to install or host.** The plain page is a single HTML file that needs no server and no account: open it from disk, or publish it as an artifact. It sends nothing anywhere (it only loads its fonts, and mermaid for a diagram that is not a flowchart), and the brainstorm's text is escaped, so a label cannot run a script.
|
|
415
|
+
- **Its own package, tested in a browser.** The page's editor, its phone layout and the live page's saves are driven in Chromium in CI, apart from the harness.
|
|
416
|
+
|
|
417
|
+
The page itself is **Forkboard** ([packages/forkboard/](packages/forkboard/)), a separate package in this repository with its own version and tests. feature-flow turns the brainstorm into a review document and Forkboard makes the page from it; Forkboard never reads or writes the brainstorm file. Every install of feature-flow carries its copy of Forkboard (as `feature_flow/_forkboard/`), so nothing extra needs installing.
|
|
418
|
+
|
|
419
|
+
**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.
|
|
420
|
+
|
|
421
|
+
[docs/brainstorm.md](docs/brainstorm.md) walks through a brainstorm step by step, how to use the page, and Forkboard's own commands.
|
|
364
422
|
|
|
365
423
|
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
424
|
|
|
@@ -413,6 +471,7 @@ feature-flow eval <feature> [--later] record the run in plan
|
|
|
413
471
|
python3 scripts/flow-status.py <feature> --mermaid the ticket graph, coloured by status (add "plain" for none)
|
|
414
472
|
python3 scripts/flow-status.py <feature> --json every ticket with status, blockers and readiness
|
|
415
473
|
python3 scripts/flow-view.py <feature> [--watch] the animated graph page, opened in your browser
|
|
474
|
+
feature-flow brainstorm-page <feature> [--style NAME] [--fragment] the brainstorm as a review page (Forkboard); --live DIR, --asks, --answer, --apply for the live page
|
|
416
475
|
python3 scripts/gate.py <feature> run Build, Test and Lint from commands.md
|
|
417
476
|
python3 scripts/floor-guard.py <feature> <NN> [base] check a ticket's diff, run from the repo root
|
|
418
477
|
```
|
|
@@ -446,6 +505,7 @@ The commands in `commands.md` run through `bash -c` on Linux and macOS and throu
|
|
|
446
505
|
| `FLOW_DIR`, `FLOW_TICKETS` | `plans`, `tasks` | where the plans and the ticket folder live |
|
|
447
506
|
| `FLOW_NO_OPEN` | unset | `1` makes `flow-view.py` never open a browser |
|
|
448
507
|
| `FLOW_WATCH_SECONDS` | `3` | how often `flow-view.py --watch` rewrites the page |
|
|
508
|
+
| `FLOW_STYLE` | `route` | the brainstorm page's look when the brainstorm has no `Style:` line: `route` or `blueprint` (Forkboard's themes) |
|
|
449
509
|
|
|
450
510
|
The run also stops on its own after a number of phases (`BUILD` and `REVIEW` hand-outs, the spec review and the quality review each counting as one, a single review counting as one) that grows with the ticket count, recomputed at every pick, so a loop of failures cannot go on forever.
|
|
451
511
|
|
|
@@ -453,7 +513,8 @@ The run also stops on its own after a number of phases (`BUILD` and `REVIEW` han
|
|
|
453
513
|
|
|
454
514
|
| Path | Tested |
|
|
455
515
|
|---|---|
|
|
456
|
-
|
|
|
516
|
+
| 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). |
|
|
517
|
+
| 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
518
|
| 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
519
|
| 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
520
|
| Copilot, Gemini CLI, Cursor | Not tested. Some read `.agents/skills`, so `--agent codex` may already work. |
|
|
@@ -472,12 +533,16 @@ Then `cd` into it, start the agent and type `/feature-flow hello` (Codex: `$feat
|
|
|
472
533
|
```bash
|
|
473
534
|
bash tests/run.sh
|
|
474
535
|
python3 -m unittest discover -s tests/py
|
|
536
|
+
python3 -m unittest discover -s packages/forkboard/tests # Forkboard, the brainstorm page
|
|
537
|
+
(cd packages/forkboard/tests/browser && npm install && npm test) # the page in Chromium
|
|
475
538
|
```
|
|
476
539
|
|
|
477
540
|
Offline and free: no model is called. The suite covers the conductor's every answer and how a run stops, sessions, handoff and takeover, a `.git` the agent cannot write, the gate, the floor guard, plan protection, the prompts and guides, both skills, the installer for both agents, the graph page and its data, the Done when checks, the test-first check, the two reviews and the debugging guide on a send-back, and the acceptance harness. `tests/run.sh` also drives a prepared demo with no model through both checks and both reviews. The page's layout and replay logic are also tested under Node (`tests/viewer-logic.test.js`, skipped when Node is absent). `.github/workflows/tests.yml` runs it on every push to `main` and every pull request, on Ubuntu and on macOS. A fourth job runs the Python unit tests on Windows, including a fixture drive that takes a two-ticket plan through `python scripts/flow.py f start` and `next` to `BUILD` and then `REVIEW`, with `FLOW_TRUSTED=1` set as the runner sets it. `tests/run.sh` itself is a bash harness and does not run on Windows. Windows is tested this way only: no real agent run has been done there.
|
|
478
541
|
|
|
479
542
|
A `package` job builds the wheel and the sdist and runs `tests/package_smoke.py` on Ubuntu (Python 3.9 and the latest), macOS and Windows: it installs the wheel in a fresh virtual environment, runs `feature-flow install`, and checks that the repo gets the same files as from `install.py` in a clone. Run it locally with `python3 -m pip install build && python3 tests/package_smoke.py`.
|
|
480
543
|
|
|
544
|
+
Two jobs test Forkboard ([packages/forkboard/](packages/forkboard/)) on its own: its unit tests and a build-and-install smoke test on Ubuntu, macOS and Windows, and the page driven in Chromium through Playwright (the diagram editor, no sideways scroll at phone width, and a live-page save that clashes with someone else's, reloads and saves again).
|
|
545
|
+
|
|
481
546
|
`RUN_REAL=1 bash tests/smoke-real.sh --interactive` is the acceptance run with Claude Code. It runs real sessions on the demo project and spends money, which is why it asks for `RUN_REAL=1`.
|
|
482
547
|
|
|
483
548
|
## Limits
|
|
@@ -488,7 +553,7 @@ feature-flow's layers are tripwires, not a security boundary. They catch acciden
|
|
|
488
553
|
- **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
554
|
- **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
555
|
- **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
|
-
- **
|
|
556
|
+
- **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
557
|
- **One ticket at a time**, with a handoff to a new session every few tickets, unless you turn on lanes.
|
|
493
558
|
- **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
559
|
|
|
@@ -503,6 +568,8 @@ Earlier versions had seven skills and an unattended loop. The five flow skills a
|
|
|
503
568
|
|
|
504
569
|
The installer never deletes the old skill folders, but it names any it finds. Delete them from `.claude/skills/` or `.agents/skills/` yourself.
|
|
505
570
|
|
|
571
|
+
**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.
|
|
572
|
+
|
|
506
573
|
## Releasing to PyPI
|
|
507
574
|
|
|
508
575
|
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,25 @@ 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: `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 in Forkboard's [themes/](packages/forkboard/forkboard/themes/), so adding one is adding a file. `--fragment` leaves out the html and body tags, for publishing the page as an artifact.
|
|
387
|
+
|
|
388
|
+

|
|
389
|
+
|
|
390
|
+
What the page is good at:
|
|
391
|
+
|
|
392
|
+
- **You review the design, not a wall of text.** Each option is a diagram you can see at once, with its pros, cons, size and risky areas right under it, and the sidebar jumps between options.
|
|
393
|
+
- **You answer by editing the diagram itself.** Drag, add, rename, connect or delete boxes, then Copy as mermaid and paste it into the chat. Your change reaches the session as a diagram, not a paraphrase.
|
|
394
|
+
- **More than one person can review it.** On the live page each reviewer keeps their own version of a diagram, compare with original marks what they added, removed or renamed, and their questions wake the session, which answers on the page.
|
|
395
|
+
- **One file, nothing to install or host.** The plain page is a single HTML file that needs no server and no account: open it from disk, or publish it as an artifact. It sends nothing anywhere (it only loads its fonts, and mermaid for a diagram that is not a flowchart), and the brainstorm's text is escaped, so a label cannot run a script.
|
|
396
|
+
- **Its own package, tested in a browser.** The page's editor, its phone layout and the live page's saves are driven in Chromium in CI, apart from the harness.
|
|
397
|
+
|
|
398
|
+
The page itself is **Forkboard** ([packages/forkboard/](packages/forkboard/)), a separate package in this repository with its own version and tests. feature-flow turns the brainstorm into a review document and Forkboard makes the page from it; Forkboard never reads or writes the brainstorm file. Every install of feature-flow carries its copy of Forkboard (as `feature_flow/_forkboard/`), so nothing extra needs installing.
|
|
399
|
+
|
|
400
|
+
**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.
|
|
401
|
+
|
|
402
|
+
[docs/brainstorm.md](docs/brainstorm.md) walks through a brainstorm step by step, how to use the page, and Forkboard's own commands.
|
|
345
403
|
|
|
346
404
|
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
405
|
|
|
@@ -394,6 +452,7 @@ feature-flow eval <feature> [--later] record the run in plan
|
|
|
394
452
|
python3 scripts/flow-status.py <feature> --mermaid the ticket graph, coloured by status (add "plain" for none)
|
|
395
453
|
python3 scripts/flow-status.py <feature> --json every ticket with status, blockers and readiness
|
|
396
454
|
python3 scripts/flow-view.py <feature> [--watch] the animated graph page, opened in your browser
|
|
455
|
+
feature-flow brainstorm-page <feature> [--style NAME] [--fragment] the brainstorm as a review page (Forkboard); --live DIR, --asks, --answer, --apply for the live page
|
|
397
456
|
python3 scripts/gate.py <feature> run Build, Test and Lint from commands.md
|
|
398
457
|
python3 scripts/floor-guard.py <feature> <NN> [base] check a ticket's diff, run from the repo root
|
|
399
458
|
```
|
|
@@ -427,6 +486,7 @@ The commands in `commands.md` run through `bash -c` on Linux and macOS and throu
|
|
|
427
486
|
| `FLOW_DIR`, `FLOW_TICKETS` | `plans`, `tasks` | where the plans and the ticket folder live |
|
|
428
487
|
| `FLOW_NO_OPEN` | unset | `1` makes `flow-view.py` never open a browser |
|
|
429
488
|
| `FLOW_WATCH_SECONDS` | `3` | how often `flow-view.py --watch` rewrites the page |
|
|
489
|
+
| `FLOW_STYLE` | `route` | the brainstorm page's look when the brainstorm has no `Style:` line: `route` or `blueprint` (Forkboard's themes) |
|
|
430
490
|
|
|
431
491
|
The run also stops on its own after a number of phases (`BUILD` and `REVIEW` hand-outs, the spec review and the quality review each counting as one, a single review counting as one) that grows with the ticket count, recomputed at every pick, so a loop of failures cannot go on forever.
|
|
432
492
|
|
|
@@ -434,7 +494,8 @@ The run also stops on its own after a number of phases (`BUILD` and `REVIEW` han
|
|
|
434
494
|
|
|
435
495
|
| Path | Tested |
|
|
436
496
|
|---|---|
|
|
437
|
-
|
|
|
497
|
+
| 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). |
|
|
498
|
+
| 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
499
|
| 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
500
|
| 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
501
|
| Copilot, Gemini CLI, Cursor | Not tested. Some read `.agents/skills`, so `--agent codex` may already work. |
|
|
@@ -453,12 +514,16 @@ Then `cd` into it, start the agent and type `/feature-flow hello` (Codex: `$feat
|
|
|
453
514
|
```bash
|
|
454
515
|
bash tests/run.sh
|
|
455
516
|
python3 -m unittest discover -s tests/py
|
|
517
|
+
python3 -m unittest discover -s packages/forkboard/tests # Forkboard, the brainstorm page
|
|
518
|
+
(cd packages/forkboard/tests/browser && npm install && npm test) # the page in Chromium
|
|
456
519
|
```
|
|
457
520
|
|
|
458
521
|
Offline and free: no model is called. The suite covers the conductor's every answer and how a run stops, sessions, handoff and takeover, a `.git` the agent cannot write, the gate, the floor guard, plan protection, the prompts and guides, both skills, the installer for both agents, the graph page and its data, the Done when checks, the test-first check, the two reviews and the debugging guide on a send-back, and the acceptance harness. `tests/run.sh` also drives a prepared demo with no model through both checks and both reviews. The page's layout and replay logic are also tested under Node (`tests/viewer-logic.test.js`, skipped when Node is absent). `.github/workflows/tests.yml` runs it on every push to `main` and every pull request, on Ubuntu and on macOS. A fourth job runs the Python unit tests on Windows, including a fixture drive that takes a two-ticket plan through `python scripts/flow.py f start` and `next` to `BUILD` and then `REVIEW`, with `FLOW_TRUSTED=1` set as the runner sets it. `tests/run.sh` itself is a bash harness and does not run on Windows. Windows is tested this way only: no real agent run has been done there.
|
|
459
522
|
|
|
460
523
|
A `package` job builds the wheel and the sdist and runs `tests/package_smoke.py` on Ubuntu (Python 3.9 and the latest), macOS and Windows: it installs the wheel in a fresh virtual environment, runs `feature-flow install`, and checks that the repo gets the same files as from `install.py` in a clone. Run it locally with `python3 -m pip install build && python3 tests/package_smoke.py`.
|
|
461
524
|
|
|
525
|
+
Two jobs test Forkboard ([packages/forkboard/](packages/forkboard/)) on its own: its unit tests and a build-and-install smoke test on Ubuntu, macOS and Windows, and the page driven in Chromium through Playwright (the diagram editor, no sideways scroll at phone width, and a live-page save that clashes with someone else's, reloads and saves again).
|
|
526
|
+
|
|
462
527
|
`RUN_REAL=1 bash tests/smoke-real.sh --interactive` is the acceptance run with Claude Code. It runs real sessions on the demo project and spends money, which is why it asks for `RUN_REAL=1`.
|
|
463
528
|
|
|
464
529
|
## Limits
|
|
@@ -469,7 +534,7 @@ feature-flow's layers are tripwires, not a security boundary. They catch acciden
|
|
|
469
534
|
- **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
535
|
- **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
536
|
- **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
|
-
- **
|
|
537
|
+
- **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
538
|
- **One ticket at a time**, with a handoff to a new session every few tickets, unless you turn on lanes.
|
|
474
539
|
- **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
540
|
|
|
@@ -484,6 +549,8 @@ Earlier versions had seven skills and an unattended loop. The five flow skills a
|
|
|
484
549
|
|
|
485
550
|
The installer never deletes the old skill folders, but it names any it finds. Delete them from `.claude/skills/` or `.agents/skills/` yourself.
|
|
486
551
|
|
|
552
|
+
**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.
|
|
553
|
+
|
|
487
554
|
## Releasing to PyPI
|
|
488
555
|
|
|
489
556
|
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 a561cb2bf1d8d8970e45065f24a736a02d9f803f09d652a26ca51b579f44cf7b
|
|
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 a561cb2bf1d8d8970e45065f24a736a02d9f803f09d652a26ca51b579f44cf7b <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 a561cb2bf1d8d8970e45065f24a736a02d9f803f09d652a26ca51b579f44cf7b --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
|