bmalph 2.6.0 → 2.7.1

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 (77) hide show
  1. package/README.md +33 -31
  2. package/bmad/lite/create-prd.md +145 -0
  3. package/dist/cli.js +2 -2
  4. package/dist/cli.js.map +1 -1
  5. package/dist/commands/check-updates.js +1 -1
  6. package/dist/commands/check-updates.js.map +1 -1
  7. package/dist/commands/doctor-checks.js +103 -0
  8. package/dist/commands/doctor-checks.js.map +1 -0
  9. package/dist/commands/doctor-health-checks.js +101 -0
  10. package/dist/commands/doctor-health-checks.js.map +1 -0
  11. package/dist/commands/doctor-runtime-checks.js +143 -0
  12. package/dist/commands/doctor-runtime-checks.js.map +1 -0
  13. package/dist/commands/doctor.js +6 -370
  14. package/dist/commands/doctor.js.map +1 -1
  15. package/dist/commands/implement.js +9 -14
  16. package/dist/commands/implement.js.map +1 -1
  17. package/dist/commands/init.js +1 -1
  18. package/dist/commands/init.js.map +1 -1
  19. package/dist/commands/run.js +11 -2
  20. package/dist/commands/run.js.map +1 -1
  21. package/dist/commands/status.js +4 -44
  22. package/dist/commands/status.js.map +1 -1
  23. package/dist/commands/upgrade.js +1 -1
  24. package/dist/commands/upgrade.js.map +1 -1
  25. package/dist/installer.js +321 -50
  26. package/dist/installer.js.map +1 -1
  27. package/dist/platform/aider.js +1 -1
  28. package/dist/platform/aider.js.map +1 -1
  29. package/dist/platform/claude-code.js +1 -1
  30. package/dist/platform/codex.js +3 -3
  31. package/dist/platform/codex.js.map +1 -1
  32. package/dist/platform/copilot.js +1 -1
  33. package/dist/platform/copilot.js.map +1 -1
  34. package/dist/platform/cursor.js +5 -4
  35. package/dist/platform/cursor.js.map +1 -1
  36. package/dist/platform/doctor-checks.js +16 -7
  37. package/dist/platform/doctor-checks.js.map +1 -1
  38. package/dist/platform/instructions-snippet.js +37 -38
  39. package/dist/platform/instructions-snippet.js.map +1 -1
  40. package/dist/platform/types.js +9 -1
  41. package/dist/platform/types.js.map +1 -1
  42. package/dist/platform/windsurf.js +1 -1
  43. package/dist/platform/windsurf.js.map +1 -1
  44. package/dist/reset.js +18 -7
  45. package/dist/reset.js.map +1 -1
  46. package/dist/run/ralph-process.js +16 -10
  47. package/dist/run/ralph-process.js.map +1 -1
  48. package/dist/transition/artifact-scan.js +3 -13
  49. package/dist/transition/artifact-scan.js.map +1 -1
  50. package/dist/transition/orchestration.js +16 -26
  51. package/dist/transition/orchestration.js.map +1 -1
  52. package/dist/transition/specs-index.js +4 -4
  53. package/dist/transition/specs-index.js.map +1 -1
  54. package/dist/transition/tech-stack.js +1 -1
  55. package/dist/transition/tech-stack.js.map +1 -1
  56. package/dist/utils/artifact-definitions.js +19 -0
  57. package/dist/utils/artifact-definitions.js.map +1 -0
  58. package/dist/utils/constants.js +4 -0
  59. package/dist/utils/constants.js.map +1 -1
  60. package/dist/utils/file-system.js +1 -1
  61. package/dist/utils/file-system.js.map +1 -1
  62. package/dist/utils/format-status.js +31 -0
  63. package/dist/utils/format-status.js.map +1 -0
  64. package/dist/utils/json.js +3 -0
  65. package/dist/utils/json.js.map +1 -1
  66. package/dist/utils/validate.js +12 -15
  67. package/dist/utils/validate.js.map +1 -1
  68. package/dist/watch/dashboard.js +22 -11
  69. package/dist/watch/dashboard.js.map +1 -1
  70. package/dist/watch/renderer.js +1 -15
  71. package/dist/watch/renderer.js.map +1 -1
  72. package/package.json +2 -2
  73. package/ralph/drivers/cursor.sh +90 -0
  74. package/ralph/ralph_loop.sh +20 -13
  75. package/ralph/templates/ralphrc.template +1 -1
  76. package/dist/platform/index.js +0 -4
  77. package/dist/platform/index.js.map +0 -1
@@ -0,0 +1,143 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import { getBundledVersions } from "../installer.js";
4
+ 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";
8
+ export async function checkCircuitBreaker(projectDir) {
9
+ 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"}`;
23
+ return {
24
+ label,
25
+ passed: false,
26
+ detail,
27
+ hint: "Ralph detected stagnation. Review logs with: bmalph status",
28
+ };
29
+ }
30
+ catch (err) {
31
+ if (isEnoent(err)) {
32
+ return { label, passed: true, detail: "not running" };
33
+ }
34
+ return {
35
+ label,
36
+ passed: false,
37
+ detail: "corrupt state file",
38
+ hint: "Delete .ralph/.circuit_breaker_state and restart Ralph",
39
+ };
40
+ }
41
+ }
42
+ export async function checkRalphSession(projectDir) {
43
+ 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 };
76
+ }
77
+ catch (err) {
78
+ if (isEnoent(err)) {
79
+ return { label, passed: true, detail: "no active session" };
80
+ }
81
+ return {
82
+ label,
83
+ passed: false,
84
+ detail: "corrupt session file",
85
+ hint: "Delete .ralph/.ralph_session to reset",
86
+ };
87
+ }
88
+ }
89
+ export async function checkApiCalls(projectDir) {
90
+ 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}` };
111
+ }
112
+ catch (err) {
113
+ if (isEnoent(err)) {
114
+ return { label, passed: true, detail: "not running" };
115
+ }
116
+ return {
117
+ label,
118
+ passed: false,
119
+ detail: "corrupt status file",
120
+ hint: "Delete .ralph/status.json to reset",
121
+ };
122
+ }
123
+ }
124
+ export async function checkUpstreamGitHubStatus(_projectDir) {
125
+ const label = "upstream status";
126
+ try {
127
+ const bundled = await getBundledVersions();
128
+ const result = await checkUpstream(bundled);
129
+ if (result.bmad === null) {
130
+ const reason = getSkipReason(result.errors);
131
+ return { label, passed: true, detail: `skipped: ${reason}` };
132
+ }
133
+ return {
134
+ label,
135
+ passed: true,
136
+ detail: `BMAD: ${result.bmad.isUpToDate ? "up to date" : "behind"}`,
137
+ };
138
+ }
139
+ catch (err) {
140
+ return { label, passed: true, detail: `skipped: ${formatError(err)}` };
141
+ }
142
+ }
143
+ //# sourceMappingURL=doctor-runtime-checks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor-runtime-checks.js","sourceRoot":"","sources":["../../src/commands/doctor-runtime-checks.ts"],"names":[],"mappings":"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"}
@@ -1,32 +1,22 @@
1
1
  import chalk from "chalk";
2
- import { readFile, stat } from "node:fs/promises";
3
- import { join } from "node:path";
4
- import { readJsonFile } from "../utils/json.js";
5
- import { readConfig } from "../utils/config.js";
6
- import { parseGitignoreLines } from "../utils/file-system.js";
7
- import { getBundledVersions } from "../installer.js";
8
- import { checkUpstream, getSkipReason } from "../utils/github.js";
9
- import { isEnoent, formatError, withErrorHandling } from "../utils/errors.js";
10
- import { validateCircuitBreakerState, validateRalphSession, validateRalphApiStatus, } from "../utils/validate.js";
11
- import { SESSION_AGE_WARNING_MS, API_USAGE_WARNING_PERCENT, CONFIG_FILE, RALPH_STATUS_FILE, } from "../utils/constants.js";
2
+ import { withErrorHandling } from "../utils/errors.js";
12
3
  import { resolveProjectPlatform } from "../platform/resolve.js";
4
+ import { checkNodeVersion, checkBash, checkJq, checkConfig, checkBmadDir, checkRalphLoop, checkRalphLib, } from "./doctor-checks.js";
5
+ import { checkGitignore, checkVersionMarker, checkUpstreamVersions, } from "./doctor-health-checks.js";
6
+ import { checkCircuitBreaker, checkRalphSession, checkApiCalls, checkUpstreamGitHubStatus, } from "./doctor-runtime-checks.js";
13
7
  export async function doctorCommand(options) {
14
8
  await withErrorHandling(async () => {
15
9
  const { failed } = await runDoctor(options);
16
- if (!options.json && failed > 0) {
10
+ if (failed > 0) {
17
11
  process.exitCode = 1;
18
12
  }
19
13
  });
20
14
  }
21
15
  export async function runDoctor(options) {
22
16
  const projectDir = options.projectDir;
23
- // Resolve platform for this project
24
17
  const platform = await resolveProjectPlatform(projectDir);
25
- // Build the check list: core checks + platform-specific checks
26
18
  const checks = buildCheckRegistry(platform);
27
- // Run all checks
28
19
  const results = await Promise.all(checks.map((check) => check.run(projectDir)));
29
- // Output
30
20
  const passed = results.filter((r) => r.passed).length;
31
21
  const failed = results.filter((r) => !r.passed).length;
32
22
  if (options.json) {
@@ -37,11 +27,7 @@ export async function runDoctor(options) {
37
27
  ...(r.detail && { detail: r.detail }),
38
28
  ...(r.hint && { hint: r.hint }),
39
29
  })),
40
- summary: {
41
- passed,
42
- failed,
43
- total: results.length,
44
- },
30
+ summary: { passed, failed, total: results.length },
45
31
  };
46
32
  console.log(JSON.stringify(output, null, 2));
47
33
  return { passed, failed };
@@ -64,349 +50,6 @@ export async function runDoctor(options) {
64
50
  }
65
51
  return { passed, failed };
66
52
  }
67
- async function checkCommandAvailable(command) {
68
- const { execSync } = await import("node:child_process");
69
- try {
70
- const cmd = process.platform === "win32" ? `where ${command}` : `which ${command}`;
71
- execSync(cmd, { stdio: "ignore" });
72
- return true;
73
- }
74
- catch {
75
- return false;
76
- }
77
- }
78
- // =============================================================================
79
- // Core check functions - platform-independent
80
- // =============================================================================
81
- async function checkNodeVersion(_projectDir) {
82
- const major = parseInt(process.versions.node.split(".")[0]);
83
- return {
84
- label: "Node version >= 20",
85
- passed: major >= 20,
86
- detail: major >= 20 ? `v${process.versions.node}` : `got v${process.versions.node}`,
87
- hint: major >= 20 ? undefined : "Install Node.js 20+ from nodejs.org or run: nvm install 20",
88
- };
89
- }
90
- async function checkBash(_projectDir) {
91
- const available = await checkCommandAvailable("bash");
92
- return {
93
- label: "bash available",
94
- passed: available,
95
- detail: available ? undefined : "bash not found in PATH",
96
- hint: available
97
- ? undefined
98
- : process.platform === "win32"
99
- ? "Install Git Bash or WSL: https://git-scm.com/downloads"
100
- : "Install bash via your package manager (apt, brew, etc.)",
101
- };
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
- }
118
- async function checkBmadDir(projectDir) {
119
- return checkDir(join(projectDir, "_bmad"), "_bmad/ directory present", "Run: bmalph init");
120
- }
121
- async function checkRalphLoop(projectDir) {
122
- return checkFileHasContent(join(projectDir, ".ralph/ralph_loop.sh"), "ralph_loop.sh present and has content", "Run: bmalph upgrade");
123
- }
124
- async function checkRalphLib(projectDir) {
125
- return checkDir(join(projectDir, ".ralph/lib"), ".ralph/lib/ directory present", "Run: bmalph upgrade");
126
- }
127
- async function checkConfig(projectDir) {
128
- const label = "bmalph/config.json exists and valid";
129
- const hint = "Run: bmalph init";
130
- const path = join(projectDir, CONFIG_FILE);
131
- try {
132
- const data = await readJsonFile(path);
133
- if (data === null) {
134
- return { label, passed: false, detail: "file not found", hint };
135
- }
136
- return { label, passed: true };
137
- }
138
- catch (err) {
139
- const msg = err instanceof Error ? err.message : "invalid";
140
- return { label, passed: false, detail: msg, hint };
141
- }
142
- }
143
- async function checkDir(dirPath, label, hint) {
144
- try {
145
- const s = await stat(dirPath);
146
- return { label, passed: s.isDirectory() };
147
- }
148
- catch (err) {
149
- if (isEnoent(err)) {
150
- return { label, passed: false, detail: "not found", hint };
151
- }
152
- return { label, passed: false, detail: `error: ${formatError(err)}`, hint };
153
- }
154
- }
155
- async function checkFileHasContent(filePath, label, hint) {
156
- try {
157
- const content = await readFile(filePath, "utf-8");
158
- return { label, passed: content.trim().length > 0 };
159
- }
160
- catch (err) {
161
- if (isEnoent(err)) {
162
- return { label, passed: false, detail: "not found", hint };
163
- }
164
- return { label, passed: false, detail: `error: ${formatError(err)}`, hint };
165
- }
166
- }
167
- async function checkGitignore(projectDir) {
168
- const label = ".gitignore has required entries";
169
- const required = [".ralph/logs/", "_bmad-output/"];
170
- try {
171
- const content = await readFile(join(projectDir, ".gitignore"), "utf-8");
172
- const existingLines = parseGitignoreLines(content);
173
- const missing = required.filter((e) => !existingLines.has(e));
174
- if (missing.length === 0) {
175
- return { label, passed: true };
176
- }
177
- return {
178
- label,
179
- passed: false,
180
- detail: `missing: ${missing.join(", ")}`,
181
- hint: `Add to .gitignore: ${missing.join(" ")}`,
182
- };
183
- }
184
- catch (err) {
185
- if (isEnoent(err)) {
186
- return {
187
- label,
188
- passed: false,
189
- detail: ".gitignore not found",
190
- hint: "Create .gitignore with: .ralph/logs/ _bmad-output/",
191
- };
192
- }
193
- return {
194
- label,
195
- passed: false,
196
- detail: `error: ${formatError(err)}`,
197
- hint: "Check file permissions on .gitignore",
198
- };
199
- }
200
- }
201
- async function checkVersionMarker(projectDir) {
202
- const label = "version marker matches";
203
- const hint = "Run: bmalph upgrade";
204
- try {
205
- const content = await readFile(join(projectDir, ".ralph/ralph_loop.sh"), "utf-8");
206
- const match = content.match(/# bmalph-version: (.+)/);
207
- if (!match) {
208
- return { label, passed: true, detail: "no marker (pre-0.8.0 install)" };
209
- }
210
- const { getPackageVersion } = await import("../installer.js");
211
- const current = getPackageVersion();
212
- if (match[1].trim() === current) {
213
- return { label, passed: true, detail: `v${current}` };
214
- }
215
- return {
216
- label,
217
- passed: false,
218
- detail: `installed: ${match[1].trim()}, current: ${current}`,
219
- hint,
220
- };
221
- }
222
- catch (err) {
223
- if (isEnoent(err)) {
224
- return { label, passed: true, detail: "no marker found" };
225
- }
226
- return { label, passed: false, detail: `error: ${formatError(err)}`, hint };
227
- }
228
- }
229
- async function checkUpstreamVersions(projectDir) {
230
- const label = "upstream versions tracked";
231
- const hint = "Run: bmalph upgrade";
232
- try {
233
- const config = await readConfig(projectDir);
234
- if (!config) {
235
- return { label, passed: false, detail: "config not found", hint: "Run: bmalph init" };
236
- }
237
- if (!config.upstreamVersions) {
238
- return { label, passed: true, detail: "not tracked (pre-1.2.0 install)" };
239
- }
240
- const bundled = getBundledVersions();
241
- const { bmadCommit } = config.upstreamVersions;
242
- const bmadMatch = bmadCommit === bundled.bmadCommit;
243
- if (bmadMatch) {
244
- return {
245
- label,
246
- passed: true,
247
- detail: `BMAD:${bmadCommit.slice(0, 8)}`,
248
- };
249
- }
250
- return {
251
- label,
252
- passed: false,
253
- detail: `outdated: BMAD:${bmadCommit.slice(0, 8)}→${bundled.bmadCommit.slice(0, 8)}`,
254
- hint,
255
- };
256
- }
257
- catch (err) {
258
- return { label, passed: false, detail: `error: ${formatError(err)}`, hint };
259
- }
260
- }
261
- async function checkCircuitBreaker(projectDir) {
262
- const label = "circuit breaker";
263
- const statePath = join(projectDir, ".ralph/.circuit_breaker_state");
264
- try {
265
- const content = await readFile(statePath, "utf-8");
266
- const parsed = JSON.parse(content);
267
- const state = validateCircuitBreakerState(parsed);
268
- if (state.state === "CLOSED") {
269
- return {
270
- label,
271
- passed: true,
272
- detail: `CLOSED (${state.consecutive_no_progress} loops without progress)`,
273
- };
274
- }
275
- if (state.state === "HALF_OPEN") {
276
- return { label, passed: true, detail: `HALF_OPEN - monitoring` };
277
- }
278
- // OPEN state is a failure
279
- return {
280
- label,
281
- passed: false,
282
- detail: `OPEN - ${state.reason ?? "stagnation detected"}`,
283
- hint: "Ralph detected stagnation. Review logs with: bmalph status",
284
- };
285
- }
286
- catch (err) {
287
- if (isEnoent(err)) {
288
- return { label, passed: true, detail: "not running" };
289
- }
290
- return {
291
- label,
292
- passed: false,
293
- detail: "corrupt state file",
294
- hint: "Delete .ralph/.circuit_breaker_state and restart Ralph",
295
- };
296
- }
297
- }
298
- async function checkRalphSession(projectDir) {
299
- const label = "Ralph session";
300
- const sessionPath = join(projectDir, ".ralph/.ralph_session");
301
- try {
302
- const content = await readFile(sessionPath, "utf-8");
303
- const parsed = JSON.parse(content);
304
- const session = validateRalphSession(parsed);
305
- if (!session.session_id || session.session_id === "") {
306
- return { label, passed: true, detail: "no active session" };
307
- }
308
- const createdAt = new Date(session.created_at);
309
- const now = new Date();
310
- const ageMs = now.getTime() - createdAt.getTime();
311
- // Handle negative age (future timestamp) gracefully
312
- if (ageMs < 0) {
313
- return {
314
- label,
315
- passed: false,
316
- detail: "invalid timestamp (future)",
317
- hint: "Delete .ralph/.ralph_session to reset",
318
- };
319
- }
320
- const ageHours = Math.floor(ageMs / (1000 * 60 * 60));
321
- const ageMinutes = Math.floor((ageMs % (1000 * 60 * 60)) / (1000 * 60));
322
- const ageStr = ageHours > 0 ? `${ageHours}h${ageMinutes}m` : `${ageMinutes}m`;
323
- // Warn if session is older than threshold
324
- const maxAgeHours = Math.floor(SESSION_AGE_WARNING_MS / (1000 * 60 * 60));
325
- if (ageMs >= SESSION_AGE_WARNING_MS) {
326
- return {
327
- label,
328
- passed: false,
329
- detail: `${ageStr} old (max ${maxAgeHours}h)`,
330
- hint: "Session is stale. Start a fresh Ralph session",
331
- };
332
- }
333
- return { label, passed: true, detail: ageStr };
334
- }
335
- catch (err) {
336
- if (isEnoent(err)) {
337
- return { label, passed: true, detail: "no active session" };
338
- }
339
- return {
340
- label,
341
- passed: false,
342
- detail: "corrupt session file",
343
- hint: "Delete .ralph/.ralph_session to reset",
344
- };
345
- }
346
- }
347
- async function checkApiCalls(projectDir) {
348
- const label = "API calls this hour";
349
- const statusPath = join(projectDir, RALPH_STATUS_FILE);
350
- try {
351
- const content = await readFile(statusPath, "utf-8");
352
- const parsed = JSON.parse(content);
353
- const status = validateRalphApiStatus(parsed);
354
- const calls = status.calls_made_this_hour;
355
- const max = status.max_calls_per_hour;
356
- // Avoid division by zero
357
- if (max <= 0) {
358
- return { label, passed: true, detail: `${calls}/unlimited` };
359
- }
360
- const percentage = (calls / max) * 100;
361
- // Warn if approaching limit
362
- if (percentage >= API_USAGE_WARNING_PERCENT) {
363
- return {
364
- label,
365
- passed: false,
366
- detail: `${calls}/${max} (approaching limit)`,
367
- hint: "Wait for rate limit reset or increase API quota",
368
- };
369
- }
370
- return { label, passed: true, detail: `${calls}/${max}` };
371
- }
372
- catch (err) {
373
- if (isEnoent(err)) {
374
- return { label, passed: true, detail: "not running" };
375
- }
376
- return {
377
- label,
378
- passed: false,
379
- detail: "corrupt status file",
380
- hint: "Delete .ralph/status.json to reset",
381
- };
382
- }
383
- }
384
- async function checkUpstreamGitHubStatus(_projectDir) {
385
- const label = "upstream status";
386
- try {
387
- const bundled = getBundledVersions();
388
- const result = await checkUpstream(bundled);
389
- // Check if request failed
390
- if (result.bmad === null) {
391
- const reason = getSkipReason(result.errors);
392
- return { label, passed: true, detail: `skipped: ${reason}` };
393
- }
394
- return {
395
- label,
396
- passed: true,
397
- detail: `BMAD: ${result.bmad.isUpToDate ? "up to date" : "behind"}`,
398
- };
399
- }
400
- catch (err) {
401
- return { label, passed: true, detail: `skipped: ${formatError(err)}` };
402
- }
403
- }
404
- // =============================================================================
405
- // Check Registry - core checks + platform-specific checks
406
- // =============================================================================
407
- /**
408
- * Core checks that apply to every platform.
409
- */
410
53
  const CORE_CHECKS = [
411
54
  { id: "node-version", run: checkNodeVersion },
412
55
  { id: "bash-available", run: checkBash },
@@ -416,9 +59,6 @@ const CORE_CHECKS = [
416
59
  { id: "ralph-loop", run: checkRalphLoop },
417
60
  { id: "ralph-lib", run: checkRalphLib },
418
61
  ];
419
- /**
420
- * Checks that run after platform-specific checks.
421
- */
422
62
  const TRAILING_CHECKS = [
423
63
  { id: "gitignore", run: checkGitignore },
424
64
  { id: "version-marker", run: checkVersionMarker },
@@ -428,10 +68,6 @@ const TRAILING_CHECKS = [
428
68
  { id: "api-calls", run: checkApiCalls },
429
69
  { id: "upstream-github", run: checkUpstreamGitHubStatus },
430
70
  ];
431
- /**
432
- * Build the full check registry for a given platform.
433
- * Core checks + platform doctor checks + trailing checks.
434
- */
435
71
  export function buildCheckRegistry(platform) {
436
72
  const platformChecks = platform.getDoctorChecks().map((pc) => ({
437
73
  id: pc.id,
@@ -1 +1 @@
1
- {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,8 @@
1
1
  import chalk from "chalk";
2
- import { access } from "node:fs/promises";
3
2
  import { join } from "node:path";
4
3
  import { runTransition } from "../transition/orchestration.js";
5
4
  import { withErrorHandling } from "../utils/errors.js";
5
+ import { exists } from "../utils/file-system.js";
6
6
  import { resolveProjectPlatform } from "../platform/resolve.js";
7
7
  import { getFullTierPlatformNames } from "../platform/registry.js";
8
8
  export async function implementCommand(options) {
@@ -11,19 +11,14 @@ export async function implementCommand(options) {
11
11
  async function runImplement(options) {
12
12
  const { projectDir, force } = options;
13
13
  // Re-run protection: warn if implement was already run
14
- try {
15
- await access(join(projectDir, ".ralph/@fix_plan.md"));
16
- if (!force) {
17
- console.log(chalk.yellow("Warning: bmalph implement has already been run."));
18
- console.log("Re-running will overwrite PROMPT.md, PROJECT_CONTEXT.md, @AGENT.md, and SPECS_INDEX.md.");
19
- console.log("Fix plan progress will be preserved.\n");
20
- console.log(`Use ${chalk.bold("--force")} to proceed anyway.`);
21
- process.exitCode = 1;
22
- return;
23
- }
24
- }
25
- catch {
26
- // fix_plan doesn't exist — first run, proceed
14
+ const alreadyRun = await exists(join(projectDir, ".ralph/@fix_plan.md"));
15
+ if (alreadyRun && !force) {
16
+ console.log(chalk.yellow("Warning: bmalph implement has already been run."));
17
+ console.log("Re-running will overwrite PROMPT.md, PROJECT_CONTEXT.md, @AGENT.md, and SPECS_INDEX.md.");
18
+ console.log("Fix plan progress will be preserved.\n");
19
+ console.log(`Use ${chalk.bold("--force")} to proceed anyway.`);
20
+ process.exitCode = 1;
21
+ return;
27
22
  }
28
23
  const platform = await resolveProjectPlatform(projectDir);
29
24
  const result = await runTransition(projectDir, { force });