bmalph 2.2.1 → 2.4.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/README.md +162 -48
- package/dist/cli.js +14 -0
- package/dist/commands/doctor.d.ts +14 -2
- package/dist/commands/doctor.js +105 -41
- package/dist/commands/implement.d.ts +6 -0
- package/dist/commands/implement.js +82 -0
- package/dist/commands/init.d.ts +1 -0
- package/dist/commands/init.js +74 -7
- package/dist/commands/reset.d.ts +7 -0
- package/dist/commands/reset.js +81 -0
- package/dist/commands/status.js +86 -10
- package/dist/commands/upgrade.js +8 -5
- package/dist/installer.d.ts +15 -4
- package/dist/installer.js +190 -101
- package/dist/platform/aider.d.ts +2 -0
- package/dist/platform/aider.js +71 -0
- package/dist/platform/claude-code.d.ts +2 -0
- package/dist/platform/claude-code.js +87 -0
- package/dist/platform/codex.d.ts +2 -0
- package/dist/platform/codex.js +67 -0
- package/dist/platform/copilot.d.ts +2 -0
- package/dist/platform/copilot.js +71 -0
- package/dist/platform/cursor.d.ts +2 -0
- package/dist/platform/cursor.js +71 -0
- package/dist/platform/detect.d.ts +7 -0
- package/dist/platform/detect.js +23 -0
- package/dist/platform/index.d.ts +4 -0
- package/dist/platform/index.js +3 -0
- package/dist/platform/registry.d.ts +4 -0
- package/dist/platform/registry.js +27 -0
- package/dist/platform/resolve.d.ts +8 -0
- package/dist/platform/resolve.js +24 -0
- package/dist/platform/types.d.ts +41 -0
- package/dist/platform/types.js +7 -0
- package/dist/platform/windsurf.d.ts +2 -0
- package/dist/platform/windsurf.js +71 -0
- package/dist/reset.d.ts +18 -0
- package/dist/reset.js +181 -0
- package/dist/transition/artifact-scan.d.ts +27 -0
- package/dist/transition/artifact-scan.js +91 -0
- package/dist/transition/artifacts.d.ts +1 -0
- package/dist/transition/artifacts.js +2 -1
- package/dist/transition/context.js +34 -0
- package/dist/transition/fix-plan.d.ts +8 -2
- package/dist/transition/fix-plan.js +33 -7
- package/dist/transition/orchestration.d.ts +2 -2
- package/dist/transition/orchestration.js +120 -41
- package/dist/transition/preflight.d.ts +6 -0
- package/dist/transition/preflight.js +154 -0
- package/dist/transition/specs-changelog.js +4 -1
- package/dist/transition/specs-index.d.ts +1 -1
- package/dist/transition/specs-index.js +24 -1
- package/dist/transition/types.d.ts +23 -1
- package/dist/utils/config.d.ts +2 -0
- package/dist/utils/dryrun.d.ts +1 -1
- package/dist/utils/dryrun.js +22 -0
- package/dist/utils/validate.js +18 -2
- package/package.json +1 -1
- package/ralph/drivers/claude-code.sh +118 -0
- package/ralph/drivers/codex.sh +81 -0
- package/ralph/ralph_import.sh +11 -0
- package/ralph/ralph_loop.sh +52 -64
- package/ralph/templates/ralphrc.template +7 -0
- package/slash-commands/bmalph-doctor.md +16 -0
- package/slash-commands/bmalph-implement.md +18 -141
- package/slash-commands/bmalph-status.md +15 -0
- package/slash-commands/bmalph-upgrade.md +15 -0
package/README.md
CHANGED
|
@@ -25,13 +25,32 @@ bmalph provides:
|
|
|
25
25
|
- `bmalph init` — Install both systems
|
|
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
|
+
|
|
30
|
+
## Supported Platforms
|
|
31
|
+
|
|
32
|
+
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.
|
|
33
|
+
|
|
34
|
+
| Platform | ID | Tier | Instructions File | Commands |
|
|
35
|
+
| -------------- | ------------- | ----------------- | --------------------------------- | ----------------------------- |
|
|
36
|
+
| Claude Code | `claude-code` | full | `CLAUDE.md` | `.claude/commands/` directory |
|
|
37
|
+
| OpenAI Codex | `codex` | full | `AGENTS.md` | Inline in instructions file |
|
|
38
|
+
| Cursor | `cursor` | instructions-only | `.cursor/rules/bmad.mdc` | None |
|
|
39
|
+
| Windsurf | `windsurf` | instructions-only | `.windsurf/rules/bmad.md` | None |
|
|
40
|
+
| GitHub Copilot | `copilot` | instructions-only | `.github/copilot-instructions.md` | None |
|
|
41
|
+
| Aider | `aider` | instructions-only | `CONVENTIONS.md` | None |
|
|
42
|
+
|
|
43
|
+
**Tiers:**
|
|
44
|
+
|
|
45
|
+
- **full** — Phases 1-4. BMAD planning + Ralph autonomous implementation loop.
|
|
46
|
+
- **instructions-only** — Phases 1-3. BMAD planning only. Ralph is not available.
|
|
29
47
|
|
|
30
48
|
## Prerequisites
|
|
31
49
|
|
|
32
50
|
- Node.js 20+
|
|
33
51
|
- Bash (WSL or Git Bash on Windows)
|
|
34
|
-
-
|
|
52
|
+
- A supported AI coding platform (see table above)
|
|
53
|
+
- For Ralph loop (Phase 4): Claude Code (`claude`) or Codex CLI (`codex`) in PATH
|
|
35
54
|
|
|
36
55
|
## Installation
|
|
37
56
|
|
|
@@ -44,9 +63,9 @@ npm install -g bmalph
|
|
|
44
63
|
```bash
|
|
45
64
|
cd my-project
|
|
46
65
|
bmalph init --name my-project
|
|
47
|
-
|
|
48
|
-
#
|
|
49
|
-
#
|
|
66
|
+
|
|
67
|
+
# To target a specific platform, add --platform (e.g. codex, cursor, windsurf)
|
|
68
|
+
# Without --platform, bmalph auto-detects or prompts interactively
|
|
50
69
|
```
|
|
51
70
|
|
|
52
71
|
## Workflow
|
|
@@ -58,17 +77,27 @@ cd my-project
|
|
|
58
77
|
bmalph init
|
|
59
78
|
```
|
|
60
79
|
|
|
80
|
+
**Platform resolution:** `--platform` flag > auto-detect from project markers > interactive prompt > default `claude-code`
|
|
81
|
+
|
|
61
82
|
This installs:
|
|
62
83
|
|
|
63
84
|
- `_bmad/` — BMAD agents and workflows
|
|
64
|
-
- `.ralph/` — Ralph loop, libs, templates
|
|
65
|
-
- `bmalph/` — State management (config.json)
|
|
66
|
-
- Updates
|
|
67
|
-
- Installs slash commands
|
|
85
|
+
- `.ralph/` — Ralph loop, libs, templates (drivers for claude-code and codex only)
|
|
86
|
+
- `bmalph/` — State management (config.json, stores selected platform)
|
|
87
|
+
- Updates the platform's instructions file with BMAD workflow instructions (e.g. `CLAUDE.md`, `AGENTS.md`, `.cursor/rules/bmad.mdc`)
|
|
88
|
+
- Installs slash commands for supported platforms (Claude Code: `.claude/commands/` directory; Codex: inline in `AGENTS.md`; other platforms: commands not installed)
|
|
89
|
+
|
|
90
|
+
### Migrating from standalone BMAD
|
|
91
|
+
|
|
92
|
+
If you already have BMAD installed (a `_bmad/` directory), `bmalph init` works as a migration path:
|
|
93
|
+
|
|
94
|
+
- `_bmad/` (framework files) will be replaced with the bmalph-managed version
|
|
95
|
+
- `_bmad-output/` (your planning artifacts: PRDs, architecture, stories) is not touched
|
|
96
|
+
- If you've customized framework files inside `_bmad/`, commit first so you can review changes with `git diff`
|
|
68
97
|
|
|
69
98
|
### Step 2: Plan with BMAD (Phases 1-3)
|
|
70
99
|
|
|
71
|
-
Work interactively in
|
|
100
|
+
Work interactively with BMAD agents in your AI coding assistant. On Claude Code, use the `/bmalph` slash command to see your current phase and available commands. On other platforms, ask the agent about BMAD phases or run `bmalph status` in terminal.
|
|
72
101
|
|
|
73
102
|
| Phase | Agent | Commands |
|
|
74
103
|
| ------------- | ---------------- | ------------------ |
|
|
@@ -124,7 +153,9 @@ Available in any phase for supporting tasks:
|
|
|
124
153
|
|
|
125
154
|
### Step 3: Implement with Ralph (Phase 4)
|
|
126
155
|
|
|
127
|
-
|
|
156
|
+
> **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.
|
|
157
|
+
|
|
158
|
+
Run `bmalph implement` from the terminal, or use the `/bmalph-implement` slash command in Claude Code.
|
|
128
159
|
|
|
129
160
|
This transitions your BMAD artifacts into Ralph's format:
|
|
130
161
|
|
|
@@ -133,10 +164,14 @@ This transitions your BMAD artifacts into Ralph's format:
|
|
|
133
164
|
3. Copies specs to `.ralph/specs/` with changelog tracking
|
|
134
165
|
4. Instructs you to start the Ralph autonomous loop
|
|
135
166
|
|
|
136
|
-
Then start Ralph:
|
|
167
|
+
Then start Ralph using the driver for your platform:
|
|
137
168
|
|
|
138
169
|
```bash
|
|
139
|
-
|
|
170
|
+
# Claude Code
|
|
171
|
+
bash .ralph/drivers/claude-code.sh
|
|
172
|
+
|
|
173
|
+
# OpenAI Codex
|
|
174
|
+
bash .ralph/drivers/codex.sh
|
|
140
175
|
```
|
|
141
176
|
|
|
142
177
|
Ralph picks stories one by one, implements with TDD, and commits. The loop stops when all stories are done or the circuit breaker triggers.
|
|
@@ -146,12 +181,12 @@ Ralph picks stories one by one, implements with TDD, and commits. The loop stops
|
|
|
146
181
|
bmalph supports iterative development cycles:
|
|
147
182
|
|
|
148
183
|
```
|
|
149
|
-
BMAD (Epic 1) →
|
|
184
|
+
BMAD (Epic 1) → bmalph implement → Ralph works on Epic 1
|
|
150
185
|
↓
|
|
151
|
-
BMAD (add Epic 2) →
|
|
186
|
+
BMAD (add Epic 2) → bmalph implement → Ralph sees changes + picks up Epic 2
|
|
152
187
|
```
|
|
153
188
|
|
|
154
|
-
**Smart Merge**: When you run
|
|
189
|
+
**Smart Merge**: When you run `bmalph implement` again after Ralph has made progress:
|
|
155
190
|
|
|
156
191
|
- Completed stories (`[x]`) are preserved in the new fix_plan
|
|
157
192
|
- New stories from BMAD are added as pending (`[ ]`)
|
|
@@ -167,6 +202,7 @@ BMAD (add Epic 2) → /bmalph-implement → Ralph sees changes + picks up Epic 2
|
|
|
167
202
|
| `bmalph doctor` | Check installation health |
|
|
168
203
|
| `bmalph check-updates` | Check if bundled BMAD/Ralph versions are up to date |
|
|
169
204
|
| `bmalph status` | Show current project status and phase |
|
|
205
|
+
| `bmalph implement` | Transition BMAD planning artifacts to Ralph format |
|
|
170
206
|
|
|
171
207
|
### Global options
|
|
172
208
|
|
|
@@ -181,10 +217,29 @@ BMAD (add Epic 2) → /bmalph-implement → Ralph sees changes + picks up Epic 2
|
|
|
181
217
|
|
|
182
218
|
### init options
|
|
183
219
|
|
|
184
|
-
| Flag | Description
|
|
185
|
-
| -------------------------- |
|
|
186
|
-
| `-n, --name <name>` | Project name
|
|
187
|
-
| `-d, --description <desc>` | Project description
|
|
220
|
+
| Flag | Description | Default |
|
|
221
|
+
| -------------------------- | ---------------------------------------------------------------------------------- | -------------- |
|
|
222
|
+
| `-n, --name <name>` | Project name | directory name |
|
|
223
|
+
| `-d, --description <desc>` | Project description | (prompted) |
|
|
224
|
+
| `--platform <id>` | Target platform (`claude-code`, `codex`, `cursor`, `windsurf`, `copilot`, `aider`) | auto-detect |
|
|
225
|
+
|
|
226
|
+
### implement options
|
|
227
|
+
|
|
228
|
+
| Flag | Description |
|
|
229
|
+
| --------- | ------------------------------------- |
|
|
230
|
+
| `--force` | Override pre-flight validation errors |
|
|
231
|
+
|
|
232
|
+
### check-updates options
|
|
233
|
+
|
|
234
|
+
| Flag | Description |
|
|
235
|
+
| -------- | -------------- |
|
|
236
|
+
| `--json` | Output as JSON |
|
|
237
|
+
|
|
238
|
+
### status options
|
|
239
|
+
|
|
240
|
+
| Flag | Description |
|
|
241
|
+
| -------- | -------------- |
|
|
242
|
+
| `--json` | Output as JSON |
|
|
188
243
|
|
|
189
244
|
### upgrade options
|
|
190
245
|
|
|
@@ -195,7 +250,13 @@ BMAD (add Epic 2) → /bmalph-implement → Ralph sees changes + picks up Epic 2
|
|
|
195
250
|
|
|
196
251
|
## Slash Commands
|
|
197
252
|
|
|
198
|
-
bmalph installs
|
|
253
|
+
bmalph installs 50 slash commands (45 BMAD + 5 bmalph). Command delivery varies by platform:
|
|
254
|
+
|
|
255
|
+
- **Claude Code** — installed as files in `.claude/commands/` (invoke with `/command-name`)
|
|
256
|
+
- **OpenAI Codex** — inlined in `AGENTS.md` (reference agents by name)
|
|
257
|
+
- **Cursor, Windsurf, Copilot, Aider** — not delivered as slash commands; use agents by name in chat
|
|
258
|
+
|
|
259
|
+
Key commands (Claude Code syntax):
|
|
199
260
|
|
|
200
261
|
| Command | Description |
|
|
201
262
|
| ----------------------- | ----------------------------------- |
|
|
@@ -218,7 +279,7 @@ For full list, run `/bmad-help` in Claude Code.
|
|
|
218
279
|
|
|
219
280
|
### Transition to Ralph
|
|
220
281
|
|
|
221
|
-
Use `/bmalph-implement` to transition from BMAD planning to Ralph implementation.
|
|
282
|
+
Use `bmalph implement` (or `/bmalph-implement` in Claude Code) to transition from BMAD planning to Ralph implementation.
|
|
222
283
|
|
|
223
284
|
## Project Structure (after init)
|
|
224
285
|
|
|
@@ -226,44 +287,64 @@ Use `/bmalph-implement` to transition from BMAD planning to Ralph implementation
|
|
|
226
287
|
project/
|
|
227
288
|
├── _bmad/ # BMAD agents, workflows, core
|
|
228
289
|
│ ├── _config/ # Generated configuration
|
|
229
|
-
│ │
|
|
290
|
+
│ │ ├── config.yaml # Platform config
|
|
291
|
+
│ │ ├── task-manifest.csv # Combined task manifest
|
|
292
|
+
│ │ ├── workflow-manifest.csv # Combined workflow manifest
|
|
293
|
+
│ │ └── bmad-help.csv # Combined help manifest
|
|
230
294
|
│ ├── core/
|
|
231
295
|
│ │ ├── agents/ # Master agent
|
|
232
296
|
│ │ ├── tasks/ # Workflow tasks
|
|
233
|
-
│ │
|
|
297
|
+
│ │ ├── workflows/ # Brainstorming, party-mode, etc.
|
|
298
|
+
│ │ ├── module.yaml # Core module metadata
|
|
299
|
+
│ │ └── module-help.csv # Core module help entries
|
|
234
300
|
│ └── bmm/
|
|
235
301
|
│ ├── agents/ # Analyst, PM, Architect, Dev, QA, etc.
|
|
302
|
+
│ ├── data/ # Templates (project-context-template.md)
|
|
236
303
|
│ ├── workflows/ # Phase 1-4 workflows
|
|
237
|
-
│
|
|
304
|
+
│ ├── teams/ # Agent team definitions
|
|
305
|
+
│ ├── module.yaml # BMM module metadata
|
|
306
|
+
│ └── module-help.csv # BMM module help entries
|
|
238
307
|
├── _bmad-output/ # BMAD planning artifacts (generated)
|
|
239
308
|
│ ├── planning-artifacts/ # PRD, architecture, stories
|
|
240
309
|
│ ├── implementation-artifacts/ # Sprint plans (optional)
|
|
241
310
|
│ └── brainstorming/ # Brainstorm sessions (optional)
|
|
242
|
-
├── .ralph/ # Ralph autonomous loop
|
|
311
|
+
├── .ralph/ # Ralph autonomous loop (drivers for claude-code and codex only)
|
|
243
312
|
│ ├── ralph_loop.sh # Main loop script
|
|
244
313
|
│ ├── ralph_import.sh # Import requirements into Ralph
|
|
245
314
|
│ ├── ralph_monitor.sh # Monitor loop progress
|
|
246
315
|
│ ├── .ralphrc # Ralph configuration
|
|
247
316
|
│ ├── RALPH-REFERENCE.md # Ralph usage reference
|
|
248
|
-
│ ├──
|
|
317
|
+
│ ├── drivers/ # Platform driver scripts
|
|
318
|
+
│ │ ├── claude-code.sh # Claude Code driver (uses `claude`)
|
|
319
|
+
│ │ └── codex.sh # OpenAI Codex driver (uses `codex exec`)
|
|
320
|
+
│ ├── lib/ # Shell libraries
|
|
321
|
+
│ ├── docs/generated/ # Generated documentation
|
|
249
322
|
│ ├── specs/ # Copied from _bmad-output during transition
|
|
250
323
|
│ ├── logs/ # Loop execution logs
|
|
251
324
|
│ ├── PROMPT.md # Iteration prompt template
|
|
252
|
-
│ ├── PROJECT_CONTEXT.md # Extracted project context (after
|
|
253
|
-
│ ├── SPECS_CHANGELOG.md # Spec diff since last run (after
|
|
325
|
+
│ ├── PROJECT_CONTEXT.md # Extracted project context (after bmalph implement)
|
|
326
|
+
│ ├── SPECS_CHANGELOG.md # Spec diff since last run (after bmalph implement)
|
|
327
|
+
│ ├── SPECS_INDEX.md # Prioritized spec file index (after bmalph implement)
|
|
254
328
|
│ ├── @AGENT.md # Agent build instructions
|
|
255
|
-
│ └── @fix_plan.md # Generated task list (after
|
|
329
|
+
│ └── @fix_plan.md # Generated task list (after bmalph implement)
|
|
256
330
|
├── bmalph/ # State management
|
|
257
|
-
│ ├── config.json # Project config (name, description)
|
|
331
|
+
│ ├── config.json # Project config (name, description, platform)
|
|
258
332
|
│ └── state/ # Phase tracking data
|
|
259
|
-
├── .claude/
|
|
260
|
-
│ └── commands/ # Slash commands
|
|
261
|
-
└──
|
|
333
|
+
├── .claude/ # Claude Code specific
|
|
334
|
+
│ └── commands/ # Slash commands (claude-code only)
|
|
335
|
+
└── <instructions file> # Varies by platform (see Supported Platforms)
|
|
262
336
|
```
|
|
263
337
|
|
|
338
|
+
The instructions file and command directory depend on the configured platform. See the [Supported Platforms](#supported-platforms) table for details.
|
|
339
|
+
|
|
264
340
|
## How Ralph Works
|
|
265
341
|
|
|
266
|
-
Ralph is a bash loop that spawns fresh
|
|
342
|
+
Ralph is a bash loop that spawns fresh AI coding sessions using a **platform driver** matching the configured platform:
|
|
343
|
+
|
|
344
|
+
- **Claude Code driver** — invokes `claude` with `--allowedTools` and session resume
|
|
345
|
+
- **Codex driver** — invokes `codex exec` with `--sandbox workspace-write`
|
|
346
|
+
|
|
347
|
+
Each iteration:
|
|
267
348
|
|
|
268
349
|
1. Pick the next unchecked story from `@fix_plan.md`
|
|
269
350
|
2. Implement with TDD (tests first, then code)
|
|
@@ -304,8 +385,8 @@ wsl --install
|
|
|
304
385
|
If you get permission errors:
|
|
305
386
|
|
|
306
387
|
```bash
|
|
307
|
-
# Unix/Mac: Make
|
|
308
|
-
chmod +x .ralph/
|
|
388
|
+
# Unix/Mac: Make driver scripts executable
|
|
389
|
+
chmod +x .ralph/drivers/*.sh
|
|
309
390
|
|
|
310
391
|
# Check file ownership
|
|
311
392
|
ls -la .ralph/
|
|
@@ -313,12 +394,14 @@ ls -la .ralph/
|
|
|
313
394
|
|
|
314
395
|
### Common Issues
|
|
315
396
|
|
|
316
|
-
| Scenario
|
|
317
|
-
|
|
|
318
|
-
| Commands fail before init
|
|
319
|
-
| Transition finds no stories
|
|
320
|
-
| Ralph stops mid-loop
|
|
321
|
-
| Doctor reports version drift
|
|
397
|
+
| Scenario | Solution |
|
|
398
|
+
| ----------------------------- | -------------------------------------------------------------- |
|
|
399
|
+
| Commands fail before init | Run `bmalph init` first |
|
|
400
|
+
| Transition finds no stories | Create stories in Phase 3 with `/create-epics-stories` |
|
|
401
|
+
| Ralph stops mid-loop | Circuit breaker detected stagnation. Check `.ralph/logs/` |
|
|
402
|
+
| Doctor reports version drift | Run `bmalph upgrade` to update bundled assets |
|
|
403
|
+
| Wrong platform detected | Re-run `bmalph init --platform <id>` with the correct platform |
|
|
404
|
+
| Ralph unavailable on platform | Ralph requires a full tier platform (claude-code or codex) |
|
|
322
405
|
|
|
323
406
|
### Reset Installation
|
|
324
407
|
|
|
@@ -326,8 +409,16 @@ If something goes wrong, you can manually reset:
|
|
|
326
409
|
|
|
327
410
|
```bash
|
|
328
411
|
# Remove bmalph directories (preserves your project code)
|
|
329
|
-
rm -rf _bmad .ralph bmalph
|
|
330
|
-
|
|
412
|
+
rm -rf _bmad .ralph bmalph
|
|
413
|
+
|
|
414
|
+
# Also remove platform-specific files:
|
|
415
|
+
# Claude Code: rm -rf .claude/commands/ and remove bmalph section from CLAUDE.md
|
|
416
|
+
# Codex: remove bmalph sections from AGENTS.md
|
|
417
|
+
# Cursor: rm .cursor/rules/bmad.mdc
|
|
418
|
+
# Windsurf: rm .windsurf/rules/bmad.md
|
|
419
|
+
# Copilot: remove bmalph sections from .github/copilot-instructions.md
|
|
420
|
+
# Aider: remove bmalph sections from CONVENTIONS.md
|
|
421
|
+
# See the Supported Platforms table for your platform's files.
|
|
331
422
|
|
|
332
423
|
# Reinitialize
|
|
333
424
|
bmalph init
|
|
@@ -338,12 +429,17 @@ bmalph init
|
|
|
338
429
|
### Initialize a new project
|
|
339
430
|
|
|
340
431
|
```bash
|
|
341
|
-
# Interactive mode (prompts for name/description)
|
|
432
|
+
# Interactive mode (prompts for name/description, auto-detects platform)
|
|
342
433
|
bmalph init
|
|
343
434
|
|
|
344
435
|
# Non-interactive mode
|
|
345
436
|
bmalph init --name my-app --description "My awesome app"
|
|
346
437
|
|
|
438
|
+
# Specify platform explicitly
|
|
439
|
+
bmalph init --name my-app --platform codex
|
|
440
|
+
bmalph init --name my-app --platform cursor
|
|
441
|
+
bmalph init --name my-app --platform windsurf
|
|
442
|
+
|
|
347
443
|
# Preview what would be created
|
|
348
444
|
bmalph init --dry-run
|
|
349
445
|
```
|
|
@@ -370,6 +466,8 @@ bmalph upgrade --dry-run
|
|
|
370
466
|
|
|
371
467
|
### After init: Next steps
|
|
372
468
|
|
|
469
|
+
**Claude Code:**
|
|
470
|
+
|
|
373
471
|
```bash
|
|
374
472
|
# 1. Open Claude Code in your project
|
|
375
473
|
claude
|
|
@@ -383,10 +481,26 @@ claude
|
|
|
383
481
|
# Phase 3: /architect → create architecture and stories
|
|
384
482
|
|
|
385
483
|
# 4. Transition to Ralph
|
|
386
|
-
#
|
|
484
|
+
# Run: bmalph implement
|
|
387
485
|
|
|
388
486
|
# 5. Start autonomous implementation
|
|
389
|
-
bash .ralph/
|
|
487
|
+
bash .ralph/drivers/claude-code.sh
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
**Other platforms:**
|
|
491
|
+
|
|
492
|
+
```bash
|
|
493
|
+
# 1. Open your project in your AI coding assistant
|
|
494
|
+
|
|
495
|
+
# 2. Ask the agent about BMAD phases to start planning
|
|
496
|
+
# Or check status from terminal: bmalph status
|
|
497
|
+
|
|
498
|
+
# 3. Reference BMAD agents by name (analyst, pm, architect)
|
|
499
|
+
# Follow phases: Analysis → Planning → Solutioning
|
|
500
|
+
|
|
501
|
+
# 4. For full tier platforms (Codex), transition to Ralph:
|
|
502
|
+
# Run: bmalph implement
|
|
503
|
+
bash .ralph/drivers/codex.sh
|
|
390
504
|
```
|
|
391
505
|
|
|
392
506
|
## Contributing
|
package/dist/cli.js
CHANGED
|
@@ -6,6 +6,8 @@ import { upgradeCommand } from "./commands/upgrade.js";
|
|
|
6
6
|
import { doctorCommand } from "./commands/doctor.js";
|
|
7
7
|
import { checkUpdatesCommand } from "./commands/check-updates.js";
|
|
8
8
|
import { statusCommand } from "./commands/status.js";
|
|
9
|
+
import { implementCommand } from "./commands/implement.js";
|
|
10
|
+
import { resetCommand } from "./commands/reset.js";
|
|
9
11
|
import { setVerbose, setQuiet } from "./utils/logger.js";
|
|
10
12
|
import { getPackageVersion } from "./installer.js";
|
|
11
13
|
import { isEnoent } from "./utils/errors.js";
|
|
@@ -55,6 +57,7 @@ program
|
|
|
55
57
|
.description("Initialize bmalph in the current project")
|
|
56
58
|
.option("-n, --name <name>", "Project name")
|
|
57
59
|
.option("-d, --description <desc>", "Project description")
|
|
60
|
+
.option("--platform <id>", "Target platform (claude-code, codex, cursor, windsurf, copilot, aider)")
|
|
58
61
|
.option("--dry-run", "Preview changes without writing files")
|
|
59
62
|
.action(async (opts) => initCommand({ ...opts, projectDir: await resolveAndValidateProjectDir() }));
|
|
60
63
|
program
|
|
@@ -78,4 +81,15 @@ program
|
|
|
78
81
|
.description("Show current project status and phase")
|
|
79
82
|
.option("--json", "Output as JSON")
|
|
80
83
|
.action(async (opts) => statusCommand({ ...opts, projectDir: await resolveAndValidateProjectDir() }));
|
|
84
|
+
program
|
|
85
|
+
.command("implement")
|
|
86
|
+
.description("Transition BMAD planning artifacts to Ralph implementation format")
|
|
87
|
+
.option("--force", "Override pre-flight validation errors")
|
|
88
|
+
.action(async (opts) => implementCommand({ ...opts, projectDir: await resolveAndValidateProjectDir() }));
|
|
89
|
+
program
|
|
90
|
+
.command("reset")
|
|
91
|
+
.description("Remove all bmalph files from the project")
|
|
92
|
+
.option("--dry-run", "Preview changes without removing files")
|
|
93
|
+
.option("--force", "Skip confirmation prompt")
|
|
94
|
+
.action(async (opts) => resetCommand({ ...opts, projectDir: await resolveAndValidateProjectDir() }));
|
|
81
95
|
void program.parseAsync();
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Platform } from "../platform/types.js";
|
|
1
2
|
/**
|
|
2
3
|
* Result of a single doctor check.
|
|
3
4
|
*/
|
|
@@ -32,8 +33,19 @@ interface DoctorResult {
|
|
|
32
33
|
}
|
|
33
34
|
export declare function runDoctor(options: DoctorOptions): Promise<DoctorResult>;
|
|
34
35
|
/**
|
|
35
|
-
*
|
|
36
|
-
*
|
|
36
|
+
* Build the full check registry for a given platform.
|
|
37
|
+
* Core checks + platform doctor checks + trailing checks.
|
|
38
|
+
*/
|
|
39
|
+
export declare function buildCheckRegistry(platform: Platform): CheckDefinition[];
|
|
40
|
+
/**
|
|
41
|
+
* Static registry for backward compatibility with existing tests.
|
|
42
|
+
* Uses claude-code platform checks (slash-command + claude-md).
|
|
43
|
+
*
|
|
44
|
+
* Note: The check ids here ("slash-command", "claude-md") intentionally differ
|
|
45
|
+
* from the live buildCheckRegistry path which uses platform-provided ids
|
|
46
|
+
* ("instructions-file"). This is for test backward compatibility only.
|
|
47
|
+
*
|
|
48
|
+
* @deprecated Use `buildCheckRegistry(platform)` for platform-aware checks.
|
|
37
49
|
*/
|
|
38
50
|
export declare const CHECK_REGISTRY: CheckDefinition[];
|
|
39
51
|
export {};
|
package/dist/commands/doctor.js
CHANGED
|
@@ -9,6 +9,7 @@ import { checkUpstream, getSkipReason } from "../utils/github.js";
|
|
|
9
9
|
import { isEnoent, formatError, withErrorHandling } from "../utils/errors.js";
|
|
10
10
|
import { validateCircuitBreakerState, validateRalphSession, validateRalphApiStatus, } from "../utils/validate.js";
|
|
11
11
|
import { SESSION_AGE_WARNING_MS, API_USAGE_WARNING_PERCENT, CONFIG_FILE, RALPH_STATUS_FILE, } from "../utils/constants.js";
|
|
12
|
+
import { resolveProjectPlatform } from "../platform/resolve.js";
|
|
12
13
|
export async function doctorCommand(options) {
|
|
13
14
|
await withErrorHandling(async () => {
|
|
14
15
|
const { failed } = await runDoctor(options);
|
|
@@ -19,8 +20,12 @@ export async function doctorCommand(options) {
|
|
|
19
20
|
}
|
|
20
21
|
export async function runDoctor(options) {
|
|
21
22
|
const projectDir = options.projectDir;
|
|
22
|
-
//
|
|
23
|
-
const
|
|
23
|
+
// Resolve platform for this project
|
|
24
|
+
const platform = await resolveProjectPlatform(projectDir);
|
|
25
|
+
// Build the check list: core checks + platform-specific checks
|
|
26
|
+
const checks = buildCheckRegistry(platform);
|
|
27
|
+
// Run all checks
|
|
28
|
+
const results = await Promise.all(checks.map((check) => check.run(projectDir)));
|
|
24
29
|
// Output
|
|
25
30
|
const passed = results.filter((r) => r.passed).length;
|
|
26
31
|
const failed = results.filter((r) => !r.passed).length;
|
|
@@ -59,10 +64,10 @@ export async function runDoctor(options) {
|
|
|
59
64
|
}
|
|
60
65
|
return { passed, failed };
|
|
61
66
|
}
|
|
62
|
-
async function
|
|
67
|
+
async function checkCommandAvailable(command) {
|
|
63
68
|
const { execSync } = await import("child_process");
|
|
64
69
|
try {
|
|
65
|
-
const cmd = process.platform === "win32" ?
|
|
70
|
+
const cmd = process.platform === "win32" ? `where ${command}` : `which ${command}`;
|
|
66
71
|
execSync(cmd, { stdio: "ignore" });
|
|
67
72
|
return true;
|
|
68
73
|
}
|
|
@@ -71,7 +76,7 @@ async function checkBashAvailable() {
|
|
|
71
76
|
}
|
|
72
77
|
}
|
|
73
78
|
// =============================================================================
|
|
74
|
-
//
|
|
79
|
+
// Core check functions - platform-independent
|
|
75
80
|
// =============================================================================
|
|
76
81
|
async function checkNodeVersion(_projectDir) {
|
|
77
82
|
const major = parseInt(process.versions.node.split(".")[0]);
|
|
@@ -83,18 +88,33 @@ async function checkNodeVersion(_projectDir) {
|
|
|
83
88
|
};
|
|
84
89
|
}
|
|
85
90
|
async function checkBash(_projectDir) {
|
|
86
|
-
const
|
|
91
|
+
const available = await checkCommandAvailable("bash");
|
|
87
92
|
return {
|
|
88
93
|
label: "bash available",
|
|
89
|
-
passed:
|
|
90
|
-
detail:
|
|
91
|
-
hint:
|
|
94
|
+
passed: available,
|
|
95
|
+
detail: available ? undefined : "bash not found in PATH",
|
|
96
|
+
hint: available
|
|
92
97
|
? undefined
|
|
93
98
|
: process.platform === "win32"
|
|
94
99
|
? "Install Git Bash or WSL: https://git-scm.com/downloads"
|
|
95
100
|
: "Install bash via your package manager (apt, brew, etc.)",
|
|
96
101
|
};
|
|
97
102
|
}
|
|
103
|
+
async function checkJq(_projectDir) {
|
|
104
|
+
const available = await checkCommandAvailable("jq");
|
|
105
|
+
return {
|
|
106
|
+
label: "jq available",
|
|
107
|
+
passed: available,
|
|
108
|
+
detail: available ? undefined : "jq not found in PATH",
|
|
109
|
+
hint: available
|
|
110
|
+
? undefined
|
|
111
|
+
: process.platform === "win32"
|
|
112
|
+
? "Install jq: choco install jq (or: winget install jqlang.jq)"
|
|
113
|
+
: process.platform === "darwin"
|
|
114
|
+
? "Install jq: brew install jq"
|
|
115
|
+
: "Install jq: sudo apt-get install jq",
|
|
116
|
+
};
|
|
117
|
+
}
|
|
98
118
|
async function checkBmadDir(projectDir) {
|
|
99
119
|
return checkDir(join(projectDir, "_bmad"), "_bmad/ directory present", "Run: bmalph init");
|
|
100
120
|
}
|
|
@@ -104,9 +124,6 @@ async function checkRalphLoop(projectDir) {
|
|
|
104
124
|
async function checkRalphLib(projectDir) {
|
|
105
125
|
return checkDir(join(projectDir, ".ralph/lib"), ".ralph/lib/ directory present", "Run: bmalph upgrade");
|
|
106
126
|
}
|
|
107
|
-
async function checkSlashCommand(projectDir) {
|
|
108
|
-
return checkFileExists(join(projectDir, ".claude/commands/bmalph.md"), ".claude/commands/bmalph.md present", "Run: bmalph init");
|
|
109
|
-
}
|
|
110
127
|
async function checkConfig(projectDir) {
|
|
111
128
|
const label = "bmalph/config.json exists and valid";
|
|
112
129
|
const hint = "Run: bmalph init";
|
|
@@ -135,12 +152,6 @@ async function checkDir(dirPath, label, hint) {
|
|
|
135
152
|
return { label, passed: false, detail: `error: ${formatError(err)}`, hint };
|
|
136
153
|
}
|
|
137
154
|
}
|
|
138
|
-
async function checkFileExists(filePath, label, hint) {
|
|
139
|
-
if (await exists(filePath)) {
|
|
140
|
-
return { label, passed: true };
|
|
141
|
-
}
|
|
142
|
-
return { label, passed: false, detail: "not found", hint };
|
|
143
|
-
}
|
|
144
155
|
async function checkFileHasContent(filePath, label, hint) {
|
|
145
156
|
try {
|
|
146
157
|
const content = await readFile(filePath, "utf-8");
|
|
@@ -153,23 +164,6 @@ async function checkFileHasContent(filePath, label, hint) {
|
|
|
153
164
|
return { label, passed: false, detail: `error: ${formatError(err)}`, hint };
|
|
154
165
|
}
|
|
155
166
|
}
|
|
156
|
-
async function checkClaudeMd(projectDir) {
|
|
157
|
-
const label = "CLAUDE.md contains BMAD snippet";
|
|
158
|
-
const hint = "Run: bmalph init";
|
|
159
|
-
try {
|
|
160
|
-
const content = await readFile(join(projectDir, "CLAUDE.md"), "utf-8");
|
|
161
|
-
if (content.includes("BMAD-METHOD Integration")) {
|
|
162
|
-
return { label, passed: true };
|
|
163
|
-
}
|
|
164
|
-
return { label, passed: false, detail: "missing BMAD-METHOD Integration section", hint };
|
|
165
|
-
}
|
|
166
|
-
catch (err) {
|
|
167
|
-
if (isEnoent(err)) {
|
|
168
|
-
return { label, passed: false, detail: "CLAUDE.md not found", hint };
|
|
169
|
-
}
|
|
170
|
-
return { label, passed: false, detail: `error: ${formatError(err)}`, hint };
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
167
|
async function checkGitignore(projectDir) {
|
|
174
168
|
const label = ".gitignore has required entries";
|
|
175
169
|
const required = [".ralph/logs/", "_bmad-output/"];
|
|
@@ -412,21 +406,24 @@ async function checkUpstreamGitHubStatus(_projectDir) {
|
|
|
412
406
|
}
|
|
413
407
|
}
|
|
414
408
|
// =============================================================================
|
|
415
|
-
// Check Registry -
|
|
409
|
+
// Check Registry - core checks + platform-specific checks
|
|
416
410
|
// =============================================================================
|
|
417
411
|
/**
|
|
418
|
-
*
|
|
419
|
-
* Each check has a unique ID and a run function that takes a project directory.
|
|
412
|
+
* Core checks that apply to every platform.
|
|
420
413
|
*/
|
|
421
|
-
|
|
414
|
+
const CORE_CHECKS = [
|
|
422
415
|
{ id: "node-version", run: checkNodeVersion },
|
|
423
416
|
{ id: "bash-available", run: checkBash },
|
|
417
|
+
{ id: "jq-available", run: checkJq },
|
|
424
418
|
{ id: "config-valid", run: checkConfig },
|
|
425
419
|
{ id: "bmad-dir", run: checkBmadDir },
|
|
426
420
|
{ id: "ralph-loop", run: checkRalphLoop },
|
|
427
421
|
{ id: "ralph-lib", run: checkRalphLib },
|
|
428
|
-
|
|
429
|
-
|
|
422
|
+
];
|
|
423
|
+
/**
|
|
424
|
+
* Checks that run after platform-specific checks.
|
|
425
|
+
*/
|
|
426
|
+
const TRAILING_CHECKS = [
|
|
430
427
|
{ id: "gitignore", run: checkGitignore },
|
|
431
428
|
{ id: "version-marker", run: checkVersionMarker },
|
|
432
429
|
{ id: "upstream-versions", run: checkUpstreamVersions },
|
|
@@ -435,3 +432,70 @@ export const CHECK_REGISTRY = [
|
|
|
435
432
|
{ id: "api-calls", run: checkApiCalls },
|
|
436
433
|
{ id: "upstream-github", run: checkUpstreamGitHubStatus },
|
|
437
434
|
];
|
|
435
|
+
/**
|
|
436
|
+
* Build the full check registry for a given platform.
|
|
437
|
+
* Core checks + platform doctor checks + trailing checks.
|
|
438
|
+
*/
|
|
439
|
+
export function buildCheckRegistry(platform) {
|
|
440
|
+
const platformChecks = platform.getDoctorChecks().map((pc) => ({
|
|
441
|
+
id: pc.id,
|
|
442
|
+
run: async (projectDir) => {
|
|
443
|
+
const result = await pc.check(projectDir);
|
|
444
|
+
return {
|
|
445
|
+
label: pc.label,
|
|
446
|
+
passed: result.passed,
|
|
447
|
+
detail: result.detail,
|
|
448
|
+
hint: result.hint,
|
|
449
|
+
};
|
|
450
|
+
},
|
|
451
|
+
}));
|
|
452
|
+
return [...CORE_CHECKS, ...platformChecks, ...TRAILING_CHECKS];
|
|
453
|
+
}
|
|
454
|
+
/**
|
|
455
|
+
* Static registry for backward compatibility with existing tests.
|
|
456
|
+
* Uses claude-code platform checks (slash-command + claude-md).
|
|
457
|
+
*
|
|
458
|
+
* Note: The check ids here ("slash-command", "claude-md") intentionally differ
|
|
459
|
+
* from the live buildCheckRegistry path which uses platform-provided ids
|
|
460
|
+
* ("instructions-file"). This is for test backward compatibility only.
|
|
461
|
+
*
|
|
462
|
+
* @deprecated Use `buildCheckRegistry(platform)` for platform-aware checks.
|
|
463
|
+
*/
|
|
464
|
+
export const CHECK_REGISTRY = (() => {
|
|
465
|
+
// Inline claude-code platform checks to avoid async import at module level
|
|
466
|
+
const slashCommandCheck = {
|
|
467
|
+
id: "slash-command",
|
|
468
|
+
run: async (projectDir) => {
|
|
469
|
+
if (await exists(join(projectDir, ".claude/commands/bmalph.md"))) {
|
|
470
|
+
return { label: ".claude/commands/bmalph.md present", passed: true };
|
|
471
|
+
}
|
|
472
|
+
return {
|
|
473
|
+
label: ".claude/commands/bmalph.md present",
|
|
474
|
+
passed: false,
|
|
475
|
+
detail: "not found",
|
|
476
|
+
hint: "Run: bmalph init",
|
|
477
|
+
};
|
|
478
|
+
},
|
|
479
|
+
};
|
|
480
|
+
const claudeMdCheck = {
|
|
481
|
+
id: "claude-md",
|
|
482
|
+
run: async (projectDir) => {
|
|
483
|
+
const label = "CLAUDE.md contains BMAD snippet";
|
|
484
|
+
const hint = "Run: bmalph init";
|
|
485
|
+
try {
|
|
486
|
+
const content = await readFile(join(projectDir, "CLAUDE.md"), "utf-8");
|
|
487
|
+
if (content.includes("BMAD-METHOD Integration")) {
|
|
488
|
+
return { label, passed: true };
|
|
489
|
+
}
|
|
490
|
+
return { label, passed: false, detail: "missing BMAD-METHOD Integration section", hint };
|
|
491
|
+
}
|
|
492
|
+
catch (err) {
|
|
493
|
+
if (isEnoent(err)) {
|
|
494
|
+
return { label, passed: false, detail: "CLAUDE.md not found", hint };
|
|
495
|
+
}
|
|
496
|
+
return { label, passed: false, detail: `error: ${formatError(err)}`, hint };
|
|
497
|
+
}
|
|
498
|
+
},
|
|
499
|
+
};
|
|
500
|
+
return [...CORE_CHECKS, slashCommandCheck, claudeMdCheck, ...TRAILING_CHECKS];
|
|
501
|
+
})();
|