@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.
Files changed (53) hide show
  1. package/CHANGELOG.md +87 -0
  2. package/LICENSE +21 -0
  3. package/README.md +162 -0
  4. package/adapters/e2e/_interface.md +42 -0
  5. package/adapters/e2e/none.md +15 -0
  6. package/adapters/e2e/playwright-mcp.md +86 -0
  7. package/adapters/issue-tracker/_interface.md +46 -0
  8. package/adapters/issue-tracker/github-issues.md +103 -0
  9. package/adapters/issue-tracker/linear.md +65 -0
  10. package/adapters/issue-tracker/none.md +26 -0
  11. package/adapters/pr/_interface.md +29 -0
  12. package/adapters/pr/github.md +61 -0
  13. package/adapters/pr/none.md +32 -0
  14. package/adapters/verify/_interface.md +26 -0
  15. package/adapters/verify/custom.md +27 -0
  16. package/adapters/verify/make.md +30 -0
  17. package/adapters/verify/pnpm.md +27 -0
  18. package/bin/flow.js +129 -0
  19. package/catalog.yaml +364 -0
  20. package/docs/adapters.md +99 -0
  21. package/docs/migrate-from-bmad.md +95 -0
  22. package/docs/profiles.md +81 -0
  23. package/docs/quickstart.md +82 -0
  24. package/lib/catalog.js +164 -0
  25. package/lib/commands/add.js +147 -0
  26. package/lib/commands/doctor.js +392 -0
  27. package/lib/commands/init.js +86 -0
  28. package/lib/commands/install.js +181 -0
  29. package/lib/commands/plan.js +108 -0
  30. package/lib/commands/remove.js +87 -0
  31. package/lib/commands/uninstall.js +157 -0
  32. package/lib/repo-root.js +53 -0
  33. package/package.json +62 -0
  34. package/schemas/catalog.schema.json +155 -0
  35. package/schemas/flow-config.schema.json +85 -0
  36. package/schemas/install-state.schema.json +79 -0
  37. package/skills/flow-doctor/SKILL.md +15 -0
  38. package/skills/flow-doctor/workflow.md +157 -0
  39. package/skills/flow-init/SKILL.md +10 -0
  40. package/skills/flow-init/workflow.md +420 -0
  41. package/skills/flow-sprint/SKILL.md +10 -0
  42. package/skills/flow-sprint/workflow.md +394 -0
  43. package/skills/flow-story/SKILL.md +12 -0
  44. package/skills/flow-story/workflow.md +531 -0
  45. package/templates/claude-md-section.md.tmpl +55 -0
  46. package/templates/flow-readme.md.tmpl +34 -0
  47. package/templates/flow.config.yaml.tmpl +94 -0
  48. package/templates/pr.md.tmpl +40 -0
  49. package/templates/retro.md.tmpl +58 -0
  50. package/templates/sprint.yaml.tmpl +18 -0
  51. package/templates/story.md.tmpl +35 -0
  52. package/tools/fix-caveman-shrink.sh +68 -0
  53. package/tools/lint-changelog.js +98 -0
@@ -0,0 +1,94 @@
1
+ # Flow project configuration — generated by /flow-init.
2
+ # Re-run /flow-init --update to regenerate. Hand-edit when needed.
3
+ #
4
+ # This file is intended to be **committed** — it captures team-wide conventions
5
+ # (adapter choices, review policy, verify command, etc) with no secrets. Per-
6
+ # developer overrides live in `flow.config.local.yaml` (gitignored) which Flow
7
+ # merges on top of this one when both are present. Secrets live in
8
+ # `~/.claude/.env.flow` (chmod 600, never committed).
9
+
10
+ version: 1
11
+ generated: {{date}}
12
+ flow_version: {{flow_version}}
13
+
14
+ # Mode controls how much ceremony flow-story applies per story.
15
+ mode: {{mode}} # mini | standard | team
16
+
17
+ # File paths (relative to project root)
18
+ sprint_file: docs/flow/sprint.yaml
19
+ stories_dir: docs/flow/stories
20
+ journeys_dir: docs/flow/journeys
21
+ retros_dir: docs/flow/retros
22
+ archive_dir: docs/flow/archive
23
+ deferred_file: docs/flow/deferred.md
24
+ artifacts_dir: docs/flow/artifacts
25
+
26
+ # Active adapters — pick one per category. Swap with /flow adapter swap.
27
+ adapters:
28
+ issue_tracker: {{adapters.issue_tracker}} # linear | github-issues | none | ...
29
+ pr: {{adapters.pr}} # github | gitlab | none | ...
30
+ e2e: {{adapters.e2e}} # playwright-mcp | playwright-cli | none | ...
31
+ verify: {{adapters.verify}} # make | pnpm | custom | ...
32
+
33
+ # Adapter config (consumed by the active adapters above)
34
+ integrations:
35
+ {{#if adapters.issue_tracker == 'github-issues'}}
36
+ issue_tracker:
37
+ repo: {{integrations.issue_tracker.repo}}
38
+ label_prefix: flow
39
+ {{/if}}
40
+ {{#if adapters.issue_tracker == 'linear'}}
41
+ issue_tracker:
42
+ team_key: {{integrations.issue_tracker.team_key}}
43
+ {{/if}}
44
+ {{#if adapters.e2e == 'playwright-mcp'}}
45
+ e2e:
46
+ base_url: {{integrations.e2e.base_url}}
47
+ journeys_dir: docs/flow/journeys
48
+ viewport: { width: 1280, height: 720 }
49
+ {{/if}}
50
+ {{#if adapters.verify == 'pnpm'}}
51
+ verify:
52
+ script: {{integrations.verify.script}}
53
+ {{/if}}
54
+ {{#if adapters.verify == 'custom'}}
55
+ verify:
56
+ command: "{{integrations.verify.command}}"
57
+ {{/if}}
58
+
59
+ # Review behaviour
60
+ review:
61
+ use_separate_model: {{review.use_separate_model}} # team mode → true; spawns reviewer agent with model override
62
+ auto_hard_review_tags: [auth, payments, migration, pii, security]
63
+ language_reviewer: {{review.language_reviewer}} # e.g. typescript-reviewer | python-reviewer | null
64
+ barrier_timeout_seconds: 900 # max wall-clock to wait on background reviewers before halting (default 15 min)
65
+
66
+ # PR behaviour
67
+ pr:
68
+ auto_merge_wait_seconds: 90 # single bounded wait under --auto-merge; CI longer than this → end turn + handoff
69
+
70
+ # Implementation behaviour
71
+ implement:
72
+ default: prp-implement # or 'direct' (no /prp-implement wrapper)
73
+ use_tdd: {{implement.use_tdd}} # invoke /tdd before /prp-implement
74
+ e2e_auto_trigger_tags: [ui, e2e, marketing, navigation]
75
+ docs_auto_trigger: {{implement.docs_auto_trigger}} # always run /update-docs in commit phase
76
+
77
+ # Secrets storage (used by env-var-auth MCPs)
78
+ secrets:
79
+ store: {{secrets.store}} # env_file | shell | onepassword
80
+
81
+ # Reference docs (Flow does NOT regenerate these — just paths for context)
82
+ reference_docs:
83
+ {{#each reference_docs}}
84
+ - {{this}}
85
+ {{/each}}
86
+
87
+ # Upstream installs (recorded for repair / update)
88
+ upstreams:
89
+ bmad:
90
+ installed: {{upstreams.bmad.installed}}
91
+ subset: {{upstreams.bmad.subset}}
92
+ ecc:
93
+ installed: {{upstreams.ecc.installed}}
94
+ subset: {{upstreams.ecc.subset}}
@@ -0,0 +1,40 @@
1
+ ## Summary
2
+
3
+ {{summary}}
4
+
5
+ {{issue_ref}}
6
+
7
+ ## What changed
8
+
9
+ {{#each changes}}
10
+ - {{this}}
11
+ {{/each}}
12
+
13
+ ## Test plan
14
+
15
+ {{#each acceptance_criteria}}
16
+ - [ ] {{this}}
17
+ {{/each}}
18
+
19
+ {{#if has_e2e}}
20
+ ## E2E
21
+
22
+ Journey ran against {{base_url}}. Artifacts at `docs/flow/artifacts/{{story_id}}/`.
23
+
24
+ {{#each e2e_passed}}
25
+ - ✓ {{this}}
26
+ {{/each}}
27
+ {{/if}}
28
+
29
+ {{#if has_verify}}
30
+ ## Verify
31
+
32
+ ```bash
33
+ $ {{verify_cmd}}
34
+ {{verify_summary}}
35
+ ```
36
+ {{/if}}
37
+
38
+ ---
39
+
40
+ 🌊 Created via [Flow](https://github.com/mhd-ghaith-abtah/flow) · story `{{story_id}}`
@@ -0,0 +1,58 @@
1
+ # {{epic_id}} — {{epic_title}} — Retro
2
+
3
+ *Generated by /flow-sprint retro on {{date}}*
4
+
5
+ ## Shipped
6
+
7
+ - **{{shipped_count}} stories**, {{commit_count}} commits, {{pr_count}} PRs
8
+ - **Cycle time:** {{avg_cycle_days}} days/story (median {{median_cycle_days}})
9
+ - **Date range:** {{date_start}} → {{date_end}}
10
+
11
+ ### Stories
12
+
13
+ {{#each stories}}
14
+ - ✓ {{this.id}} {{this.title}} ({{this.cycle_days}}d)
15
+ {{/each}}
16
+
17
+ ## What worked
18
+
19
+ <!-- 2-4 bullets. Concrete, not platitudes. Examples:
20
+ - Tokens-first approach kept components consistent (E1-002, E1-003 reused tokens cleanly)
21
+ - Playwright MCP smoke test caught a console error in E1-002 (PR #14)
22
+ -->
23
+
24
+ -
25
+
26
+ ## What didn't
27
+
28
+ <!-- 1-3 bullets. Specific cases, not generalities. Examples:
29
+ - E1-004 theme switcher hit a Tailwind v4 SSR issue mid-implement; scope expanded — should have planned with /plan first
30
+ - Two deferred items still open (see deferred.md): X, Y
31
+ -->
32
+
33
+ -
34
+
35
+ ## Carry into next epic
36
+
37
+ <!-- Adjustments to make next time. Examples:
38
+ - Always use /plan for stories tagged 'client-side'
39
+ - Add a `client_side: true` story field that triggers --plan auto
40
+ -->
41
+
42
+ -
43
+
44
+ ## Open deferred items at epic close
45
+
46
+ {{#if open_deferred_count > 0}}
47
+ {{#each open_deferred}}
48
+ - {{this}}
49
+ {{/each}}
50
+ {{else}}
51
+ *(none)*
52
+ {{/if}}
53
+
54
+ ## Next
55
+
56
+ ```bash
57
+ /flow-sprint add "<title>" --epic E{{next_epic_num}} --tags <list>
58
+ ```
@@ -0,0 +1,18 @@
1
+ # Flow sprint state — single source of truth for story tracking.
2
+ # Edit via /flow-sprint subcommands rather than by hand when possible.
3
+
4
+ version: 1
5
+ project: {{project_name}}
6
+ generated: {{date}}
7
+ last_updated: {{timestamp}}
8
+
9
+ # STATUS LEGEND
10
+ # backlog — not started
11
+ # doing — branch checked out, work in progress
12
+ # review — PR open, awaiting merge
13
+ # done — PR merged, story archived
14
+ # cancelled — abandoned (see story file Notes for reason)
15
+
16
+ epics: []
17
+
18
+ stories: []
@@ -0,0 +1,35 @@
1
+ # {{story_id}} — {{title}}
2
+
3
+ **Epic:** {{epic_id}} — {{epic_title}}
4
+ {{#if issue}}**Issue:** {{issue}}{{/if}}
5
+ **Tags:** {{tags_csv}}
6
+ **Status:** {{status}}
7
+
8
+ **Why:** {{why}}
9
+
10
+ {{#if refs}}
11
+ **Refs:**
12
+ {{#each refs}}
13
+ - {{this}}
14
+ {{/each}}
15
+ {{/if}}
16
+
17
+ ## Acceptance
18
+ {{#each acceptance_criteria}}
19
+ - [ ] {{this}}
20
+ {{/each}}
21
+
22
+ ## Files
23
+ {{#each files}}
24
+ - {{this}}
25
+ {{/each}}
26
+
27
+ {{#if has_e2e}}
28
+ ## E2E Journey
29
+ - navigate /
30
+ - assert visible "{{expected_heading}}"
31
+ - assert no console errors
32
+ {{/if}}
33
+
34
+ ## Notes
35
+ <!-- Decisions, deferred items, follow-ups appear here during implementation. -->
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/env bash
2
+ # tools/fix-caveman-shrink.sh — print the commands needed to fix a broken
3
+ # caveman-shrink MCP registration.
4
+ #
5
+ # Background: caveman-shrink is an MCP *proxy* — it must wrap an upstream MCP
6
+ # server (passed as extra command-line args). The Caveman installer sometimes
7
+ # registers it standalone (no upstream args), which crashes the proxy on first
8
+ # call with the error "-32000: server failed to start" because index.js exits
9
+ # immediately at the "missing upstream command" guard.
10
+ #
11
+ # This script does NOT execute `claude mcp` for you — modifying MCP
12
+ # registration affects every Claude Code session, so we print the exact
13
+ # commands and let you run them yourself.
14
+ #
15
+ # Usage:
16
+ # tools/fix-caveman-shrink.sh # wraps context7 (default)
17
+ # tools/fix-caveman-shrink.sh playwright # wrap a known preset
18
+ # tools/fix-caveman-shrink.sh 'npx -y @org/x' # pass full upstream command
19
+
20
+ set -euo pipefail
21
+
22
+ UPSTREAM="${1:-context7}"
23
+
24
+ # Bash 3.2 (macOS default) doesn't support associative arrays — use case.
25
+ case "$UPSTREAM" in
26
+ context7)
27
+ UPSTREAM_CMD="npx -y @upstash/context7-mcp@latest"
28
+ ;;
29
+ playwright)
30
+ UPSTREAM_CMD="npx -y @playwright/mcp@latest"
31
+ ;;
32
+ filesystem)
33
+ UPSTREAM_CMD="npx -y @modelcontextprotocol/server-filesystem $HOME"
34
+ ;;
35
+ *)
36
+ # Treat as a literal upstream command.
37
+ UPSTREAM_CMD="$UPSTREAM"
38
+ UPSTREAM="(custom)"
39
+ ;;
40
+ esac
41
+
42
+ cat <<EOF
43
+ ━━━ fix-caveman-shrink ━━━
44
+
45
+ caveman-shrink is registered standalone (no upstream wrap) — it will crash with
46
+ \`-32000: server failed to start\` on the first call.
47
+
48
+ To fix, run these two commands yourself (they modify your Claude Code MCP
49
+ registration globally — review them before executing):
50
+
51
+ 1. Remove the broken registration:
52
+
53
+ claude mcp remove caveman-shrink
54
+
55
+ 2. Re-add it as a wrapper around '${UPSTREAM}' (${UPSTREAM_CMD}):
56
+
57
+ claude mcp add caveman-shrink -- npx caveman-shrink ${UPSTREAM_CMD}
58
+
59
+ Verify:
60
+
61
+ claude mcp get caveman-shrink
62
+
63
+ The fixed registration should show 'caveman-shrink' followed by the upstream
64
+ command. Restart Claude Code if MCP isn't picked up.
65
+
66
+ Known upstream presets: context7, playwright, filesystem.
67
+ Or pass the full upstream command as a single arg.
68
+ EOF
@@ -0,0 +1,98 @@
1
+ #!/usr/bin/env node
2
+ // tools/lint-changelog.js — enforce CONTRIBUTING.md's "one-line entries" rule.
3
+ //
4
+ // CHANGELOG entries under ### Added / ### Changed / ### Fixed / ### Removed
5
+ // must each be a single line. A wrapped entry (a continuation line that
6
+ // doesn't start with `- `, `#`, or a blank line) is a violation. Excludes
7
+ // indented continuation under fenced code blocks and list-of-list bullets.
8
+ //
9
+ // Exit codes:
10
+ // 0 — all entries one-line
11
+ // 1 — at least one wrapped entry
12
+ // 2 — usage error / file not found
13
+
14
+ import { readFileSync, existsSync } from 'node:fs';
15
+ import { resolve } from 'node:path';
16
+
17
+ const path = process.argv[2];
18
+ if (!path) {
19
+ console.error('usage: lint-changelog.js <CHANGELOG.md>');
20
+ process.exit(2);
21
+ }
22
+ if (!existsSync(path)) {
23
+ console.error(`✗ File not found: ${path}`);
24
+ process.exit(2);
25
+ }
26
+
27
+ const text = readFileSync(resolve(path), 'utf-8');
28
+ const lines = text.split('\n');
29
+
30
+ let inEntrySection = false;
31
+ let inCodeBlock = false;
32
+ let currentEntryStart = -1; // line number of the most recent `- ` entry, or -1
33
+ const violations = [];
34
+
35
+ for (let i = 0; i < lines.length; i++) {
36
+ const line = lines[i];
37
+
38
+ // Track fenced code blocks — entries inside them are not subject to the rule.
39
+ if (line.trim().startsWith('```')) {
40
+ inCodeBlock = !inCodeBlock;
41
+ continue;
42
+ }
43
+ if (inCodeBlock) continue;
44
+
45
+ // Entry sections start with `### Added | Changed | Fixed | Removed | Deprecated | Security`.
46
+ const sectionMatch = line.match(/^###\s+(Added|Changed|Fixed|Removed|Deprecated|Security)\b/);
47
+ if (sectionMatch) {
48
+ inEntrySection = true;
49
+ currentEntryStart = -1;
50
+ continue;
51
+ }
52
+
53
+ // Any other heading ends the entry section.
54
+ if (line.startsWith('#')) {
55
+ inEntrySection = false;
56
+ currentEntryStart = -1;
57
+ continue;
58
+ }
59
+
60
+ if (!inEntrySection) continue;
61
+
62
+ // Blank line ends the current entry (no continuation).
63
+ if (line.trim() === '') {
64
+ currentEntryStart = -1;
65
+ continue;
66
+ }
67
+
68
+ // Entry line starts with `- ` (top-level bullet).
69
+ if (line.startsWith('- ')) {
70
+ currentEntryStart = i + 1; // 1-indexed
71
+ continue;
72
+ }
73
+
74
+ // Indented sub-bullet or literal block — allowed for nested lists.
75
+ if (line.startsWith(' ') || line.startsWith('\t')) {
76
+ continue;
77
+ }
78
+
79
+ // Otherwise it's wrapped prose (starts at column 0, follows a `- ` entry).
80
+ if (currentEntryStart > 0) {
81
+ violations.push({ entryLine: currentEntryStart, wrapLine: i + 1, sample: line.slice(0, 80) });
82
+ currentEntryStart = -1; // only flag once per entry
83
+ }
84
+ }
85
+
86
+ if (violations.length === 0) {
87
+ console.log(`✓ CHANGELOG entries are one-line (${path})`);
88
+ process.exit(0);
89
+ }
90
+
91
+ console.error(`✗ Found ${violations.length} wrapped CHANGELOG entr${violations.length === 1 ? 'y' : 'ies'} in ${path}:`);
92
+ for (const v of violations) {
93
+ console.error(` Line ${v.wrapLine} continues the entry that started at line ${v.entryLine}:`);
94
+ console.error(` "${v.sample}${v.sample.length === 80 ? '…' : ''}"`);
95
+ }
96
+ console.error('');
97
+ console.error('CONTRIBUTING.md requires one-line entries. Move detail into a referenced doc or split into multiple entries.');
98
+ process.exit(1);