bemadralphy 0.3.1 → 0.3.3
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 +27 -0
- package/dist/beads/parse-tasks.d.ts +2 -0
- package/dist/beads/parse-tasks.js +12 -0
- package/dist/beads/parse-tasks.js.map +1 -0
- package/dist/cli.js +27 -2
- package/dist/cli.js.map +1 -1
- package/dist/docs/pr-body.d.ts +8 -0
- package/dist/docs/pr-body.js +11 -0
- package/dist/docs/pr-body.js.map +1 -0
- package/dist/engines/cli.d.ts +14 -0
- package/dist/engines/cli.js +72 -0
- package/dist/engines/cli.js.map +1 -0
- package/dist/engines/prompt-template.d.ts +2 -0
- package/dist/engines/prompt-template.js +96 -0
- package/dist/engines/prompt-template.js.map +1 -0
- package/dist/engines/stub.d.ts +2 -0
- package/dist/engines/stub.js +17 -0
- package/dist/engines/stub.js.map +1 -0
- package/dist/git/worktrees.d.ts +11 -0
- package/dist/git/worktrees.js +63 -0
- package/dist/git/worktrees.js.map +1 -0
- package/dist/orchestrator.d.ts +1 -0
- package/dist/orchestrator.js +75 -10
- package/dist/orchestrator.js.map +1 -1
- package/dist/planning/bmad.d.ts +3 -0
- package/dist/planning/bmad.js +20 -0
- package/dist/planning/bmad.js.map +1 -0
- package/dist/pr/create.d.ts +2 -0
- package/dist/pr/create.js +65 -0
- package/dist/pr/create.js.map +1 -0
- package/dist/quality/gates.d.ts +12 -0
- package/dist/quality/gates.js +54 -0
- package/dist/quality/gates.js.map +1 -0
- package/dist/release.d.ts +3 -0
- package/dist/release.js +88 -0
- package/dist/release.js.map +1 -0
- package/dist/specs/changes.d.ts +7 -0
- package/dist/specs/changes.js +20 -0
- package/dist/specs/changes.js.map +1 -0
- package/dist/specs/merge-summary.d.ts +2 -0
- package/dist/specs/merge-summary.js +19 -0
- package/dist/specs/merge-summary.js.map +1 -0
- package/dist/swarm/native.d.ts +14 -0
- package/dist/swarm/native.js +112 -0
- package/dist/swarm/native.js.map +1 -0
- package/dist/swarm/parse.d.ts +5 -0
- package/dist/swarm/parse.js +20 -0
- package/dist/swarm/parse.js.map +1 -0
- package/dist/tasks/output.d.ts +7 -0
- package/dist/tasks/output.js +15 -0
- package/dist/tasks/output.js.map +1 -0
- package/dist/utils/failures.d.ts +2 -0
- package/dist/utils/failures.js +22 -0
- package/dist/utils/failures.js.map +1 -0
- package/dist/utils/resume.d.ts +1 -0
- package/dist/utils/resume.js +14 -0
- package/dist/utils/resume.js.map +1 -0
- package/dist/utils/retry.d.ts +1 -0
- package/dist/utils/retry.js +19 -0
- package/dist/utils/retry.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -191,6 +191,10 @@ npx bemadralphy status
|
|
|
191
191
|
# Show run history (human or JSON)
|
|
192
192
|
npx bemadralphy history
|
|
193
193
|
npx bemadralphy history --output json
|
|
194
|
+
|
|
195
|
+
# Check local dependency readiness
|
|
196
|
+
npx bemadralphy doctor
|
|
197
|
+
npx bemadralphy doctor --output json
|
|
194
198
|
```
|
|
195
199
|
|
|
196
200
|
---
|
|
@@ -414,6 +418,23 @@ yarn global add bemadralphy
|
|
|
414
418
|
curl -fsSL https://raw.githubusercontent.com/hxp-pxh/BeMadRalphy/main/install.sh | bash
|
|
415
419
|
```
|
|
416
420
|
|
|
421
|
+
Verify the install:
|
|
422
|
+
|
|
423
|
+
```bash
|
|
424
|
+
bemadralphy --version
|
|
425
|
+
bemadralphy --help
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
If your shell cannot find `bemadralphy` right after global install:
|
|
429
|
+
|
|
430
|
+
```bash
|
|
431
|
+
# still works without global PATH wiring
|
|
432
|
+
npx bemadralphy --help
|
|
433
|
+
|
|
434
|
+
# if you use a custom npm prefix, add its bin dir to PATH
|
|
435
|
+
export PATH="$(npm config get prefix)/bin:$PATH"
|
|
436
|
+
```
|
|
437
|
+
|
|
417
438
|
### Docker
|
|
418
439
|
|
|
419
440
|
```bash
|
|
@@ -479,6 +500,12 @@ node dist/cli.js --help
|
|
|
479
500
|
- Execute fails for unknown/unavailable engines.
|
|
480
501
|
- Verify/Post fail if OpenSpec commands fail.
|
|
481
502
|
|
|
503
|
+
`init` is now soft for onboarding:
|
|
504
|
+
|
|
505
|
+
- Always scaffolds `.bemadralphy/`, `openspec/`, `_bmad-output/`, and starter `idea.md`.
|
|
506
|
+
- If `bd`, `bmad`, or `openspec` are missing, it completes with warnings and reports missing CLIs.
|
|
507
|
+
- Use `bemadralphy doctor` to check readiness before full pipeline runs.
|
|
508
|
+
|
|
482
509
|
Typical recovery flow:
|
|
483
510
|
|
|
484
511
|
```bash
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export function parseTasksMarkdown(contents) {
|
|
2
|
+
const lines = contents.split(/\r?\n/).filter((line) => line.startsWith('|'));
|
|
3
|
+
const rows = lines
|
|
4
|
+
.map((line) => line.split('|').map((part) => part.trim()))
|
|
5
|
+
.filter((parts) => parts.length >= 4 && parts[1] !== 'ID' && parts[1] !== '---');
|
|
6
|
+
return rows.map((parts) => ({
|
|
7
|
+
id: parts[1],
|
|
8
|
+
title: parts[2],
|
|
9
|
+
status: parts[3],
|
|
10
|
+
}));
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=parse-tasks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-tasks.js","sourceRoot":"","sources":["../../src/beads/parse-tasks.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,kBAAkB,CAAC,QAAgB;IACjD,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7E,MAAM,IAAI,GAAG,KAAK;SACf,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;SACzD,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC;IACnF,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAC1B,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC;QACZ,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;QACf,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;KACjB,CAAC,CAAC,CAAC;AACN,CAAC"}
|
package/dist/cli.js
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { Command } from 'commander';
|
|
3
|
-
import {
|
|
3
|
+
import { readFileSync } from 'node:fs';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
import { runDoctor, runExplore, runHistory, runInit, runPipeline, runReplay, runStatus, } from './orchestrator.js';
|
|
4
7
|
const program = new Command();
|
|
5
8
|
program
|
|
6
9
|
.name('bemadralphy')
|
|
7
10
|
.description('CLI orchestrator for end-to-end automated coding pipelines')
|
|
8
|
-
.version(
|
|
11
|
+
.version(resolveCliVersion());
|
|
9
12
|
program
|
|
10
13
|
.command('init')
|
|
11
14
|
.description('Initialize BMAD, Beads, and BeMadRalphy config')
|
|
@@ -54,6 +57,13 @@ program
|
|
|
54
57
|
.action(async (options) => {
|
|
55
58
|
await runHistory(options.output);
|
|
56
59
|
});
|
|
60
|
+
program
|
|
61
|
+
.command('doctor')
|
|
62
|
+
.description('Check local environment dependencies and readiness')
|
|
63
|
+
.option('--output <format>', 'Output format: text|json', 'text')
|
|
64
|
+
.action(async (options) => {
|
|
65
|
+
await runDoctor(options.output);
|
|
66
|
+
});
|
|
57
67
|
program
|
|
58
68
|
.command('replay <runId>')
|
|
59
69
|
.description('Replay a previous run from history')
|
|
@@ -92,4 +102,19 @@ function maybeOption(command, key, value) {
|
|
|
92
102
|
}
|
|
93
103
|
return undefined;
|
|
94
104
|
}
|
|
105
|
+
function resolveCliVersion() {
|
|
106
|
+
try {
|
|
107
|
+
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
108
|
+
const packageJsonPath = path.join(here, '..', 'package.json');
|
|
109
|
+
const raw = readFileSync(packageJsonPath, 'utf-8');
|
|
110
|
+
const parsed = JSON.parse(raw);
|
|
111
|
+
if (typeof parsed.version === 'string' && parsed.version.trim().length > 0) {
|
|
112
|
+
return parsed.version;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
// fall through to default
|
|
117
|
+
}
|
|
118
|
+
return '0.0.0';
|
|
119
|
+
}
|
|
95
120
|
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export function generatePrBody(input) {
|
|
2
|
+
const lines = [];
|
|
3
|
+
lines.push('## Summary', '', input.summary, '');
|
|
4
|
+
lines.push('## Changes', '', ...input.changes.map((c) => `- ${c}`), '');
|
|
5
|
+
lines.push('## Tests', '', ...input.tests.map((t) => `- ${t}`), '');
|
|
6
|
+
if (input.linkedIssues && input.linkedIssues.length > 0) {
|
|
7
|
+
lines.push('## Linked Issues', '', ...input.linkedIssues.map((i) => `- ${i}`), '');
|
|
8
|
+
}
|
|
9
|
+
return lines.join('\n');
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=pr-body.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pr-body.js","sourceRoot":"","sources":["../../src/docs/pr-body.ts"],"names":[],"mappings":"AAQA,MAAM,UAAU,cAAc,CAAC,KAAkB;IAC/C,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,EAAE,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAChD,KAAK,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;IACxE,KAAK,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;IAEpE,IAAI,KAAK,CAAC,YAAY,IAAI,KAAK,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxD,KAAK,CAAC,IAAI,CAAC,kBAAkB,EAAE,EAAE,EAAE,GAAG,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;IACrF,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { EngineAdapter } from './types.js';
|
|
2
|
+
type CliAdapterConfig = {
|
|
3
|
+
name: string;
|
|
4
|
+
hasNativeSwarm: boolean;
|
|
5
|
+
permissionFlags?: string[];
|
|
6
|
+
defaultCommand: string;
|
|
7
|
+
envCommand: string;
|
|
8
|
+
envArgs: string;
|
|
9
|
+
};
|
|
10
|
+
export declare function createCliAdapter(config: CliAdapterConfig): EngineAdapter;
|
|
11
|
+
export declare function resolveCommand(config: CliAdapterConfig): string;
|
|
12
|
+
export declare function resolveArgs(config: CliAdapterConfig, prompt: string, promptFile: string, taskId: string): string[];
|
|
13
|
+
export declare function parseArgsEnv(raw?: string): string[] | null;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { mkdir, writeFile } from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { commandExists, runCommand } from '../utils/exec.js';
|
|
4
|
+
import { logInfo } from '../utils/logging.js';
|
|
5
|
+
import { renderTaskPrompt } from './prompt-template.js';
|
|
6
|
+
export function createCliAdapter(config) {
|
|
7
|
+
return {
|
|
8
|
+
name: config.name,
|
|
9
|
+
hasNativeSwarm: config.hasNativeSwarm,
|
|
10
|
+
permissionFlags: config.permissionFlags ?? [],
|
|
11
|
+
async checkAvailable() {
|
|
12
|
+
const command = resolveCommand(config);
|
|
13
|
+
return commandExists(command);
|
|
14
|
+
},
|
|
15
|
+
async execute(task, options) {
|
|
16
|
+
const command = resolveCommand(config);
|
|
17
|
+
const cwd = options.cwd ?? process.cwd();
|
|
18
|
+
const prompt = await renderTaskPrompt(cwd, task);
|
|
19
|
+
const promptFile = await writePromptFile(cwd, task.id, prompt);
|
|
20
|
+
const args = resolveArgs(config, prompt, promptFile, task.id);
|
|
21
|
+
try {
|
|
22
|
+
const { stdout, stderr } = await runCommand(command, args, cwd);
|
|
23
|
+
const output = stdout.trim() ? stdout : stderr;
|
|
24
|
+
return { status: 'success', output };
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
28
|
+
logInfo(`engine "${config.name}" failed: ${message}`);
|
|
29
|
+
return { status: 'failed', error: message };
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
export function resolveCommand(config) {
|
|
35
|
+
return process.env[config.envCommand] ?? config.defaultCommand;
|
|
36
|
+
}
|
|
37
|
+
export function resolveArgs(config, prompt, promptFile, taskId) {
|
|
38
|
+
const raw = process.env[config.envArgs];
|
|
39
|
+
const args = parseArgsEnv(raw) ?? ['--prompt-file', '{promptFile}'];
|
|
40
|
+
return args.map((arg) => arg
|
|
41
|
+
.replaceAll('{prompt}', prompt)
|
|
42
|
+
.replaceAll('{promptFile}', promptFile)
|
|
43
|
+
.replaceAll('{taskId}', taskId));
|
|
44
|
+
}
|
|
45
|
+
export function parseArgsEnv(raw) {
|
|
46
|
+
if (!raw || !raw.trim()) {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
const trimmed = raw.trim();
|
|
50
|
+
if (trimmed.startsWith('[')) {
|
|
51
|
+
try {
|
|
52
|
+
const parsed = JSON.parse(trimmed);
|
|
53
|
+
if (Array.isArray(parsed)) {
|
|
54
|
+
return parsed.map((item) => String(item));
|
|
55
|
+
}
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return trimmed.split(/\s+/).filter(Boolean);
|
|
63
|
+
}
|
|
64
|
+
async function writePromptFile(projectRoot, taskId, prompt) {
|
|
65
|
+
const dir = path.join(projectRoot, '.bemadralphy', 'prompts');
|
|
66
|
+
await mkdir(dir, { recursive: true });
|
|
67
|
+
const safeId = taskId.replace(/[^a-zA-Z0-9._-]+/g, '_');
|
|
68
|
+
const promptPath = path.join(dir, `${safeId}.md`);
|
|
69
|
+
await writeFile(promptPath, `${prompt}\n`, 'utf-8');
|
|
70
|
+
return promptPath;
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/engines/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { access, readFile } from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { parse } from 'yaml';
|
|
4
|
+
const DEFAULT_TEMPLATE = [
|
|
5
|
+
'# Task',
|
|
6
|
+
'ID: {{task.id}}',
|
|
7
|
+
'Title: {{task.title}}',
|
|
8
|
+
'Description: {{task.description}}',
|
|
9
|
+
'',
|
|
10
|
+
'# Project',
|
|
11
|
+
'Root: {{project.root}}',
|
|
12
|
+
'Idea: {{project.idea}}',
|
|
13
|
+
'Decisions:',
|
|
14
|
+
'{{project.decisions}}',
|
|
15
|
+
'',
|
|
16
|
+
'# Instructions',
|
|
17
|
+
'- Work in this repository.',
|
|
18
|
+
'- Update tests if needed.',
|
|
19
|
+
'- Summarize changes and list any risks.',
|
|
20
|
+
'',
|
|
21
|
+
].join('\n');
|
|
22
|
+
export async function renderTaskPrompt(projectRoot, task) {
|
|
23
|
+
const template = await loadTemplate(projectRoot);
|
|
24
|
+
const intake = await loadIntake(projectRoot);
|
|
25
|
+
const decisions = formatDecisions(intake?.decisions ?? {});
|
|
26
|
+
const values = new Map([
|
|
27
|
+
['{{task.id}}', task.id],
|
|
28
|
+
['{{task.title}}', task.title],
|
|
29
|
+
['{{task.description}}', task.description ?? 'n/a'],
|
|
30
|
+
['{{project.root}}', projectRoot],
|
|
31
|
+
['{{project.idea}}', intake?.idea?.trim() || 'n/a'],
|
|
32
|
+
['{{project.decisions}}', decisions],
|
|
33
|
+
]);
|
|
34
|
+
let rendered = template;
|
|
35
|
+
for (const [key, value] of values) {
|
|
36
|
+
rendered = rendered.replaceAll(key, value);
|
|
37
|
+
}
|
|
38
|
+
return rendered;
|
|
39
|
+
}
|
|
40
|
+
async function loadTemplate(projectRoot) {
|
|
41
|
+
const overridePath = process.env.BEMADRALPHY_PROMPT_TEMPLATE;
|
|
42
|
+
const candidates = [
|
|
43
|
+
overridePath,
|
|
44
|
+
path.join(projectRoot, '.bemadralphy', 'prompts', 'task.md'),
|
|
45
|
+
path.join(projectRoot, '.bemadralphy', 'prompt.md'),
|
|
46
|
+
].filter(Boolean);
|
|
47
|
+
for (const candidate of candidates) {
|
|
48
|
+
if (await exists(candidate)) {
|
|
49
|
+
return readFile(candidate, 'utf-8');
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return DEFAULT_TEMPLATE;
|
|
53
|
+
}
|
|
54
|
+
async function loadIntake(projectRoot) {
|
|
55
|
+
try {
|
|
56
|
+
const intakePath = path.join(projectRoot, '.bemadralphy', 'intake.yaml');
|
|
57
|
+
const contents = await readFile(intakePath, 'utf-8');
|
|
58
|
+
const parsed = (parse(contents) ?? {});
|
|
59
|
+
return {
|
|
60
|
+
decisions: (parsed.decisions ?? {}),
|
|
61
|
+
idea: typeof parsed.idea === 'string' ? parsed.idea : undefined,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
function formatDecisions(decisions) {
|
|
69
|
+
const keys = Object.keys(decisions);
|
|
70
|
+
if (keys.length === 0) {
|
|
71
|
+
return '- None';
|
|
72
|
+
}
|
|
73
|
+
return keys
|
|
74
|
+
.sort()
|
|
75
|
+
.map((key) => `- ${key}: ${formatDecisionValue(decisions[key])}`)
|
|
76
|
+
.join('\n');
|
|
77
|
+
}
|
|
78
|
+
function formatDecisionValue(value) {
|
|
79
|
+
if (value === null || value === undefined) {
|
|
80
|
+
return 'n/a';
|
|
81
|
+
}
|
|
82
|
+
if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
|
|
83
|
+
return String(value);
|
|
84
|
+
}
|
|
85
|
+
return JSON.stringify(value);
|
|
86
|
+
}
|
|
87
|
+
async function exists(targetPath) {
|
|
88
|
+
try {
|
|
89
|
+
await access(targetPath);
|
|
90
|
+
return true;
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=prompt-template.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-template.js","sourceRoot":"","sources":["../../src/engines/prompt-template.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { commandExists } from '../utils/exec.js';
|
|
2
|
+
import { logInfo } from '../utils/logging.js';
|
|
3
|
+
export function createStubAdapter(name, hasNativeSwarm, permissionFlags = [], commandName = name) {
|
|
4
|
+
return {
|
|
5
|
+
name,
|
|
6
|
+
hasNativeSwarm,
|
|
7
|
+
permissionFlags,
|
|
8
|
+
async checkAvailable() {
|
|
9
|
+
return commandExists(commandName);
|
|
10
|
+
},
|
|
11
|
+
async execute(task, options) {
|
|
12
|
+
logInfo(`engine "${name}" not implemented (task=${task.id}, dryRun=${Boolean(options.dryRun)})`);
|
|
13
|
+
return { status: 'skipped', output: 'engine not implemented' };
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=stub.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stub.js","sourceRoot":"","sources":["../../src/engines/stub.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAG9C,MAAM,UAAU,iBAAiB,CAC/B,IAAY,EACZ,cAAuB,EACvB,kBAA4B,EAAE,EAC9B,cAAsB,IAAI;IAE1B,OAAO;QACL,IAAI;QACJ,cAAc;QACd,eAAe;QACf,KAAK,CAAC,cAAc;YAClB,OAAO,aAAa,CAAC,WAAW,CAAC,CAAC;QACpC,CAAC;QACD,KAAK,CAAC,OAAO,CAAC,IAAgB,EAAE,OAAuB;YACrD,OAAO,CACL,WAAW,IAAI,2BAA2B,IAAI,CAAC,EAAE,YAAY,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CACxF,CAAC;YACF,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,wBAAwB,EAAE,CAAC;QACjE,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type Worktree = {
|
|
2
|
+
path: string;
|
|
3
|
+
branch: string;
|
|
4
|
+
};
|
|
5
|
+
export declare function isWorktreeModeEnabled(): Promise<boolean>;
|
|
6
|
+
export declare function isCleanWorkingTree(projectRoot: string): Promise<boolean>;
|
|
7
|
+
export declare function isCleanStatus(status: string): boolean;
|
|
8
|
+
export declare function createWorktree(projectRoot: string, taskId: string): Promise<Worktree>;
|
|
9
|
+
export declare function removeWorktree(projectRoot: string, worktree: Worktree): Promise<void>;
|
|
10
|
+
export declare function commitAndMerge(projectRoot: string, worktree: Worktree, message: string): Promise<void>;
|
|
11
|
+
export declare function abortMerge(projectRoot: string): Promise<void>;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { mkdir, rm } from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { runCommand } from '../utils/exec.js';
|
|
4
|
+
import { logInfo } from '../utils/logging.js';
|
|
5
|
+
export async function isWorktreeModeEnabled() {
|
|
6
|
+
return process.env.BEMADRALPHY_WORKTREES === '1';
|
|
7
|
+
}
|
|
8
|
+
export async function isCleanWorkingTree(projectRoot) {
|
|
9
|
+
const { stdout } = await runCommand('git', ['status', '--porcelain'], projectRoot);
|
|
10
|
+
return isCleanStatus(stdout);
|
|
11
|
+
}
|
|
12
|
+
export function isCleanStatus(status) {
|
|
13
|
+
return status.trim().length === 0;
|
|
14
|
+
}
|
|
15
|
+
export async function createWorktree(projectRoot, taskId) {
|
|
16
|
+
const worktreesDir = path.join(projectRoot, '.bemadralphy', 'worktrees');
|
|
17
|
+
await mkdir(worktreesDir, { recursive: true });
|
|
18
|
+
const slug = slugify(taskId);
|
|
19
|
+
const worktreePath = path.join(worktreesDir, slug);
|
|
20
|
+
const branch = `bemadralphy/${slug}`;
|
|
21
|
+
await runCommand('git', ['worktree', 'add', '-b', branch, worktreePath], projectRoot);
|
|
22
|
+
logInfo(`worktree: created ${worktreePath} (${branch})`);
|
|
23
|
+
return { path: worktreePath, branch };
|
|
24
|
+
}
|
|
25
|
+
export async function removeWorktree(projectRoot, worktree) {
|
|
26
|
+
await runCommand('git', ['worktree', 'remove', '--force', worktree.path], projectRoot);
|
|
27
|
+
await rm(worktree.path, { recursive: true, force: true });
|
|
28
|
+
logInfo(`worktree: removed ${worktree.path}`);
|
|
29
|
+
}
|
|
30
|
+
export async function commitAndMerge(projectRoot, worktree, message) {
|
|
31
|
+
const { stdout } = await runCommand('git', ['status', '--porcelain'], worktree.path);
|
|
32
|
+
if (stdout.trim().length === 0) {
|
|
33
|
+
logInfo(`worktree: no changes for ${worktree.branch}`);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
await runCommand('git', ['add', '-A'], worktree.path);
|
|
37
|
+
await runCommand('git', ['commit', '-m', message], worktree.path);
|
|
38
|
+
try {
|
|
39
|
+
await runCommand('git', ['merge', '--no-ff', worktree.branch], projectRoot);
|
|
40
|
+
logInfo(`worktree: merged ${worktree.branch}`);
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
logInfo(`worktree: merge failed for ${worktree.branch}`);
|
|
44
|
+
throw error;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
export async function abortMerge(projectRoot) {
|
|
48
|
+
try {
|
|
49
|
+
await runCommand('git', ['merge', '--abort'], projectRoot);
|
|
50
|
+
logInfo('worktree: merge aborted');
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
logInfo('worktree: merge abort failed');
|
|
54
|
+
throw error;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function slugify(input) {
|
|
58
|
+
return input
|
|
59
|
+
.toLowerCase()
|
|
60
|
+
.replace(/[^a-z0-9-]+/g, '-')
|
|
61
|
+
.replace(/^-+|-+$/g, '');
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=worktrees.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worktrees.js","sourceRoot":"","sources":["../../src/git/worktrees.ts"],"names":[],"mappings":"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"}
|
package/dist/orchestrator.d.ts
CHANGED
|
@@ -25,4 +25,5 @@ export declare function runExplore(query: string): Promise<void>;
|
|
|
25
25
|
export declare function runStatus(output?: OutputFormat): Promise<void>;
|
|
26
26
|
export declare function runHistory(output?: OutputFormat): Promise<void>;
|
|
27
27
|
export declare function runReplay(runId: string, options?: Partial<RunOptions>): Promise<void>;
|
|
28
|
+
export declare function runDoctor(output?: OutputFormat): Promise<void>;
|
|
28
29
|
export {};
|
package/dist/orchestrator.js
CHANGED
|
@@ -8,7 +8,7 @@ import { loadPlugins, runPhaseHooks } from './plugins/index.js';
|
|
|
8
8
|
import { executePhase, explorePhase, intakePhase, planningPhase, postPhase, scaffoldPhase, steeringPhase, syncPhase, verifyPhase, } from './phases/index.js';
|
|
9
9
|
import { loadState, saveState } from './state.js';
|
|
10
10
|
import { generateSpecs } from './specs/index.js';
|
|
11
|
-
import {
|
|
11
|
+
import { commandExists, runCommand } from './utils/exec.js';
|
|
12
12
|
import { configureLogger, logError, logInfo, logProgress, logSummary, } from './utils/logging.js';
|
|
13
13
|
const PHASES = [
|
|
14
14
|
{ name: 'intake', run: intakePhase },
|
|
@@ -46,13 +46,40 @@ export async function runInit(projectRoot = process.cwd()) {
|
|
|
46
46
|
].join('\n'), 'utf-8');
|
|
47
47
|
logInfo('init: created starter idea.md');
|
|
48
48
|
}
|
|
49
|
-
await
|
|
50
|
-
await
|
|
51
|
-
await
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
49
|
+
const hasBd = await commandExists('bd');
|
|
50
|
+
const hasBmad = await commandExists('bmad');
|
|
51
|
+
const hasOpenSpec = await commandExists('openspec');
|
|
52
|
+
if (hasBd) {
|
|
53
|
+
await runCommand('bd', ['init'], projectRoot);
|
|
54
|
+
logInfo('init: Beads initialized');
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
logInfo('init: bd not found; skipped Beads init. Install from https://github.com/steveyegge/beads.');
|
|
58
|
+
}
|
|
59
|
+
if (hasOpenSpec) {
|
|
60
|
+
await generateSpecs(projectRoot);
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
logInfo('init: openspec not found; skipped OpenSpec init. Install with: npm install -g @fission-ai/openspec');
|
|
64
|
+
}
|
|
65
|
+
if (!hasBmad) {
|
|
66
|
+
logInfo('init: bmad not found; planning phase will fail until installed (npm install -g bmad-method).');
|
|
67
|
+
}
|
|
68
|
+
const missingRequired = ['bd', 'bmad', 'openspec'].filter((cli) => {
|
|
69
|
+
if (cli === 'bd') {
|
|
70
|
+
return !hasBd;
|
|
71
|
+
}
|
|
72
|
+
if (cli === 'bmad') {
|
|
73
|
+
return !hasBmad;
|
|
74
|
+
}
|
|
75
|
+
return !hasOpenSpec;
|
|
76
|
+
});
|
|
77
|
+
if (missingRequired.length > 0) {
|
|
78
|
+
logInfo(`init: partial setup complete. Missing CLIs: ${missingRequired.join(', ')}`);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
logInfo('init: completed scaffold of .bemadralphy, openspec/, and _bmad-output/');
|
|
82
|
+
}
|
|
56
83
|
}
|
|
57
84
|
export async function runPipeline(options) {
|
|
58
85
|
const normalized = await resolveRunOptions(options);
|
|
@@ -220,7 +247,7 @@ export async function runStatus(output = 'text') {
|
|
|
220
247
|
const projectRoot = process.cwd();
|
|
221
248
|
const state = await loadState(projectRoot);
|
|
222
249
|
if (!state) {
|
|
223
|
-
logInfo('status: no state found (.bemadralphy/state.yaml missing)');
|
|
250
|
+
logInfo('status: no state found (.bemadralphy/state.yaml missing). Run "bemadralphy init" to get started.');
|
|
224
251
|
return;
|
|
225
252
|
}
|
|
226
253
|
if (output === 'json') {
|
|
@@ -237,7 +264,7 @@ export async function runHistory(output = 'text') {
|
|
|
237
264
|
return;
|
|
238
265
|
}
|
|
239
266
|
if (records.length === 0) {
|
|
240
|
-
logInfo('history: no runs found');
|
|
267
|
+
logInfo('history: no runs found. Run "bemadralphy init" then "bemadralphy run" to create your first run.');
|
|
241
268
|
return;
|
|
242
269
|
}
|
|
243
270
|
for (const row of records) {
|
|
@@ -262,6 +289,37 @@ export async function runReplay(runId, options = {}) {
|
|
|
262
289
|
};
|
|
263
290
|
await runPipeline(replayOptions);
|
|
264
291
|
}
|
|
292
|
+
export async function runDoctor(output = 'text') {
|
|
293
|
+
configureLogger({ outputFormat: output });
|
|
294
|
+
const checks = await Promise.all([
|
|
295
|
+
checkDependency('node', true, `found ${process.version}`),
|
|
296
|
+
checkDependency('npm', true, 'required for npm-based install/update flows'),
|
|
297
|
+
checkDependency('bd', true, 'Install from https://github.com/steveyegge/beads.'),
|
|
298
|
+
checkDependency('bmad', true, 'Install with: npm install -g bmad-method'),
|
|
299
|
+
checkDependency('openspec', true, 'Install with: npm install -g @fission-ai/openspec'),
|
|
300
|
+
checkDependency('ralphy', false, 'Install with: npm install -g ralphy-cli'),
|
|
301
|
+
checkDependency('gh', false, 'Install GitHub CLI from https://cli.github.com/'),
|
|
302
|
+
checkDependency('ollama', false, 'Install from https://ollama.com/download for local models.'),
|
|
303
|
+
]);
|
|
304
|
+
const missingRequired = checks.filter((entry) => entry.required && !entry.installed);
|
|
305
|
+
if (output === 'json') {
|
|
306
|
+
logSummary({
|
|
307
|
+
status: missingRequired.length === 0 ? 'ok' : 'degraded',
|
|
308
|
+
checks,
|
|
309
|
+
missingRequired: missingRequired.map((entry) => entry.name),
|
|
310
|
+
});
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
for (const check of checks) {
|
|
314
|
+
const state = check.installed ? 'ok' : check.required ? 'missing' : 'optional-missing';
|
|
315
|
+
logInfo(`doctor: ${check.name}=${state}${check.hint ? ` (${check.hint})` : ''}`);
|
|
316
|
+
}
|
|
317
|
+
if (missingRequired.length > 0) {
|
|
318
|
+
logInfo(`doctor: missing required CLIs (${missingRequired.map((entry) => entry.name).join(', ')}). Install them before running full pipeline.`);
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
logInfo('doctor: environment looks good for full pipeline runs.');
|
|
322
|
+
}
|
|
265
323
|
function stateFrom(ctx, phase, status, lastError) {
|
|
266
324
|
const phaseIndex = PHASES.findIndex((entry) => entry.name === phase);
|
|
267
325
|
const nextPhase = phaseIndex >= 0 ? PHASES[phaseIndex + 1]?.name : undefined;
|
|
@@ -374,4 +432,11 @@ async function appendFailure(projectRoot, runId, phase, message) {
|
|
|
374
432
|
await mkdir(path.dirname(failuresPath), { recursive: true });
|
|
375
433
|
await writeFile(failuresPath, `${new Date().toISOString()} runId=${runId} phase=${phase} error=${message}\n`, { encoding: 'utf-8', flag: 'a' });
|
|
376
434
|
}
|
|
435
|
+
async function checkDependency(name, required, hint) {
|
|
436
|
+
if (name === 'node') {
|
|
437
|
+
return { name, required, installed: true, hint };
|
|
438
|
+
}
|
|
439
|
+
const installed = await commandExists(name);
|
|
440
|
+
return { name, required, installed, hint: installed ? undefined : hint };
|
|
441
|
+
}
|
|
377
442
|
//# sourceMappingURL=orchestrator.js.map
|