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.
- package/README.md +33 -31
- package/bmad/lite/create-prd.md +145 -0
- package/dist/cli.js +2 -2
- package/dist/cli.js.map +1 -1
- package/dist/commands/check-updates.js +1 -1
- package/dist/commands/check-updates.js.map +1 -1
- package/dist/commands/doctor-checks.js +103 -0
- package/dist/commands/doctor-checks.js.map +1 -0
- package/dist/commands/doctor-health-checks.js +101 -0
- package/dist/commands/doctor-health-checks.js.map +1 -0
- package/dist/commands/doctor-runtime-checks.js +143 -0
- package/dist/commands/doctor-runtime-checks.js.map +1 -0
- package/dist/commands/doctor.js +6 -370
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/implement.js +9 -14
- package/dist/commands/implement.js.map +1 -1
- package/dist/commands/init.js +1 -1
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/run.js +11 -2
- package/dist/commands/run.js.map +1 -1
- package/dist/commands/status.js +4 -44
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/upgrade.js +1 -1
- package/dist/commands/upgrade.js.map +1 -1
- package/dist/installer.js +321 -50
- package/dist/installer.js.map +1 -1
- package/dist/platform/aider.js +1 -1
- package/dist/platform/aider.js.map +1 -1
- package/dist/platform/claude-code.js +1 -1
- package/dist/platform/codex.js +3 -3
- package/dist/platform/codex.js.map +1 -1
- package/dist/platform/copilot.js +1 -1
- package/dist/platform/copilot.js.map +1 -1
- package/dist/platform/cursor.js +5 -4
- package/dist/platform/cursor.js.map +1 -1
- package/dist/platform/doctor-checks.js +16 -7
- package/dist/platform/doctor-checks.js.map +1 -1
- package/dist/platform/instructions-snippet.js +37 -38
- package/dist/platform/instructions-snippet.js.map +1 -1
- package/dist/platform/types.js +9 -1
- package/dist/platform/types.js.map +1 -1
- package/dist/platform/windsurf.js +1 -1
- package/dist/platform/windsurf.js.map +1 -1
- package/dist/reset.js +18 -7
- package/dist/reset.js.map +1 -1
- package/dist/run/ralph-process.js +16 -10
- package/dist/run/ralph-process.js.map +1 -1
- package/dist/transition/artifact-scan.js +3 -13
- package/dist/transition/artifact-scan.js.map +1 -1
- package/dist/transition/orchestration.js +16 -26
- package/dist/transition/orchestration.js.map +1 -1
- package/dist/transition/specs-index.js +4 -4
- package/dist/transition/specs-index.js.map +1 -1
- package/dist/transition/tech-stack.js +1 -1
- package/dist/transition/tech-stack.js.map +1 -1
- package/dist/utils/artifact-definitions.js +19 -0
- package/dist/utils/artifact-definitions.js.map +1 -0
- package/dist/utils/constants.js +4 -0
- package/dist/utils/constants.js.map +1 -1
- package/dist/utils/file-system.js +1 -1
- package/dist/utils/file-system.js.map +1 -1
- package/dist/utils/format-status.js +31 -0
- package/dist/utils/format-status.js.map +1 -0
- package/dist/utils/json.js +3 -0
- package/dist/utils/json.js.map +1 -1
- package/dist/utils/validate.js +12 -15
- package/dist/utils/validate.js.map +1 -1
- package/dist/watch/dashboard.js +22 -11
- package/dist/watch/dashboard.js.map +1 -1
- package/dist/watch/renderer.js +1 -15
- package/dist/watch/renderer.js.map +1 -1
- package/package.json +2 -2
- package/ralph/drivers/cursor.sh +90 -0
- package/ralph/ralph_loop.sh +20 -13
- package/ralph/templates/ralphrc.template +1 -1
- package/dist/platform/index.js +0 -4
- 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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"}
|
package/dist/commands/doctor.js
CHANGED
|
@@ -1,32 +1,22 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
|
-
import {
|
|
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 (
|
|
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
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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 });
|