flow-workflows 0.64.0 → 0.65.0-rc.2

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.
Files changed (30) hide show
  1. package/README.md +43 -8
  2. package/adapters/codex/CORE.md +18 -1
  3. package/adapters/codex/skills/flow-bug-review/SKILL.md +29 -0
  4. package/adapters/codex/skills/flow-doctor/SKILL.md +21 -0
  5. package/adapters/codex/skills/flow-feat-review/SKILL.md +29 -0
  6. package/adapters/codex/skills/flow-init/SKILL.md +10 -0
  7. package/adapters/codex/skills/flow-work-status/SKILL.md +2 -0
  8. package/adapters/gemini/CORE.md +18 -1
  9. package/adapters/gemini/commands/flow/bug/review.toml +29 -0
  10. package/adapters/gemini/commands/flow/doctor.toml +21 -0
  11. package/adapters/gemini/commands/flow/feat/review.toml +29 -0
  12. package/adapters/gemini/commands/flow/init.toml +10 -0
  13. package/adapters/gemini/commands/flow/work/status.toml +2 -0
  14. package/adapters/hermes/CORE.md +18 -1
  15. package/adapters/hermes/skills/flow-bug-review/SKILL.md +29 -0
  16. package/adapters/hermes/skills/flow-doctor/SKILL.md +21 -0
  17. package/adapters/hermes/skills/flow-feat-review/SKILL.md +29 -0
  18. package/adapters/hermes/skills/flow-init/SKILL.md +10 -0
  19. package/adapters/hermes/skills/flow-work-status/SKILL.md +2 -0
  20. package/adapters/opencode/CORE.md +18 -1
  21. package/adapters/opencode/commands/flow-bug-review.md +29 -0
  22. package/adapters/opencode/commands/flow-doctor.md +21 -0
  23. package/adapters/opencode/commands/flow-feat-review.md +29 -0
  24. package/adapters/opencode/commands/flow-init.md +10 -0
  25. package/adapters/opencode/commands/flow-work-status.md +2 -0
  26. package/bin/cli.mjs +543 -4
  27. package/package.json +1 -1
  28. package/plugins/flow/.claude-plugin/plugin.json +1 -1
  29. package/plugins/flow/CHANGELOG.md +69 -0
  30. package/plugins/flow/examples/FLOW.template.md +20 -0
@@ -5,6 +5,75 @@ plugin and is what `/flow:news` reads to show you what changed since your previo
5
5
 
6
6
  The canonical, richest notes live in the [GitHub Releases](https://github.com/mashware/flow-workflows/releases).
7
7
 
8
+ ## v0.65.0 — Every phase rediscovered the same context, and nobody knew what it cost · 2026-09-17
9
+
10
+ **In short**
11
+ - **A round gathers its material once.** `npx flow-workflows bundle` prints one context pack — worklist, diff, changed files, the repo's own analysis output, the work's handoff — instead of every reviewer paying to rediscover it.
12
+ - **The panel can run outside the agentic loop.** With `agents.exec_cmd` set, `npx flow-workflows review` runs one reviewer per role in **one turn each**, deduplicated — and that is what runs when the key is there, not one option among two.
13
+ - **What a phase spent is written down.** `meta.json.cost[]` records the figure the harness reported, `"not reported"` when it reported none and never an estimate; `flow cost`, `/flow:work:status` and the review artifact read it back.
14
+ - **A change can be run before it is tagged — and the candidate's own code is what runs.** Candidates publish under the `next` channel so `latest` never moves; the commands pin the CLI to the plugin's own version, so a candidate's commands can never be served by the previous release's CLI; and a session that has ended up with two copies of the plugin says so instead of running a mixture.
15
+ - **Two claims stopped being promises.** The preflight now refuses a line that *depends* on one ecosystem, and a test pins the four answer shapes the review CLI has to unwrap.
16
+
17
+ A phase costs turns times context. The API keeps no state, so ten calls spent finding out what
18
+ changed cost ten times the context they find — and `review` made that worse by construction: every
19
+ member of a panel ran its own `git diff`, opened the same files, and read the same code, paying for
20
+ that material once per agent. `bundle` gathers it for the whole round in a single call, and
21
+ `quality.static_analysis` — a key that until now only ran at the end — is copied into the pack
22
+ verbatim, so a reviewer no longer spends its turns hunting for what a linter already knew.
23
+
24
+ It knows nothing about any ecosystem, which is the constraint that decided its shape. Which paths to
25
+ leave out of the diff comes from the new `git.diff_exclude`; which command reports problems comes
26
+ from the existing `quality.static_analysis`; that command's output is copied out rather than parsed,
27
+ because parsing it is exactly what would tie the plugin to one toolchain. One size rule governs the
28
+ whole pack: a file over the limit is out of both the contents and the diff, and is named with its
29
+ size.
30
+
31
+ `agents.exec_cmd` is the other half. A reviewer that only has to read a pack and answer does not
32
+ need an agentic loop, and where the key is set the round now runs one non-interactive invocation per
33
+ role — any harness, any vendor, a script of your own — with the findings deduplicated in code rather
34
+ than by a model reading eight reports. It arrived as an alternative the panel *could* take, and a
35
+ real run showed what that costs: the familiar path wins every time, in silence. So it is the path
36
+ when the key is set, with three named ways back to the agentic panel, and the review artifact now
37
+ records which one ran — a round that skipped the CLI and one that used it read the same otherwise.
38
+
39
+ Cost stopped being a design argument and became a number. Every phase that can measure what it spent
40
+ appends one entry to `meta.json.cost[]`, and the two rules are what make the block worth having: a
41
+ harness that reports nothing is recorded as `"not reported"` rather than estimated, and a phase with
42
+ no entry measured nothing — absence is not zero. The `Cost:` line of a review, meanwhile, stopped
43
+ counting subagents: a headcount is not a bill, and saying so was cheaper than pretending otherwise.
44
+
45
+ None of this requires anything of an existing repo. An empty `agents.exec_cmd` is the default and
46
+ the agentic panel runs exactly as before; a `FLOW.md` written before any of these keys existed still
47
+ produces a pack; a work with no cost block simply has none. What a machine without node loses is the
48
+ saving, not the review — the CLI failing for any reason is a documented fallback to reading the diff
49
+ from git, and `/flow:doctor` now checks for that CLI so it is a line in a diagnosis rather than a
50
+ surprise mid-phase.
51
+
52
+ Finally, two things this repo asserted about itself and never checked. `check_no_stack_leak` reads
53
+ every line of the plugin and fails the ones that *depend* on a single ecosystem — naming several is
54
+ a detection table and passes, naming one is a leak — with three narrow exemptions and no exemption
55
+ at all under `bin/`. And a change to the flow can now be installed before it is tagged: an rc
56
+ publishes under `next`, `claude --plugin-dir` loads a branch over the release you use daily, and npm
57
+ serves a branch straight from git for the other harnesses.
58
+
59
+ The first candidate then proved that last sentence half-true, in the only way that counts — a real
60
+ work, driven end to end, on a real repo. Two things a page of prose could not have found. The
61
+ commands call the CLI unpinned, so an unpinned fetch resolves the channel a candidate deliberately
62
+ does not move: the candidate's own commands were served the **previous** release's CLI, `bundle` came
63
+ back *"Unknown command"*, and the round took the documented fallback — correctly, silently, for a
64
+ reason that had nothing to do with the machine. Every `flow-workflows` call now carries the plugin's
65
+ own version, and the preflight refuses a tree where the manifest, the npm package and `flow-core`
66
+ do not state the same number, because a pin is only worth having if the number it asks for was
67
+ published. And loading a branch over an installed copy leaves **two** plugins of the same name: the
68
+ session took its commands from the branch and its shared rules from the release, ran perfectly, and
69
+ recorded the wrong thing. `flow-core` now states which version it belongs to, so any session can
70
+ compare it against the plugin it is running and name both numbers at its first stop; `/flow:doctor`
71
+ checks it outright, and `RELEASING.md` says to disable the installed copy rather than rely on either.
72
+
73
+ What made all of this visible was the `Review path` line added above — a round that fell back and a
74
+ round that did not are one line apart in the artifact, and without that line this release would have
75
+ shipped believing its own notes.
76
+
8
77
  ## v0.64.0 — Announcing the next step was how the run ended · 2026-09-16
9
78
 
10
79
  **In short**
@@ -69,6 +69,12 @@ Branch and Pull/Merge Request conventions.
69
69
  - `cli:` # Empty = the default for `host` in the table above. Set it for a self-hosted forge, a wrapper, or
70
70
  # a host with no CLI of its own (`bitbucket`), where the commands degrade to plain git and say so.
71
71
  - `default_base:` # base for new branches, e.g. `origin/master` or `origin/main`.
72
+ - `diff_exclude:` # paths kept out of the diff a phase reads, one per line with `- `. Generated files nobody reviews —
73
+ # dependency locks, generated migrations, compiled assets, recorded fixtures — cost context in every
74
+ # phase that opens the diff and in every reviewer launched over it. Empty = exclude nothing.
75
+ # `/flow:init` proposes what it finds. Git pathspec syntax, so a glob works. e.g.:
76
+ # - '*.lock'
77
+ # - 'assets/build/**'
72
78
  - `branch_pattern:` # e.g. `{PREFIX}{TICKET}-{slug}`. `{slug}` in English, kebab-case. Empty = `{PREFIX}{TICKET}-{slug}`.
73
79
  - `assignee:` # user to assign the MR/PR to. Empty = do not assign.
74
80
  - `squash:` # `true` | `false` (squash-before-merge).
@@ -180,6 +186,18 @@ Two keys below configure the **parallel fan-out** (approach panel in `design` §
180
186
  sweep in `investigate` §3.A, finding verification in `review`) instead of naming an agent. The
181
187
  fan-out runs as plain parallel subagents — the primitive every harness has.
182
188
 
189
+ - `exec_cmd:` # how to invoke a harness NON-interactively, so `flow review` can run one reviewer per role in one
190
+ # turn each instead of an agentic loop each. `{ROLE}` and `{SCHEMA}` are substituted; the diff and
191
+ # the brief arrive on stdin. **Empty = the agentic panel inside `/flow:*:review` reviews, exactly
192
+ # as before** — this key is the opt-in, nothing changes without it. It takes any command: a
193
+ # subscription login, an API key, another vendor's CLI, or a script of your own. When it is set,
194
+ # that command picks the model and `models.agents`/`models.workers` no longer apply to review.
195
+ # Quote `{SCHEMA}` with DOUBLE quotes: the substitution escapes for that context and single
196
+ # quotes would hand the command invalid JSON. A harness that answers in an envelope of its own
197
+ # is unwrapped here — no `jq` needed. Measured: one reviewer over a small diff ≈ $0.17, so a
198
+ # four-role round ≈ $0.70, which is what `budget_max` below is bounding. e.g.:
199
+ # - claude -p --model sonnet --output-format json --json-schema "{SCHEMA}"
200
+ # - codex exec --model <m>
183
201
  - `fanout_max:` # max subagents per parallel round. Empty = 4. Lower it to keep the flow cheap; what a cap drops is always reported
184
202
  - `budget_max:` # max subagents ONE command run may launch in total, summed over every round (flow-core §6). Empty = 12. `0` = no ceiling
185
203
  # (not recommended). `fanout_max` bounds a round; this bounds the command — `/flow:*:review` composes a panel, area
@@ -195,6 +213,8 @@ command composes itself — the panel in `review`, the delegated pieces in `buil
195
213
  `validate` — not to the prompts this plugin already writes out with their own cap.
196
214
 
197
215
  - `report_max_words:` # word cap every brief you write for a subagent carries. Empty = 250. Not a style rule: a report too long for the harness to carry is truncated in transit and reaches you as silence
216
+ # Output tokens are the most expensive kind and are never served from cache,
217
+ # so this is a cost ceiling as much as a format rule
198
218
  - `stall_after_minutes:` # a fan-out agent past this with nothing written to its named path is stopped, its brief split in two, and relaunched. Empty = 25 —
199
219
  # a guess from one session, not a measurement. Lower it if your rounds are short and you would rather relaunch early; raise it
200
220
  # for agents that legitimately read for half an hour before writing