@mhd-ghaith-abtah/flow 0.7.2-beta.0
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.
- package/CHANGELOG.md +87 -0
- package/LICENSE +21 -0
- package/README.md +162 -0
- package/adapters/e2e/_interface.md +42 -0
- package/adapters/e2e/none.md +15 -0
- package/adapters/e2e/playwright-mcp.md +86 -0
- package/adapters/issue-tracker/_interface.md +46 -0
- package/adapters/issue-tracker/github-issues.md +103 -0
- package/adapters/issue-tracker/linear.md +65 -0
- package/adapters/issue-tracker/none.md +26 -0
- package/adapters/pr/_interface.md +29 -0
- package/adapters/pr/github.md +61 -0
- package/adapters/pr/none.md +32 -0
- package/adapters/verify/_interface.md +26 -0
- package/adapters/verify/custom.md +27 -0
- package/adapters/verify/make.md +30 -0
- package/adapters/verify/pnpm.md +27 -0
- package/bin/flow.js +129 -0
- package/catalog.yaml +364 -0
- package/docs/adapters.md +99 -0
- package/docs/migrate-from-bmad.md +95 -0
- package/docs/profiles.md +81 -0
- package/docs/quickstart.md +82 -0
- package/lib/catalog.js +164 -0
- package/lib/commands/add.js +147 -0
- package/lib/commands/doctor.js +392 -0
- package/lib/commands/init.js +86 -0
- package/lib/commands/install.js +181 -0
- package/lib/commands/plan.js +108 -0
- package/lib/commands/remove.js +87 -0
- package/lib/commands/uninstall.js +157 -0
- package/lib/repo-root.js +53 -0
- package/package.json +62 -0
- package/schemas/catalog.schema.json +155 -0
- package/schemas/flow-config.schema.json +85 -0
- package/schemas/install-state.schema.json +79 -0
- package/skills/flow-doctor/SKILL.md +15 -0
- package/skills/flow-doctor/workflow.md +157 -0
- package/skills/flow-init/SKILL.md +10 -0
- package/skills/flow-init/workflow.md +420 -0
- package/skills/flow-sprint/SKILL.md +10 -0
- package/skills/flow-sprint/workflow.md +394 -0
- package/skills/flow-story/SKILL.md +12 -0
- package/skills/flow-story/workflow.md +531 -0
- package/templates/claude-md-section.md.tmpl +55 -0
- package/templates/flow-readme.md.tmpl +34 -0
- package/templates/flow.config.yaml.tmpl +94 -0
- package/templates/pr.md.tmpl +40 -0
- package/templates/retro.md.tmpl +58 -0
- package/templates/sprint.yaml.tmpl +18 -0
- package/templates/story.md.tmpl +35 -0
- package/tools/fix-caveman-shrink.sh +68 -0
- package/tools/lint-changelog.js +98 -0
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
# flow-init Workflow
|
|
2
|
+
|
|
3
|
+
**Output style — Caveman mandate.** All user-facing output from this workflow (status banners, prompts, error messages, plan tables, smoke-test results) MUST be Caveman-mode: fragments OK, drop articles / filler / pleasantries / hedging, keep code & commit & security text normal. If `caveman` skill registered, prefer phrasing that mirrors its style. Examples:
|
|
4
|
+
- "📦 Installing Caveman…" not "I'll go ahead and install Caveman now if that's okay with you."
|
|
5
|
+
- "✓ 7 skills · 6 hooks · 1 MCP" not "Caveman was successfully installed with seven skills, six hooks, and one MCP server."
|
|
6
|
+
- "✗ verify exit 1. Run `make verify` directly." not "Unfortunately the verification step failed; you might want to try running make verify directly to investigate."
|
|
7
|
+
|
|
8
|
+
**Goal:** install Flow into a project (and globally where needed), delegating to upstream installers for BMad and ECC, configuring MCP servers, scaffolding `docs/flow/`, and recording everything in `install-state.json` so `repair`, `update`, and `uninstall` work later.
|
|
9
|
+
|
|
10
|
+
**Authority:** the catalog at `catalog.yaml` is the single source of truth for available components, profiles, adapters, MCPs, and upstream presets. This workflow reads it; it does not duplicate its contents.
|
|
11
|
+
|
|
12
|
+
**Idempotency:** re-running `/flow-init` on a project that's already configured re-reads `install-state.json`, presents the current state, and offers `--update` or `--repair` rather than reinstalling blindly.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
<workflow>
|
|
17
|
+
|
|
18
|
+
<step n="1" goal="Locate the catalog and existing state">
|
|
19
|
+
<action>Resolve `{{repo_root}}`:
|
|
20
|
+
- If env `FLOW_REPO_ROOT` is set, use it.
|
|
21
|
+
- Else if running from `~/.claude/skills/flow-init/`, walk up to find a directory containing `catalog.yaml` (npm install path is typically `~/.npm-global/lib/node_modules/@mhd-ghaith-abtah/flow/`).
|
|
22
|
+
- Else if the CWD contains `catalog.yaml`, use the CWD (dev mode).
|
|
23
|
+
- Else HALT with "catalog.yaml not found — re-install Flow (clone https://github.com/mhd-ghaith-abtah/flow and run `tools/dev-link.sh`, or wait for npm v0.7).".
|
|
24
|
+
</action>
|
|
25
|
+
|
|
26
|
+
<action>Load `{{catalog}}` from `{{repo_root}}/catalog.yaml`. Validate against `{{repo_root}}/schemas/catalog.schema.json` if present.</action>
|
|
27
|
+
|
|
28
|
+
<action>Determine scopes:
|
|
29
|
+
- `{{home_scope_root}}` = `$HOME/.claude`
|
|
30
|
+
- `{{project_scope_root}}` = `$CWD/.claude`
|
|
31
|
+
</action>
|
|
32
|
+
|
|
33
|
+
<action>Read `{{home_state}}` from `{{home_scope_root}}/flow/install-state.json` if it exists, else initialize empty.</action>
|
|
34
|
+
<action>Read `{{project_state}}` from `{{project_scope_root}}/flow/install-state.json` if it exists, else initialize empty.</action>
|
|
35
|
+
</step>
|
|
36
|
+
|
|
37
|
+
<step n="2" goal="Detect project shape">
|
|
38
|
+
<action>Probe in parallel:
|
|
39
|
+
- Git: `git rev-parse --show-toplevel 2>/dev/null` → `{{git_root}}`
|
|
40
|
+
- Remote: `git remote get-url origin 2>/dev/null` → `{{origin_url}}`
|
|
41
|
+
- Package manager: presence of `pnpm-lock.yaml`, `yarn.lock`, `package-lock.json`, `Cargo.toml`, `go.mod`, `requirements.txt`, etc. → `{{pkg_manager}}` + `{{primary_stack}}`
|
|
42
|
+
- Framework: scan `package.json` dependencies for next, astro, react, vue, svelte, etc. → `{{framework}}`
|
|
43
|
+
- CLAUDE.md presence: `{{has_claude_md}}`
|
|
44
|
+
- BMad: `test -d _bmad` or `test -d docs/_bmad-output` → `{{bmad_installed}}` (parse `_bmad/_config/manifest.yaml` for version if present)
|
|
45
|
+
- ECC: `test -d ~/.claude/rules/common` → `{{ecc_installed}}` (read `~/.claude/rules/VERSION` if present)
|
|
46
|
+
- MCPs already installed: `claude mcp list` → `{{existing_mcps}}` (list of names)
|
|
47
|
+
- CLIs available: probe `git`, `gh`, `glab`, `jq`, `yq`, `make`, `pnpm`, `npm`, `yarn` → `{{available_clis}}`
|
|
48
|
+
- Existing Flow install (this project): presence of `.claude/flow.config.yaml` → `{{flow_already_configured}}`
|
|
49
|
+
</action>
|
|
50
|
+
|
|
51
|
+
<output>━━━ Detected ━━━
|
|
52
|
+
- Project: {{git_root or CWD}}
|
|
53
|
+
- Stack: {{primary_stack}}{{ + framework if any}}
|
|
54
|
+
- Package manager: {{pkg_manager}}
|
|
55
|
+
- BMad: {{bmad_installed ? version : "not installed"}}
|
|
56
|
+
- ECC: {{ecc_installed ? version : "not installed"}}
|
|
57
|
+
- MCPs: {{existing_mcps.join(", ") or "none"}}
|
|
58
|
+
- CLAUDE.md: {{has_claude_md ? "present" : "missing"}}
|
|
59
|
+
- Flow: {{flow_already_configured ? "already configured" : "first install"}}
|
|
60
|
+
</output>
|
|
61
|
+
</step>
|
|
62
|
+
|
|
63
|
+
<step n="3" goal="Branch on existing install vs first-time">
|
|
64
|
+
<check if="{{flow_already_configured}} AND no --update AND no --repair flag passed">
|
|
65
|
+
<output>⚠ Flow is already configured in this project (`{{project_scope_root}}/flow.config.yaml` exists).</output>
|
|
66
|
+
<ask>What would you like to do?
|
|
67
|
+
[1] Show status and exit
|
|
68
|
+
[2] Run --update (re-resolve catalog, install delta)
|
|
69
|
+
[3] Run --repair (restore missing files from catalog)
|
|
70
|
+
[4] Re-run init from scratch (will not lose flow.config.yaml or sprint.yaml)
|
|
71
|
+
[q] Quit
|
|
72
|
+
</ask>
|
|
73
|
+
<action>Branch on user choice. For [1] delegate to `flow-status` skill (or print the state file contents). For [2] set `{{mode}} = update`. For [3] set `{{mode}} = repair`. For [4] set `{{mode}} = fresh`. For [q] HALT.</action>
|
|
74
|
+
</check>
|
|
75
|
+
<action>Default: `{{mode}} = fresh` for new installs, `update`/`repair` if flag passed.</action>
|
|
76
|
+
</step>
|
|
77
|
+
|
|
78
|
+
<step n="4" goal="Profile + customization Q&A">
|
|
79
|
+
<ask>Q1 — Profile? (matches `catalog.profiles`)
|
|
80
|
+
Recommended based on detection: {{ recommended_profile derived from: solo + 1 repo + has Makefile → standard; multi-repo or planinout-like → team; else mini }}
|
|
81
|
+
Options: minimal | mini | standard | team
|
|
82
|
+
</ask>
|
|
83
|
+
|
|
84
|
+
<ask>Q2 — Issue tracker?
|
|
85
|
+
Options for adapters in family `issue-tracker`: {{ catalog.adapters where family == issue-tracker }}
|
|
86
|
+
Default for {{profile}}: {{profile.adapters of family issue-tracker}}
|
|
87
|
+
</ask>
|
|
88
|
+
|
|
89
|
+
<ask>Q3 — PR platform? (adapters family `pr`)</ask>
|
|
90
|
+
<ask>Q4 — E2E? (adapters family `e2e`)</ask>
|
|
91
|
+
<ask>Q5 — Verify command? (adapters family `verify`)</ask>
|
|
92
|
+
|
|
93
|
+
<ask>Q6 — BMad?
|
|
94
|
+
Options: {{ catalog.upstreams.bmad.curated_subsets keys }}
|
|
95
|
+
Default for {{profile}}: {{profile.bmad_subset}}
|
|
96
|
+
</ask>
|
|
97
|
+
|
|
98
|
+
<ask>Q7 — ECC?
|
|
99
|
+
Options: {{ catalog.upstreams.ecc.curated_subsets keys }}
|
|
100
|
+
Default for {{profile}}: {{profile.ecc_subset}}
|
|
101
|
+
</ask>
|
|
102
|
+
|
|
103
|
+
<ask>Q7b — Caveman compression mode? (Flow expects Caveman installed — it cuts response tokens ~46% input / ~75% output)
|
|
104
|
+
Options: {{ catalog.upstreams.caveman.curated_subsets keys }}
|
|
105
|
+
Default for {{profile}}: {{profile.caveman_subset}} (typically `full`)
|
|
106
|
+
Choose `none` only if you have a specific reason. If Caveman isn't installed, Flow will offer to install it via curl-pipe-bash with a confirmation prompt.
|
|
107
|
+
</ask>
|
|
108
|
+
|
|
109
|
+
<check if="{{bmad_installed}} AND {{project has docs/_bmad-output/implementation-artifacts/sprint-status.yaml}}">
|
|
110
|
+
<ask>Q8 — Migrate existing BMad state to Flow?
|
|
111
|
+
[y] Import sprint-status.yaml + story files + deferred-work into docs/flow/, archive _bmad/
|
|
112
|
+
[n] Keep BMad alongside (Flow reads BMad sprint-status as fallback)
|
|
113
|
+
[skip] Don't touch BMad state
|
|
114
|
+
</ask>
|
|
115
|
+
</check>
|
|
116
|
+
|
|
117
|
+
<ask>Q9 — Where should Flow store secrets (API tokens for env-var-auth MCPs)?
|
|
118
|
+
[a] ~/.claude/.env.flow (gitignored, chmod 600) [recommended]
|
|
119
|
+
[b] I'll set env vars in my shell profile myself — just print the export lines
|
|
120
|
+
[c] 1Password CLI (`op`) — detected: {{ test -x op ? "yes" : "no" }}
|
|
121
|
+
</ask>
|
|
122
|
+
</step>
|
|
123
|
+
|
|
124
|
+
<step n="5" goal="Resolve the plan">
|
|
125
|
+
<action>Compute `{{plan}}`:
|
|
126
|
+
- Resolve profile inheritance (follow `extends:` chain in catalog)
|
|
127
|
+
- Apply user's adapter overrides (Q2–Q5)
|
|
128
|
+
- Resolve BMad delegation args (`{{bmad_cmd}}` = "npx bmad-method install" + base_args + module_arg + modules + config kvs)
|
|
129
|
+
- Resolve ECC delegation args (`{{ecc_cmd}}` = "<installer_path>" + base_args + profile_arg + profile + with/without lists)
|
|
130
|
+
- Resolve MCPs to install (union of `mcps` referenced by selected adapters + profile's mcps list, minus those already in `{{existing_mcps}}`)
|
|
131
|
+
- Resolve CLIs to install (any `needs_cli` for selected adapters not in `{{available_clis}}`)
|
|
132
|
+
- Resolve Flow's own components (always: core:flow-skills, core:flow-templates, core:flow-state-store)
|
|
133
|
+
</action>
|
|
134
|
+
|
|
135
|
+
<output>━━━ Plan ━━━
|
|
136
|
+
Flow components:
|
|
137
|
+
{{plan.flow_components — file copies, target paths}}
|
|
138
|
+
Adapters:
|
|
139
|
+
{{plan.adapters — markdown files to copy + their config keys}}
|
|
140
|
+
BMad delegation:
|
|
141
|
+
$ {{bmad_cmd}}
|
|
142
|
+
ECC delegation:
|
|
143
|
+
$ {{ecc_cmd}}
|
|
144
|
+
MCPs to install:
|
|
145
|
+
{{plan.mcps each: claude mcp add ... + scope + auth note}}
|
|
146
|
+
CLIs missing (manual install required):
|
|
147
|
+
{{plan.missing_clis with install hints from catalog}}
|
|
148
|
+
Project scaffold:
|
|
149
|
+
- .claude/flow.config.yaml
|
|
150
|
+
- docs/flow/sprint.yaml
|
|
151
|
+
- docs/flow/stories/, journeys/, retros/, archive/
|
|
152
|
+
- docs/flow/deferred.md
|
|
153
|
+
- docs/flow/README.md
|
|
154
|
+
- CLAUDE.md (Workflow section)
|
|
155
|
+
{{ if migrate_bmad: }}
|
|
156
|
+
BMad migration:
|
|
157
|
+
- sprint-status.yaml → sprint.yaml ({{N stories}})
|
|
158
|
+
- deferred-work.md → deferred.md ({{N items}})
|
|
159
|
+
- Archive _bmad/ → _bmad.archived/
|
|
160
|
+
</output>
|
|
161
|
+
|
|
162
|
+
<ask>Proceed? [Y/n/dry-run-only]</ask>
|
|
163
|
+
<check if="user chose dry-run-only OR --dry-run was passed">
|
|
164
|
+
<action>Save the plan as `{{project_scope_root}}/flow/install-plan.json`. End turn.</action>
|
|
165
|
+
</check>
|
|
166
|
+
</step>
|
|
167
|
+
|
|
168
|
+
<step n="6" goal="Execute — Flow's own files">
|
|
169
|
+
<action>For each operation in `{{plan.flow_components}}` AND `{{plan.adapters}}.ops`:
|
|
170
|
+
- **Dev-mount detection (do this FIRST for every copy op):**
|
|
171
|
+
1. Check whether `destinationPath` already exists as a symbolic link (`test -L "$destinationPath"`).
|
|
172
|
+
2. If yes, resolve it: `readlink "$destinationPath"` → `{{resolved}}`.
|
|
173
|
+
3. If `{{resolved}}` equals `sourcePath` (or matches `{{repo_root}}/...` for the source's relative form), this is a **dev-mount** placed by `tools/dev-link.sh`. SKIP the copy and record the op as `{ kind: "skip-dev-mount", destinationPath, resolves_to: resolved }` in state.
|
|
174
|
+
4. If `{{resolved}}` is anywhere else, HALT with: "Unexpected symlink at {{destinationPath}} → {{resolved}}. Refusing to overwrite. Resolve manually or pass `--force-overwrite-symlinks`."
|
|
175
|
+
- **Otherwise** (target is not a symlink, or doesn't exist):
|
|
176
|
+
- copy-file / ensure-dir / touch as specified in the operation.
|
|
177
|
+
- Record each operation in `{{home_state}}.operations` with sourcePath, destinationPath, moduleId, ownership: managed.
|
|
178
|
+
</action>
|
|
179
|
+
<output>✓ Installed {{N}} Flow files ({{skipped_count}} skipped — dev-mount detected, content already live)</output>
|
|
180
|
+
</step>
|
|
181
|
+
|
|
182
|
+
<step n="7" goal="Execute — delegate to BMad if requested">
|
|
183
|
+
<check if="{{plan.bmad_subset}} != none">
|
|
184
|
+
<action>Run `{{bmad_cmd}}` via execa (stream stdout/stderr live to user). Capture exit code.</action>
|
|
185
|
+
<check if="exit code != 0">
|
|
186
|
+
<output>⚠ BMad installer exited {{code}}. See output above. You can continue without BMad and re-run later.</output>
|
|
187
|
+
<ask>Continue Flow install? [Y/n]</ask>
|
|
188
|
+
</check>
|
|
189
|
+
<action>**Pin upstream version** (issue #12). After install: read the version from the first existing path in `catalog.upstreams.bmad.detect.version_path_candidates` (typically `_bmad/_config/manifest.yaml` → `version` field). If unparseable, store the literal commit hash from `git -C _bmad rev-parse HEAD 2>/dev/null`; if neither available, store `"unknown@{{date}}"` so doctor can still detect drift.</action>
|
|
190
|
+
<action>Record in `{{home_state}}.upstreams.bmad`: { subset, modules, exit_code, ran_at, version: <pinned-version> }</action>
|
|
191
|
+
</check>
|
|
192
|
+
</step>
|
|
193
|
+
|
|
194
|
+
<step n="8" goal="Execute — delegate to ECC if requested">
|
|
195
|
+
<check if="{{plan.ecc_subset}} != none">
|
|
196
|
+
<action>Resolve `{{ecc_installer_path}}` from catalog.upstreams.ecc.detect.installer_path_candidates. If none found, fall back to `npx @everything-claude-code/ecc install`.</action>
|
|
197
|
+
<action>Run `{{ecc_cmd}}` via execa (stream live). Capture exit code.</action>
|
|
198
|
+
<action>**Pin upstream version** (issue #12). After install: read `~/.claude/rules/VERSION` (path from `catalog.upstreams.ecc.detect.version_path`). If absent, fall back to `git -C ~/.claude/rules log -1 --format=%H 2>/dev/null` or `"unknown@{{date}}"`.</action>
|
|
199
|
+
<action>Record in `{{home_state}}.upstreams.ecc`: { subset, profile, exit_code, ran_at, version: <pinned-version> }</action>
|
|
200
|
+
</check>
|
|
201
|
+
</step>
|
|
202
|
+
|
|
203
|
+
<step n="8b" goal="Execute — install Caveman (default: required for all profiles)">
|
|
204
|
+
<check if="{{plan.caveman_subset}} != none">
|
|
205
|
+
<action>Run detection: `{{catalog.upstreams.caveman.detect.check_cmd}}` → `{{caveman_present}}`.</action>
|
|
206
|
+
|
|
207
|
+
<check if="{{caveman_present}} == true">
|
|
208
|
+
<output>✓ Caveman already installed — leaving in place.</output>
|
|
209
|
+
<action>**Pin upstream version** (issue #12). Read Caveman's installed version: try `cat ~/.claude/plugins/cache/caveman/caveman/*/package.json | jq -r .version 2>/dev/null` then `cat ~/.claude/skills/caveman/SKILL.md | grep -oE 'version: [0-9.]+' | head -1` then fall back to `"unknown@{{date}}"`.</action>
|
|
210
|
+
<action>Record in `{{home_state}}.upstreams.caveman`: { subset, mode, installed: pre-existing, ran_at, version: <pinned-version> }.</action>
|
|
211
|
+
</check>
|
|
212
|
+
|
|
213
|
+
<check if="{{caveman_present}} == false">
|
|
214
|
+
<output>📦 Caveman not detected. About to install via curl-pipe-bash:
|
|
215
|
+
|
|
216
|
+
$ {{catalog.upstreams.caveman.installer.cmd}}
|
|
217
|
+
|
|
218
|
+
Caveman is an output-compression layer ({{plan.caveman_subset}} mode). It modifies all Claude Code sessions globally to cut response tokens.
|
|
219
|
+
Source: {{catalog.upstreams.caveman.repo}}
|
|
220
|
+
</output>
|
|
221
|
+
|
|
222
|
+
<check if="$FLOW_INSPECT_INSTALL_SCRIPTS == 1">
|
|
223
|
+
<action>Download the script to `/tmp/caveman-install.sh` first. Compute + print:
|
|
224
|
+
- File path
|
|
225
|
+
- `wc -l` count
|
|
226
|
+
- SHA-256: `shasum -a 256 /tmp/caveman-install.sh | cut -d' ' -f1`
|
|
227
|
+
|
|
228
|
+
This lets the user cross-check the hash against a known-good value before running.
|
|
229
|
+
Ask "Inspect? [Y/n]" — if Y, print the file. Then ask "Run? [Y/n]".
|
|
230
|
+
</action>
|
|
231
|
+
</check>
|
|
232
|
+
<check if="$FLOW_INSPECT_INSTALL_SCRIPTS != 1 AND NOT --yes">
|
|
233
|
+
<ask>Run the curl-pipe-bash install? [Y/n/inspect]</ask>
|
|
234
|
+
<check if="user picks inspect">
|
|
235
|
+
<action>Switch behavior to download-first (as if $FLOW_INSPECT_INSTALL_SCRIPTS=1). Re-ask.</action>
|
|
236
|
+
</check>
|
|
237
|
+
</check>
|
|
238
|
+
|
|
239
|
+
<action>Execute the install command via Bash. Stream output. Capture exit code.</action>
|
|
240
|
+
<action>Verify install: run `{{catalog.upstreams.caveman.installer.verify_after_cmd}}`. If it fails, HALT with "Caveman installer reported success but verification failed. Check {{path}}".</action>
|
|
241
|
+
|
|
242
|
+
<action>Set Caveman mode to `{{plan.caveman_mode}}` (from the chosen subset). Caveman's install script may handle this; if not, document the post-install command the user should run (e.g. `/caveman full`).</action>
|
|
243
|
+
|
|
244
|
+
<action>**Pin upstream version** (issue #12). Read Caveman's installed version (same resolution chain as the pre-existing branch above). If install was successful but version can't be read, store `"installed-{{date}}"`.</action>
|
|
245
|
+
<action>Record in `{{home_state}}.upstreams.caveman`: { subset, mode, installed_at, source: "curl-pipe-bash", repo, exit_code, version: <pinned-version> }.</action>
|
|
246
|
+
</check>
|
|
247
|
+
|
|
248
|
+
<!-- Project-scope opt-in (issue #9 follow-up). Upstream Caveman PR
|
|
249
|
+
https://github.com/JuliusBrussee/caveman/pull/407 added project-scope
|
|
250
|
+
gating via .caveman-disable / .caveman-enable marker files in CWD.
|
|
251
|
+
Flow drops the enable marker so this project always activates caveman
|
|
252
|
+
even if the user later flips the global default to off (e.g., because
|
|
253
|
+
they don't want caveman in unrelated repos). Idempotent — re-running
|
|
254
|
+
/flow-init is safe. -->
|
|
255
|
+
<action>Drop `.caveman-enable` marker (zero-byte file) in the project root if not already present. This makes the project's intent explicit: "caveman ON here regardless of global default". Useful for teams where some developers run Caveman in only-Flow-projects allowlist mode.</action>
|
|
256
|
+
</check>
|
|
257
|
+
|
|
258
|
+
<check if="{{plan.caveman_subset}} == none">
|
|
259
|
+
<output>⚠ Caveman skipped via explicit `none` subset. Flow's outputs may consume more tokens than expected. To re-enable later: `/flow init --update` and pick a caveman_subset.</output>
|
|
260
|
+
</check>
|
|
261
|
+
</step>
|
|
262
|
+
|
|
263
|
+
<step n="9" goal="Execute — install MCPs">
|
|
264
|
+
<action>For each MCP in `{{plan.mcps}}`:
|
|
265
|
+
1. Run `{{mcp.install_cmd}}` (typically `claude mcp add <name> npx <package>`). Stream output.
|
|
266
|
+
2. If `{{mcp.auth}} == api_token`:
|
|
267
|
+
- For each env var in `{{mcp.env}}`:
|
|
268
|
+
- Prompt user (mask if `secret: true`)
|
|
269
|
+
- Append to chosen secrets store (`.env.flow` / shell-profile-instructions / 1Password)
|
|
270
|
+
3. If `{{mcp.auth}} == oauth_browser`:
|
|
271
|
+
- Print `{{mcp.auth_instructions}}` verbatim
|
|
272
|
+
- Mark in state: `auth: pending`
|
|
273
|
+
4. Verify reachable: re-run `claude mcp list` and confirm the MCP appears.
|
|
274
|
+
5. Record in `{{home_state}}.mcps[mcp.id]`.
|
|
275
|
+
</action>
|
|
276
|
+
|
|
277
|
+
<action>For each MCP runtime_dep (e.g., Playwright Chromium download), run the install_cmd in the project root.</action>
|
|
278
|
+
</step>
|
|
279
|
+
|
|
280
|
+
<step n="10" goal="Scaffold project files">
|
|
281
|
+
<action>Write `{{project_scope_root}}/flow.config.yaml` from `{{repo_root}}/templates/flow.config.yaml.tmpl`, filling in:
|
|
282
|
+
- mode = {{profile}}
|
|
283
|
+
- active adapters = {{user's picks}}
|
|
284
|
+
- integrations = config keys collected from selected adapters
|
|
285
|
+
- secrets_store choice from Q9
|
|
286
|
+
</action>
|
|
287
|
+
|
|
288
|
+
<action>Create directories: `docs/flow/{stories,journeys,retros,archive}`.</action>
|
|
289
|
+
<action>Write `docs/flow/sprint.yaml` from `{{repo_root}}/templates/sprint.yaml.tmpl` (empty stories list).</action>
|
|
290
|
+
<action>Write `docs/flow/deferred.md` (empty header).</action>
|
|
291
|
+
<action>Write `docs/flow/README.md` from `{{repo_root}}/templates/flow-readme.md.tmpl`.</action>
|
|
292
|
+
|
|
293
|
+
<check if="{{has_claude_md}}">
|
|
294
|
+
<action>Append the Flow Workflow section from `{{repo_root}}/templates/claude-md-section.md.tmpl` to `CLAUDE.md`, marked with `<!-- flow-managed:begin -->` / `<!-- flow-managed:end -->` so future updates can replace cleanly.</action>
|
|
295
|
+
</check>
|
|
296
|
+
<check if="NOT {{has_claude_md}}">
|
|
297
|
+
<action>Write a minimal `CLAUDE.md` that includes the Flow section + a TODO marker for project-specific guidance.</action>
|
|
298
|
+
</check>
|
|
299
|
+
</step>
|
|
300
|
+
|
|
301
|
+
<step n="11" goal="Migrate BMad state if user opted in (Q8)">
|
|
302
|
+
<check if="user answered yes to Q8">
|
|
303
|
+
<!-- Backup + rollback (issue #19). Stage backups before ANY write so the
|
|
304
|
+
user can restore if the migration produces a malformed sprint.yaml. -->
|
|
305
|
+
<action>**Backup before migration.** Set `{{backup_ts}}` = `date -u +%Y%m%dT%H%M%SZ`. Copy:
|
|
306
|
+
- `docs/_bmad-output/implementation-artifacts/sprint-status.yaml` → `docs/_bmad-output/implementation-artifacts/sprint-status.yaml.flow-backup-{{backup_ts}}`
|
|
307
|
+
- `docs/_bmad-output/implementation-artifacts/deferred-work.md` → `…/deferred-work.md.flow-backup-{{backup_ts}}` (if present)
|
|
308
|
+
- Any pre-existing `docs/flow/sprint.yaml` → `docs/flow/sprint.yaml.flow-backup-{{backup_ts}}` (if Flow is re-migrating into a non-empty target)
|
|
309
|
+
|
|
310
|
+
Record the backup paths in `{{project_state}}.migrations.bmad.backups = [<path>, …]`. If any copy fails, HALT — do NOT proceed with the migration.
|
|
311
|
+
</action>
|
|
312
|
+
|
|
313
|
+
<action>Read `docs/_bmad-output/implementation-artifacts/sprint-status.yaml`. For each story key matching `e\d+-s\d+-...`:
|
|
314
|
+
- Parse epic + story number + title
|
|
315
|
+
- Map BMad status → Flow status (backlog→backlog, ready-for-dev→backlog, in-progress→doing, review→review, done→done)
|
|
316
|
+
- Append entry to `docs/flow/sprint.yaml` under `stories:`
|
|
317
|
+
- Generate `docs/flow/stories/E{N}-S{M}-{title}.md` stub using `{{repo_root}}/templates/story.md.tmpl`, prefilling title + epic + sprint-status
|
|
318
|
+
</action>
|
|
319
|
+
|
|
320
|
+
<action>**Validate the produced sprint.yaml.** Parse it; if the parse fails OR the produced file has zero stories when the source had non-zero, treat the migration as failed → restore each backed-up file from its `.flow-backup-{{backup_ts}}` snapshot, delete the produced files, and HALT with the parse error. The user can fix sprint-status.yaml and re-run `flow-init --update --migrate-bmad`.</action>
|
|
321
|
+
|
|
322
|
+
<action>Read `docs/_bmad-output/implementation-artifacts/deferred-work.md`. For each non-folded entry, append a one-line summary to `docs/flow/deferred.md`.</action>
|
|
323
|
+
|
|
324
|
+
<action>**Do NOT rename or remove `_bmad/`.** Leave it in place so BMad slash commands keep working in this project (the global `bmad-*` skills resolve `_bmad/scripts/...` paths relative to project root). Flow ignores it. The user can archive manually later via `mv _bmad _bmad.archived` once they're sure they're done with BMad in this project, or run `flow uninstall --archive-bmad` in v0.2+.</action>
|
|
325
|
+
|
|
326
|
+
<action>Keep `docs/_bmad-output/planning-artifacts/` in place as reference docs (Flow's `flow.config.yaml > reference_docs` points at it).</action>
|
|
327
|
+
|
|
328
|
+
<action>Record migration in `{{project_state}}.migrations.bmad`: { from_version, stories_imported, deferred_imported, bmad_kept_in_place: true, backups: [<paths>], backup_ts: {{backup_ts}} }</action>
|
|
329
|
+
|
|
330
|
+
<output>✓ Migration complete.
|
|
331
|
+
|
|
332
|
+
Backups staged at `*.flow-backup-{{backup_ts}}` next to the original BMad files. To roll back:
|
|
333
|
+
|
|
334
|
+
rm -rf docs/flow/
|
|
335
|
+
git checkout flow.config.yaml # if it was new
|
|
336
|
+
mv docs/_bmad-output/implementation-artifacts/sprint-status.yaml.flow-backup-{{backup_ts}} \
|
|
337
|
+
docs/_bmad-output/implementation-artifacts/sprint-status.yaml
|
|
338
|
+
|
|
339
|
+
Or run `flow uninstall --restore-backup {{backup_ts}}` once that command lands in v0.2.
|
|
340
|
+
</output>
|
|
341
|
+
</check>
|
|
342
|
+
</step>
|
|
343
|
+
|
|
344
|
+
<step n="11b" goal="Optional planning audit (post-migration)">
|
|
345
|
+
<!-- If the migration brought in a non-trivial number of stories, offer to
|
|
346
|
+
run a scope review immediately. Catches over-scoped epics-stories.md
|
|
347
|
+
early — before the user is committed to executing 40+ stories. -->
|
|
348
|
+
<check if="migrated_stories_count > 10">
|
|
349
|
+
<output>📋 Migrated {{migrated_stories_count}} stories across {{migrated_epics_count}} epics from BMad.
|
|
350
|
+
|
|
351
|
+
That's a lot of scope. Before you start executing, worth a 5-min scope review? It reads sprint.yaml + story files + PRD/architecture (if present in reference_docs) and proposes merges / drops / splits / adds.
|
|
352
|
+
|
|
353
|
+
Output: `docs/flow/scope-reviews/{{date}}.md` — review then apply interactively.
|
|
354
|
+
</output>
|
|
355
|
+
<ask>Run scope review now? [Y/n/later]
|
|
356
|
+
Y → invoke `/flow-sprint scope-review --include-prd` immediately
|
|
357
|
+
n → skip; you can still run it any time
|
|
358
|
+
later → record a midpoint reminder so /flow-sprint status prompts you again at 50% done
|
|
359
|
+
</ask>
|
|
360
|
+
|
|
361
|
+
<check if="user picks Y">
|
|
362
|
+
<action>Invoke `flow-sprint` skill via Skill tool with arg `scope-review --include-prd`. The user will iterate through suggestions interactively per that skill's flow.</action>
|
|
363
|
+
</check>
|
|
364
|
+
<check if="user picks later">
|
|
365
|
+
<action>Set `docs/flow/sprint.yaml > metadata.scope_review_pending = true` (defaults the midpoint prompt to "high signal" so it surfaces more prominently when reached).</action>
|
|
366
|
+
</check>
|
|
367
|
+
</check>
|
|
368
|
+
</step>
|
|
369
|
+
|
|
370
|
+
<step n="12" goal="Persist state">
|
|
371
|
+
<action>Write `{{home_state}}` to `{{home_scope_root}}/flow/install-state.json` (pretty JSON, schema version `flow.install.v1`).</action>
|
|
372
|
+
<action>Write `{{project_state}}` to `{{project_scope_root}}/flow/install-state.json`.</action>
|
|
373
|
+
<action>Ensure `{{project_scope_root}}/flow/install-state.json` is in `.gitignore` (don't commit secrets references).</action>
|
|
374
|
+
<action>Ensure `flow.config.local.yaml` is in `.gitignore` (per-developer override of `flow.config.yaml`; the base config IS committed for team-share, the local override is not).</action>
|
|
375
|
+
<action>Ensure `~/.claude/.env.flow` has `chmod 600` if it was created in Q9.</action>
|
|
376
|
+
</step>
|
|
377
|
+
|
|
378
|
+
<step n="13" goal="Smoke test (flow doctor inline)">
|
|
379
|
+
<action>Invoke the doctor checklist:
|
|
380
|
+
- All selected adapter files present at expected paths
|
|
381
|
+
- All selected MCPs reachable (`claude mcp list`)
|
|
382
|
+
- All required CLIs in $PATH
|
|
383
|
+
- flow.config.yaml validates against schema
|
|
384
|
+
- sprint.yaml parses
|
|
385
|
+
- Secrets file readable if used
|
|
386
|
+
- BMad / ECC paths recorded match what's actually installed
|
|
387
|
+
</action>
|
|
388
|
+
<output>━━━ Smoke ━━━
|
|
389
|
+
{{table of checks with ✓ / ✗}}
|
|
390
|
+
</output>
|
|
391
|
+
</step>
|
|
392
|
+
|
|
393
|
+
<step n="14" goal="Done">
|
|
394
|
+
<output>🎯 Flow installed.
|
|
395
|
+
|
|
396
|
+
Profile: {{profile}}
|
|
397
|
+
Adapters: {{summary}}
|
|
398
|
+
MCPs: {{installed mcps}}
|
|
399
|
+
{{ if any auth: pending: "Action required: complete OAuth for {{mcps}} (instructions printed above)." }}
|
|
400
|
+
|
|
401
|
+
Next steps:
|
|
402
|
+
/flow-sprint add "<title>" --epic E1 --tags <list> # add a story
|
|
403
|
+
/flow-sprint status # show sprint
|
|
404
|
+
/flow-sprint next # start work on the next backlog story
|
|
405
|
+
/flow-story # advance the active story
|
|
406
|
+
flow doctor # health check anytime
|
|
407
|
+
</output>
|
|
408
|
+
</step>
|
|
409
|
+
|
|
410
|
+
</workflow>
|
|
411
|
+
|
|
412
|
+
---
|
|
413
|
+
|
|
414
|
+
## Handling failures
|
|
415
|
+
|
|
416
|
+
- **BMad installer fails:** the user can re-run `flow install --profile <p> --bmad-subset <s>` once the upstream issue is fixed. Flow records the attempted command in state so the user can re-paste it.
|
|
417
|
+
- **ECC installer fails:** same — `flow install --profile <p> --ecc-subset <s>` is the re-run.
|
|
418
|
+
- **MCP install fails (network, package not found):** Flow halts the MCP phase, records the failure, lets the user pick a different adapter (e.g., issue-tracker-none instead of linear) and re-runs install.
|
|
419
|
+
- **Migration parser fails on BMad sprint-status.yaml:** Flow falls back to "no migration" mode and prints the parse error so the user can fix the YAML and re-run with `--migrate-bmad`.
|
|
420
|
+
- **CLAUDE.md append collision (existing flow-managed block):** Flow refuses to silently overwrite; emits a diff and asks the user to confirm.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: flow-sprint
|
|
3
|
+
description: 'Sprint state manager for Flow. Maintains docs/flow/sprint.yaml: add epics, add stories, mark next, flip status, run retros, list deferred items, scope-review (audit + adjust scope mid-flight). Subcommands: init | add-epic | add | next | status | done | deferred | retro | import-bmad | scope-review. Use when the user runs /flow-sprint, /flow-sprint <subcommand>, or asks to track sprint state.'
|
|
4
|
+
argument-hint: '<add-epic|add|next|status|done|deferred|retro|import-bmad|scope-review> [args]'
|
|
5
|
+
version: 0.5.0
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
Follow the instructions in ./workflow.md.
|
|
9
|
+
|
|
10
|
+
`sprint.yaml` lives at `docs/flow/sprint.yaml` (configurable via `flow.config.yaml > sprint_file`). All operations are read-modify-write — never lose comments or formatting. Every status flip also calls the active `issue-tracker` adapter (loaded from `flow.config.yaml > adapters.issue_tracker`) so external state stays in sync.
|