bmalph 2.5.0 → 2.7.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 (176) hide show
  1. package/README.md +50 -36
  2. package/bmad/lite/create-prd.md +145 -0
  3. package/dist/cli.js +13 -4
  4. package/dist/cli.js.map +1 -0
  5. package/dist/commands/check-updates.js +3 -18
  6. package/dist/commands/check-updates.js.map +1 -0
  7. package/dist/commands/doctor-checks.js +103 -0
  8. package/dist/commands/doctor-checks.js.map +1 -0
  9. package/dist/commands/doctor-health-checks.js +101 -0
  10. package/dist/commands/doctor-health-checks.js.map +1 -0
  11. package/dist/commands/doctor-runtime-checks.js +143 -0
  12. package/dist/commands/doctor-runtime-checks.js.map +1 -0
  13. package/dist/commands/doctor.js +6 -372
  14. package/dist/commands/doctor.js.map +1 -0
  15. package/dist/commands/implement.js +14 -17
  16. package/dist/commands/implement.js.map +1 -0
  17. package/dist/commands/init.js +26 -47
  18. package/dist/commands/init.js.map +1 -0
  19. package/dist/commands/reset.js +7 -10
  20. package/dist/commands/reset.js.map +1 -0
  21. package/dist/commands/run.js +46 -0
  22. package/dist/commands/run.js.map +1 -0
  23. package/dist/commands/status.js +8 -46
  24. package/dist/commands/status.js.map +1 -0
  25. package/dist/commands/upgrade.js +8 -11
  26. package/dist/commands/upgrade.js.map +1 -0
  27. package/dist/commands/watch.js +5 -5
  28. package/dist/commands/watch.js.map +1 -0
  29. package/dist/installer.js +332 -78
  30. package/dist/installer.js.map +1 -0
  31. package/dist/platform/aider.js +8 -64
  32. package/dist/platform/aider.js.map +1 -0
  33. package/dist/platform/claude-code.js +6 -40
  34. package/dist/platform/claude-code.js.map +1 -0
  35. package/dist/platform/codex.js +8 -60
  36. package/dist/platform/codex.js.map +1 -0
  37. package/dist/platform/copilot.js +11 -66
  38. package/dist/platform/copilot.js.map +1 -0
  39. package/dist/platform/cursor.js +10 -65
  40. package/dist/platform/cursor.js.map +1 -0
  41. package/dist/platform/detect.js +2 -1
  42. package/dist/platform/detect.js.map +1 -0
  43. package/dist/platform/doctor-checks.js +70 -0
  44. package/dist/platform/doctor-checks.js.map +1 -0
  45. package/dist/platform/instructions-snippet.js +74 -0
  46. package/dist/platform/instructions-snippet.js.map +1 -0
  47. package/dist/platform/registry.js +7 -0
  48. package/dist/platform/registry.js.map +1 -0
  49. package/dist/platform/resolve.js +1 -0
  50. package/dist/platform/resolve.js.map +1 -0
  51. package/dist/platform/types.js +10 -1
  52. package/dist/platform/types.js.map +1 -0
  53. package/dist/platform/windsurf.js +8 -64
  54. package/dist/platform/windsurf.js.map +1 -0
  55. package/dist/reset.js +24 -27
  56. package/dist/reset.js.map +1 -0
  57. package/dist/run/ralph-process.js +95 -0
  58. package/dist/run/ralph-process.js.map +1 -0
  59. package/dist/run/run-dashboard.js +104 -0
  60. package/dist/run/run-dashboard.js.map +1 -0
  61. package/dist/run/types.js +2 -0
  62. package/dist/run/types.js.map +1 -0
  63. package/dist/transition/artifact-scan.js +6 -15
  64. package/dist/transition/artifact-scan.js.map +1 -0
  65. package/dist/transition/artifacts.js +2 -1
  66. package/dist/transition/artifacts.js.map +1 -0
  67. package/dist/transition/context.js +1 -0
  68. package/dist/transition/context.js.map +1 -0
  69. package/dist/transition/fix-plan.js +1 -0
  70. package/dist/transition/fix-plan.js.map +1 -0
  71. package/dist/transition/index.js +1 -0
  72. package/dist/transition/index.js.map +1 -0
  73. package/dist/transition/orchestration.js +19 -28
  74. package/dist/transition/orchestration.js.map +1 -0
  75. package/dist/transition/preflight.js +1 -0
  76. package/dist/transition/preflight.js.map +1 -0
  77. package/dist/transition/specs-changelog.js +3 -2
  78. package/dist/transition/specs-changelog.js.map +1 -0
  79. package/dist/transition/specs-index.js +7 -6
  80. package/dist/transition/specs-index.js.map +1 -0
  81. package/dist/transition/story-parsing.js +1 -0
  82. package/dist/transition/story-parsing.js.map +1 -0
  83. package/dist/transition/tech-stack.js +2 -1
  84. package/dist/transition/tech-stack.js.map +1 -0
  85. package/dist/transition/types.js +1 -0
  86. package/dist/transition/types.js.map +1 -0
  87. package/dist/utils/artifact-definitions.js +19 -0
  88. package/dist/utils/artifact-definitions.js.map +1 -0
  89. package/dist/utils/config.js +3 -2
  90. package/dist/utils/config.js.map +1 -0
  91. package/dist/utils/constants.js +12 -49
  92. package/dist/utils/constants.js.map +1 -0
  93. package/dist/utils/dryrun.js +1 -20
  94. package/dist/utils/dryrun.js.map +1 -0
  95. package/dist/utils/errors.js +1 -19
  96. package/dist/utils/errors.js.map +1 -0
  97. package/dist/utils/file-system.js +34 -3
  98. package/dist/utils/file-system.js.map +1 -0
  99. package/dist/utils/format-status.js +31 -0
  100. package/dist/utils/format-status.js.map +1 -0
  101. package/dist/utils/github.js +21 -8
  102. package/dist/utils/github.js.map +1 -0
  103. package/dist/utils/json.js +5 -1
  104. package/dist/utils/json.js.map +1 -0
  105. package/dist/utils/logger.js +1 -14
  106. package/dist/utils/logger.js.map +1 -0
  107. package/dist/utils/state.js +3 -2
  108. package/dist/utils/state.js.map +1 -0
  109. package/dist/utils/validate.js +18 -13
  110. package/dist/utils/validate.js.map +1 -0
  111. package/dist/watch/dashboard.js +23 -11
  112. package/dist/watch/dashboard.js.map +1 -0
  113. package/dist/watch/file-watcher.js +5 -2
  114. package/dist/watch/file-watcher.js.map +1 -0
  115. package/dist/watch/renderer.js +2 -15
  116. package/dist/watch/renderer.js.map +1 -0
  117. package/dist/watch/state-reader.js +19 -9
  118. package/dist/watch/state-reader.js.map +1 -0
  119. package/dist/watch/types.js +1 -0
  120. package/dist/watch/types.js.map +1 -0
  121. package/package.json +4 -6
  122. package/ralph/drivers/copilot.sh +89 -0
  123. package/ralph/drivers/cursor.sh +90 -0
  124. package/ralph/ralph_loop.sh +20 -13
  125. package/ralph/templates/ralphrc.template +1 -1
  126. package/slash-commands/bmalph-watch.md +2 -0
  127. package/dist/cli.d.ts +0 -1
  128. package/dist/commands/check-updates.d.ts +0 -5
  129. package/dist/commands/doctor.d.ts +0 -40
  130. package/dist/commands/implement.d.ts +0 -6
  131. package/dist/commands/init.d.ts +0 -9
  132. package/dist/commands/reset.d.ts +0 -7
  133. package/dist/commands/status.d.ts +0 -7
  134. package/dist/commands/upgrade.d.ts +0 -7
  135. package/dist/commands/watch.d.ts +0 -6
  136. package/dist/installer.d.ts +0 -33
  137. package/dist/platform/aider.d.ts +0 -2
  138. package/dist/platform/claude-code.d.ts +0 -2
  139. package/dist/platform/codex.d.ts +0 -2
  140. package/dist/platform/copilot.d.ts +0 -2
  141. package/dist/platform/cursor.d.ts +0 -2
  142. package/dist/platform/detect.d.ts +0 -7
  143. package/dist/platform/index.d.ts +0 -4
  144. package/dist/platform/index.js +0 -3
  145. package/dist/platform/registry.d.ts +0 -4
  146. package/dist/platform/resolve.d.ts +0 -8
  147. package/dist/platform/types.d.ts +0 -41
  148. package/dist/platform/windsurf.d.ts +0 -2
  149. package/dist/reset.d.ts +0 -18
  150. package/dist/transition/artifact-scan.d.ts +0 -27
  151. package/dist/transition/artifacts.d.ts +0 -1
  152. package/dist/transition/context.d.ts +0 -19
  153. package/dist/transition/fix-plan.d.ts +0 -21
  154. package/dist/transition/index.d.ts +0 -9
  155. package/dist/transition/orchestration.d.ts +0 -2
  156. package/dist/transition/preflight.d.ts +0 -6
  157. package/dist/transition/specs-changelog.d.ts +0 -3
  158. package/dist/transition/specs-index.d.ts +0 -22
  159. package/dist/transition/story-parsing.d.ts +0 -7
  160. package/dist/transition/tech-stack.d.ts +0 -3
  161. package/dist/transition/types.d.ts +0 -82
  162. package/dist/utils/config.d.ts +0 -13
  163. package/dist/utils/constants.d.ts +0 -70
  164. package/dist/utils/dryrun.d.ts +0 -7
  165. package/dist/utils/errors.d.ts +0 -63
  166. package/dist/utils/file-system.d.ts +0 -24
  167. package/dist/utils/github.d.ts +0 -83
  168. package/dist/utils/json.d.ts +0 -7
  169. package/dist/utils/logger.d.ts +0 -9
  170. package/dist/utils/state.d.ts +0 -24
  171. package/dist/utils/validate.d.ts +0 -44
  172. package/dist/watch/dashboard.d.ts +0 -4
  173. package/dist/watch/file-watcher.d.ts +0 -9
  174. package/dist/watch/renderer.d.ts +0 -16
  175. package/dist/watch/state-reader.d.ts +0 -9
  176. package/dist/watch/types.d.ts +0 -55
package/README.md CHANGED
@@ -26,23 +26,24 @@ bmalph provides:
26
26
  - `bmalph upgrade` — Update to latest versions
27
27
  - `bmalph doctor` — Check installation health
28
28
  - `bmalph implement` — Transition from BMAD to Ralph
29
+ - `bmalph run` — Start Ralph loop with live dashboard
29
30
  - `bmalph check-updates` — Check for upstream updates
30
31
  - `bmalph status` — Show project status and phase
31
32
  - `bmalph reset` — Remove all bmalph files
32
- - `bmalph watch`Live Ralph loop dashboard
33
+ - ~~`bmalph watch`~~_(deprecated)_ Use `bmalph run` instead
33
34
 
34
35
  ## Supported Platforms
35
36
 
36
37
  bmalph works with multiple AI coding assistants. Each platform gets BMAD planning (Phases 1-3). The Ralph autonomous loop (Phase 4) requires a CLI-based platform.
37
38
 
38
- | Platform | ID | Tier | Instructions File | Commands |
39
- | -------------- | ------------- | ----------------- | --------------------------------- | ----------------------------- |
40
- | Claude Code | `claude-code` | full | `CLAUDE.md` | `.claude/commands/` directory |
41
- | OpenAI Codex | `codex` | full | `AGENTS.md` | Inline in instructions file |
42
- | Cursor | `cursor` | instructions-only | `.cursor/rules/bmad.mdc` | None |
43
- | Windsurf | `windsurf` | instructions-only | `.windsurf/rules/bmad.md` | None |
44
- | GitHub Copilot | `copilot` | instructions-only | `.github/copilot-instructions.md` | None |
45
- | Aider | `aider` | instructions-only | `CONVENTIONS.md` | None |
39
+ | Platform | ID | Tier | Instructions File | Commands |
40
+ | -------------- | ------------- | ------------------- | --------------------------------- | -------------------------------- |
41
+ | Claude Code | `claude-code` | full | `CLAUDE.md` | `.claude/commands/` directory |
42
+ | OpenAI Codex | `codex` | full | `AGENTS.md` | Codex Skills (`.agents/skills/`) |
43
+ | Cursor | `cursor` | full (experimental) | `.cursor/rules/bmad.mdc` | `_bmad/COMMANDS.md` |
44
+ | Windsurf | `windsurf` | instructions-only | `.windsurf/rules/bmad.md` | `_bmad/COMMANDS.md` |
45
+ | GitHub Copilot | `copilot` | full (experimental) | `.github/copilot-instructions.md` | `_bmad/COMMANDS.md` |
46
+ | Aider | `aider` | instructions-only | `CONVENTIONS.md` | `_bmad/COMMANDS.md` |
46
47
 
47
48
  **Tiers:**
48
49
 
@@ -54,7 +55,7 @@ bmalph works with multiple AI coding assistants. Each platform gets BMAD plannin
54
55
  - Node.js 20+
55
56
  - Bash (WSL or Git Bash on Windows)
56
57
  - A supported AI coding platform (see table above)
57
- - For Ralph loop (Phase 4): Claude Code (`claude`) or Codex CLI (`codex`) in PATH
58
+ - For Ralph loop (Phase 4): Claude Code (`claude`), Codex CLI (`codex`), Copilot CLI (`copilot`), or Cursor CLI (`agent`) in PATH
58
59
 
59
60
  ## Installation
60
61
 
@@ -86,10 +87,10 @@ bmalph init
86
87
  This installs:
87
88
 
88
89
  - `_bmad/` — BMAD agents and workflows
89
- - `.ralph/` — Ralph loop, libs, templates (drivers for claude-code and codex only)
90
+ - `.ralph/` — Ralph loop, libs, templates (drivers for claude-code, codex, copilot, and cursor)
90
91
  - `bmalph/` — State management (config.json, stores selected platform)
91
92
  - Updates the platform's instructions file with BMAD workflow instructions (e.g. `CLAUDE.md`, `AGENTS.md`, `.cursor/rules/bmad.mdc`)
92
- - Installs slash commands for supported platforms (Claude Code: `.claude/commands/` directory; Codex: inline in `AGENTS.md`; other platforms: commands not installed)
93
+ - Installs slash commands for supported platforms (Claude Code: `.claude/commands/` directory; Codex: `.agents/skills/`; other platforms: `_bmad/COMMANDS.md` reference index)
93
94
 
94
95
  ### Migrating from standalone BMAD
95
96
 
@@ -157,7 +158,7 @@ Available in any phase for supporting tasks:
157
158
 
158
159
  ### Step 3: Implement with Ralph (Phase 4)
159
160
 
160
- > **Note:** Ralph is only available on **full** tier platforms (Claude Code, OpenAI Codex). Instructions-only platforms (Cursor, Windsurf, Copilot, Aider) support Phases 1-3 only.
161
+ > **Note:** Ralph is only available on **full** tier platforms (Claude Code, OpenAI Codex, GitHub Copilot, Cursor). Instructions-only platforms (Windsurf, Aider) support Phases 1-3 only. GitHub Copilot and Cursor support is experimental.
161
162
 
162
163
  Run `bmalph implement` from the terminal, or use the `/bmalph-implement` slash command in Claude Code.
163
164
 
@@ -168,16 +169,14 @@ This transitions your BMAD artifacts into Ralph's format:
168
169
  3. Copies specs to `.ralph/specs/` with changelog tracking
169
170
  4. Instructs you to start the Ralph autonomous loop
170
171
 
171
- Then start Ralph using the driver for your platform:
172
+ Then start Ralph:
172
173
 
173
174
  ```bash
174
- # Claude Code
175
- bash .ralph/drivers/claude-code.sh
176
-
177
- # OpenAI Codex
178
- bash .ralph/drivers/codex.sh
175
+ bmalph run
179
176
  ```
180
177
 
178
+ > **Advanced:** You can also run drivers directly with `bash .ralph/drivers/claude-code.sh`, `bash .ralph/drivers/codex.sh`, `bash .ralph/drivers/copilot.sh`, or `bash .ralph/drivers/cursor.sh`.
179
+
181
180
  Ralph picks stories one by one, implements with TDD, and commits. The loop stops when all stories are done or the circuit breaker triggers.
182
181
 
183
182
  ### Incremental Development
@@ -207,8 +206,9 @@ BMAD (add Epic 2) → bmalph implement → Ralph sees changes + picks up Epic 2
207
206
  | `bmalph check-updates` | Check if bundled BMAD/Ralph versions are up to date |
208
207
  | `bmalph status` | Show current project status and phase |
209
208
  | `bmalph implement` | Transition BMAD planning artifacts to Ralph format |
209
+ | `bmalph run` | Start Ralph loop with live dashboard |
210
210
  | `bmalph reset` | Remove all bmalph files from the project |
211
- | `bmalph watch` | Live dashboard showing Ralph loop status |
211
+ | `bmalph watch` | _(deprecated)_ Use `bmalph run` instead |
212
212
 
213
213
  ### Global options
214
214
 
@@ -268,8 +268,18 @@ BMAD (add Epic 2) → bmalph implement → Ralph sees changes + picks up Epic 2
268
268
  | `--dry-run` | Preview changes |
269
269
  | `--force` | Skip confirmation prompt |
270
270
 
271
+ ### run options
272
+
273
+ | Flag | Description |
274
+ | --------------------- | -------------------------------------------------------------- |
275
+ | `--driver <platform>` | Override platform driver (claude-code, codex, copilot, cursor) |
276
+ | `--interval <ms>` | Dashboard refresh interval in milliseconds (default: 2000) |
277
+ | `--no-dashboard` | Run Ralph without the dashboard overlay |
278
+
271
279
  ### watch options
272
280
 
281
+ > **Deprecated:** Use `bmalph run` instead. The `watch` command will be removed in a future release.
282
+
273
283
  | Flag | Description |
274
284
  | ----------------- | ------------------------------------------------ |
275
285
  | `--interval <ms>` | Refresh interval in milliseconds (default: 2000) |
@@ -279,8 +289,8 @@ BMAD (add Epic 2) → bmalph implement → Ralph sees changes + picks up Epic 2
279
289
  bmalph installs 51 slash commands (45 BMAD + 6 bmalph). Command delivery varies by platform:
280
290
 
281
291
  - **Claude Code** — installed as files in `.claude/commands/` (invoke with `/command-name`)
282
- - **OpenAI Codex** — inlined in `AGENTS.md` (reference agents by name)
283
- - **Cursor, Windsurf, Copilot, Aider** — not delivered as slash commands; use agents by name in chat
292
+ - **OpenAI Codex** — delivered as Codex Skills in `.agents/skills/` (invoke with `$command-name`)
293
+ - **Cursor, Windsurf, Copilot, Aider** — discoverable via `_bmad/COMMANDS.md` reference index
284
294
 
285
295
  Key commands (Claude Code syntax):
286
296
 
@@ -334,7 +344,7 @@ project/
334
344
  │ ├── planning-artifacts/ # PRD, architecture, stories
335
345
  │ ├── implementation-artifacts/ # Sprint plans (optional)
336
346
  │ └── brainstorming/ # Brainstorm sessions (optional)
337
- ├── .ralph/ # Ralph autonomous loop (drivers for claude-code and codex only)
347
+ ├── .ralph/ # Ralph autonomous loop (drivers for claude-code, codex, copilot, and cursor)
338
348
  │ ├── ralph_loop.sh # Main loop script
339
349
  │ ├── ralph_import.sh # Import requirements into Ralph
340
350
  │ ├── ralph_monitor.sh # Monitor loop progress
@@ -342,7 +352,9 @@ project/
342
352
  │ ├── RALPH-REFERENCE.md # Ralph usage reference
343
353
  │ ├── drivers/ # Platform driver scripts
344
354
  │ │ ├── claude-code.sh # Claude Code driver (uses `claude`)
345
- │ │ └── codex.sh # OpenAI Codex driver (uses `codex exec`)
355
+ │ │ ├── codex.sh # OpenAI Codex driver (uses `codex exec`)
356
+ │ │ ├── copilot.sh # GitHub Copilot driver (uses `copilot`, experimental)
357
+ │ │ └── cursor.sh # Cursor driver (uses `agent`, experimental)
346
358
  │ ├── lib/ # Shell libraries
347
359
  │ ├── docs/generated/ # Generated documentation
348
360
  │ ├── specs/ # Copied from _bmad-output during transition
@@ -369,6 +381,8 @@ Ralph is a bash loop that spawns fresh AI coding sessions using a **platform dri
369
381
 
370
382
  - **Claude Code driver** — invokes `claude` with `--allowedTools` and session resume
371
383
  - **Codex driver** — invokes `codex exec` with `--sandbox workspace-write`
384
+ - **Copilot driver** _(experimental)_ — invokes `copilot --autopilot --yolo` with plain-text output
385
+ - **Cursor driver** _(experimental)_ — invokes `agent --print --force` with NDJSON streaming
372
386
 
373
387
  Each iteration:
374
388
 
@@ -383,7 +397,7 @@ Safety mechanisms:
383
397
  - **Response analyzer** — detects stuck or repeating outputs
384
398
  - **Completion** — loop exits when all `@fix_plan.md` items are checked off
385
399
 
386
- Press `Ctrl+C` to stop the loop at any time.
400
+ Run `bmalph run` to start the loop with a live dashboard, or `bmalph run --no-dashboard` for headless mode. Press `Ctrl+C` to stop the loop at any time.
387
401
 
388
402
  ## Troubleshooting
389
403
 
@@ -420,14 +434,14 @@ ls -la .ralph/
420
434
 
421
435
  ### Common Issues
422
436
 
423
- | Scenario | Solution |
424
- | ----------------------------- | -------------------------------------------------------------- |
425
- | Commands fail before init | Run `bmalph init` first |
426
- | Transition finds no stories | Create stories in Phase 3 with `/create-epics-stories` |
427
- | Ralph stops mid-loop | Circuit breaker detected stagnation. Check `.ralph/logs/` |
428
- | Doctor reports version drift | Run `bmalph upgrade` to update bundled assets |
429
- | Wrong platform detected | Re-run `bmalph init --platform <id>` with the correct platform |
430
- | Ralph unavailable on platform | Ralph requires a full tier platform (claude-code or codex) |
437
+ | Scenario | Solution |
438
+ | ----------------------------- | ---------------------------------------------------------------------------- |
439
+ | Commands fail before init | Run `bmalph init` first |
440
+ | Transition finds no stories | Create stories in Phase 3 with `/create-epics-stories` |
441
+ | Ralph stops mid-loop | Circuit breaker detected stagnation. Check `.ralph/logs/` |
442
+ | Doctor reports version drift | Run `bmalph upgrade` to update bundled assets |
443
+ | Wrong platform detected | Re-run `bmalph init --platform <id>` with the correct platform |
444
+ | Ralph unavailable on platform | Ralph requires a full tier platform (claude-code, codex, copilot, or cursor) |
431
445
 
432
446
  ### Reset Installation
433
447
 
@@ -518,7 +532,7 @@ claude
518
532
  # Run: bmalph implement
519
533
 
520
534
  # 5. Start autonomous implementation
521
- bash .ralph/drivers/claude-code.sh
535
+ bmalph run
522
536
  ```
523
537
 
524
538
  **Other platforms:**
@@ -532,9 +546,9 @@ bash .ralph/drivers/claude-code.sh
532
546
  # 3. Reference BMAD agents by name (analyst, pm, architect)
533
547
  # Follow phases: Analysis → Planning → Solutioning
534
548
 
535
- # 4. For full tier platforms (Codex), transition to Ralph:
549
+ # 4. For full tier platforms (Codex, Copilot, Cursor), transition to Ralph:
536
550
  # Run: bmalph implement
537
- bash .ralph/drivers/codex.sh
551
+ # Then: bmalph run
538
552
  ```
539
553
 
540
554
  ## Contributing
@@ -0,0 +1,145 @@
1
+ # Condensed PRD Generator
2
+
3
+ > Single-prompt PRD generation for any AI platform. Combines BMAD-METHOD quality rules, project-type guidance, and domain requirements into one actionable reference.
4
+
5
+ ## Instructions
6
+
7
+ 1. Read the user's product brief (or ask them to describe their product)
8
+ 2. Detect the **project type** and **domain** from the brief using the tables below
9
+ 3. Apply the quality rules and generate a complete PRD
10
+ 4. The PRD should be information-dense, measurable, and traceable
11
+
12
+ ---
13
+
14
+ ## PRD Structure (9 Required Sections)
15
+
16
+ ### 1. Executive Summary
17
+ Vision, differentiator, target users. One paragraph max.
18
+
19
+ ### 2. Success Criteria
20
+ Measurable outcomes using SMART criteria:
21
+ - **S**pecific: precisely defined
22
+ - **M**easurable: quantifiable with test criteria
23
+ - **A**ttainable: realistic within constraints
24
+ - **R**elevant: aligns with business objectives
25
+ - **T**raceable: links to source requirement
26
+
27
+ ### 3. Product Scope
28
+ Define MVP, Growth, and Vision phases. What's in scope for each phase, what's explicitly out of scope.
29
+
30
+ ### 4. User Journeys
31
+ Comprehensive coverage of how users interact with the product. Each journey should map to functional requirements.
32
+
33
+ ### 5. Domain Requirements
34
+ Industry-specific compliance and regulatory requirements (if applicable). See Domain Guidance below.
35
+
36
+ ### 6. Innovation Analysis
37
+ Competitive differentiation and novel approaches (if applicable).
38
+
39
+ ### 7. Project-Type Requirements
40
+ Platform-specific and architecture-specific needs. See Project Type Guidance below.
41
+
42
+ ### 8. Functional Requirements (FRs)
43
+ Capability contract. Each FR must be:
44
+ - A **capability**, not implementation ("Users can reset password via email" not "System sends JWT")
45
+ - **Measurable** with test criteria ("loads in under 2 seconds" not "fast")
46
+ - **Specific** with concrete quantities ("up to 100 concurrent users" not "multiple users")
47
+ - **Traceable** to a user journey or success criterion
48
+
49
+ **FR Anti-Patterns to Avoid:**
50
+ - Subjective adjectives: "easy to use", "intuitive", "user-friendly", "fast", "responsive"
51
+ - Implementation leakage: technology names, specific libraries, implementation details
52
+ - Vague quantifiers: "multiple", "several", "various"
53
+ - Missing test criteria: "The system shall provide notifications" (when? how fast? to whom?)
54
+
55
+ ### 9. Non-Functional Requirements (NFRs)
56
+ Quality attributes. Each NFR must follow this template:
57
+ > "The system shall [metric] [condition] [measurement method]"
58
+
59
+ Examples:
60
+ - "API response time under 200ms for 95th percentile as measured by APM monitoring"
61
+ - "99.9% uptime during business hours as measured by cloud provider SLA"
62
+ - "Support 10,000 concurrent users as measured by load testing"
63
+
64
+ **NFR Anti-Patterns to Avoid:**
65
+ - Unmeasurable claims: "The system shall be scalable" → specify scale target
66
+ - Missing context: "Response time under 1 second" → specify percentile, load conditions
67
+
68
+ ---
69
+
70
+ ## Quality Rules
71
+
72
+ ### Information Density
73
+ Every sentence must carry information weight. Zero fluff.
74
+
75
+ **Replace:**
76
+ - "The system will allow users to..." → "Users can..."
77
+ - "It is important to note that..." → State the fact directly
78
+ - "In order to..." → "To..."
79
+
80
+ ### Traceability Chain
81
+ ```
82
+ Vision → Success Criteria → User Journeys → Functional Requirements
83
+ ```
84
+ Every FR must trace back to a user need. Every success criterion must connect to the vision.
85
+
86
+ ### Dual Audience
87
+ The PRD serves both humans (stakeholders review) and AI agents (downstream consumption for UX design, architecture, epics, and implementation). Use:
88
+ - Level 2 headings (`##`) for all main sections
89
+ - Consistent structure and patterns
90
+ - Precise, testable language
91
+
92
+ ---
93
+
94
+ ## Project Type Guidance
95
+
96
+ Detect the project type from the brief and apply the relevant guidance.
97
+
98
+ | Type | Detection Signals | Key Questions | Focus Sections | Skip Sections |
99
+ |------|------------------|---------------|----------------|---------------|
100
+ | API/Backend | API, REST, GraphQL, backend, service, endpoints | Endpoints needed? Auth method? Rate limits? Versioning? | Endpoint specs, auth model, data schemas, error codes, rate limits | UX/UI, visual design, user journeys |
101
+ | Mobile App | iOS, Android, app, mobile | Native or cross-platform? Offline needed? Push notifications? Store compliance? | Platform reqs, device permissions, offline mode, push strategy, store compliance | Desktop features, CLI commands |
102
+ | SaaS B2B | SaaS, B2B, platform, dashboard, teams, enterprise | Multi-tenant? Permission model? Subscription tiers? Integrations? | Tenant model, RBAC matrix, subscription tiers, integration list, compliance | CLI interface, mobile-first |
103
+ | Developer Tool | SDK, library, package, npm, pip, framework | Language support? Package managers? IDE integration? Documentation? | Language matrix, installation methods, API surface, code examples, migration guide | Visual design, store compliance |
104
+ | CLI Tool | CLI, command, terminal, bash, script | Interactive or scriptable? Output formats? Config method? | Command structure, output formats, config schema, scripting support | Visual design, UX principles |
105
+ | Web App | website, webapp, browser, SPA, PWA | SPA or MPA? Browser support? SEO needed? Real-time? Accessibility? | Browser matrix, responsive design, performance targets, SEO, accessibility | Native features, CLI commands |
106
+ | Desktop App | desktop, Windows, Mac, Linux, native | Cross-platform? Auto-update? System integration? Offline? | Platform support, system integration, update strategy, offline capabilities | Web SEO, mobile features |
107
+ | IoT/Embedded | IoT, embedded, device, sensor, hardware | Hardware specs? Connectivity? Power constraints? Security? OTA updates? | Hardware reqs, connectivity protocol, power profile, security model, update mechanism | Visual UI, browser support |
108
+ | Blockchain/Web3 | blockchain, crypto, DeFi, NFT, smart contract | Chain selection? Wallet integration? Gas optimization? Security audit? | Chain specs, wallet support, smart contracts, security audit, gas optimization | Traditional auth, centralized DB |
109
+ | Game | game, player, gameplay, level, character | Use the BMAD Game Module agent and workflows instead | Game brief, GDD | Most sections |
110
+
111
+ ---
112
+
113
+ ## Domain Guidance
114
+
115
+ Detect the domain from the brief and ensure mandatory requirements are included.
116
+
117
+ | Domain | Signals | Complexity | Key Concerns |
118
+ |--------|---------|------------|--------------|
119
+ | Healthcare | medical, clinical, FDA, patient, HIPAA, therapy | High | FDA approval, clinical validation, HIPAA compliance, patient safety, MFA, audit logging, PHI encryption |
120
+ | Fintech | payment, banking, trading, KYC, AML, transaction | High | PCI-DSS Level 1, AML/KYC compliance, SOX controls, financial audit trails, fraud prevention |
121
+ | GovTech | government, federal, civic, public sector, citizen | High | NIST framework, Section 508 accessibility (WCAG 2.1 AA), FedRAMP, data residency, procurement rules |
122
+ | EdTech | education, learning, student, teacher, LMS | Medium | COPPA/FERPA student privacy, accessibility, content moderation, age verification, curriculum standards |
123
+ | Aerospace | aircraft, spacecraft, aviation, drone, satellite | High | DO-178C compliance, safety certification, simulation accuracy, export controls (ITAR) |
124
+ | Automotive | vehicle, autonomous, ADAS, automotive, EV | High | ISO 26262 functional safety, V2X communication, real-time requirements, certification |
125
+ | Scientific | research, algorithm, simulation, ML, AI, data science | Medium | Reproducibility, validation methodology, statistical validity, computational resources |
126
+ | LegalTech | legal, law, contract, compliance, litigation | High | Legal ethics, bar regulations, data retention, attorney-client privilege, court integration |
127
+ | InsureTech | insurance, claims, underwriting, actuarial, policy | High | Insurance regulations by state, actuarial standards, fraud detection, regulatory reporting |
128
+ | Energy | energy, utility, grid, solar, wind, power | High | NERC grid compliance, environmental regulations, safety requirements, SCADA systems |
129
+ | Process Control | industrial automation, PLC, SCADA, DCS, OT | High | IEC 62443 OT cybersecurity, functional safety, real-time control, legacy integration |
130
+ | Building Automation | BAS, BMS, HVAC, smart building, life safety | High | Life safety codes, building energy standards, multi-trade interoperability, commissioning |
131
+ | General | (no specific signals) | Low | Standard security, user experience, performance |
132
+
133
+ **Critical:** Missing domain-specific requirements in the PRD means they'll be missed in architecture and implementation. Always check the domain table and include applicable requirements.
134
+
135
+ ---
136
+
137
+ ## Output Format
138
+
139
+ Generate the PRD as a markdown document with:
140
+ - `##` headings for each of the 9 required sections
141
+ - Tables where appropriate (user journeys, requirements)
142
+ - Specific, measurable language throughout
143
+ - No filler words or conversational padding
144
+ - Domain requirements section populated based on detected domain
145
+ - Project-type specific sections included/skipped per guidance
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
- import { resolve } from "path";
2
- import { stat } from "fs/promises";
1
+ import { resolve } from "node:path";
2
+ import { stat } from "node:fs/promises";
3
3
  import { Command } from "commander";
4
4
  import { initCommand } from "./commands/init.js";
5
5
  import { upgradeCommand } from "./commands/upgrade.js";
@@ -9,6 +9,7 @@ import { statusCommand } from "./commands/status.js";
9
9
  import { implementCommand } from "./commands/implement.js";
10
10
  import { resetCommand } from "./commands/reset.js";
11
11
  import { watchCommand } from "./commands/watch.js";
12
+ import { runCommand } from "./commands/run.js";
12
13
  import { setVerbose, setQuiet } from "./utils/logger.js";
13
14
  import { getPackageVersion } from "./installer.js";
14
15
  import { isEnoent } from "./utils/errors.js";
@@ -16,7 +17,7 @@ const program = new Command();
16
17
  program
17
18
  .name("bmalph")
18
19
  .description("BMAD-METHOD + Ralph integration — structured planning to autonomous implementation")
19
- .version(getPackageVersion())
20
+ .version(await getPackageVersion())
20
21
  .option("--verbose", "Enable debug logging")
21
22
  .option("--no-color", "Disable colored output")
22
23
  .option("--quiet", "Suppress non-essential output")
@@ -95,7 +96,15 @@ program
95
96
  .action(async (opts) => resetCommand({ ...opts, projectDir: await resolveAndValidateProjectDir() }));
96
97
  program
97
98
  .command("watch")
98
- .description("Live dashboard showing Ralph loop status, circuit breaker, and activity")
99
+ .description("[deprecated] Use 'bmalph run' instead")
99
100
  .option("--interval <ms>", "Refresh interval in milliseconds (default: 2000)")
100
101
  .action(async (opts) => watchCommand({ ...opts, projectDir: await resolveAndValidateProjectDir() }));
102
+ program
103
+ .command("run")
104
+ .description("Start Ralph loop with live dashboard")
105
+ .option("--driver <platform>", "Override platform driver (claude-code, codex, copilot, cursor)")
106
+ .option("--interval <ms>", "Dashboard refresh interval in milliseconds (default: 2000)")
107
+ .option("--no-dashboard", "Run Ralph without the dashboard overlay")
108
+ .action(async (opts) => runCommand({ ...opts, projectDir: await resolveAndValidateProjectDir() }));
101
109
  void program.parseAsync();
110
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -1,12 +1,12 @@
1
1
  import chalk from "chalk";
2
2
  import { getBundledVersions } from "../installer.js";
3
- import { checkUpstream } from "../utils/github.js";
3
+ import { checkUpstream, getErrorReason, } from "../utils/github.js";
4
4
  import { withErrorHandling } from "../utils/errors.js";
5
5
  export async function checkUpdatesCommand(options = {}) {
6
6
  await withErrorHandling(() => runCheckUpdates(options));
7
7
  }
8
8
  async function runCheckUpdates(options) {
9
- const bundled = getBundledVersions();
9
+ const bundled = await getBundledVersions();
10
10
  if (!options.json) {
11
11
  console.log(chalk.dim("Checking upstream versions...\n"));
12
12
  }
@@ -45,19 +45,4 @@ async function runCheckUpdates(options) {
45
45
  console.log(chalk.yellow("Updates available."));
46
46
  }
47
47
  }
48
- function getErrorReason(error) {
49
- switch (error.type) {
50
- case "network":
51
- return "network error";
52
- case "timeout":
53
- return "request timed out";
54
- case "rate-limit":
55
- return "rate limited";
56
- case "not-found":
57
- return "repository not found";
58
- case "api-error":
59
- return `API error (${error.status || "unknown"})`;
60
- default:
61
- return "unknown error";
62
- }
63
- }
48
+ //# sourceMappingURL=check-updates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-updates.js","sourceRoot":"","sources":["../../src/commands/check-updates.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,103 @@
1
+ import { readFile, stat } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import { readJsonFile } from "../utils/json.js";
4
+ import { isEnoent, formatError } from "../utils/errors.js";
5
+ import { CONFIG_FILE } from "../utils/constants.js";
6
+ export async function checkCommandAvailable(command) {
7
+ const { execFileSync } = await import("node:child_process");
8
+ try {
9
+ const bin = process.platform === "win32" ? "where" : "which";
10
+ execFileSync(bin, [command], { stdio: "ignore" });
11
+ return true;
12
+ }
13
+ catch {
14
+ return false;
15
+ }
16
+ }
17
+ export async function checkNodeVersion(_projectDir) {
18
+ const major = parseInt(process.versions.node.split(".")[0]);
19
+ return {
20
+ label: "Node version >= 20",
21
+ passed: major >= 20,
22
+ detail: major >= 20 ? `v${process.versions.node}` : `got v${process.versions.node}`,
23
+ hint: major >= 20 ? undefined : "Install Node.js 20+ from nodejs.org or run: nvm install 20",
24
+ };
25
+ }
26
+ export async function checkBash(_projectDir) {
27
+ const available = await checkCommandAvailable("bash");
28
+ return {
29
+ label: "bash available",
30
+ passed: available,
31
+ detail: available ? undefined : "bash not found in PATH",
32
+ hint: available
33
+ ? undefined
34
+ : process.platform === "win32"
35
+ ? "Install Git Bash or WSL: https://git-scm.com/downloads"
36
+ : "Install bash via your package manager (apt, brew, etc.)",
37
+ };
38
+ }
39
+ export async function checkJq(_projectDir) {
40
+ const available = await checkCommandAvailable("jq");
41
+ return {
42
+ label: "jq available",
43
+ passed: available,
44
+ detail: available ? undefined : "jq not found in PATH",
45
+ hint: available
46
+ ? undefined
47
+ : process.platform === "win32"
48
+ ? "Install jq: choco install jq (or: winget install jqlang.jq)"
49
+ : process.platform === "darwin"
50
+ ? "Install jq: brew install jq"
51
+ : "Install jq: sudo apt-get install jq",
52
+ };
53
+ }
54
+ export async function checkBmadDir(projectDir) {
55
+ return checkDir(join(projectDir, "_bmad"), "_bmad/ directory present", "Run: bmalph init");
56
+ }
57
+ export async function checkRalphLoop(projectDir) {
58
+ return checkFileHasContent(join(projectDir, ".ralph/ralph_loop.sh"), "ralph_loop.sh present and has content", "Run: bmalph upgrade");
59
+ }
60
+ export async function checkRalphLib(projectDir) {
61
+ return checkDir(join(projectDir, ".ralph/lib"), ".ralph/lib/ directory present", "Run: bmalph upgrade");
62
+ }
63
+ export async function checkConfig(projectDir) {
64
+ const label = "bmalph/config.json exists and valid";
65
+ const hint = "Run: bmalph init";
66
+ const path = join(projectDir, CONFIG_FILE);
67
+ try {
68
+ const data = await readJsonFile(path);
69
+ if (data === null) {
70
+ return { label, passed: false, detail: "file not found", hint };
71
+ }
72
+ return { label, passed: true };
73
+ }
74
+ catch (err) {
75
+ const msg = err instanceof Error ? err.message : "invalid";
76
+ return { label, passed: false, detail: msg, hint };
77
+ }
78
+ }
79
+ export async function checkDir(dirPath, label, hint) {
80
+ try {
81
+ const s = await stat(dirPath);
82
+ return { label, passed: s.isDirectory() };
83
+ }
84
+ catch (err) {
85
+ if (isEnoent(err)) {
86
+ return { label, passed: false, detail: "not found", hint };
87
+ }
88
+ return { label, passed: false, detail: `error: ${formatError(err)}`, hint };
89
+ }
90
+ }
91
+ export async function checkFileHasContent(filePath, label, hint) {
92
+ try {
93
+ const content = await readFile(filePath, "utf-8");
94
+ return { label, passed: content.trim().length > 0 };
95
+ }
96
+ catch (err) {
97
+ if (isEnoent(err)) {
98
+ return { label, passed: false, detail: "not found", hint };
99
+ }
100
+ return { label, passed: false, detail: `error: ${formatError(err)}`, hint };
101
+ }
102
+ }
103
+ //# sourceMappingURL=doctor-checks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor-checks.js","sourceRoot":"","sources":["../../src/commands/doctor-checks.ts"],"names":[],"mappings":"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"}