bmalph 2.7.5 → 2.7.7

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 (67) hide show
  1. package/README.md +20 -5
  2. package/dist/commands/doctor-runtime-checks.js +104 -86
  3. package/dist/commands/doctor-runtime-checks.js.map +1 -1
  4. package/dist/commands/run.js +11 -2
  5. package/dist/commands/run.js.map +1 -1
  6. package/dist/commands/watch.js +5 -0
  7. package/dist/commands/watch.js.map +1 -1
  8. package/dist/installer/bmad-assets.js +182 -0
  9. package/dist/installer/bmad-assets.js.map +1 -0
  10. package/dist/installer/commands.js +324 -0
  11. package/dist/installer/commands.js.map +1 -0
  12. package/dist/installer/install.js +42 -0
  13. package/dist/installer/install.js.map +1 -0
  14. package/dist/installer/metadata.js +56 -0
  15. package/dist/installer/metadata.js.map +1 -0
  16. package/dist/installer/project-files.js +169 -0
  17. package/dist/installer/project-files.js.map +1 -0
  18. package/dist/installer/ralph-assets.js +91 -0
  19. package/dist/installer/ralph-assets.js.map +1 -0
  20. package/dist/installer/template-files.js +187 -0
  21. package/dist/installer/template-files.js.map +1 -0
  22. package/dist/installer/types.js +2 -0
  23. package/dist/installer/types.js.map +1 -0
  24. package/dist/installer.js +5 -843
  25. package/dist/installer.js.map +1 -1
  26. package/dist/run/run-dashboard.js +20 -6
  27. package/dist/run/run-dashboard.js.map +1 -1
  28. package/dist/transition/artifact-loading.js +91 -0
  29. package/dist/transition/artifact-loading.js.map +1 -0
  30. package/dist/transition/context-output.js +85 -0
  31. package/dist/transition/context-output.js.map +1 -0
  32. package/dist/transition/context.js +11 -3
  33. package/dist/transition/context.js.map +1 -1
  34. package/dist/transition/fix-plan-sync.js +119 -0
  35. package/dist/transition/fix-plan-sync.js.map +1 -0
  36. package/dist/transition/orchestration.js +25 -362
  37. package/dist/transition/orchestration.js.map +1 -1
  38. package/dist/transition/specs-sync.js +78 -2
  39. package/dist/transition/specs-sync.js.map +1 -1
  40. package/dist/utils/ralph-runtime-state.js +222 -0
  41. package/dist/utils/ralph-runtime-state.js.map +1 -0
  42. package/dist/utils/state.js +17 -16
  43. package/dist/utils/state.js.map +1 -1
  44. package/dist/utils/validate.js +16 -0
  45. package/dist/utils/validate.js.map +1 -1
  46. package/dist/watch/dashboard.js +25 -21
  47. package/dist/watch/dashboard.js.map +1 -1
  48. package/dist/watch/frame-writer.js +83 -0
  49. package/dist/watch/frame-writer.js.map +1 -0
  50. package/dist/watch/renderer.js +214 -49
  51. package/dist/watch/renderer.js.map +1 -1
  52. package/dist/watch/state-reader.js +87 -44
  53. package/dist/watch/state-reader.js.map +1 -1
  54. package/package.json +1 -1
  55. package/ralph/RALPH-REFERENCE.md +34 -14
  56. package/ralph/drivers/claude-code.sh +27 -0
  57. package/ralph/drivers/codex.sh +11 -0
  58. package/ralph/drivers/copilot.sh +11 -0
  59. package/ralph/drivers/cursor.sh +11 -0
  60. package/ralph/lib/circuit_breaker.sh +3 -3
  61. package/ralph/lib/date_utils.sh +28 -9
  62. package/ralph/lib/enable_core.sh +10 -2
  63. package/ralph/lib/response_analyzer.sh +252 -40
  64. package/ralph/ralph_import.sh +9 -1
  65. package/ralph/ralph_loop.sh +548 -128
  66. package/ralph/templates/PROMPT.md +20 -5
  67. package/ralph/templates/ralphrc.template +14 -4
package/README.md CHANGED
@@ -394,7 +394,7 @@ The instructions file and command directory depend on the configured platform. S
394
394
 
395
395
  Ralph is a bash loop that spawns fresh AI coding sessions using a **platform driver** matching the configured platform:
396
396
 
397
- - **Claude Code driver** — invokes `claude` with `--output-format json`, `--allowedTools`, and explicit `--resume <session_id>`
397
+ - **Claude Code driver** — invokes `claude` with `--output-format json`, `--permission-mode bypassPermissions`, `--allowedTools`, and explicit `--resume <session_id>`
398
398
  - **Codex driver** — invokes `codex exec --json --sandbox workspace-write` with explicit `--resume <session_id>`
399
399
  - **Copilot driver** _(experimental)_ — invokes `copilot --autopilot --yolo` with plain-text output
400
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
@@ -447,13 +447,28 @@ wsl --install
447
447
  If you get permission errors:
448
448
 
449
449
  ```bash
450
- # Unix/Mac: Make driver scripts executable
451
- chmod +x .ralph/drivers/*.sh
450
+ # Claude Code only: broaden the tool allowlist in the managed config
451
+ # .ralph/.ralphrc
452
+ ALLOWED_TOOLS="Write,Read,Edit,MultiEdit,Glob,Grep,Task,TodoWrite,WebFetch,WebSearch,EnterPlanMode,ExitPlanMode,NotebookEdit,Bash"
452
453
 
453
- # Check file ownership
454
- ls -la .ralph/
454
+ # Keep interactive approval workflows out of unattended Claude loops
455
+ CLAUDE_PERMISSION_MODE="bypassPermissions"
456
+
457
+ # Keep the loop unattended by continuing after detected denials
458
+ PERMISSION_DENIAL_MODE="continue"
459
+
460
+ # Reset stale session state and restart
461
+ bash .ralph/ralph_loop.sh --reset-session
462
+ bmalph run
455
463
  ```
456
464
 
465
+ Notes:
466
+
467
+ - `ALLOWED_TOOLS` only applies to the Claude Code driver and controls normal tool access.
468
+ - `CLAUDE_PERMISSION_MODE="bypassPermissions"` keeps unattended Claude loops out of interactive approval flows without relying on the unsupported `afk-mode` beta header.
469
+ - Codex, Cursor, and Copilot use their native sandbox/approval settings instead.
470
+ - Fresh installs default to unattended mode and discourage in-loop user questions via `.ralph/PROMPT.md`.
471
+
457
472
  ### Common Issues
458
473
 
459
474
  | Scenario | Solution |
@@ -1,83 +1,53 @@
1
- import { readFile } from "node:fs/promises";
2
- import { join } from "node:path";
3
1
  import { getBundledVersions } from "../installer.js";
4
2
  import { checkUpstream, getSkipReason } from "../utils/github.js";
5
- import { isEnoent, formatError } from "../utils/errors.js";
6
- import { validateCircuitBreakerState, validateRalphSession, validateRalphApiStatus, } from "../utils/validate.js";
7
- import { SESSION_AGE_WARNING_MS, API_USAGE_WARNING_PERCENT, RALPH_STATUS_FILE, } from "../utils/constants.js";
3
+ import { formatError } from "../utils/errors.js";
4
+ import { readRalphCircuitBreaker, readRalphRuntimeSession, readRalphRuntimeStatus, } from "../utils/ralph-runtime-state.js";
5
+ import { SESSION_AGE_WARNING_MS, API_USAGE_WARNING_PERCENT } from "../utils/constants.js";
8
6
  export async function checkCircuitBreaker(projectDir) {
9
7
  const label = "circuit breaker";
10
- const statePath = join(projectDir, ".ralph/.circuit_breaker_state");
11
- try {
12
- const content = await readFile(statePath, "utf-8");
13
- const parsed = JSON.parse(content);
14
- const state = validateCircuitBreakerState(parsed);
15
- if (state.state === "CLOSED") {
16
- const detail = `CLOSED (${state.consecutive_no_progress} loops without progress)`;
17
- return { label, passed: true, detail };
18
- }
19
- if (state.state === "HALF_OPEN") {
20
- return { label, passed: true, detail: `HALF_OPEN - monitoring` };
21
- }
22
- const detail = `OPEN - ${state.reason ?? "stagnation detected"}`;
8
+ const result = await readRalphCircuitBreaker(projectDir);
9
+ if (result.kind === "missing") {
10
+ return { label, passed: true, detail: "not running" };
11
+ }
12
+ if (result.kind === "invalid") {
23
13
  return {
24
14
  label,
25
15
  passed: false,
26
- detail,
27
- hint: "Ralph detected stagnation. Review logs with: bmalph status",
16
+ detail: "corrupt state file",
17
+ hint: "Delete .ralph/.circuit_breaker_state and restart Ralph",
28
18
  };
29
19
  }
30
- catch (err) {
31
- if (isEnoent(err)) {
32
- return { label, passed: true, detail: "not running" };
33
- }
20
+ if (result.kind === "unreadable") {
34
21
  return {
35
22
  label,
36
23
  passed: false,
37
- detail: "corrupt state file",
38
- hint: "Delete .ralph/.circuit_breaker_state and restart Ralph",
24
+ detail: "unreadable state file",
25
+ hint: "Check file permissions or locks on .ralph/.circuit_breaker_state and restart Ralph",
39
26
  };
40
27
  }
28
+ const state = result.value;
29
+ if (state.state === "CLOSED") {
30
+ const detail = `CLOSED (${state.consecutiveNoProgress} loops without progress)`;
31
+ return { label, passed: true, detail };
32
+ }
33
+ if (state.state === "HALF_OPEN") {
34
+ return { label, passed: true, detail: "HALF_OPEN - monitoring" };
35
+ }
36
+ const detail = `OPEN - ${state.reason ?? "stagnation detected"}`;
37
+ return {
38
+ label,
39
+ passed: false,
40
+ detail,
41
+ hint: "Ralph detected stagnation. Review logs with: bmalph status",
42
+ };
41
43
  }
42
44
  export async function checkRalphSession(projectDir) {
43
45
  const label = "Ralph session";
44
- const sessionPath = join(projectDir, ".ralph/.ralph_session");
45
- try {
46
- const content = await readFile(sessionPath, "utf-8");
47
- const parsed = JSON.parse(content);
48
- const session = validateRalphSession(parsed);
49
- if (!session.session_id || session.session_id === "") {
50
- return { label, passed: true, detail: "no active session" };
51
- }
52
- const createdAt = new Date(session.created_at);
53
- const now = new Date();
54
- const ageMs = now.getTime() - createdAt.getTime();
55
- if (ageMs < 0) {
56
- return {
57
- label,
58
- passed: false,
59
- detail: "invalid timestamp (future)",
60
- hint: "Delete .ralph/.ralph_session to reset",
61
- };
62
- }
63
- const ageHours = Math.floor(ageMs / (1000 * 60 * 60));
64
- const ageMinutes = Math.floor((ageMs % (1000 * 60 * 60)) / (1000 * 60));
65
- const ageStr = ageHours > 0 ? `${ageHours}h${ageMinutes}m` : `${ageMinutes}m`;
66
- const maxAgeHours = Math.floor(SESSION_AGE_WARNING_MS / (1000 * 60 * 60));
67
- if (ageMs >= SESSION_AGE_WARNING_MS) {
68
- return {
69
- label,
70
- passed: false,
71
- detail: `${ageStr} old (max ${maxAgeHours}h)`,
72
- hint: "Session is stale. Start a fresh Ralph session",
73
- };
74
- }
75
- return { label, passed: true, detail: ageStr };
46
+ const result = await readRalphRuntimeSession(projectDir);
47
+ if (result.kind === "missing") {
48
+ return { label, passed: true, detail: "no active session" };
76
49
  }
77
- catch (err) {
78
- if (isEnoent(err)) {
79
- return { label, passed: true, detail: "no active session" };
80
- }
50
+ if (result.kind === "invalid") {
81
51
  return {
82
52
  label,
83
53
  passed: false,
@@ -85,34 +55,59 @@ export async function checkRalphSession(projectDir) {
85
55
  hint: "Delete .ralph/.ralph_session to reset",
86
56
  };
87
57
  }
58
+ if (result.kind === "unreadable") {
59
+ return {
60
+ label,
61
+ passed: false,
62
+ detail: "unreadable session file",
63
+ hint: "Check file permissions or locks on .ralph/.ralph_session and retry",
64
+ };
65
+ }
66
+ const session = result.value;
67
+ if (session.kind === "inactive") {
68
+ return { label, passed: true, detail: "no active session" };
69
+ }
70
+ const createdAt = new Date(session.created_at);
71
+ const createdAtMs = createdAt.getTime();
72
+ if (Number.isNaN(createdAtMs)) {
73
+ return {
74
+ label,
75
+ passed: false,
76
+ detail: "invalid timestamp",
77
+ hint: "Delete .ralph/.ralph_session to reset",
78
+ };
79
+ }
80
+ const now = new Date();
81
+ const ageMs = now.getTime() - createdAtMs;
82
+ if (ageMs < 0) {
83
+ return {
84
+ label,
85
+ passed: false,
86
+ detail: "invalid timestamp (future)",
87
+ hint: "Delete .ralph/.ralph_session to reset",
88
+ };
89
+ }
90
+ const ageHours = Math.floor(ageMs / (1000 * 60 * 60));
91
+ const ageMinutes = Math.floor((ageMs % (1000 * 60 * 60)) / (1000 * 60));
92
+ const ageStr = ageHours > 0 ? `${ageHours}h${ageMinutes}m` : `${ageMinutes}m`;
93
+ const maxAgeHours = Math.floor(SESSION_AGE_WARNING_MS / (1000 * 60 * 60));
94
+ if (ageMs >= SESSION_AGE_WARNING_MS) {
95
+ return {
96
+ label,
97
+ passed: false,
98
+ detail: `${ageStr} old (max ${maxAgeHours}h)`,
99
+ hint: "Session is stale. Start a fresh Ralph session",
100
+ };
101
+ }
102
+ return { label, passed: true, detail: ageStr };
88
103
  }
89
104
  export async function checkApiCalls(projectDir) {
90
105
  const label = "API calls this hour";
91
- const statusPath = join(projectDir, RALPH_STATUS_FILE);
92
- try {
93
- const content = await readFile(statusPath, "utf-8");
94
- const parsed = JSON.parse(content);
95
- const status = validateRalphApiStatus(parsed);
96
- const calls = status.calls_made_this_hour;
97
- const max = status.max_calls_per_hour;
98
- if (max <= 0) {
99
- return { label, passed: true, detail: `${calls}/unlimited` };
100
- }
101
- const percentage = (calls / max) * 100;
102
- if (percentage >= API_USAGE_WARNING_PERCENT) {
103
- return {
104
- label,
105
- passed: false,
106
- detail: `${calls}/${max} (approaching limit)`,
107
- hint: "Wait for rate limit reset or increase API quota",
108
- };
109
- }
110
- return { label, passed: true, detail: `${calls}/${max}` };
106
+ const result = await readRalphRuntimeStatus(projectDir);
107
+ if (result.kind === "missing") {
108
+ return { label, passed: true, detail: "not running" };
111
109
  }
112
- catch (err) {
113
- if (isEnoent(err)) {
114
- return { label, passed: true, detail: "not running" };
115
- }
110
+ if (result.kind === "invalid") {
116
111
  return {
117
112
  label,
118
113
  passed: false,
@@ -120,6 +115,29 @@ export async function checkApiCalls(projectDir) {
120
115
  hint: "Delete .ralph/status.json to reset",
121
116
  };
122
117
  }
118
+ if (result.kind === "unreadable") {
119
+ return {
120
+ label,
121
+ passed: false,
122
+ detail: "unreadable status file",
123
+ hint: "Check file permissions or locks on .ralph/status.json and retry",
124
+ };
125
+ }
126
+ const calls = result.value.callsMadeThisHour;
127
+ const max = result.value.maxCallsPerHour;
128
+ if (max <= 0) {
129
+ return { label, passed: true, detail: `${calls}/unlimited` };
130
+ }
131
+ const percentage = (calls / max) * 100;
132
+ if (percentage >= API_USAGE_WARNING_PERCENT) {
133
+ return {
134
+ label,
135
+ passed: false,
136
+ detail: `${calls}/${max} (approaching limit)`,
137
+ hint: "Wait for rate limit reset or increase API quota",
138
+ };
139
+ }
140
+ return { label, passed: true, detail: `${calls}/${max}` };
123
141
  }
124
142
  export async function checkUpstreamGitHubStatus(_projectDir) {
125
143
  const label = "upstream status";
@@ -1 +1 @@
1
- {"version":3,"file":"doctor-runtime-checks.js","sourceRoot":"","sources":["../../src/commands/doctor-runtime-checks.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"doctor-runtime-checks.js","sourceRoot":"","sources":["../../src/commands/doctor-runtime-checks.ts"],"names":[],"mappings":"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"}
@@ -6,6 +6,7 @@ import { validateCursorRuntime } from "../platform/cursor-runtime-checks.js";
6
6
  import { validateBashAvailable, validateRalphLoop, spawnRalphLoop } from "../run/ralph-process.js";
7
7
  import { startRunDashboard } from "../run/run-dashboard.js";
8
8
  import { parseInterval } from "../utils/validate.js";
9
+ import { getDashboardTerminalSupport } from "../watch/frame-writer.js";
9
10
  export async function runCommand(options) {
10
11
  await withErrorHandling(() => executeRun(options));
11
12
  }
@@ -24,14 +25,22 @@ async function executeRun(options) {
24
25
  console.log(chalk.yellow(`Warning: ${platform.displayName} support is experimental`));
25
26
  }
26
27
  const interval = parseInterval(options.interval);
28
+ let useDashboard = dashboard;
29
+ if (useDashboard) {
30
+ const terminalSupport = getDashboardTerminalSupport();
31
+ if (!terminalSupport.supported) {
32
+ console.log(chalk.yellow(`Warning: dashboard disabled. ${terminalSupport.reason}`));
33
+ useDashboard = false;
34
+ }
35
+ }
27
36
  await Promise.all([validateBashAvailable(), validateRalphLoop(projectDir)]);
28
37
  if (platform.id === "cursor") {
29
38
  await validateCursorRuntime(projectDir);
30
39
  }
31
40
  const ralph = spawnRalphLoop(projectDir, platform.id, {
32
- inheritStdio: !dashboard,
41
+ inheritStdio: !useDashboard,
33
42
  });
34
- if (dashboard) {
43
+ if (useDashboard) {
35
44
  await startRunDashboard({ projectDir, interval, ralph });
36
45
  if (ralph.state === "stopped") {
37
46
  applyRalphExitCode(ralph.exitCode);
@@ -1 +1 @@
1
- {"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"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"}
@@ -3,6 +3,7 @@ import { readConfig } from "../utils/config.js";
3
3
  import { withErrorHandling } from "../utils/errors.js";
4
4
  import { parseInterval } from "../utils/validate.js";
5
5
  import { startDashboard } from "../watch/dashboard.js";
6
+ import { getDashboardTerminalSupport } from "../watch/frame-writer.js";
6
7
  export async function watchCommand(options) {
7
8
  await withErrorHandling(() => runWatch(options));
8
9
  }
@@ -14,6 +15,10 @@ async function runWatch(options) {
14
15
  throw new Error("Project not initialized. Run: bmalph init");
15
16
  }
16
17
  const interval = parseInterval(options.interval);
18
+ const terminalSupport = getDashboardTerminalSupport();
19
+ if (!terminalSupport.supported) {
20
+ throw new Error(terminalSupport.reason);
21
+ }
17
22
  await startDashboard({ projectDir, interval });
18
23
  }
19
24
  //# sourceMappingURL=watch.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"watch.js","sourceRoot":"","sources":["../../src/commands/watch.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,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAOvD,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAA4B;IAC7D,MAAM,iBAAiB,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;AACnD,CAAC;AAED,KAAK,UAAU,QAAQ,CAAC,OAA4B;IAClD,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,kEAAkE,CAAC,CAAC,CAAC;IAEhG,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IAEtC,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,aAAa,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAEjD,MAAM,cAAc,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,CAAC;AACjD,CAAC"}
1
+ {"version":3,"file":"watch.js","sourceRoot":"","sources":["../../src/commands/watch.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,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAC;AAOvE,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAA4B;IAC7D,MAAM,iBAAiB,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;AACnD,CAAC;AAED,KAAK,UAAU,QAAQ,CAAC,OAA4B;IAClD,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,kEAAkE,CAAC,CAAC,CAAC;IAEhG,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IAEtC,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,aAAa,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACjD,MAAM,eAAe,GAAG,2BAA2B,EAAE,CAAC;IACtD,IAAI,CAAC,eAAe,CAAC,SAAS,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;IAC1C,CAAC;IAED,MAAM,cAAc,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,CAAC;AACjD,CAAC"}
@@ -0,0 +1,182 @@
1
+ import { cp, mkdir, readFile, rename, rm } from "node:fs/promises";
2
+ import { basename, join } from "node:path";
3
+ import { debug, warn } from "../utils/logger.js";
4
+ import { atomicWriteFile, exists } from "../utils/file-system.js";
5
+ import { formatError, isEnoent } from "../utils/errors.js";
6
+ import { CONFIG_FILE } from "../utils/constants.js";
7
+ import { classifyCommands, generateCommandIndex } from "./commands.js";
8
+ export async function installBmadAssets(projectDir, bundledBmadDir, slashCommandsDir, platform) {
9
+ const bmadSwap = await prepareBmadSwap(projectDir, bundledBmadDir);
10
+ // Swap in.
11
+ try {
12
+ await rename(bmadSwap.staged, bmadSwap.dest);
13
+ }
14
+ catch (err) {
15
+ // Restore original on failure.
16
+ debug(`Rename failed, restoring original: ${formatError(err)}`);
17
+ try {
18
+ await rename(bmadSwap.backup, bmadSwap.dest);
19
+ }
20
+ catch (restoreErr) {
21
+ if (!isEnoent(restoreErr)) {
22
+ debug(`Could not restore _bmad.old: ${formatError(restoreErr)}`);
23
+ }
24
+ }
25
+ throw err;
26
+ }
27
+ const classified = await (async () => {
28
+ try {
29
+ return await finalizeBmadInstall(projectDir, slashCommandsDir, platform);
30
+ }
31
+ catch (err) {
32
+ return await rollbackBmadFinalization(bmadSwap, err);
33
+ }
34
+ })();
35
+ await commitBmadSwap(bmadSwap);
36
+ return classified;
37
+ }
38
+ export async function generateManifests(projectDir) {
39
+ const configDir = join(projectDir, "_bmad/_config");
40
+ await mkdir(configDir, { recursive: true });
41
+ const coreHelpPath = join(projectDir, "_bmad/core/module-help.csv");
42
+ const bmmHelpPath = join(projectDir, "_bmad/bmm/module-help.csv");
43
+ // Validate CSV files exist before reading
44
+ if (!(await exists(coreHelpPath))) {
45
+ throw new Error(`Core module-help.csv not found at ${coreHelpPath}. BMAD installation may be incomplete.`);
46
+ }
47
+ if (!(await exists(bmmHelpPath))) {
48
+ throw new Error(`BMM module-help.csv not found at ${bmmHelpPath}. BMAD installation may be incomplete.`);
49
+ }
50
+ const coreContent = await readFile(coreHelpPath, "utf-8");
51
+ const bmmContent = await readFile(bmmHelpPath, "utf-8");
52
+ // Extract header from core (first line) and data lines from both
53
+ const coreLines = coreContent.trimEnd().split(/\r?\n/);
54
+ const bmmLines = bmmContent.trimEnd().split(/\r?\n/);
55
+ if (!coreLines[0]?.trim()) {
56
+ throw new Error(`Core module-help.csv is empty at ${coreHelpPath}`);
57
+ }
58
+ if (!bmmLines[0]?.trim()) {
59
+ throw new Error(`BMM module-help.csv is empty at ${bmmHelpPath}`);
60
+ }
61
+ const normalize = (line) => line.replace(/,+$/, "");
62
+ const header = normalize(coreLines[0]);
63
+ const bmmHeader = normalize(bmmLines[0]);
64
+ // Validate headers match (warn if mismatch but continue)
65
+ if (header && bmmHeader && header !== bmmHeader) {
66
+ warn(`CSV header mismatch detected. BMAD modules may have incompatible formats.`);
67
+ debug(`CSV header mismatch details - core: "${header.slice(0, 50)}...", bmm: "${bmmHeader.slice(0, 50)}..."`);
68
+ }
69
+ const coreData = coreLines
70
+ .slice(1)
71
+ .filter((l) => l.trim())
72
+ .map(normalize);
73
+ const bmmData = bmmLines
74
+ .slice(1)
75
+ .filter((l) => l.trim())
76
+ .map(normalize);
77
+ const combined = [header, ...coreData, ...bmmData].join("\n") + "\n";
78
+ await atomicWriteFile(join(configDir, "task-manifest.csv"), combined);
79
+ await atomicWriteFile(join(configDir, "workflow-manifest.csv"), combined);
80
+ await atomicWriteFile(join(configDir, "bmad-help.csv"), combined);
81
+ }
82
+ async function prepareBmadSwap(projectDir, bundledBmadDir) {
83
+ const dest = join(projectDir, "_bmad");
84
+ const backup = join(projectDir, "_bmad.old");
85
+ const staged = join(projectDir, "_bmad.new");
86
+ const destExists = await exists(dest);
87
+ const backupExists = await exists(backup);
88
+ let hasBackup = false;
89
+ if (destExists && backupExists) {
90
+ throw new Error("Found both _bmad and _bmad.old from a previous failed install or upgrade. " +
91
+ "Restore or remove one of them before retrying.");
92
+ }
93
+ if (backupExists) {
94
+ hasBackup = true;
95
+ debug("Found existing _bmad.old from previous failed rollback, preserving backup");
96
+ }
97
+ else if (destExists) {
98
+ try {
99
+ await rename(dest, backup);
100
+ hasBackup = true;
101
+ }
102
+ catch (err) {
103
+ if (!isEnoent(err))
104
+ throw err;
105
+ debug("_bmad disappeared before it could be preserved, continuing without backup");
106
+ }
107
+ }
108
+ else {
109
+ debug("No existing _bmad to preserve (first install)");
110
+ }
111
+ // Stage new content.
112
+ await rm(staged, { recursive: true, force: true });
113
+ await cp(bundledBmadDir, staged, { recursive: true, dereference: false });
114
+ return { dest, backup, staged, hasBackup };
115
+ }
116
+ async function finalizeBmadInstall(projectDir, slashCommandsDir, platform) {
117
+ await generateManifests(projectDir);
118
+ const classified = await classifyCommands(projectDir, slashCommandsDir);
119
+ await generateCommandIndex(projectDir, classified);
120
+ const projectName = await deriveProjectName(projectDir);
121
+ const escapedName = projectName.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
122
+ await atomicWriteFile(join(projectDir, "_bmad/config.yaml"), `# BMAD Configuration - Generated by bmalph
123
+ platform: ${platform.id}
124
+ project_name: "${escapedName}"
125
+ output_folder: _bmad-output
126
+ user_name: BMad
127
+ communication_language: English
128
+ document_output_language: English
129
+ user_skill_level: intermediate
130
+ planning_artifacts: _bmad-output/planning-artifacts
131
+ implementation_artifacts: _bmad-output/implementation-artifacts
132
+ project_knowledge: docs
133
+ modules:
134
+ - bmm
135
+ `);
136
+ return classified;
137
+ }
138
+ async function rollbackBmadFinalization(swap, error) {
139
+ debug(`BMAD finalization failed after swap: ${formatError(error)}`);
140
+ try {
141
+ await rm(swap.dest, { recursive: true, force: true });
142
+ if (swap.hasBackup) {
143
+ await rename(swap.backup, swap.dest);
144
+ }
145
+ }
146
+ catch (rollbackErr) {
147
+ throw new Error("BMAD finalization failed after swap and rollback also failed. " +
148
+ `Original error: ${formatError(error)}. ` +
149
+ `Rollback error: ${formatError(rollbackErr)}`, {
150
+ cause: rollbackErr,
151
+ });
152
+ }
153
+ if (swap.hasBackup) {
154
+ throw new Error("BMAD finalization failed after swap; previous BMAD installation was restored.", {
155
+ cause: error,
156
+ });
157
+ }
158
+ throw new Error("BMAD finalization failed after swap; incomplete BMAD installation was cleaned up.", {
159
+ cause: error,
160
+ });
161
+ }
162
+ async function commitBmadSwap(swap) {
163
+ if (!swap.hasBackup)
164
+ return;
165
+ await rm(swap.backup, { recursive: true, force: true });
166
+ }
167
+ async function deriveProjectName(projectDir) {
168
+ try {
169
+ const configPath = join(projectDir, CONFIG_FILE);
170
+ const raw = await readFile(configPath, "utf-8");
171
+ const config = JSON.parse(raw);
172
+ if (config.name)
173
+ return config.name;
174
+ }
175
+ catch (err) {
176
+ if (!isEnoent(err)) {
177
+ warn(`Could not read ${CONFIG_FILE}: ${formatError(err)}`);
178
+ }
179
+ }
180
+ return basename(projectDir);
181
+ }
182
+ //# sourceMappingURL=bmad-assets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bmad-assets.js","sourceRoot":"","sources":["../../src/installer/bmad-assets.ts"],"names":[],"mappings":"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"}