bmalph 2.7.4 → 2.7.5
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 +68 -30
- package/dist/commands/doctor-checks.js +5 -4
- package/dist/commands/doctor-checks.js.map +1 -1
- package/dist/commands/run.js +4 -0
- package/dist/commands/run.js.map +1 -1
- package/dist/commands/status.js +12 -3
- package/dist/commands/status.js.map +1 -1
- package/dist/installer.js +101 -48
- package/dist/installer.js.map +1 -1
- package/dist/platform/cursor-runtime-checks.js +81 -0
- package/dist/platform/cursor-runtime-checks.js.map +1 -0
- package/dist/platform/cursor.js +4 -3
- package/dist/platform/cursor.js.map +1 -1
- package/dist/platform/detect.js +28 -5
- package/dist/platform/detect.js.map +1 -1
- package/dist/platform/instructions-snippet.js +18 -0
- package/dist/platform/instructions-snippet.js.map +1 -1
- package/dist/platform/resolve.js +23 -5
- package/dist/platform/resolve.js.map +1 -1
- package/dist/run/ralph-process.js +84 -15
- package/dist/run/ralph-process.js.map +1 -1
- package/dist/transition/artifact-scan.js +15 -3
- package/dist/transition/artifact-scan.js.map +1 -1
- package/package.json +1 -1
- package/ralph/RALPH-REFERENCE.md +27 -3
- package/ralph/drivers/cursor.sh +47 -29
- package/ralph/lib/response_analyzer.sh +93 -10
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
[](https://github.com/LarsCowe/bmalph/actions/workflows/ci.yml)
|
|
8
8
|
[](https://codecov.io/gh/LarsCowe/bmalph)
|
|
9
9
|
|
|
10
|
-
[BMAD-METHOD](https://github.com/bmad-code-org/BMAD-METHOD) planning + [Ralph](https://github.com/snarktank/ralph) autonomous implementation,
|
|
10
|
+
[BMAD-METHOD](https://github.com/bmad-code-org/BMAD-METHOD) planning + [Ralph](https://github.com/snarktank/ralph) autonomous implementation, wired through platform-specific instructions, skills, and command indexes.
|
|
11
11
|
|
|
12
12
|
<p align="center">
|
|
13
13
|
<img src="docs/bmalph-diagram-light.svg" alt="bmalph workflow diagram" width="800" />
|
|
@@ -70,7 +70,8 @@ cd my-project
|
|
|
70
70
|
bmalph init --name my-project
|
|
71
71
|
|
|
72
72
|
# To target a specific platform, add --platform (e.g. codex, cursor, windsurf)
|
|
73
|
-
# Without --platform, bmalph auto-detects
|
|
73
|
+
# Without --platform, bmalph auto-detects strong project markers and
|
|
74
|
+
# prompts interactively when detection is ambiguous or missing
|
|
74
75
|
```
|
|
75
76
|
|
|
76
77
|
## Workflow
|
|
@@ -84,13 +85,15 @@ bmalph init
|
|
|
84
85
|
|
|
85
86
|
**Platform resolution:** `--platform` flag > auto-detect from project markers > interactive prompt > default `claude-code`
|
|
86
87
|
|
|
88
|
+
Strong markers such as `.cursor/`, `.claude/`, `.windsurf/`, `.github/copilot-instructions.md`, and `.aider.conf.yml` are auto-detected directly. Root-only `AGENTS.md` and `CLAUDE.md` are treated as weak hints and may still trigger the interactive platform prompt.
|
|
89
|
+
|
|
87
90
|
This installs:
|
|
88
91
|
|
|
89
92
|
- `_bmad/` — BMAD agents and workflows
|
|
90
93
|
- `.ralph/` — Ralph loop, libs, templates (drivers for claude-code, codex, copilot, and cursor)
|
|
91
94
|
- `bmalph/` — State management (config.json, stores selected platform)
|
|
92
95
|
- Updates the platform's instructions file with BMAD workflow instructions (e.g. `CLAUDE.md`, `AGENTS.md`, `.cursor/rules/bmad.mdc`)
|
|
93
|
-
-
|
|
96
|
+
- Delivers BMAD commands using the platform's native mechanism (Claude Code: `.claude/commands/`; Codex: `.agents/skills/`; Cursor, Windsurf, Copilot, and Aider: `_bmad/COMMANDS.md`)
|
|
94
97
|
|
|
95
98
|
### Migrating from standalone BMAD
|
|
96
99
|
|
|
@@ -102,7 +105,12 @@ If you already have BMAD installed (a `_bmad/` directory), `bmalph init` works a
|
|
|
102
105
|
|
|
103
106
|
### Step 2: Plan with BMAD (Phases 1-3)
|
|
104
107
|
|
|
105
|
-
Work interactively with BMAD agents in your AI coding assistant.
|
|
108
|
+
Work interactively with BMAD agents in your AI coding assistant.
|
|
109
|
+
|
|
110
|
+
- **Claude Code** — use `/bmalph` to see your current phase and available commands.
|
|
111
|
+
- **OpenAI Codex** — use Codex Skills such as `$analyst` and `$create-prd`.
|
|
112
|
+
- **Cursor** — Read `_bmad/COMMANDS.md` and ask Cursor to run the BMAD master agent.
|
|
113
|
+
- **Windsurf, Copilot, Aider** — use `_bmad/COMMANDS.md` as the command reference and ask the assistant to follow the named BMAD workflow.
|
|
106
114
|
|
|
107
115
|
| Phase | Agent | Commands |
|
|
108
116
|
| ------------- | ---------------- | ------------------ |
|
|
@@ -110,7 +118,7 @@ Work interactively with BMAD agents in your AI coding assistant. On Claude Code,
|
|
|
110
118
|
| 2 Planning | PM / UX Designer | CP, VP, EP, CU |
|
|
111
119
|
| 3 Solutioning | Architect / PM | CA, CE, IR |
|
|
112
120
|
|
|
113
|
-
Validation commands (
|
|
121
|
+
Validation commands (`validate-brief`, `validate-prd`, `validate-ux`, `validate-architecture`, `validate-epics-stories`) run the same workflow in Validate mode. In Claude Code, invoke them as slash commands; on other platforms use the equivalent entry from `_bmad/COMMANDS.md` or Codex Skills.
|
|
114
122
|
|
|
115
123
|
**Phase 1 — Analysis**
|
|
116
124
|
|
|
@@ -152,7 +160,7 @@ Available in any phase for supporting tasks:
|
|
|
152
160
|
- `AR` Adversarial Review — critical content review for QA
|
|
153
161
|
- `US` Update Standards — update tech-writer documentation standards
|
|
154
162
|
- `EC` Explain Concept — create technical explanations with examples
|
|
155
|
-
-
|
|
163
|
+
- `_bmad/COMMANDS.md` — generated command reference for platforms without native slash commands
|
|
156
164
|
|
|
157
165
|
> **Note:** `EP` means Edit PRD in the bmm workflow (Phase 2) and Editorial Review — Prose in the core module. `PM` is Party Mode in core. The bmm meanings are the primary workflow codes.
|
|
158
166
|
|
|
@@ -284,13 +292,14 @@ BMAD (add Epic 2) → bmalph implement → Ralph sees changes + picks up Epic 2
|
|
|
284
292
|
| ----------------- | ------------------------------------------------ |
|
|
285
293
|
| `--interval <ms>` | Refresh interval in milliseconds (default: 2000) |
|
|
286
294
|
|
|
287
|
-
##
|
|
295
|
+
## Command Delivery
|
|
288
296
|
|
|
289
|
-
bmalph
|
|
297
|
+
bmalph bundles 51 BMAD and bmalph command definitions. Delivery varies by platform:
|
|
290
298
|
|
|
291
299
|
- **Claude Code** — installed as files in `.claude/commands/` (invoke with `/command-name`)
|
|
292
300
|
- **OpenAI Codex** — delivered as Codex Skills in `.agents/skills/` (invoke with `$command-name`)
|
|
293
|
-
- **Cursor
|
|
301
|
+
- **Cursor** — discoverable via `_bmad/COMMANDS.md`; ask Cursor to run the BMAD master agent
|
|
302
|
+
- **Windsurf, Copilot, Aider** — discoverable via `_bmad/COMMANDS.md` reference index
|
|
294
303
|
|
|
295
304
|
Key commands (Claude Code syntax):
|
|
296
305
|
|
|
@@ -311,7 +320,11 @@ Key commands (Claude Code syntax):
|
|
|
311
320
|
| `/create-epics-stories` | Create epics and stories |
|
|
312
321
|
| `/bmad-help` | List all BMAD commands |
|
|
313
322
|
|
|
314
|
-
For full list
|
|
323
|
+
For the full list:
|
|
324
|
+
|
|
325
|
+
- Claude Code: run `/bmad-help`
|
|
326
|
+
- OpenAI Codex: inspect `.agents/skills/`
|
|
327
|
+
- Cursor, Windsurf, Copilot, Aider: open `_bmad/COMMANDS.md`
|
|
315
328
|
|
|
316
329
|
### Transition to Ralph
|
|
317
330
|
|
|
@@ -322,8 +335,9 @@ Use `bmalph implement` (or `/bmalph-implement` in Claude Code) to transition fro
|
|
|
322
335
|
```
|
|
323
336
|
project/
|
|
324
337
|
├── _bmad/ # BMAD agents, workflows, core
|
|
325
|
-
│ ├──
|
|
326
|
-
│
|
|
338
|
+
│ ├── config.yaml # Generated platform/project config
|
|
339
|
+
│ ├── COMMANDS.md # Generated command reference index
|
|
340
|
+
│ ├── _config/ # Generated manifests
|
|
327
341
|
│ │ ├── task-manifest.csv # Combined task manifest
|
|
328
342
|
│ │ ├── workflow-manifest.csv # Combined workflow manifest
|
|
329
343
|
│ │ └── bmad-help.csv # Combined help manifest
|
|
@@ -380,10 +394,10 @@ The instructions file and command directory depend on the configured platform. S
|
|
|
380
394
|
|
|
381
395
|
Ralph is a bash loop that spawns fresh AI coding sessions using a **platform driver** matching the configured platform:
|
|
382
396
|
|
|
383
|
-
- **Claude Code driver** — invokes `claude` with `--allowedTools
|
|
384
|
-
- **Codex driver** — invokes `codex exec
|
|
397
|
+
- **Claude Code driver** — invokes `claude` with `--output-format json`, `--allowedTools`, and explicit `--resume <session_id>`
|
|
398
|
+
- **Codex driver** — invokes `codex exec --json --sandbox workspace-write` with explicit `--resume <session_id>`
|
|
385
399
|
- **Copilot driver** _(experimental)_ — invokes `copilot --autopilot --yolo` with plain-text output
|
|
386
|
-
- **Cursor driver** _(experimental)_ — invokes `cursor-agent --
|
|
400
|
+
- **Cursor driver** _(experimental)_ — invokes `cursor-agent -p --force --output-format json`, persists `session_id` for `--resume`, and switches to `stream-json` only for live output
|
|
387
401
|
|
|
388
402
|
Each iteration:
|
|
389
403
|
|
|
@@ -398,6 +412,12 @@ Safety mechanisms:
|
|
|
398
412
|
- **Response analyzer** — detects stuck or repeating outputs
|
|
399
413
|
- **Completion** — loop exits when all `@fix_plan.md` items are checked off
|
|
400
414
|
|
|
415
|
+
Cursor-specific runtime checks:
|
|
416
|
+
|
|
417
|
+
- `bmalph doctor` validates `command -v jq` in the bash environment Ralph uses
|
|
418
|
+
- `bmalph doctor` validates `command -v cursor-agent` and `cursor-agent status`
|
|
419
|
+
- `bmalph run --driver cursor` runs the same bash-scoped preflight before the loop starts
|
|
420
|
+
|
|
401
421
|
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.
|
|
402
422
|
|
|
403
423
|
## Troubleshooting
|
|
@@ -436,21 +456,24 @@ ls -la .ralph/
|
|
|
436
456
|
|
|
437
457
|
### Common Issues
|
|
438
458
|
|
|
439
|
-
| Scenario | Solution
|
|
440
|
-
| ----------------------------- |
|
|
441
|
-
| Commands fail before init | Run `bmalph init` first
|
|
442
|
-
| Transition finds no stories | Create stories in Phase 3 with `/create-epics-stories`
|
|
443
|
-
| Ralph stops mid-loop | Circuit breaker detected stagnation. Check `.ralph/logs/`
|
|
444
|
-
| Doctor reports version drift | Run `bmalph upgrade` to update bundled assets
|
|
445
|
-
| Wrong platform detected | Re-run `bmalph init --platform <id>` with the correct platform
|
|
446
|
-
| Ralph unavailable on platform | Ralph requires a full tier platform (claude-code, codex, copilot, or cursor)
|
|
459
|
+
| Scenario | Solution |
|
|
460
|
+
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------ |
|
|
461
|
+
| Commands fail before init | Run `bmalph init` first |
|
|
462
|
+
| Transition finds no stories | Create stories in Phase 3 with `/create-epics-stories`, the matching Codex Skill, or the `_bmad/COMMANDS.md` entry |
|
|
463
|
+
| Ralph stops mid-loop | Circuit breaker detected stagnation. Check `.ralph/logs/` |
|
|
464
|
+
| Doctor reports version drift | Run `bmalph upgrade` to update bundled assets |
|
|
465
|
+
| Wrong platform detected | Re-run `bmalph init --platform <id>` with the correct platform |
|
|
466
|
+
| Ralph unavailable on platform | Ralph requires a full tier platform (claude-code, codex, copilot, or cursor) |
|
|
447
467
|
|
|
448
468
|
### Windows: Cursor Driver
|
|
449
469
|
|
|
450
470
|
`bmalph run --driver cursor` is experimental on Windows and is designed for Git Bash.
|
|
451
471
|
|
|
452
472
|
- `bmalph` prefers a working Git Bash install instead of Windows `bash.exe` shims.
|
|
453
|
-
- The
|
|
473
|
+
- The official binary is `cursor-agent`. The driver also accepts `cursor-agent.cmd`, `agent`, `agent.cmd`, and `%LOCALAPPDATA%\\cursor-agent\\*.cmd` as compatibility fallbacks.
|
|
474
|
+
- The main Ralph loop uses `cursor-agent -p --force --output-format json` and stores Cursor's `session_id` for `--resume` on the next loop.
|
|
475
|
+
- Live display switches to `stream-json`; background execution stays on JSON mode for reliable parsing.
|
|
476
|
+
- Cursor preflight is bash-scoped: `command -v jq`, `command -v cursor-agent`, and `cursor-agent status` must all succeed in the same shell Ralph uses.
|
|
454
477
|
- On Windows, the driver sends Cursor a short bootstrap prompt that tells it to read the Ralph files from `.ralph/` instead of trying to inline the full prompt on the command line.
|
|
455
478
|
|
|
456
479
|
### Reset Installation
|
|
@@ -545,18 +568,33 @@ claude
|
|
|
545
568
|
bmalph run
|
|
546
569
|
```
|
|
547
570
|
|
|
548
|
-
**
|
|
571
|
+
**OpenAI Codex:**
|
|
572
|
+
|
|
573
|
+
```bash
|
|
574
|
+
# 1. Open your project in your AI coding assistant
|
|
575
|
+
|
|
576
|
+
# 2. Use Codex Skills such as $analyst, $create-prd, and $architect
|
|
577
|
+
# See .agents/skills/ and _bmad/COMMANDS.md for the full catalog
|
|
578
|
+
|
|
579
|
+
# 3. Follow phases: Analysis -> Planning -> Solutioning
|
|
580
|
+
|
|
581
|
+
# 4. Transition to Ralph
|
|
582
|
+
# Run: bmalph implement
|
|
583
|
+
# Then: bmalph run
|
|
584
|
+
```
|
|
585
|
+
|
|
586
|
+
**Cursor, Copilot, Windsurf, Aider:**
|
|
549
587
|
|
|
550
588
|
```bash
|
|
551
589
|
# 1. Open your project in your AI coding assistant
|
|
552
590
|
|
|
553
|
-
# 2.
|
|
554
|
-
#
|
|
591
|
+
# 2. Read _bmad/COMMANDS.md for the available BMAD agents and workflows
|
|
592
|
+
# On Cursor specifically: ask Cursor to run the BMAD master agent
|
|
555
593
|
|
|
556
|
-
# 3.
|
|
557
|
-
#
|
|
594
|
+
# 3. Follow phases: Analysis -> Planning -> Solutioning
|
|
595
|
+
# Or check progress from terminal: bmalph status
|
|
558
596
|
|
|
559
|
-
# 4. For full tier platforms (
|
|
597
|
+
# 4. For full tier platforms (Cursor and Copilot), transition to Ralph:
|
|
560
598
|
# Run: bmalph implement
|
|
561
599
|
# Then: bmalph run
|
|
562
600
|
```
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { readFile, stat } from "node:fs/promises";
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
-
import { resolveBashCommand } from "../run/ralph-process.js";
|
|
3
|
+
import { resolveBashCommand, runBashCommand } from "../run/ralph-process.js";
|
|
4
4
|
import { readJsonFile } from "../utils/json.js";
|
|
5
5
|
import { isEnoent, formatError } from "../utils/errors.js";
|
|
6
6
|
import { CONFIG_FILE } from "../utils/constants.js";
|
|
@@ -43,12 +43,13 @@ export async function checkBash(_projectDir) {
|
|
|
43
43
|
};
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
|
-
export async function checkJq(
|
|
47
|
-
const
|
|
46
|
+
export async function checkJq(projectDir) {
|
|
47
|
+
const result = await runBashCommand("command -v jq", { cwd: projectDir });
|
|
48
|
+
const available = result.exitCode === 0;
|
|
48
49
|
return {
|
|
49
50
|
label: "jq available",
|
|
50
51
|
passed: available,
|
|
51
|
-
detail: available ? undefined : "jq not found in PATH",
|
|
52
|
+
detail: available ? undefined : "jq not found in bash PATH",
|
|
52
53
|
hint: available
|
|
53
54
|
? undefined
|
|
54
55
|
: process.platform === "win32"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor-checks.js","sourceRoot":"","sources":["../../src/commands/doctor-checks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"doctor-checks.js","sourceRoot":"","sources":["../../src/commands/doctor-checks.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/run.js
CHANGED
|
@@ -2,6 +2,7 @@ import chalk from "chalk";
|
|
|
2
2
|
import { readConfig } from "../utils/config.js";
|
|
3
3
|
import { withErrorHandling } from "../utils/errors.js";
|
|
4
4
|
import { isPlatformId, getPlatform, getFullTierPlatformNames } from "../platform/registry.js";
|
|
5
|
+
import { validateCursorRuntime } from "../platform/cursor-runtime-checks.js";
|
|
5
6
|
import { validateBashAvailable, validateRalphLoop, spawnRalphLoop } from "../run/ralph-process.js";
|
|
6
7
|
import { startRunDashboard } from "../run/run-dashboard.js";
|
|
7
8
|
import { parseInterval } from "../utils/validate.js";
|
|
@@ -24,6 +25,9 @@ async function executeRun(options) {
|
|
|
24
25
|
}
|
|
25
26
|
const interval = parseInterval(options.interval);
|
|
26
27
|
await Promise.all([validateBashAvailable(), validateRalphLoop(projectDir)]);
|
|
28
|
+
if (platform.id === "cursor") {
|
|
29
|
+
await validateCursorRuntime(projectDir);
|
|
30
|
+
}
|
|
27
31
|
const ralph = spawnRalphLoop(projectDir, platform.id, {
|
|
28
32
|
inheritStdio: !dashboard,
|
|
29
33
|
});
|
package/dist/commands/run.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AAC9F,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACnG,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAUrD,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,OAA0B;IACzD,MAAM,iBAAiB,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC;AACrD,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,OAA0B;IAClD,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;IAE1C,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,UAAU,CAAC,CAAC;IAC5C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC/D,CAAC;IAED,MAAM,QAAQ,GAAG,eAAe,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;IAClE,IAAI,QAAQ,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CACb,wCAAwC,wBAAwB,EAAE,KAAK;YACrE,YAAY,QAAQ,CAAC,WAAW,EAAE,CACrC,CAAC;IACJ,CAAC;IAED,IAAI,QAAQ,CAAC,YAAY,EAAE,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,YAAY,QAAQ,CAAC,WAAW,0BAA0B,CAAC,CAAC,CAAC;IACxF,CAAC;IAED,MAAM,QAAQ,GAAG,aAAa,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAEjD,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,qBAAqB,EAAE,EAAE,iBAAiB,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AAC9F,OAAO,EAAE,qBAAqB,EAAE,MAAM,sCAAsC,CAAC;AAC7E,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACnG,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAUrD,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,OAA0B;IACzD,MAAM,iBAAiB,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC;AACrD,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,OAA0B;IAClD,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;IAE1C,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,UAAU,CAAC,CAAC;IAC5C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC/D,CAAC;IAED,MAAM,QAAQ,GAAG,eAAe,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;IAClE,IAAI,QAAQ,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CACb,wCAAwC,wBAAwB,EAAE,KAAK;YACrE,YAAY,QAAQ,CAAC,WAAW,EAAE,CACrC,CAAC;IACJ,CAAC;IAED,IAAI,QAAQ,CAAC,YAAY,EAAE,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,YAAY,QAAQ,CAAC,WAAW,0BAA0B,CAAC,CAAC,CAAC;IACxF,CAAC;IAED,MAAM,QAAQ,GAAG,aAAa,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAEjD,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,qBAAqB,EAAE,EAAE,iBAAiB,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IAC5E,IAAI,QAAQ,CAAC,EAAE,KAAK,QAAQ,EAAE,CAAC;QAC7B,MAAM,qBAAqB,CAAC,UAAU,CAAC,CAAC;IAC1C,CAAC;IAED,MAAM,KAAK,GAAG,cAAc,CAAC,UAAU,EAAE,QAAQ,CAAC,EAAE,EAAE;QACpD,YAAY,EAAE,CAAC,SAAS;KACzB,CAAC,CAAC;IAEH,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,iBAAiB,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;QACzD,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAC9B,kBAAkB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;SAAM,CAAC;QACN,MAAM,QAAQ,GAAG,MAAM,IAAI,OAAO,CAAgB,CAAC,OAAO,EAAE,EAAE;YAC5D,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;QACH,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IAC/B,CAAC;AACH,CAAC;AAED,SAAS,kBAAkB,CAAC,IAAmB;IAC7C,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;QAC3C,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAC1B,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CACtB,cAAkC,EAClC,cAA2B;IAE3B,MAAM,EAAE,GAAG,cAAc,IAAI,cAAc,IAAI,aAAa,CAAC;IAC7D,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,qBAAqB,EAAE,EAAE,CAAC,CAAC;IAC7C,CAAC;IACD,OAAO,WAAW,CAAC,EAAE,CAAC,CAAC;AACzB,CAAC"}
|
package/dist/commands/status.js
CHANGED
|
@@ -7,6 +7,9 @@ import { ARTIFACT_DEFINITIONS } from "../utils/artifact-definitions.js";
|
|
|
7
7
|
import { resolveProjectPlatform } from "../platform/resolve.js";
|
|
8
8
|
import { getFullTierPlatformNames } from "../platform/registry.js";
|
|
9
9
|
import { scanProjectArtifacts } from "../transition/artifact-scan.js";
|
|
10
|
+
function getCursorNextAction() {
|
|
11
|
+
return "Read _bmad/COMMANDS.md and ask Cursor to run the BMAD master agent";
|
|
12
|
+
}
|
|
10
13
|
export async function statusCommand(options) {
|
|
11
14
|
await withErrorHandling(() => runStatus(options));
|
|
12
15
|
}
|
|
@@ -27,12 +30,14 @@ export async function runStatus(options) {
|
|
|
27
30
|
if (storedPhase === 4) {
|
|
28
31
|
ralphStatus = await readRalphStatus(projectDir);
|
|
29
32
|
}
|
|
33
|
+
// Resolve platform for next action hints
|
|
34
|
+
const platform = await resolveProjectPlatform(projectDir);
|
|
30
35
|
// Scan artifacts for phases 1-3 to detect actual progress
|
|
31
36
|
let artifactScan = null;
|
|
32
37
|
let phase = storedPhase;
|
|
33
38
|
let phaseDetected = false;
|
|
34
39
|
if (phase < 4) {
|
|
35
|
-
artifactScan = await scanProjectArtifacts(projectDir);
|
|
40
|
+
artifactScan = await scanProjectArtifacts(projectDir, platform.id);
|
|
36
41
|
if (artifactScan && artifactScan.detectedPhase > phase) {
|
|
37
42
|
phase = artifactScan.detectedPhase;
|
|
38
43
|
phaseDetected = true;
|
|
@@ -40,8 +45,6 @@ export async function runStatus(options) {
|
|
|
40
45
|
}
|
|
41
46
|
const phaseName = getPhaseLabel(phase);
|
|
42
47
|
const phaseInfo = getPhaseInfo(phase);
|
|
43
|
-
// Resolve platform for next action hints
|
|
44
|
-
const platform = await resolveProjectPlatform(projectDir);
|
|
45
48
|
// Determine next action — use artifact-based suggestion when available
|
|
46
49
|
const nextAction = artifactScan && phaseDetected
|
|
47
50
|
? artifactScan.nextAction
|
|
@@ -147,8 +150,14 @@ function getNextAction(phase, status, ralphStatus, platform) {
|
|
|
147
150
|
}
|
|
148
151
|
switch (phase) {
|
|
149
152
|
case 1:
|
|
153
|
+
if (platform.id === "cursor") {
|
|
154
|
+
return getCursorNextAction();
|
|
155
|
+
}
|
|
150
156
|
return "Run /analyst to start analysis";
|
|
151
157
|
case 2:
|
|
158
|
+
if (platform.id === "cursor") {
|
|
159
|
+
return getCursorNextAction();
|
|
160
|
+
}
|
|
152
161
|
return "Run /pm to create PRD";
|
|
153
162
|
case 3:
|
|
154
163
|
return "Run: bmalph implement";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC5F,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AA6BtE,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAAsB;IACxD,MAAM,iBAAiB,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;AACpD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,OAAsB;IACpD,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IAEtC,kCAAkC;IAClC,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,UAAU,CAAC,CAAC;IAC5C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC,CAAC;QACpE,OAAO;IACT,CAAC;IAED,qBAAqB;IACrB,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,UAAU,CAAC,CAAC;IAC1C,MAAM,WAAW,GAAG,KAAK,EAAE,YAAY,IAAI,CAAC,CAAC;IAC7C,MAAM,MAAM,GAAG,KAAK,EAAE,MAAM,IAAI,UAAU,CAAC;IAE3C,+CAA+C;IAC/C,IAAI,WAAW,GAAG,IAAI,CAAC;IACvB,IAAI,WAAW,KAAK,CAAC,EAAE,CAAC;QACtB,WAAW,GAAG,MAAM,eAAe,CAAC,UAAU,CAAC,CAAC;IAClD,CAAC;IAED,0DAA0D;IAC1D,IAAI,YAAY,GAA+B,IAAI,CAAC;IACpD,IAAI,KAAK,GAAG,WAAW,CAAC;IACxB,IAAI,aAAa,GAAG,KAAK,CAAC;IAE1B,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QACd,YAAY,GAAG,MAAM,oBAAoB,CAAC,UAAU,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"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"}
|
package/dist/installer.js
CHANGED
|
@@ -391,6 +391,91 @@ function formatCommandTable(heading, entries, thirdCol = "Invocation") {
|
|
|
391
391
|
}
|
|
392
392
|
return lines.join("\n") + "\n";
|
|
393
393
|
}
|
|
394
|
+
async function prepareBmadSwap(projectDir, bundledBmadDir) {
|
|
395
|
+
const dest = join(projectDir, "_bmad");
|
|
396
|
+
const backup = join(projectDir, "_bmad.old");
|
|
397
|
+
const staged = join(projectDir, "_bmad.new");
|
|
398
|
+
const destExists = await exists(dest);
|
|
399
|
+
const backupExists = await exists(backup);
|
|
400
|
+
let hasBackup = false;
|
|
401
|
+
if (destExists && backupExists) {
|
|
402
|
+
throw new Error("Found both _bmad and _bmad.old from a previous failed install or upgrade. " +
|
|
403
|
+
"Restore or remove one of them before retrying.");
|
|
404
|
+
}
|
|
405
|
+
if (backupExists) {
|
|
406
|
+
hasBackup = true;
|
|
407
|
+
debug("Found existing _bmad.old from previous failed rollback, preserving backup");
|
|
408
|
+
}
|
|
409
|
+
else if (destExists) {
|
|
410
|
+
try {
|
|
411
|
+
await rename(dest, backup);
|
|
412
|
+
hasBackup = true;
|
|
413
|
+
}
|
|
414
|
+
catch (err) {
|
|
415
|
+
if (!isEnoent(err))
|
|
416
|
+
throw err;
|
|
417
|
+
debug("_bmad disappeared before it could be preserved, continuing without backup");
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
else {
|
|
421
|
+
debug("No existing _bmad to preserve (first install)");
|
|
422
|
+
}
|
|
423
|
+
// Stage new content.
|
|
424
|
+
await rm(staged, { recursive: true, force: true });
|
|
425
|
+
await cp(bundledBmadDir, staged, { recursive: true, dereference: false });
|
|
426
|
+
return { dest, backup, staged, hasBackup };
|
|
427
|
+
}
|
|
428
|
+
async function finalizeBmadInstall(projectDir, slashCommandsDir, platform) {
|
|
429
|
+
await generateManifests(projectDir);
|
|
430
|
+
const classified = await classifyCommands(projectDir, slashCommandsDir);
|
|
431
|
+
await generateCommandIndex(projectDir, classified);
|
|
432
|
+
const projectName = await deriveProjectName(projectDir);
|
|
433
|
+
const escapedName = projectName.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
434
|
+
await atomicWriteFile(join(projectDir, "_bmad/config.yaml"), `# BMAD Configuration - Generated by bmalph
|
|
435
|
+
platform: ${platform.id}
|
|
436
|
+
project_name: "${escapedName}"
|
|
437
|
+
output_folder: _bmad-output
|
|
438
|
+
user_name: BMad
|
|
439
|
+
communication_language: English
|
|
440
|
+
document_output_language: English
|
|
441
|
+
user_skill_level: intermediate
|
|
442
|
+
planning_artifacts: _bmad-output/planning-artifacts
|
|
443
|
+
implementation_artifacts: _bmad-output/implementation-artifacts
|
|
444
|
+
project_knowledge: docs
|
|
445
|
+
modules:
|
|
446
|
+
- bmm
|
|
447
|
+
`);
|
|
448
|
+
return classified;
|
|
449
|
+
}
|
|
450
|
+
async function rollbackBmadFinalization(swap, error) {
|
|
451
|
+
debug(`BMAD finalization failed after swap: ${formatError(error)}`);
|
|
452
|
+
try {
|
|
453
|
+
await rm(swap.dest, { recursive: true, force: true });
|
|
454
|
+
if (swap.hasBackup) {
|
|
455
|
+
await rename(swap.backup, swap.dest);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
catch (rollbackErr) {
|
|
459
|
+
throw new Error("BMAD finalization failed after swap and rollback also failed. " +
|
|
460
|
+
`Original error: ${formatError(error)}. ` +
|
|
461
|
+
`Rollback error: ${formatError(rollbackErr)}`, {
|
|
462
|
+
cause: rollbackErr,
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
if (swap.hasBackup) {
|
|
466
|
+
throw new Error("BMAD finalization failed after swap; previous BMAD installation was restored.", {
|
|
467
|
+
cause: error,
|
|
468
|
+
});
|
|
469
|
+
}
|
|
470
|
+
throw new Error("BMAD finalization failed after swap; incomplete BMAD installation was cleaned up.", {
|
|
471
|
+
cause: error,
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
async function commitBmadSwap(swap) {
|
|
475
|
+
if (!swap.hasBackup)
|
|
476
|
+
return;
|
|
477
|
+
await rm(swap.backup, { recursive: true, force: true });
|
|
478
|
+
}
|
|
394
479
|
export async function copyBundledAssets(projectDir, platform) {
|
|
395
480
|
const p = platform ?? (await getDefaultPlatform());
|
|
396
481
|
const bmadDir = getBundledBmadDir();
|
|
@@ -406,33 +491,17 @@ export async function copyBundledAssets(projectDir, platform) {
|
|
|
406
491
|
if (!(await exists(slashCommandsDir))) {
|
|
407
492
|
throw new Error(`Slash commands directory not found at ${slashCommandsDir}. Package may be corrupted.`);
|
|
408
493
|
}
|
|
409
|
-
// Atomic copy: rename-aside pattern to prevent data loss
|
|
410
|
-
const
|
|
411
|
-
|
|
412
|
-
const bmadNew = join(projectDir, "_bmad.new");
|
|
413
|
-
// Clean leftover from previous failed attempt
|
|
414
|
-
await rm(bmadOld, { recursive: true, force: true });
|
|
415
|
-
// Move original aside (tolerate ENOENT on first install)
|
|
494
|
+
// Atomic copy: rename-aside pattern to prevent data loss.
|
|
495
|
+
const bmadSwap = await prepareBmadSwap(projectDir, bmadDir);
|
|
496
|
+
// Swap in.
|
|
416
497
|
try {
|
|
417
|
-
await rename(
|
|
498
|
+
await rename(bmadSwap.staged, bmadSwap.dest);
|
|
418
499
|
}
|
|
419
500
|
catch (err) {
|
|
420
|
-
|
|
421
|
-
throw err;
|
|
422
|
-
debug("No existing _bmad to preserve (first install)");
|
|
423
|
-
}
|
|
424
|
-
// Stage new content
|
|
425
|
-
await rm(bmadNew, { recursive: true, force: true });
|
|
426
|
-
await cp(bmadDir, bmadNew, { recursive: true, dereference: false });
|
|
427
|
-
// Swap in
|
|
428
|
-
try {
|
|
429
|
-
await rename(bmadNew, bmadDest);
|
|
430
|
-
}
|
|
431
|
-
catch (err) {
|
|
432
|
-
// Restore original on failure
|
|
501
|
+
// Restore original on failure.
|
|
433
502
|
debug(`Rename failed, restoring original: ${formatError(err)}`);
|
|
434
503
|
try {
|
|
435
|
-
await rename(
|
|
504
|
+
await rename(bmadSwap.backup, bmadSwap.dest);
|
|
436
505
|
}
|
|
437
506
|
catch (restoreErr) {
|
|
438
507
|
if (!isEnoent(restoreErr)) {
|
|
@@ -441,35 +510,19 @@ export async function copyBundledAssets(projectDir, platform) {
|
|
|
441
510
|
}
|
|
442
511
|
throw err;
|
|
443
512
|
}
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
513
|
+
const classified = await (async () => {
|
|
514
|
+
try {
|
|
515
|
+
return await finalizeBmadInstall(projectDir, slashCommandsDir, p);
|
|
516
|
+
}
|
|
517
|
+
catch (err) {
|
|
518
|
+
return await rollbackBmadFinalization(bmadSwap, err);
|
|
519
|
+
}
|
|
520
|
+
})();
|
|
521
|
+
await commitBmadSwap(bmadSwap);
|
|
522
|
+
// Generate Codex Skills for skills-based platforms.
|
|
453
523
|
if (p.commandDelivery.kind === "skills") {
|
|
454
524
|
await generateSkills(projectDir, classified);
|
|
455
525
|
}
|
|
456
|
-
// Generate _bmad/config.yaml with platform-specific value
|
|
457
|
-
const projectName = await deriveProjectName(projectDir);
|
|
458
|
-
const escapedName = projectName.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
459
|
-
await atomicWriteFile(join(projectDir, "_bmad/config.yaml"), `# BMAD Configuration - Generated by bmalph
|
|
460
|
-
platform: ${p.id}
|
|
461
|
-
project_name: "${escapedName}"
|
|
462
|
-
output_folder: _bmad-output
|
|
463
|
-
user_name: BMad
|
|
464
|
-
communication_language: English
|
|
465
|
-
document_output_language: English
|
|
466
|
-
user_skill_level: intermediate
|
|
467
|
-
planning_artifacts: _bmad-output/planning-artifacts
|
|
468
|
-
implementation_artifacts: _bmad-output/implementation-artifacts
|
|
469
|
-
project_knowledge: docs
|
|
470
|
-
modules:
|
|
471
|
-
- bmm
|
|
472
|
-
`);
|
|
473
526
|
// Copy Ralph templates → .ralph/
|
|
474
527
|
await mkdir(join(projectDir, ".ralph"), { recursive: true });
|
|
475
528
|
// Preserve customized PROMPT.md and @AGENT.md on upgrade
|