Repository navigation
Releases
v0.79.0
Scratch files live in the feature folder and go away at finish.
Changed
- Scratch files now go in the feature folder, not
/tmp. A bound session's bash calls, and every project command a gate runs (flow test, checks, build, dev, seed, health), now run withTMPDIRset to.dev-flow/<slug>/tmp/. Throwaway scripts,mktempoutput and test fixtures created withos.tmpdir()(the smoke suite alone makes about 40 per run) land there instead of piling up in the OS temp dir.flow finishremoves the folder with the feature, andflow abortdrops it when it unbinds. The prefix goes on after the guards have judged the command, so no guard ever sees it. Unbound sessions are unchanged.
v0.78.0
flow init asks better questions and writes your answers itself.
Fixed
- npm drafts wrote
build = npm build/run = npm dev, which npm rejects with "Unknown command". Scripts now run asnpm run <script>(onlytest/startkeep the shorthand), and bun's test isbun run test, becausebun testis bun's own runner, not your script. - The draft no longer invents
versionFile = package.jsonwhen no version file exists (doctor flagged it on day one). - The "app runs locally; visual pass" checklist item is now
(ui)-only, so libraries and CLIs aren't asked about screens. - With a UI, the draft dialog no longer appears before the setup questions are shown.
- With husky or lefthook setting
core.hooksPath, init no longer installs a hook git never runs. It prints the lines to add to the manager's hook instead.
Added
flow init --answers key=value …/--answers-file <path>apply setup answers as targeted edits (merge, forge, version, artifact, preflight, commands,check.<name>blocks). They preview the summary and a diff, and write only with--confirmed.--write-file <path>writes a whole file.--trackcommits the playbook. Every write prints its diff.- Setup questions carry
detected:/accept:/why:lines. The interactive first init accepts every detected value in one dialog, then offers the commit. - Detection reads:
- lint/typecheck/format scripts (and clippy,
go vet, ruff/mypy) →flow-checkblocks - Makefile/justfile/Taskfile targets
- CI workflow commands and publish steps → a suggested
artifactcheck - Dockerfile/compose → suggested
preflight/dev .env/secrets/on disk → draftedprotect/forbidguard rules- existing tags →
versionTag - the changelog file, monorepo workspaces, and CLAUDE.md/AGENTS.md/CONTRIBUTING.md
- lint/typecheck/format scripts (and clippy,
- The summary shown in the init dialog lists safety rules, and says when no version file is set.
docs/playbook.mdopens with a Quickstart and four typical playbooks.
v0.77.0
The finish reflection is done by a separate reviewer, and plugin feedback goes upstream. The driving agent used to review its own session inline (biased, and blind to its workers' transcripts), wrote findings straight into the project's reflections.md — dev-flow complaints included — and reminded the operator about open reflections on every turn.
Added
flow_stageopreflect: a fresh read-only pi session reviews the driver's transcript and everyflow_stageworker transcript (found by theirparentSessionheader), re-checks the open items, dedupes against them and the upstream issues, and returns numbered findings — each docs / code / plugin with a fold or drop recommendation. It runs in the main checkout at any stage; finish is its standard moment. A reported run is recorded on the flow, and a finish question without one says so (advisory, never a block).- At finish the operator decides fold or drop per finding: fold docs →
## playbook(docs flow), fold code →## code(patch flow), fold plugin → a GitHub issue on the dev-flow repo; drop records nothing. flow reflect --code "<note>"and a## codesection for fixes that touch project code.- Timed nudges: fix the open reflections now? fires when an item recurred this session, is ≥ 14 days old, ≥ 3 playbook items wait (one docs flow), or a code item waits between flows; tidy fires at ≥ 5 closed, closed ≥ open (≥ 3), or a closed item ≥ 30 days old.
Changed
flow reflect --pluginnever writesreflections.md: it prints the upstream recipe (search, thengh issue createwith the— reflection fromtail the fold matches). A plugin-shaped note without a flag does the same. In the dev-flow repo itself plugin is code and files under## code.--bothis gone;reflect movetakes--playbook|--code.- Existing
## pluginrows are kept verbatim, never added to, and flagged byflow doctorandreflect listto be filed upstream (or moved to## codein the dev-flow repo). - Open-reflection reminders left the per-turn stage context of a feature in progress; they surface at the release stage, at finish, in an unbound session, and in
flow status/flow doctor.
v0.76.0
The status bar now lists the flows. In pi-web the footer was text — nothing to click, and no way to see what was in flight without asking the agent.
Added
- In pi-web, dev-flow carries a collapsible flow-list widget beside the footer: a
dev-flowchip in the status shelf whose panel shows one line per unfinished flow —→marks the session's bound flow, the stage word is spelled out, footer markers (⚡ 📚 🎱 💬) and⚠️on failing checks read exactly as in the footer. It repaints at session start, at every run start and after every gate, and hides while nothing is open. The terminal keeps the footer as its only surface.
v0.75.0
flow_stage workers are now visible in pi-web. A delegated worker used to be a session pi-web never mentioned — the operator watched the driving session go quiet.
Added
flow_stageworkers register themselves as pi-web subagents: the worker's session file carries thepi-web:subagentmeta where pi-web's scanner looks for it (first data entry) and a terminal result when the run ends, so the worker appears in the session's Agents menu under profileflow-implement/flow-review— ✓ with its REPORT, ✗ failed, or interrupted. The row settles when the run ends; while it runs pi-web displays it as interrupted, because only pi-web's own sessions can prove liveness. Plain pi is unchanged, and a stamp that cannot write never breaks a worker.
v0.74.0
Audit: gaps closed, dead code out. A full read of the extension, core and playbook parser after 0.73.0's reset.
Fixed
flow approve --yoloandflow release --no-versionnow take effect only after the operator answers the checkpoint. Before, a refused or headless call still saved yolo/no-version, so it applied to the next gate.- A session opened inside a feature worktree now drives the main checkout's flow. Before,
flowgates, the footer, the context injection, compaction and claims read the worktree's own.dev-flow/; only the guards resolved the main checkout. flow healthnow runs aflow-check healthblock (it used to requirehealth =). The health probe insideflow checknow seeds first and retries withinhealthWait, the same probe verify runs.- A
health =key plus aflow-check healthblock no longer produce twohealthchecks. - The drafted mockup checklist item is now
(ui)-only, so non-UI features no longer have to confirm it. - Aborting a plan-stage feature that has a written plan now needs the operator's word (
--confirmed, or a dialog).
Removed
- The unreachable
donestage.flow finishdeletes the state, so nothing ever wrote it. - Legacy compatibility:
- the
project.jsonrefusal and doctor finding; - the
.currentcleanup; - the
github/release.githubalias forreleases; release.*keys under## global(use## release/## pre-release);- inline
(plugin)markers in flatreflections.mdfiles; - release-done re-reading the manifest for flows approved before the release gate recorded their version.
- the
- Re-running
flow initon an existing playbook no longer offers to regenerate it. It always refused for a hand-edited file anyway, and now it prints the doctor's findings. - An edit-tool write in a worktree no longer wipes recorded checks on the spot. The worktree fingerprint at verify/release is the single staleness check, and it already catches bash edits.
- An auto-compaction no longer queues a
reflections.mditem.
Changed
- Repeated git, forge and registry probes now go through shared helpers.
flow helpis shorter.- The checkout guard sees a branch behind leading flags (
git checkout -f feat/x) and ignores paths after--.
v0.72.0
- The implement stage must be worked, not just driven. A session could always judge its own implement work too small to delegate and author it inline —
flow verifyproved the tree, never who wrote it. Now a normal feature's verify refuses unless every commit the branch holds falls inside aflow_stageworker's recorded run window: each finished worker appends its window to a dev-flow-ownedstage-sessions/delegations.log(a session cannot sign its own proof — the ledger is refused to edit/write tools and counted as state tampering in bash), and an after-the-fact amend or rebase surfaces as an uncovered sha no write guard could ever see. While a normal feature is at implement, its own worktree is closed to its driver's edit/write tools and open to the worker that was sent to do it; the injected implement hint, the playbook and the skill no longer offer the inline escape.--docsand--patch— the operator-granted inline modes — are exempt, and there is no flag or yolo path around the rule. Heads-up for flows already at implement when you upgrade: their existing commits precede any ledger, so their nextflow verifyrefuses — delegate a worker that finishes (or redoes) the work. - A session inside a feature worktree is judged by the main checkout's flow truth. Workers run with cwd = the worktree, whose own tracked
.dev-flow/holds onlyproject.md— so the guard found zero features and every worker since worktrees existed heardno active flowwhen it reached for the edit tool: real workers authored everything through bash, the one surface the guard never policed. A linked worktree now resolves to its main checkout for feature, binding and state reads, and the write guard's worker half fires for the first time. A plain human session opened inside a worktree reads as a driver there — deliberate: worker-ness is a registration, not a location.
v0.70.0
- A flow's workers are one family in the picker. Every
flow_stageworker is now stamped as a child of the session that delegated it: its header carriesparentSession→ the driver's session file, and its transcript lands in the driver's own session bucket.pi --resumetherefore nests the whole family under the driver in its default Current Folder scope, Threaded sort, with no scope switch — and because the worker's name carries its outcome (✓ 🔍 · PASS · stamp attack,✗ 🔨 #3 · hard-cut), the tree reads without opening a single row. One layout boundary: with a configured session directory that is not the checkout's default, the folder scope filters by each session's own cwd, so workers — whose cwd is the worktree — sit one Tab away under All, still threaded. - The family has a text view for hosts without a tree. The settled card and
flow_stage { op: "status" }list every worker this session spawned: picker name, message count, last-write time (local wall-clock), transcript path, newest first, older ones folded behind one counted line. The run the card or status is reporting on is left out — it is the section above it — and the section appears only inside a flow. A host with no file-backed session gets the flow's owntranscripts.loginstead, labelled as the coarser source it is. Reading a bucket costs ~15 ms per MB of its history, so a polled live view re-reads at most once per two seconds while the settled card and an idle status always read fresh.
v0.69.0
- Workers, so the conversation that talks to you stays lean.
flow_stagenow delegates to disposable worker sessions with a fresh context, and the skill makes delegation the default for non-trivial implement work: the driver keeps the claim, the gates and the checkpoints, and receives one bounded stage report. A verify worker (op: "verify") is an independent, check-only checker of the implement work — and its PASS is now a hard precondition offlow verify: the stamp belongs to the exact tree it read (worktree and the plan dir it judged against), so any edit anywhere — including a mid-stage plan amendment — drops it like a tier-1 record; a fresh FAIL deletes a contradicted PASS; a reviewer that moves the tree through bash anyway (file, HEAD, branch pointer or plan) voids its own verdict and gets snapshotted. A reflect worker (op: "reflect") reviews the finished flow — driver transcript plus every worker transcript, durably indexed instage-sessions/transcripts.log— returning tagged findings to route through Fold?/Fix?/Drop?. - Workers are visible while they work. The tool card streams the live tail (current tool, last assistant line, ✓/✗ results, elapsed against budget, usage); the picker shows a live session named by role, ordinal and purpose —
⏳ 🔍 · stamp attack,⏳ 🔨 #2 · wire ops— renamed at the end with its outcome:✓ 🔍 · PASS · stamp attack,✓ 🔨 #2 · 3 commits · wire ops,✗ 🔨 #3 · hard-cut. A footer beat ticks while a worker runs,stage-live.logis tail-able,flow_stage { op: "status" }prints the same on any host, anddev-flow:worker-*events put every run on the bus for other extensions. - Pre-plan discipline: an unbound session may plan freely but writes nothing —
plan.mdbelongs to the flow folder and is only written afterflow startbinds the slug, so discussing an idea can never leave edits behind.
v0.68.1
flow abortleaves no ghost (gh#138). Aborting a feature whose worktree exists now stampsabortedon the kept state, and the doctor's git-consistency sweep skips stamped states — doing the cleanup the abort echo prints (git worktree remove,git branch -D) no longer becomes ahas no worktreefinding that every laterflow doctorrepeats.flow releaseproves a clean worktree (gh#131). A merge ships the branch, not the working tree — an uncommitted fix at the Release gate is a fix that never ships. The gate now refuses while the worktree holds uncommitted paths (listing them), and the approved line printscommits: N ahead of <default>, M uncommitted path(s)next to what verify prints;flow finish's worktree-cleanup refusal names the paths too, not just the count.- Merging waits for green CI (gh#134). The shipped release recipe and the release-stage hint now print
gh pr checks <n> --watchbeside the merge command: a locally-green branch can still fail checks that only CI runs, and merging with them red turns the default branch red.