Skip to content

Commit be7a1aa

Browse files
authored
Merge pull request #7 from gmickel/chore/port-upstream-0.17.1
Port upstream flow-next 0.17.1
2 parents 990e9eb + 5d5b145 commit be7a1aa

8 files changed

Lines changed: 807 additions & 194 deletions

File tree

.opencode/bin/flowctl.py

Lines changed: 632 additions & 179 deletions
Large diffs are not rendered by default.

.opencode/skill/flow-next-opencode-plan-review/SKILL.md

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,9 @@ $FLOWCTL opencode plan-review "$EPIC_ID" --receipt "$RECEIPT_PATH"
140140
# Output includes VERDICT=SHIP|NEEDS_WORK|MAJOR_RETHINK
141141
```
142142

143-
On NEEDS_WORK: fix plan via `$FLOWCTL epic set-plan`, then re-run (receipt enables session continuity).
143+
On NEEDS_WORK: fix plan via `$FLOWCTL epic set-plan` AND sync affected task specs via `$FLOWCTL task set-spec`, then re-run (receipt enables session continuity).
144+
145+
**Note**: `opencode plan-review` automatically includes task specs in the review prompt.
144146

145147
### RepoPrompt Backend
146148

@@ -153,8 +155,12 @@ $FLOWCTL cat <id>
153155
eval "$($FLOWCTL rp setup-review --repo-root "$REPO_ROOT" --summary "Review plan for <EPIC_ID>: <summary>")"
154156
# Outputs W=<window> T=<tab>. If fails → <promise>RETRY</promise>
155157

156-
# Step 3: Augment selection
158+
# Step 3: Augment selection - add epic AND task specs
157159
$FLOWCTL rp select-add --window "$W" --tab "$T" .flow/specs/<epic-id>.md
160+
# Add all task specs for this epic
161+
for task_spec in .flow/tasks/${EPIC_ID}.*.md; do
162+
[[ -f "$task_spec" ]] && $FLOWCTL rp select-add --window "$W" --tab "$T" "$task_spec"
163+
done
158164

159165
# Step 4: Build and send review prompt (see workflow.md)
160166
$FLOWCTL rp chat-send --window "$W" --tab "$T" --message-file /tmp/review-prompt.md --new-chat --chat-name "Plan Review: <EPIC_ID>"
@@ -169,10 +175,22 @@ $FLOWCTL epic set-plan-review-status <EPIC_ID> --status ship --json
169175
If verdict is NEEDS_WORK, loop internally until SHIP:
170176

171177
1. **Parse issues** from reviewer feedback
172-
2. **Fix plan** via `$FLOWCTL epic set-plan <EPIC_ID> --file /tmp/updated-plan.md`
173-
3. **Re-review**:
178+
2. **Fix epic spec** via `$FLOWCTL epic set-plan <EPIC_ID> --file /tmp/updated-plan.md`
179+
3. **Sync affected task specs** - If epic changes affect task specs, update them:
180+
```bash
181+
$FLOWCTL task set-spec <TASK_ID> --file - --json <<'EOF'
182+
<updated task spec content>
183+
EOF
184+
```
185+
Task specs need updating when epic changes affect:
186+
- State/enum values referenced in tasks
187+
- Acceptance criteria that tasks implement
188+
- Approach/design decisions tasks depend on
189+
- Lock/retry/error handling semantics
190+
- API signatures or type definitions
191+
4. **Re-review**:
174192
- **OpenCode**: re-run reviewer subagent with updated plan
175193
- **RP**: `$FLOWCTL rp chat-send --window "$W" --tab "$T" --message-file /tmp/re-review.md` (NO `--new-chat`)
176-
4. **Repeat** until `<verdict>SHIP</verdict>`
194+
5. **Repeat** until `<verdict>SHIP</verdict>`
177195
178196
**CRITICAL**: For RP, re-reviews must stay in the SAME chat so reviewer has context. Only use `--new-chat` on the FIRST review.

.opencode/skill/flow-next-opencode-plan-review/workflow.md

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -158,14 +158,19 @@ Builder selects context automatically. Review and add must-haves:
158158
# See what builder selected
159159
$FLOWCTL rp select-get --window "$W" --tab "$T"
160160

161-
# Always add the plan spec
161+
# Always add the epic spec
162162
$FLOWCTL rp select-add --window "$W" --tab "$T" .flow/specs/<epic-id>.md
163163

164+
# Always add ALL task specs for this epic
165+
for task_spec in .flow/tasks/${EPIC_ID}.*.md; do
166+
[[ -f "$task_spec" ]] && $FLOWCTL rp select-add --window "$W" --tab "$T" "$task_spec"
167+
done
168+
164169
# Add PRD/architecture docs if found
165170
$FLOWCTL rp select-add --window "$W" --tab "$T" docs/prd.md
166171
```
167172

168-
**Why this matters:** Chat only sees selected files.
173+
**Why this matters:** Chat only sees selected files. Reviewer needs both epic spec AND task specs to check for consistency.
169174

170175
---
171176

@@ -199,6 +204,18 @@ If you cannot find `<file_contents>`, ask for the files to be re-attached before
199204
## Review Focus
200205
[USER'S FOCUS AREAS]
201206
207+
## Review Scope
208+
209+
You are reviewing:
210+
1. **Epic spec** - The high-level plan
211+
2. **Task specs** - Individual task breakdowns
212+
213+
**CRITICAL**: Check for consistency between epic and tasks. Flag if:
214+
- Task specs contradict or miss epic requirements
215+
- Task acceptance criteria don't align with epic acceptance criteria
216+
- Task approaches would need to change based on epic design decisions
217+
- Epic mentions states/enums/types that tasks don't account for
218+
202219
## Review Criteria
203220
204221
Conduct a John Carmack-level review:
@@ -210,6 +227,7 @@ Conduct a John Carmack-level review:
210227
5. **Risks** - Blockers identified? Security gaps? Mitigation?
211228
6. **Scope** - Right-sized? Over/under-engineering?
212229
7. **Testability** - How will we verify this works?
230+
8. **Consistency** - Do task specs align with epic spec?
213231
214232
## Output Format
215233
@@ -291,7 +309,20 @@ If verdict is NEEDS_WORK:
291309
$FLOWCTL checkpoint restore --epic <EPIC_ID> --json
292310
```
293311
294-
4. **Re-review with fix summary** (only AFTER step 3):
312+
4. **Sync affected task specs** - If epic changes affect task specs, update them:
313+
```bash
314+
$FLOWCTL task set-spec <TASK_ID> --file - --json <<'EOF'
315+
<updated task spec content>
316+
EOF
317+
```
318+
Task specs need updating when epic changes affect:
319+
- State/enum values referenced in tasks
320+
- Acceptance criteria that tasks implement
321+
- Approach/design decisions tasks depend on
322+
- Lock/retry/error handling semantics
323+
- API signatures or type definitions
324+
325+
5. **Re-review with fix summary** (only AFTER steps 3-4):
295326
296327
**IMPORTANT**: Do NOT re-add files already in the selection. RepoPrompt auto-refreshes
297328
file contents on every message. Only use `select-add` for NEW files created during fixes:
@@ -315,12 +346,14 @@ If verdict is NEEDS_WORK:
315346
316347
$FLOWCTL rp chat-send --window "$W" --tab "$T" --message-file /tmp/re-review.md
317348
```
318-
5. **Repeat** until Ship
349+
6. **Repeat** until Ship
319350
320351
**Anti-pattern**: Re-adding already-selected files before re-review. RP auto-refreshes; re-adding can cause issues.
321352
322353
**Anti-pattern**: Re-reviewing without calling `epic set-plan` first. This wastes reviewer time and loops forever.
323354
355+
**Anti-pattern**: Updating epic spec without syncing affected task specs. Causes reviewer to flag consistency issues again.
356+
324357
---
325358
326359
## Failure Recovery

.opencode/skill/flow-next-opencode-setup/templates/usage.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ Task tracking for AI agents. All state lives in `.flow/`.
2222
└── meta.json # Project metadata
2323
```
2424

25+
Runtime state (status, assignee, evidence) is stored in `.git/flow-state/` (not tracked).
26+
2527
## IDs
2628

2729
- Epics: `fn-N` (e.g., fn-1, fn-2)
@@ -46,6 +48,8 @@ Task tracking for AI agents. All state lives in `.flow/`.
4648
# Status
4749
.flow/bin/flowctl ready --epic fn-1 # What's ready to work on
4850
.flow/bin/flowctl validate --all # Check structure
51+
.flow/bin/flowctl state-path # Show runtime state directory
52+
.flow/bin/flowctl migrate-state --clean # Optional migration + cleanup
4953

5054
# Create
5155
.flow/bin/flowctl epic create --title "..."

.opencode/version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.2.4
1+
0.2.5

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,18 @@
22

33
## Unreleased
44

5+
**Restores parity with upstream Claude Code plugin (flow-next 0.17.0 + 0.17.1).**
6+
7+
### Ported from upstream 0.17.0 → 0.17.1
8+
9+
- **Runtime state store** — Task runtime fields move to `.git/flow-state/` (worktree-safe)
10+
- **StateStore with locking** — fcntl-based per-task locks for race-safe updates
11+
- **New commands**`flowctl state-path` + `flowctl migrate-state [--clean]`
12+
- **Checkpoint schema v2** — Includes runtime state in save/restore
13+
- **Plan review includes task specs** — Both RP and OpenCode review epic + task specs for consistency
14+
- **Plan review consistency checks** — New criteria + anti-pattern: update epic without syncing tasks
15+
- **Task spec full replacement**`flowctl task set-spec --file` (supports stdin)
16+
517
**Restores parity with upstream Claude Code plugin (flow-next 0.12.10 + 0.13.0).**
618

719
### Planning Workflow Changes (ported from upstream 0.13.0)

README.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,39 @@ Teams can work in parallel branches without coordination servers:
288288
* **Actor resolution**: Auto-detects from git email, `FLOW_ACTOR` env, or `$USER`
289289
* **Local validation**: `flowctl validate --all` catches issues before commit
290290

291+
### Parallel Worktrees
292+
293+
Multiple agents can work simultaneously in different git worktrees, sharing task state:
294+
295+
```bash
296+
# Main repo
297+
git worktree add ../feature-a fn-1-branch
298+
git worktree add ../feature-b fn-2-branch
299+
300+
# Both worktrees share task state via .git/flow-state/
301+
cd ../feature-a && flowctl start fn-1.1 # Agent A claims task
302+
cd ../feature-b && flowctl start fn-2.1 # Agent B claims different task
303+
```
304+
305+
**How it works:**
306+
- Runtime state (status, assignee, evidence) lives in `.git/flow-state/` — shared across worktrees
307+
- Definition files (title, description, deps) stay in `.flow/` — tracked in git
308+
- Per-task `fcntl` locking prevents race conditions
309+
310+
**State directory resolution:**
311+
1. `FLOW_STATE_DIR` env (explicit override)
312+
2. `git --git-common-dir` + `/flow-state` (worktree-aware)
313+
3. `.flow/state` fallback (non-git or old git)
314+
315+
**Commands:**
316+
```bash
317+
flowctl state-path # Show resolved state directory
318+
flowctl migrate-state # Migrate existing repo (optional)
319+
flowctl migrate-state --clean # Migrate + remove runtime from tracked files
320+
```
321+
322+
**Backward compatible** — existing repos work without migration. The merged read path automatically falls back to definition files when no state file exists.
323+
291324
### Zero Dependencies
292325

293326
Everything is bundled:
@@ -515,6 +548,8 @@ This creates a complete audit trail: what was planned, what was done, how it was
515548
└── decisions.md
516549
```
517550

551+
Runtime state (status, assignee, evidence) is stored in `.git/flow-state/` (not tracked).
552+
518553
### ID Format
519554

520555
* **Epic**: `fn-N-xxx` where `xxx` is a 3-character alphanumeric suffix
@@ -540,6 +575,7 @@ flowctl epic close fn-1
540575
flowctl task create --epic fn-1 --title "..." --deps fn-1.2,fn-1.3 --priority 10
541576
flowctl task set-description fn-1.1 --file desc.md
542577
flowctl task set-acceptance fn-1.1 --file accept.md
578+
flowctl task set-spec fn-1.1 --file spec.md
543579

544580
flowctl dep add fn-1.3 fn-1.2
545581

@@ -555,6 +591,9 @@ flowctl cat fn-1
555591
flowctl validate --epic fn-1
556592
flowctl validate --all
557593

594+
flowctl state-path
595+
flowctl migrate-state --clean
596+
558597
flowctl review-backend # Get configured review backend (ASK if not set)
559598
flowctl config set review.backend opencode # Set default backend
560599
```

docs/flowctl.md

Lines changed: 59 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ CLI for `.flow/` task tracking. Agents must use flowctl for all writes.
77
## Available Commands
88

99
```
10-
init, detect, epic, task, dep, show, epics, tasks, list, cat, ready, next, start, done, block, validate, config, memory, prep-chat, rp, opencode, codex, checkpoint, status
10+
init, detect, epic, task, dep, show, epics, tasks, list, cat, ready, next, start, done, block, validate, config, memory, prep-chat, rp, opencode, codex, checkpoint, status, state-path, migrate-state
1111
```
1212

1313
## Multi-User Safety
@@ -21,6 +21,23 @@ Works out of the box for parallel branches. No setup required.
2121

2222
**Optional**: Add CI gate with `docs/ci-workflow-example.yml` to block bad PRs.
2323

24+
## Runtime State (Worktrees)
25+
26+
Runtime task state (status, assignee, evidence) lives in `.git/flow-state/` and is shared across worktrees.
27+
Definition files (title, deps, specs) remain in `.flow/` and are tracked in git.
28+
29+
State directory resolution:
30+
1. `FLOW_STATE_DIR` env (override)
31+
2. `git --git-common-dir` + `/flow-state` (worktree-aware)
32+
3. `.flow/state` fallback (non-git)
33+
34+
Useful commands:
35+
```bash
36+
flowctl state-path # Show resolved state directory
37+
flowctl migrate-state # Migrate existing repo (optional)
38+
flowctl migrate-state --clean # Migrate + remove runtime from tracked files
39+
```
40+
2441
## File Structure
2542

2643
```
@@ -37,6 +54,8 @@ Works out of the box for parallel branches. No setup required.
3754
└── usage.md # (optional) CLI reference via /flow-next:setup
3855
```
3956

57+
Runtime state (status, assignee, evidence) is stored in `.git/flow-state/` (not tracked).
58+
4059
Flowctl accepts schema v1 and v2; new fields are optional and defaulted.
4160

4261
New fields:
@@ -147,13 +166,19 @@ flowctl task set-acceptance fn-1.2 --file accept.md [--json]
147166

148167
### task set-spec
149168

150-
Set description and acceptance in one call (fewer writes).
169+
Set task spec (full replacement or section patches).
151170

171+
Full replacement:
172+
```bash
173+
flowctl task set-spec fn-1.2 --file spec.md [--json]
174+
```
175+
176+
Section patches:
152177
```bash
153178
flowctl task set-spec fn-1.2 --description desc.md --acceptance accept.md [--json]
154179
```
155180

156-
Both `--description` and `--acceptance` are optional; supply one or both.
181+
`--description` and `--acceptance` are optional; supply one or both. Use `--file -` for stdin.
157182

158183
### task reset
159184

@@ -554,7 +579,7 @@ References: src/middleware.py:45 (calls authenticate), tests/test_auth.py:12
554579

555580
| Review | Criteria |
556581
|--------|----------|
557-
| Plan | Completeness, Feasibility, Clarity, Architecture, Risks, Scope, Testability |
582+
| Plan | Completeness, Feasibility, Clarity, Architecture, Risks, Scope, Testability, Consistency |
558583
| Impl | Correctness, Simplicity, DRY, Architecture, Edge Cases, Tests, Security |
559584

560585
**Receipt schema (Ralph-compatible):**
@@ -586,7 +611,7 @@ flowctl checkpoint restore --epic fn-1 [--json]
586611
flowctl checkpoint delete --epic fn-1 [--json]
587612
```
588613

589-
Checkpoints preserve full epic + task state. Useful when compaction occurs during plan-review cycles.
614+
Checkpoints preserve full epic + task state (including runtime state). Useful when compaction occurs during plan-review cycles.
590615

591616
### status
592617

@@ -603,6 +628,35 @@ Output:
603628

604629
Human-readable output shows epic/task counts and any active Ralph runs.
605630

631+
### state-path
632+
633+
Show resolved runtime state directory (worktree-aware).
634+
635+
```bash
636+
flowctl state-path [--json]
637+
flowctl state-path --task fn-1.2 [--json]
638+
```
639+
640+
Example output:
641+
```json
642+
{"success": true, "state_dir": "/repo/.git/flow-state", "task_state_path": "/repo/.git/flow-state/tasks/fn-1.2.state.json"}
643+
```
644+
645+
### migrate-state
646+
647+
Migrate runtime state from tracked task definitions into the shared state directory.
648+
649+
```bash
650+
flowctl migrate-state [--clean] [--json]
651+
```
652+
653+
What it does:
654+
1. Scans `.flow/tasks/*.json` for runtime fields
655+
2. Writes runtime state to `.git/flow-state/tasks/*.state.json`
656+
3. Optional `--clean` removes runtime fields from tracked task JSONs
657+
658+
Backward compatible: repos work without migration. Use `--clean` only if you want a clean diff.
659+
606660
## Ralph Receipts
607661

608662
Review receipts are **not** managed by flowctl. They are written by the review skills when `REVIEW_RECEIPT_PATH` is set (Ralph sets this env var).

0 commit comments

Comments
 (0)