bemadralphy 0.1.0 → 0.3.0

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 (100) hide show
  1. package/README.md +75 -2
  2. package/dist/cli.js +62 -10
  3. package/dist/cli.js.map +1 -1
  4. package/dist/config.d.ts +16 -0
  5. package/dist/config.js +44 -0
  6. package/dist/config.js.map +1 -0
  7. package/dist/cost.d.ts +8 -0
  8. package/dist/cost.js +46 -2
  9. package/dist/cost.js.map +1 -1
  10. package/dist/engines/index.js +2 -0
  11. package/dist/engines/index.js.map +1 -1
  12. package/dist/engines/ollama.d.ts +1 -0
  13. package/dist/engines/ollama.js +13 -0
  14. package/dist/engines/ollama.js.map +1 -0
  15. package/dist/history.d.ts +16 -0
  16. package/dist/history.js +35 -0
  17. package/dist/history.js.map +1 -0
  18. package/dist/index.d.ts +1 -1
  19. package/dist/index.js +1 -1
  20. package/dist/index.js.map +1 -1
  21. package/dist/orchestrator.d.ts +18 -7
  22. package/dist/orchestrator.js +310 -33
  23. package/dist/orchestrator.js.map +1 -1
  24. package/dist/phases/execute.js +31 -10
  25. package/dist/phases/execute.js.map +1 -1
  26. package/dist/phases/index.d.ts +1 -1
  27. package/dist/phases/index.js.map +1 -1
  28. package/dist/phases/intake.js +63 -3
  29. package/dist/phases/intake.js.map +1 -1
  30. package/dist/phases/types.d.ts +8 -0
  31. package/dist/plugins/index.d.ts +10 -0
  32. package/dist/plugins/index.js +59 -0
  33. package/dist/plugins/index.js.map +1 -0
  34. package/dist/plugins/types.d.ts +13 -0
  35. package/dist/plugins/types.js +2 -0
  36. package/dist/plugins/types.js.map +1 -0
  37. package/dist/state.d.ts +10 -0
  38. package/dist/state.js.map +1 -1
  39. package/dist/swarm/detector.d.ts +5 -1
  40. package/dist/swarm/detector.js +29 -4
  41. package/dist/swarm/detector.js.map +1 -1
  42. package/dist/swarm/types.d.ts +7 -0
  43. package/dist/utils/logging.d.ts +11 -1
  44. package/dist/utils/logging.js +56 -3
  45. package/dist/utils/logging.js.map +1 -1
  46. package/package.json +1 -1
  47. package/dist/beads/parse-tasks.d.ts +0 -2
  48. package/dist/beads/parse-tasks.js +0 -12
  49. package/dist/beads/parse-tasks.js.map +0 -1
  50. package/dist/docs/pr-body.d.ts +0 -8
  51. package/dist/docs/pr-body.js +0 -11
  52. package/dist/docs/pr-body.js.map +0 -1
  53. package/dist/engines/cli.d.ts +0 -14
  54. package/dist/engines/cli.js +0 -72
  55. package/dist/engines/cli.js.map +0 -1
  56. package/dist/engines/prompt-template.d.ts +0 -2
  57. package/dist/engines/prompt-template.js +0 -96
  58. package/dist/engines/prompt-template.js.map +0 -1
  59. package/dist/engines/stub.d.ts +0 -2
  60. package/dist/engines/stub.js +0 -17
  61. package/dist/engines/stub.js.map +0 -1
  62. package/dist/git/worktrees.d.ts +0 -11
  63. package/dist/git/worktrees.js +0 -63
  64. package/dist/git/worktrees.js.map +0 -1
  65. package/dist/planning/bmad.d.ts +0 -3
  66. package/dist/planning/bmad.js +0 -20
  67. package/dist/planning/bmad.js.map +0 -1
  68. package/dist/pr/create.d.ts +0 -2
  69. package/dist/pr/create.js +0 -65
  70. package/dist/pr/create.js.map +0 -1
  71. package/dist/quality/gates.d.ts +0 -12
  72. package/dist/quality/gates.js +0 -54
  73. package/dist/quality/gates.js.map +0 -1
  74. package/dist/release.d.ts +0 -3
  75. package/dist/release.js +0 -88
  76. package/dist/release.js.map +0 -1
  77. package/dist/specs/changes.d.ts +0 -7
  78. package/dist/specs/changes.js +0 -20
  79. package/dist/specs/changes.js.map +0 -1
  80. package/dist/specs/merge-summary.d.ts +0 -2
  81. package/dist/specs/merge-summary.js +0 -19
  82. package/dist/specs/merge-summary.js.map +0 -1
  83. package/dist/swarm/native.d.ts +0 -14
  84. package/dist/swarm/native.js +0 -112
  85. package/dist/swarm/native.js.map +0 -1
  86. package/dist/swarm/parse.d.ts +0 -5
  87. package/dist/swarm/parse.js +0 -20
  88. package/dist/swarm/parse.js.map +0 -1
  89. package/dist/tasks/output.d.ts +0 -7
  90. package/dist/tasks/output.js +0 -15
  91. package/dist/tasks/output.js.map +0 -1
  92. package/dist/utils/failures.d.ts +0 -2
  93. package/dist/utils/failures.js +0 -22
  94. package/dist/utils/failures.js.map +0 -1
  95. package/dist/utils/resume.d.ts +0 -1
  96. package/dist/utils/resume.js +0 -14
  97. package/dist/utils/resume.js.map +0 -1
  98. package/dist/utils/retry.d.ts +0 -1
  99. package/dist/utils/retry.js +0 -19
  100. package/dist/utils/retry.js.map +0 -1
package/README.md CHANGED
@@ -2,8 +2,12 @@
2
2
 
3
3
  **Be**(ads) + (B)**Mad** + **Ralphy** + [OpenSpec](https://github.com/Fission-AI/OpenSpec) — four tools, one pipeline, zero gaps. **CLI-only.**
4
4
 
5
+ BeMadRalphy is a product-delivery operating system for AI-assisted teams: methodology first, code generation second.
6
+
5
7
  > End-to-end automated coding: idea in → planning → task graph → swarm-aware execution → living specs → deployment.
6
8
 
9
+ [![npm version](https://img.shields.io/npm/v/bemadralphy.svg)](https://www.npmjs.com/package/bemadralphy)
10
+ [![npm downloads](https://img.shields.io/npm/dm/bemadralphy.svg)](https://www.npmjs.com/package/bemadralphy)
7
11
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
8
12
 
9
13
  ## Status
@@ -41,6 +45,14 @@ BeMadRalphy is a CLI orchestrator that merges:
41
45
 
42
46
  Into a single, seamless pipeline that takes you from a rough idea to a deployed, documented, and tested codebase — with minimal human intervention.
43
47
 
48
+ ### Positioning and ICP
49
+
50
+ - Primary ICP: product teams of 2-10 engineers shipping continuously
51
+ - Secondary ICPs: solo builders and agencies operating repeatable delivery workflows
52
+ - Differentiation: not "write code faster," but "ship products systematically" via BMAD-driven intent-to-delivery
53
+
54
+ For full positioning rationale and risk mitigation strategy, see [`docs/positioning.md`](docs/positioning.md).
55
+
44
56
  ---
45
57
 
46
58
  ## The 9-Phase Pipeline
@@ -126,6 +138,7 @@ flowchart TD
126
138
  - `qwen`: `ralphy --qwen --max-iterations 1 <task>`
127
139
  - `copilot`: `ralphy --copilot --max-iterations 1 <task>`
128
140
  - `gemini`: `gemini <task>`
141
+ - `ollama`: `ollama run <model> <task>` (default model via `OLLAMA_MODEL` or `llama3.2`)
129
142
  - `ralphy`: `ralphy --max-iterations 1 <task>`
130
143
 
131
144
  ---
@@ -157,11 +170,27 @@ npx bemadralphy run
157
170
  # Run with specific options
158
171
  npx bemadralphy run --mode auto --engine claude --max-parallel 5 --budget 50
159
172
 
173
+ # Run with execution/audience profiles
174
+ npx bemadralphy run --execution-profile safe --audience-profile product-team
175
+
176
+ # Preview pipeline and estimated cost without execution
177
+ npx bemadralphy run --dry-run --output json
178
+
179
+ # Resume a failed/interrupted run
180
+ npx bemadralphy run --resume
181
+
182
+ # Replay a previous run from history
183
+ npx bemadralphy replay <runId> --from-phase execute
184
+
160
185
  # Explore before planning (optional)
161
186
  npx bemadralphy explore "How should I structure authentication?"
162
187
 
163
188
  # Check pipeline status
164
189
  npx bemadralphy status
190
+
191
+ # Show run history (human or JSON)
192
+ npx bemadralphy history
193
+ npx bemadralphy history --output json
165
194
  ```
166
195
 
167
196
  ---
@@ -277,11 +306,11 @@ your-project/
277
306
 
278
307
  ---
279
308
 
280
- ## Configuration (planned)
309
+ ## Configuration
281
310
 
282
311
  ### `.bemadralphy/state.yaml`
283
312
 
284
- Tracks pipeline state for resumability:
313
+ Tracks pipeline state for resumability and recovery:
285
314
 
286
315
  ```yaml
287
316
  phase: execution
@@ -291,8 +320,38 @@ last_gate: architecture
291
320
  tasks_completed: 12
292
321
  tasks_total: 24
293
322
  cost_usd: 3.47
323
+ status: running
324
+ resumeFromPhase: execute
325
+ ```
326
+
327
+ ### Run defaults via config file
328
+
329
+ You can define persistent defaults in either `.bemadralphyrc` (YAML/JSON) or `bemad.config.js`.
330
+
331
+ Example `.bemadralphyrc`:
332
+
333
+ ```yaml
334
+ mode: hybrid
335
+ engine: ollama
336
+ maxParallel: 2
337
+ executionProfile: balanced
338
+ output: text
339
+ plugins:
340
+ - ./bemad.plugins/local-plugin.mjs
294
341
  ```
295
342
 
343
+ Example `bemad.config.js`:
344
+
345
+ ```js
346
+ export default {
347
+ mode: 'hybrid',
348
+ engine: 'ralphy',
349
+ output: 'json',
350
+ };
351
+ ```
352
+
353
+ CLI flags always override config file values.
354
+
296
355
  ### Flags
297
356
 
298
357
  | Flag | Description |
@@ -301,10 +360,23 @@ cost_usd: 3.47
301
360
  | `--engine <name>` | AI engine to use |
302
361
  | `--planning-engine <name>` | Override engine for planning phase only |
303
362
  | `--max-parallel N` | Max parallel tasks (default: 3) |
363
+ | `--execution-profile <profile>` | Guardrails profile: `safe\|balanced\|fast` |
364
+ | `--audience-profile <profile>` | ICP profile: `solo-dev\|agency-team\|product-team\|enterprise-team` |
304
365
  | `--budget N` | Cost cap in USD |
305
366
  | `--brownfield` | Force brownfield mode |
306
367
  | `--swarm native\|process\|off` | Override swarm detection |
307
368
  | `--create-pr` | Create PRs for each task |
369
+ | `--dry-run` | Preflight plan + cost estimate only |
370
+ | `--resume` | Resume from latest checkpoint |
371
+ | `--from-phase <name>` | Start at a specific phase |
372
+ | `--output text\|json` | Human-readable or structured output |
373
+ | `--plugin <paths...>` | Load custom plugin modules |
374
+
375
+ ### Execution profiles
376
+
377
+ - `safe`: single-lane execution defaults, process-mode bias, lowest coordination risk
378
+ - `balanced` (default): controlled concurrency for day-to-day product work
379
+ - `fast`: maximum requested concurrency for throughput-focused runs
308
380
 
309
381
  ---
310
382
 
@@ -382,6 +454,7 @@ node dist/cli.js --help
382
454
  - BMAD CLI (`bmad`)
383
455
  - Beads CLI (`bd`)
384
456
  - OpenSpec CLI (`openspec`)
457
+ - Optional local engine: Ollama (`ollama`) when using `--engine ollama`
385
458
 
386
459
  ## Fail-Fast Behavior
387
460
 
package/dist/cli.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { Command } from 'commander';
3
- import { runExplore, runInit, runPipeline, runStatus } from './orchestrator.js';
3
+ import { runExplore, runHistory, runInit, runPipeline, runReplay, runStatus } from './orchestrator.js';
4
4
  const program = new Command();
5
5
  program
6
6
  .name('bemadralphy')
@@ -15,17 +15,24 @@ program
15
15
  program
16
16
  .command('run')
17
17
  .description('Run the full pipeline')
18
- .option('--mode <mode>', 'Autonomy mode: auto|hybrid|supervised', 'hybrid')
18
+ .option('--mode <mode>', 'Autonomy mode: auto|hybrid|supervised')
19
19
  .option('--engine <name>', 'AI engine to use')
20
20
  .option('--planning-engine <name>', 'Override engine for planning phase only')
21
- .option('--max-parallel <n>', 'Max parallel tasks', (v) => Number(v), 3)
21
+ .option('--max-parallel <n>', 'Max parallel tasks', (v) => Number(v))
22
+ .option('--execution-profile <profile>', 'Execution guardrails profile: safe|balanced|fast')
23
+ .option('--audience-profile <profile>', 'Target audience profile: solo-dev|agency-team|product-team|enterprise-team')
22
24
  .option('--budget <usd>', 'Cost cap in USD', (v) => Number(v))
23
- .option('--brownfield', 'Force brownfield mode', false)
25
+ .option('--brownfield', 'Force brownfield mode')
24
26
  .option('--swarm <mode>', 'Override swarm detection: native|process|off')
25
- .option('--create-pr', 'Create PRs per task', false)
26
- .option('--dry-run', 'Plan only; do not execute', false)
27
- .action(async (options) => {
28
- await runPipeline(options);
27
+ .option('--create-pr', 'Create PRs per task')
28
+ .option('--dry-run', 'Preview plan and estimated cost without execution')
29
+ .option('--resume', 'Resume from latest checkpoint')
30
+ .option('--from-phase <phase>', 'Start from a specific phase')
31
+ .option('--output <format>', 'Output format: text|json', 'text')
32
+ .option('--plugin <paths...>', 'Load plugin module(s) from path')
33
+ .action(async (options, command) => {
34
+ const resolved = resolveRunOptions(options, command);
35
+ await runPipeline(resolved);
29
36
  });
30
37
  program
31
38
  .command('explore <query>')
@@ -36,8 +43,53 @@ program
36
43
  program
37
44
  .command('status')
38
45
  .description('Show pipeline status')
39
- .action(async () => {
40
- await runStatus();
46
+ .option('--output <format>', 'Output format: text|json', 'text')
47
+ .action(async (options) => {
48
+ await runStatus(options.output);
49
+ });
50
+ program
51
+ .command('history')
52
+ .description('Show previous pipeline runs')
53
+ .option('--output <format>', 'Output format: text|json', 'text')
54
+ .action(async (options) => {
55
+ await runHistory(options.output);
56
+ });
57
+ program
58
+ .command('replay <runId>')
59
+ .description('Replay a previous run from history')
60
+ .option('--from-phase <phase>', 'Replay from a specific phase')
61
+ .option('--output <format>', 'Output format: text|json', 'text')
62
+ .action(async (runId, options) => {
63
+ await runReplay(runId, {
64
+ fromPhase: options.fromPhase,
65
+ output: options.output,
66
+ });
41
67
  });
42
68
  program.parse();
69
+ function resolveRunOptions(options, command) {
70
+ return {
71
+ mode: maybeOption(command, 'mode', options.mode),
72
+ engine: maybeOption(command, 'engine', options.engine),
73
+ planningEngine: maybeOption(command, 'planningEngine', options.planningEngine),
74
+ maxParallel: maybeOption(command, 'maxParallel', options.maxParallel),
75
+ executionProfile: maybeOption(command, 'executionProfile', options.executionProfile),
76
+ audienceProfile: maybeOption(command, 'audienceProfile', options.audienceProfile),
77
+ budget: maybeOption(command, 'budget', options.budget),
78
+ brownfield: maybeOption(command, 'brownfield', options.brownfield),
79
+ swarm: maybeOption(command, 'swarm', options.swarm),
80
+ createPr: maybeOption(command, 'createPr', options.createPr),
81
+ dryRun: maybeOption(command, 'dryRun', options.dryRun),
82
+ resume: maybeOption(command, 'resume', options.resume),
83
+ fromPhase: maybeOption(command, 'fromPhase', options.fromPhase),
84
+ output: maybeOption(command, 'output', options.output),
85
+ plugins: maybeOption(command, 'plugin', options.plugin),
86
+ };
87
+ }
88
+ function maybeOption(command, key, value) {
89
+ const source = command.getOptionValueSource(key);
90
+ if (source === 'cli') {
91
+ return value;
92
+ }
93
+ return undefined;
94
+ }
43
95
  //# 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,UAAU,EAAE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAEhF,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,aAAa,CAAC;KACnB,WAAW,CAAC,4DAA4D,CAAC;KACzE,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,gDAAgD,CAAC;KAC7D,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,MAAM,OAAO,EAAE,CAAC;AAClB,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,KAAK,CAAC;KACd,WAAW,CAAC,uBAAuB,CAAC;KACpC,MAAM,CAAC,eAAe,EAAE,uCAAuC,EAAE,QAAQ,CAAC;KAC1E,MAAM,CAAC,iBAAiB,EAAE,kBAAkB,CAAC;KAC7C,MAAM,CAAC,0BAA0B,EAAE,yCAAyC,CAAC;KAC7E,MAAM,CAAC,oBAAoB,EAAE,oBAAoB,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;KACvE,MAAM,CAAC,gBAAgB,EAAE,iBAAiB,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;KAC7D,MAAM,CAAC,cAAc,EAAE,uBAAuB,EAAE,KAAK,CAAC;KACtD,MAAM,CAAC,gBAAgB,EAAE,8CAA8C,CAAC;KACxE,MAAM,CAAC,aAAa,EAAE,qBAAqB,EAAE,KAAK,CAAC;KACnD,MAAM,CAAC,WAAW,EAAE,2BAA2B,EAAE,KAAK,CAAC;KACvD,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;IACxB,MAAM,WAAW,CAAC,OAAO,CAAC,CAAC;AAC7B,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,iBAAiB,CAAC;KAC1B,WAAW,CAAC,kDAAkD,CAAC;KAC/D,MAAM,CAAC,KAAK,EAAE,KAAa,EAAE,EAAE;IAC9B,MAAM,UAAU,CAAC,KAAK,CAAC,CAAC;AAC1B,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,sBAAsB,CAAC;KACnC,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,MAAM,SAAS,EAAE,CAAC;AACpB,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,KAAK,EAAE,CAAC"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { OutputFormat } from './utils/logging.js';
2
+ export type RunConfig = {
3
+ mode?: 'auto' | 'hybrid' | 'supervised';
4
+ engine?: string;
5
+ planningEngine?: string;
6
+ maxParallel?: number;
7
+ executionProfile?: 'safe' | 'balanced' | 'fast';
8
+ audienceProfile?: 'solo-dev' | 'agency-team' | 'product-team' | 'enterprise-team';
9
+ budget?: number;
10
+ brownfield?: boolean;
11
+ swarm?: 'native' | 'process' | 'off';
12
+ createPr?: boolean;
13
+ output?: OutputFormat;
14
+ plugins?: string[];
15
+ };
16
+ export declare function loadRunConfig(projectRoot: string): Promise<RunConfig>;
package/dist/config.js ADDED
@@ -0,0 +1,44 @@
1
+ import { access, readFile } from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { pathToFileURL } from 'node:url';
4
+ import { parse } from 'yaml';
5
+ const FILE_CANDIDATES = ['.bemadralphyrc', 'bemad.config.json', 'bemad.config.js', 'bemad.config.mjs'];
6
+ export async function loadRunConfig(projectRoot) {
7
+ for (const candidate of FILE_CANDIDATES) {
8
+ const fullPath = path.join(projectRoot, candidate);
9
+ if (!(await exists(fullPath))) {
10
+ continue;
11
+ }
12
+ if (candidate.endsWith('.js') || candidate.endsWith('.mjs')) {
13
+ return loadJsConfig(fullPath);
14
+ }
15
+ const raw = await readFile(fullPath, 'utf-8');
16
+ return parseTextConfig(raw);
17
+ }
18
+ return {};
19
+ }
20
+ function parseTextConfig(contents) {
21
+ const trimmed = contents.trim();
22
+ if (!trimmed) {
23
+ return {};
24
+ }
25
+ if (trimmed.startsWith('{')) {
26
+ return JSON.parse(trimmed);
27
+ }
28
+ return parse(trimmed) ?? {};
29
+ }
30
+ async function loadJsConfig(fullPath) {
31
+ const loaded = await import(pathToFileURL(fullPath).href);
32
+ const exported = loaded.default ?? loaded.config ?? loaded;
33
+ return (exported ?? {});
34
+ }
35
+ async function exists(targetPath) {
36
+ try {
37
+ await access(targetPath);
38
+ return true;
39
+ }
40
+ catch {
41
+ return false;
42
+ }
43
+ }
44
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,KAAK,EAAE,MAAM,MAAM,CAAC;AAkB7B,MAAM,eAAe,GAAG,CAAC,gBAAgB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,kBAAkB,CAAC,CAAC;AAEvG,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,WAAmB;IACrD,KAAK,MAAM,SAAS,IAAI,eAAe,EAAE,CAAC;QACxC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;QACnD,IAAI,CAAC,CAAC,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC;YAC9B,SAAS;QACX,CAAC;QACD,IAAI,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YAC5D,OAAO,YAAY,CAAC,QAAQ,CAAC,CAAC;QAChC,CAAC;QACD,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC9C,OAAO,eAAe,CAAC,GAAG,CAAC,CAAC;IAC9B,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,SAAS,eAAe,CAAC,QAAgB;IACvC,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC;IAChC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC5B,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAc,CAAC;IAC1C,CAAC;IACD,OAAQ,KAAK,CAAC,OAAO,CAAe,IAAI,EAAE,CAAC;AAC7C,CAAC;AAED,KAAK,UAAU,YAAY,CAAC,QAAgB;IAC1C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC;IAC1D,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC;IAC3D,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAc,CAAC;AACvC,CAAC;AAED,KAAK,UAAU,MAAM,CAAC,UAAkB;IACtC,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC;QACzB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
package/dist/cost.d.ts CHANGED
@@ -4,3 +4,11 @@ export declare class CostTracker {
4
4
  getTotal(): number;
5
5
  persist(projectRoot: string): Promise<void>;
6
6
  }
7
+ export type CostEstimate = {
8
+ estimatedUsd: number;
9
+ minUsd: number;
10
+ maxUsd: number;
11
+ taskCount: number;
12
+ heuristic: string;
13
+ };
14
+ export declare function estimateRunCost(projectRoot: string, maxParallel: number): Promise<CostEstimate>;
package/dist/cost.js CHANGED
@@ -1,5 +1,6 @@
1
- import { mkdir, writeFile } from 'node:fs/promises';
1
+ import { mkdir, readFile, writeFile } from 'node:fs/promises';
2
2
  import path from 'node:path';
3
+ import { runCommand } from './utils/exec.js';
3
4
  export class CostTracker {
4
5
  totalUsd = 0;
5
6
  addCost(amountUsd) {
@@ -12,7 +13,50 @@ export class CostTracker {
12
13
  const dir = path.join(projectRoot, '.bemadralphy');
13
14
  await mkdir(dir, { recursive: true });
14
15
  const costPath = path.join(dir, 'cost.log');
15
- await writeFile(costPath, `${this.totalUsd}\n`, 'utf-8');
16
+ const existing = await safeRead(costPath);
17
+ const row = JSON.stringify({
18
+ ts: new Date().toISOString(),
19
+ totalUsd: Number(this.totalUsd.toFixed(4)),
20
+ });
21
+ await writeFile(costPath, `${existing}${row}\n`, 'utf-8');
16
22
  }
17
23
  }
24
+ export async function estimateRunCost(projectRoot, maxParallel) {
25
+ const taskCount = await estimateReadyTasks(projectRoot);
26
+ const baseCost = 0.08;
27
+ const perTask = 0.07;
28
+ const concurrencyMultiplier = Math.max(1, Math.min(maxParallel || 1, 8)) * 0.01;
29
+ const estimatedUsd = baseCost + taskCount * (perTask + concurrencyMultiplier);
30
+ return {
31
+ estimatedUsd: round4(estimatedUsd),
32
+ minUsd: round4(estimatedUsd * 0.65),
33
+ maxUsd: round4(estimatedUsd * 1.45),
34
+ taskCount,
35
+ heuristic: 'Heuristic estimate based on ready Beads tasks and configured parallelism; actual token usage varies by model and task size.',
36
+ };
37
+ }
38
+ async function estimateReadyTasks(projectRoot) {
39
+ try {
40
+ const { stdout } = await runCommand('bd', ['ready'], projectRoot);
41
+ const ids = stdout.match(/bd-[a-zA-Z0-9-]+/g);
42
+ if (!ids) {
43
+ return 0;
44
+ }
45
+ return new Set(ids).size;
46
+ }
47
+ catch {
48
+ return 0;
49
+ }
50
+ }
51
+ async function safeRead(filePath) {
52
+ try {
53
+ return await readFile(filePath, 'utf-8');
54
+ }
55
+ catch {
56
+ return '';
57
+ }
58
+ }
59
+ function round4(value) {
60
+ return Number(value.toFixed(4));
61
+ }
18
62
  //# sourceMappingURL=cost.js.map
package/dist/cost.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cost.js","sourceRoot":"","sources":["../src/cost.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,OAAO,WAAW;IACd,QAAQ,GAAG,CAAC,CAAC;IAErB,OAAO,CAAC,SAAiB;QACvB,IAAI,CAAC,QAAQ,IAAI,SAAS,CAAC;IAC7B,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,WAAmB;QAC/B,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;QACnD,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACtC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;QAC5C,MAAM,SAAS,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,QAAQ,IAAI,EAAE,OAAO,CAAC,CAAC;IAC3D,CAAC;CACF"}
1
+ {"version":3,"file":"cost.js","sourceRoot":"","sources":["../src/cost.ts"],"names":[],"mappings":"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"}
@@ -4,6 +4,7 @@ import { copilotAdapter } from './copilot.js';
4
4
  import { cursorAdapter } from './cursor.js';
5
5
  import { geminiAdapter } from './gemini.js';
6
6
  import { kimiAdapter } from './kimi.js';
7
+ import { ollamaAdapter } from './ollama.js';
7
8
  import { opencodeAdapter } from './opencode.js';
8
9
  import { qwenAdapter } from './qwen.js';
9
10
  import { ralphyAdapter } from './ralphy.js';
@@ -14,6 +15,7 @@ export const engineAdapters = {
14
15
  cursor: cursorAdapter,
15
16
  gemini: geminiAdapter,
16
17
  kimi: kimiAdapter,
18
+ ollama: ollamaAdapter,
17
19
  opencode: opencodeAdapter,
18
20
  qwen: qwenAdapter,
19
21
  ralphy: ralphyAdapter,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/engines/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG5C,MAAM,CAAC,MAAM,cAAc,GAAkC;IAC3D,MAAM,EAAE,aAAa;IACrB,KAAK,EAAE,YAAY;IACnB,OAAO,EAAE,cAAc;IACvB,MAAM,EAAE,aAAa;IACrB,MAAM,EAAE,aAAa;IACrB,IAAI,EAAE,WAAW;IACjB,QAAQ,EAAE,eAAe;IACzB,IAAI,EAAE,WAAW;IACjB,MAAM,EAAE,aAAa;CACtB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/engines/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG5C,MAAM,CAAC,MAAM,cAAc,GAAkC;IAC3D,MAAM,EAAE,aAAa;IACrB,KAAK,EAAE,YAAY;IACnB,OAAO,EAAE,cAAc;IACvB,MAAM,EAAE,aAAa;IACrB,MAAM,EAAE,aAAa;IACrB,IAAI,EAAE,WAAW;IACjB,MAAM,EAAE,aAAa;IACrB,QAAQ,EAAE,eAAe;IACzB,IAAI,EAAE,WAAW;IACjB,MAAM,EAAE,aAAa;CACtB,CAAC"}
@@ -0,0 +1 @@
1
+ export declare const ollamaAdapter: import("./types.js").EngineAdapter;
@@ -0,0 +1,13 @@
1
+ import { createCliAdapter } from './cli-adapter.js';
2
+ export const ollamaAdapter = createCliAdapter({
3
+ name: 'ollama',
4
+ commandName: 'ollama',
5
+ hasNativeSwarm: false,
6
+ buildArgs: (_task, prompt) => {
7
+ const model = process.env.OLLAMA_MODEL?.trim() || 'llama3.2';
8
+ return ['run', model, prompt];
9
+ },
10
+ unavailableHint: 'Install Ollama and run `ollama pull <model>`.',
11
+ failureHint: 'Ensure the Ollama daemon is running and the selected model is available.',
12
+ });
13
+ //# sourceMappingURL=ollama.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ollama.js","sourceRoot":"","sources":["../../src/engines/ollama.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpD,MAAM,CAAC,MAAM,aAAa,GAAG,gBAAgB,CAAC;IAC5C,IAAI,EAAE,QAAQ;IACd,WAAW,EAAE,QAAQ;IACrB,cAAc,EAAE,KAAK;IACrB,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;QAC3B,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,IAAI,EAAE,IAAI,UAAU,CAAC;QAC7D,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAChC,CAAC;IACD,eAAe,EAAE,+CAA+C;IAChE,WAAW,EAAE,0EAA0E;CACxF,CAAC,CAAC"}
@@ -0,0 +1,16 @@
1
+ export type RunHistoryRecord = {
2
+ runId: string;
3
+ startedAt: string;
4
+ finishedAt?: string;
5
+ status: 'running' | 'failed' | 'completed';
6
+ mode: 'auto' | 'hybrid' | 'supervised';
7
+ engine?: string;
8
+ output?: 'text' | 'json';
9
+ phase?: string;
10
+ resumeFromPhase?: string;
11
+ options: Record<string, unknown>;
12
+ error?: string;
13
+ };
14
+ export declare function appendRunHistory(projectRoot: string, record: RunHistoryRecord): Promise<void>;
15
+ export declare function readRunHistory(projectRoot: string): Promise<RunHistoryRecord[]>;
16
+ export declare function findRunHistory(projectRoot: string, runId: string): Promise<RunHistoryRecord | null>;
@@ -0,0 +1,35 @@
1
+ import { mkdir, readFile, writeFile } from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ const RUNS_PATH = ['.bemadralphy', 'runs.jsonl'];
4
+ export async function appendRunHistory(projectRoot, record) {
5
+ const fullPath = path.join(projectRoot, ...RUNS_PATH);
6
+ await mkdir(path.dirname(fullPath), { recursive: true });
7
+ const existing = await safeRead(fullPath);
8
+ await writeFile(fullPath, `${existing}${JSON.stringify(record)}\n`, 'utf-8');
9
+ }
10
+ export async function readRunHistory(projectRoot) {
11
+ const fullPath = path.join(projectRoot, ...RUNS_PATH);
12
+ const raw = await safeRead(fullPath);
13
+ if (!raw.trim()) {
14
+ return [];
15
+ }
16
+ return raw
17
+ .split('\n')
18
+ .map((line) => line.trim())
19
+ .filter(Boolean)
20
+ .map((line) => JSON.parse(line));
21
+ }
22
+ export async function findRunHistory(projectRoot, runId) {
23
+ const rows = await readRunHistory(projectRoot);
24
+ const found = rows.find((row) => row.runId === runId);
25
+ return found ?? null;
26
+ }
27
+ async function safeRead(filePath) {
28
+ try {
29
+ return await readFile(filePath, 'utf-8');
30
+ }
31
+ catch {
32
+ return '';
33
+ }
34
+ }
35
+ //# sourceMappingURL=history.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history.js","sourceRoot":"","sources":["../src/history.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,IAAI,MAAM,WAAW,CAAC;AAgB7B,MAAM,SAAS,GAAG,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC;AAEjD,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,WAAmB,EACnB,MAAwB;IAExB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,SAAS,CAAC,CAAC;IACtD,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzD,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC1C,MAAM,SAAS,CAAC,QAAQ,EAAE,GAAG,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AAC/E,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,WAAmB;IACtD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,SAAS,CAAC,CAAC;IACtD,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACrC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC;QAChB,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,OAAO,GAAG;SACP,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SAC1B,MAAM,CAAC,OAAO,CAAC;SACf,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAqB,CAAC,CAAC;AACzD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,WAAmB,EACnB,KAAa;IAEb,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,WAAW,CAAC,CAAC;IAC/C,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC;IACtD,OAAO,KAAK,IAAI,IAAI,CAAC;AACvB,CAAC;AAED,KAAK,UAAU,QAAQ,CAAC,QAAgB;IACtC,IAAI,CAAC;QACH,OAAO,MAAM,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC3C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export { runExplore, runInit, runPipeline, runStatus } from './orchestrator.js';
1
+ export { runExplore, runHistory, runInit, runPipeline, runReplay, runStatus } from './orchestrator.js';
2
2
  export type { RunOptions } from './orchestrator.js';
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- export { runExplore, runInit, runPipeline, runStatus } from './orchestrator.js';
1
+ export { runExplore, runHistory, runInit, runPipeline, runReplay, runStatus } from './orchestrator.js';
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC"}
@@ -1,17 +1,28 @@
1
- import { type PipelineMode } from './phases/index.js';
1
+ import { type AudienceProfile, type ExecutionProfile, type PipelineMode } from './phases/index.js';
2
+ import { type OutputFormat } from './utils/logging.js';
2
3
  export type RunOptions = {
3
- mode: PipelineMode;
4
+ mode?: PipelineMode;
4
5
  engine?: string;
5
6
  planningEngine?: string;
6
- maxParallel: number;
7
+ maxParallel?: number;
8
+ executionProfile?: ExecutionProfile;
9
+ audienceProfile?: AudienceProfile;
7
10
  budget?: number;
8
- brownfield: boolean;
11
+ brownfield?: boolean;
9
12
  swarm?: 'native' | 'process' | 'off';
10
- createPr: boolean;
11
- dryRun: boolean;
13
+ createPr?: boolean;
14
+ dryRun?: boolean;
15
+ resume?: boolean;
16
+ fromPhase?: PipelinePhaseName;
17
+ output?: OutputFormat;
18
+ plugins?: string[];
12
19
  projectRoot?: string;
13
20
  };
21
+ type PipelinePhaseName = 'intake' | 'planning' | 'steering' | 'scaffold' | 'sync' | 'execute' | 'verify' | 'post';
14
22
  export declare function runInit(projectRoot?: string): Promise<void>;
15
23
  export declare function runPipeline(options: RunOptions): Promise<void>;
16
24
  export declare function runExplore(query: string): Promise<void>;
17
- export declare function runStatus(): Promise<void>;
25
+ export declare function runStatus(output?: OutputFormat): Promise<void>;
26
+ export declare function runHistory(output?: OutputFormat): Promise<void>;
27
+ export declare function runReplay(runId: string, options?: Partial<RunOptions>): Promise<void>;
28
+ export {};