bemadralphy 0.1.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 (207) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +468 -0
  3. package/dist/beads/adapter.d.ts +5 -0
  4. package/dist/beads/adapter.js +16 -0
  5. package/dist/beads/adapter.js.map +1 -0
  6. package/dist/beads/index.d.ts +3 -0
  7. package/dist/beads/index.js +4 -0
  8. package/dist/beads/index.js.map +1 -0
  9. package/dist/beads/parse-tasks.d.ts +2 -0
  10. package/dist/beads/parse-tasks.js +12 -0
  11. package/dist/beads/parse-tasks.js.map +1 -0
  12. package/dist/beads/tasks-md.d.ts +6 -0
  13. package/dist/beads/tasks-md.js +8 -0
  14. package/dist/beads/tasks-md.js.map +1 -0
  15. package/dist/beads/writer.d.ts +12 -0
  16. package/dist/beads/writer.js +60 -0
  17. package/dist/beads/writer.js.map +1 -0
  18. package/dist/cli.d.ts +2 -0
  19. package/dist/cli.js +43 -0
  20. package/dist/cli.js.map +1 -0
  21. package/dist/cost.d.ts +6 -0
  22. package/dist/cost.js +18 -0
  23. package/dist/cost.js.map +1 -0
  24. package/dist/docs/pr-body.d.ts +8 -0
  25. package/dist/docs/pr-body.js +11 -0
  26. package/dist/docs/pr-body.js.map +1 -0
  27. package/dist/engines/claude.d.ts +1 -0
  28. package/dist/engines/claude.js +11 -0
  29. package/dist/engines/claude.js.map +1 -0
  30. package/dist/engines/cli-adapter.d.ts +12 -0
  31. package/dist/engines/cli-adapter.js +36 -0
  32. package/dist/engines/cli-adapter.js.map +1 -0
  33. package/dist/engines/cli.d.ts +14 -0
  34. package/dist/engines/cli.js +72 -0
  35. package/dist/engines/cli.js.map +1 -0
  36. package/dist/engines/codex.d.ts +1 -0
  37. package/dist/engines/codex.js +10 -0
  38. package/dist/engines/codex.js.map +1 -0
  39. package/dist/engines/copilot.d.ts +1 -0
  40. package/dist/engines/copilot.js +10 -0
  41. package/dist/engines/copilot.js.map +1 -0
  42. package/dist/engines/cursor.d.ts +1 -0
  43. package/dist/engines/cursor.js +10 -0
  44. package/dist/engines/cursor.js.map +1 -0
  45. package/dist/engines/gemini.d.ts +1 -0
  46. package/dist/engines/gemini.js +10 -0
  47. package/dist/engines/gemini.js.map +1 -0
  48. package/dist/engines/index.d.ts +2 -0
  49. package/dist/engines/index.js +21 -0
  50. package/dist/engines/index.js.map +1 -0
  51. package/dist/engines/kimi.d.ts +1 -0
  52. package/dist/engines/kimi.js +10 -0
  53. package/dist/engines/kimi.js.map +1 -0
  54. package/dist/engines/opencode.d.ts +1 -0
  55. package/dist/engines/opencode.js +10 -0
  56. package/dist/engines/opencode.js.map +1 -0
  57. package/dist/engines/prompt-template.d.ts +2 -0
  58. package/dist/engines/prompt-template.js +96 -0
  59. package/dist/engines/prompt-template.js.map +1 -0
  60. package/dist/engines/qwen.d.ts +1 -0
  61. package/dist/engines/qwen.js +10 -0
  62. package/dist/engines/qwen.js.map +1 -0
  63. package/dist/engines/ralphy.d.ts +1 -0
  64. package/dist/engines/ralphy.js +10 -0
  65. package/dist/engines/ralphy.js.map +1 -0
  66. package/dist/engines/stub.d.ts +2 -0
  67. package/dist/engines/stub.js +17 -0
  68. package/dist/engines/stub.js.map +1 -0
  69. package/dist/engines/types.d.ts +21 -0
  70. package/dist/engines/types.js +2 -0
  71. package/dist/engines/types.js.map +1 -0
  72. package/dist/errors.d.ts +12 -0
  73. package/dist/errors.js +13 -0
  74. package/dist/errors.js.map +1 -0
  75. package/dist/git/worktrees.d.ts +11 -0
  76. package/dist/git/worktrees.js +63 -0
  77. package/dist/git/worktrees.js.map +1 -0
  78. package/dist/index.d.ts +2 -0
  79. package/dist/index.js +2 -0
  80. package/dist/index.js.map +1 -0
  81. package/dist/locks.d.ts +10 -0
  82. package/dist/locks.js +23 -0
  83. package/dist/locks.js.map +1 -0
  84. package/dist/orchestrator.d.ts +17 -0
  85. package/dist/orchestrator.js +99 -0
  86. package/dist/orchestrator.js.map +1 -0
  87. package/dist/permissions.d.ts +5 -0
  88. package/dist/permissions.js +19 -0
  89. package/dist/permissions.js.map +1 -0
  90. package/dist/phases/execute.d.ts +2 -0
  91. package/dist/phases/execute.js +78 -0
  92. package/dist/phases/execute.js.map +1 -0
  93. package/dist/phases/explore.d.ts +1 -0
  94. package/dist/phases/explore.js +5 -0
  95. package/dist/phases/explore.js.map +1 -0
  96. package/dist/phases/index.d.ts +10 -0
  97. package/dist/phases/index.js +10 -0
  98. package/dist/phases/index.js.map +1 -0
  99. package/dist/phases/intake.d.ts +2 -0
  100. package/dist/phases/intake.js +67 -0
  101. package/dist/phases/intake.js.map +1 -0
  102. package/dist/phases/planning.d.ts +2 -0
  103. package/dist/phases/planning.js +8 -0
  104. package/dist/phases/planning.js.map +1 -0
  105. package/dist/phases/post.d.ts +2 -0
  106. package/dist/phases/post.js +21 -0
  107. package/dist/phases/post.js.map +1 -0
  108. package/dist/phases/scaffold.d.ts +2 -0
  109. package/dist/phases/scaffold.js +6 -0
  110. package/dist/phases/scaffold.js.map +1 -0
  111. package/dist/phases/steering.d.ts +2 -0
  112. package/dist/phases/steering.js +10 -0
  113. package/dist/phases/steering.js.map +1 -0
  114. package/dist/phases/sync.d.ts +2 -0
  115. package/dist/phases/sync.js +25 -0
  116. package/dist/phases/sync.js.map +1 -0
  117. package/dist/phases/types.d.ts +22 -0
  118. package/dist/phases/types.js +2 -0
  119. package/dist/phases/types.js.map +1 -0
  120. package/dist/phases/verify.d.ts +2 -0
  121. package/dist/phases/verify.js +8 -0
  122. package/dist/phases/verify.js.map +1 -0
  123. package/dist/planning/bmad.d.ts +3 -0
  124. package/dist/planning/bmad.js +20 -0
  125. package/dist/planning/bmad.js.map +1 -0
  126. package/dist/planning/index.d.ts +2 -0
  127. package/dist/planning/index.js +37 -0
  128. package/dist/planning/index.js.map +1 -0
  129. package/dist/planning/validate.d.ts +7 -0
  130. package/dist/planning/validate.js +20 -0
  131. package/dist/planning/validate.js.map +1 -0
  132. package/dist/pr/create.d.ts +2 -0
  133. package/dist/pr/create.js +65 -0
  134. package/dist/pr/create.js.map +1 -0
  135. package/dist/quality/gates.d.ts +12 -0
  136. package/dist/quality/gates.js +54 -0
  137. package/dist/quality/gates.js.map +1 -0
  138. package/dist/release.d.ts +3 -0
  139. package/dist/release.js +88 -0
  140. package/dist/release.js.map +1 -0
  141. package/dist/specs/archive.d.ts +1 -0
  142. package/dist/specs/archive.js +12 -0
  143. package/dist/specs/archive.js.map +1 -0
  144. package/dist/specs/changes.d.ts +7 -0
  145. package/dist/specs/changes.js +20 -0
  146. package/dist/specs/changes.js.map +1 -0
  147. package/dist/specs/delta.d.ts +1 -0
  148. package/dist/specs/delta.js +8 -0
  149. package/dist/specs/delta.js.map +1 -0
  150. package/dist/specs/generate.d.ts +1 -0
  151. package/dist/specs/generate.js +8 -0
  152. package/dist/specs/generate.js.map +1 -0
  153. package/dist/specs/index.d.ts +3 -0
  154. package/dist/specs/index.js +4 -0
  155. package/dist/specs/index.js.map +1 -0
  156. package/dist/specs/merge-summary.d.ts +2 -0
  157. package/dist/specs/merge-summary.js +19 -0
  158. package/dist/specs/merge-summary.js.map +1 -0
  159. package/dist/state.d.ts +12 -0
  160. package/dist/state.js +20 -0
  161. package/dist/state.js.map +1 -0
  162. package/dist/steering/index.d.ts +2 -0
  163. package/dist/steering/index.js +115 -0
  164. package/dist/steering/index.js.map +1 -0
  165. package/dist/swarm/claude-teams.d.ts +1 -0
  166. package/dist/swarm/claude-teams.js +8 -0
  167. package/dist/swarm/claude-teams.js.map +1 -0
  168. package/dist/swarm/codex-sdk.d.ts +1 -0
  169. package/dist/swarm/codex-sdk.js +8 -0
  170. package/dist/swarm/codex-sdk.js.map +1 -0
  171. package/dist/swarm/detector.d.ts +3 -0
  172. package/dist/swarm/detector.js +16 -0
  173. package/dist/swarm/detector.js.map +1 -0
  174. package/dist/swarm/index.d.ts +5 -0
  175. package/dist/swarm/index.js +5 -0
  176. package/dist/swarm/index.js.map +1 -0
  177. package/dist/swarm/kimi-parl.d.ts +1 -0
  178. package/dist/swarm/kimi-parl.js +8 -0
  179. package/dist/swarm/kimi-parl.js.map +1 -0
  180. package/dist/swarm/native.d.ts +14 -0
  181. package/dist/swarm/native.js +112 -0
  182. package/dist/swarm/native.js.map +1 -0
  183. package/dist/swarm/parse.d.ts +5 -0
  184. package/dist/swarm/parse.js +20 -0
  185. package/dist/swarm/parse.js.map +1 -0
  186. package/dist/swarm/types.d.ts +5 -0
  187. package/dist/swarm/types.js +2 -0
  188. package/dist/swarm/types.js.map +1 -0
  189. package/dist/tasks/output.d.ts +7 -0
  190. package/dist/tasks/output.js +15 -0
  191. package/dist/tasks/output.js.map +1 -0
  192. package/dist/utils/exec.d.ts +18 -0
  193. package/dist/utils/exec.js +52 -0
  194. package/dist/utils/exec.js.map +1 -0
  195. package/dist/utils/failures.d.ts +2 -0
  196. package/dist/utils/failures.js +22 -0
  197. package/dist/utils/failures.js.map +1 -0
  198. package/dist/utils/logging.d.ts +1 -0
  199. package/dist/utils/logging.js +5 -0
  200. package/dist/utils/logging.js.map +1 -0
  201. package/dist/utils/resume.d.ts +1 -0
  202. package/dist/utils/resume.js +14 -0
  203. package/dist/utils/resume.js.map +1 -0
  204. package/dist/utils/retry.d.ts +1 -0
  205. package/dist/utils/retry.js +19 -0
  206. package/dist/utils/retry.js.map +1 -0
  207. package/package.json +81 -0
package/dist/cli.js ADDED
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import { runExplore, runInit, runPipeline, runStatus } from './orchestrator.js';
4
+ const program = new Command();
5
+ program
6
+ .name('bemadralphy')
7
+ .description('CLI orchestrator for end-to-end automated coding pipelines')
8
+ .version('0.1.0');
9
+ program
10
+ .command('init')
11
+ .description('Initialize BMAD, Beads, and BeMadRalphy config')
12
+ .action(async () => {
13
+ await runInit();
14
+ });
15
+ program
16
+ .command('run')
17
+ .description('Run the full pipeline')
18
+ .option('--mode <mode>', 'Autonomy mode: auto|hybrid|supervised', 'hybrid')
19
+ .option('--engine <name>', 'AI engine to use')
20
+ .option('--planning-engine <name>', 'Override engine for planning phase only')
21
+ .option('--max-parallel <n>', 'Max parallel tasks', (v) => Number(v), 3)
22
+ .option('--budget <usd>', 'Cost cap in USD', (v) => Number(v))
23
+ .option('--brownfield', 'Force brownfield mode', false)
24
+ .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);
29
+ });
30
+ program
31
+ .command('explore <query>')
32
+ .description('Investigate a codebase or domain before planning')
33
+ .action(async (query) => {
34
+ await runExplore(query);
35
+ });
36
+ program
37
+ .command('status')
38
+ .description('Show pipeline status')
39
+ .action(async () => {
40
+ await runStatus();
41
+ });
42
+ program.parse();
43
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +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"}
package/dist/cost.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ export declare class CostTracker {
2
+ private totalUsd;
3
+ addCost(amountUsd: number): void;
4
+ getTotal(): number;
5
+ persist(projectRoot: string): Promise<void>;
6
+ }
package/dist/cost.js ADDED
@@ -0,0 +1,18 @@
1
+ import { mkdir, writeFile } from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ export class CostTracker {
4
+ totalUsd = 0;
5
+ addCost(amountUsd) {
6
+ this.totalUsd += amountUsd;
7
+ }
8
+ getTotal() {
9
+ return this.totalUsd;
10
+ }
11
+ async persist(projectRoot) {
12
+ const dir = path.join(projectRoot, '.bemadralphy');
13
+ await mkdir(dir, { recursive: true });
14
+ const costPath = path.join(dir, 'cost.log');
15
+ await writeFile(costPath, `${this.totalUsd}\n`, 'utf-8');
16
+ }
17
+ }
18
+ //# sourceMappingURL=cost.js.map
@@ -0,0 +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"}
@@ -0,0 +1,8 @@
1
+ export type PrBodyInput = {
2
+ title: string;
3
+ summary: string;
4
+ changes: string[];
5
+ tests: string[];
6
+ linkedIssues?: string[];
7
+ };
8
+ export declare function generatePrBody(input: PrBodyInput): string;
@@ -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 @@
1
+ export declare const claudeAdapter: import("./types.js").EngineAdapter;
@@ -0,0 +1,11 @@
1
+ import { createCliAdapter } from './cli-adapter.js';
2
+ export const claudeAdapter = createCliAdapter({
3
+ name: 'claude',
4
+ commandName: 'ralphy',
5
+ hasNativeSwarm: true,
6
+ permissionFlags: ['--dangerously-skip-permissions'],
7
+ buildArgs: (_task, prompt) => ['--claude', '--max-iterations', '1', prompt],
8
+ unavailableHint: 'Install ralphy and ensure it is on PATH.',
9
+ failureHint: 'Ensure Claude access is configured in ralphy.',
10
+ });
11
+ //# sourceMappingURL=claude.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/engines/claude.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,IAAI;IACpB,eAAe,EAAE,CAAC,gCAAgC,CAAC;IACnD,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC,UAAU,EAAE,kBAAkB,EAAE,GAAG,EAAE,MAAM,CAAC;IAC3E,eAAe,EAAE,0CAA0C;IAC3D,WAAW,EAAE,+CAA+C;CAC7D,CAAC,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { EngineAdapter, EngineTask } from './types.js';
2
+ type CliAdapterOptions = {
3
+ name: string;
4
+ commandName: string;
5
+ hasNativeSwarm: boolean;
6
+ permissionFlags?: string[];
7
+ buildArgs: (task: EngineTask, prompt: string) => string[];
8
+ unavailableHint?: string;
9
+ failureHint?: string;
10
+ };
11
+ export declare function createCliAdapter(options: CliAdapterOptions): EngineAdapter;
12
+ export {};
@@ -0,0 +1,36 @@
1
+ import { commandExists, runCommand } from '../utils/exec.js';
2
+ function taskPrompt(task) {
3
+ const description = task.description?.trim() ? `\n\n${task.description.trim()}` : '';
4
+ return `Task ID: ${task.id}\nTitle: ${task.title}${description}`;
5
+ }
6
+ export function createCliAdapter(options) {
7
+ const permissionFlags = options.permissionFlags ?? [];
8
+ return {
9
+ name: options.name,
10
+ hasNativeSwarm: options.hasNativeSwarm,
11
+ permissionFlags,
12
+ async checkAvailable() {
13
+ return commandExists(options.commandName);
14
+ },
15
+ async execute(task, executeOptions) {
16
+ const cwd = executeOptions.cwd;
17
+ const prompt = taskPrompt(task);
18
+ const args = options.buildArgs(task, prompt);
19
+ if (executeOptions.dryRun) {
20
+ return { status: 'skipped', output: `${options.name} dry run: ${task.id}` };
21
+ }
22
+ try {
23
+ const result = await runCommand(options.commandName, args, cwd);
24
+ return { status: 'success', output: result.stdout.trim() || result.stderr.trim() };
25
+ }
26
+ catch (error) {
27
+ const hint = options.failureHint ?? options.unavailableHint;
28
+ return {
29
+ status: 'failed',
30
+ error: `engine "${options.name}" failed: ${error.message}${hint ? ` (${hint})` : ''}`,
31
+ };
32
+ }
33
+ },
34
+ };
35
+ }
36
+ //# sourceMappingURL=cli-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-adapter.js","sourceRoot":"","sources":["../../src/engines/cli-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAa7D,SAAS,UAAU,CAAC,IAAgB;IAClC,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACrF,OAAO,YAAY,IAAI,CAAC,EAAE,YAAY,IAAI,CAAC,KAAK,GAAG,WAAW,EAAE,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,OAA0B;IACzD,MAAM,eAAe,GAAG,OAAO,CAAC,eAAe,IAAI,EAAE,CAAC;IAEtD,OAAO;QACL,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,cAAc,EAAE,OAAO,CAAC,cAAc;QACtC,eAAe;QACf,KAAK,CAAC,cAAc;YAClB,OAAO,aAAa,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QAC5C,CAAC;QACD,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,cAAc;YAChC,MAAM,GAAG,GAAG,cAAc,CAAC,GAAG,CAAC;YAC/B,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;YAChC,MAAM,IAAI,GAAG,OAAO,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YAE7C,IAAI,cAAc,CAAC,MAAM,EAAE,CAAC;gBAC1B,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,aAAa,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC;YAC9E,CAAC;YAED,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,WAAW,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;gBAChE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;YACrF,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,IAAI,GAAG,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,eAAe,CAAC;gBAC5D,OAAO;oBACL,MAAM,EAAE,QAAQ;oBAChB,KAAK,EAAE,WAAW,OAAO,CAAC,IAAI,aAAc,KAAe,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;iBACjG,CAAC;YACJ,CAAC;QACH,CAAC;KACF,CAAC;AACJ,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 @@
1
+ export declare const codexAdapter: import("./types.js").EngineAdapter;
@@ -0,0 +1,10 @@
1
+ import { createCliAdapter } from './cli-adapter.js';
2
+ export const codexAdapter = createCliAdapter({
3
+ name: 'codex',
4
+ commandName: 'ralphy',
5
+ hasNativeSwarm: true,
6
+ buildArgs: (_task, prompt) => ['--codex', '--max-iterations', '1', prompt],
7
+ unavailableHint: 'Install ralphy and ensure it is on PATH.',
8
+ failureHint: 'Ensure Codex access is configured in ralphy.',
9
+ });
10
+ //# sourceMappingURL=codex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex.js","sourceRoot":"","sources":["../../src/engines/codex.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpD,MAAM,CAAC,MAAM,YAAY,GAAG,gBAAgB,CAAC;IAC3C,IAAI,EAAE,OAAO;IACb,WAAW,EAAE,QAAQ;IACrB,cAAc,EAAE,IAAI;IACpB,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC,SAAS,EAAE,kBAAkB,EAAE,GAAG,EAAE,MAAM,CAAC;IAC1E,eAAe,EAAE,0CAA0C;IAC3D,WAAW,EAAE,8CAA8C;CAC5D,CAAC,CAAC"}
@@ -0,0 +1 @@
1
+ export declare const copilotAdapter: import("./types.js").EngineAdapter;
@@ -0,0 +1,10 @@
1
+ import { createCliAdapter } from './cli-adapter.js';
2
+ export const copilotAdapter = createCliAdapter({
3
+ name: 'copilot',
4
+ commandName: 'ralphy',
5
+ hasNativeSwarm: false,
6
+ buildArgs: (_task, prompt) => ['--copilot', '--max-iterations', '1', prompt],
7
+ unavailableHint: 'Install ralphy and ensure it is on PATH.',
8
+ failureHint: 'Ensure GitHub Copilot integration is configured in ralphy.',
9
+ });
10
+ //# sourceMappingURL=copilot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"copilot.js","sourceRoot":"","sources":["../../src/engines/copilot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpD,MAAM,CAAC,MAAM,cAAc,GAAG,gBAAgB,CAAC;IAC7C,IAAI,EAAE,SAAS;IACf,WAAW,EAAE,QAAQ;IACrB,cAAc,EAAE,KAAK;IACrB,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,kBAAkB,EAAE,GAAG,EAAE,MAAM,CAAC;IAC5E,eAAe,EAAE,0CAA0C;IAC3D,WAAW,EAAE,4DAA4D;CAC1E,CAAC,CAAC"}
@@ -0,0 +1 @@
1
+ export declare const cursorAdapter: import("./types.js").EngineAdapter;
@@ -0,0 +1,10 @@
1
+ import { createCliAdapter } from './cli-adapter.js';
2
+ export const cursorAdapter = createCliAdapter({
3
+ name: 'cursor',
4
+ commandName: 'ralphy',
5
+ hasNativeSwarm: false,
6
+ buildArgs: (_task, prompt) => ['--cursor', '--max-iterations', '1', prompt],
7
+ unavailableHint: 'Install ralphy and ensure it is on PATH.',
8
+ failureHint: 'Ensure Cursor integration is configured in ralphy.',
9
+ });
10
+ //# sourceMappingURL=cursor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor.js","sourceRoot":"","sources":["../../src/engines/cursor.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,CAAC,CAAC,UAAU,EAAE,kBAAkB,EAAE,GAAG,EAAE,MAAM,CAAC;IAC3E,eAAe,EAAE,0CAA0C;IAC3D,WAAW,EAAE,oDAAoD;CAClE,CAAC,CAAC"}
@@ -0,0 +1 @@
1
+ export declare const geminiAdapter: import("./types.js").EngineAdapter;
@@ -0,0 +1,10 @@
1
+ import { createCliAdapter } from './cli-adapter.js';
2
+ export const geminiAdapter = createCliAdapter({
3
+ name: 'gemini',
4
+ commandName: 'gemini',
5
+ hasNativeSwarm: false,
6
+ buildArgs: (_task, prompt) => [prompt],
7
+ unavailableHint: 'Install Gemini CLI and ensure it is on PATH.',
8
+ failureHint: 'Ensure Gemini CLI is authenticated.',
9
+ });
10
+ //# sourceMappingURL=gemini.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gemini.js","sourceRoot":"","sources":["../../src/engines/gemini.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,CAAC,CAAC,MAAM,CAAC;IACtC,eAAe,EAAE,8CAA8C;IAC/D,WAAW,EAAE,qCAAqC;CACnD,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { EngineAdapter } from './types.js';
2
+ export declare const engineAdapters: Record<string, EngineAdapter>;
@@ -0,0 +1,21 @@
1
+ import { claudeAdapter } from './claude.js';
2
+ import { codexAdapter } from './codex.js';
3
+ import { copilotAdapter } from './copilot.js';
4
+ import { cursorAdapter } from './cursor.js';
5
+ import { geminiAdapter } from './gemini.js';
6
+ import { kimiAdapter } from './kimi.js';
7
+ import { opencodeAdapter } from './opencode.js';
8
+ import { qwenAdapter } from './qwen.js';
9
+ import { ralphyAdapter } from './ralphy.js';
10
+ export const engineAdapters = {
11
+ claude: claudeAdapter,
12
+ codex: codexAdapter,
13
+ copilot: copilotAdapter,
14
+ cursor: cursorAdapter,
15
+ gemini: geminiAdapter,
16
+ kimi: kimiAdapter,
17
+ opencode: opencodeAdapter,
18
+ qwen: qwenAdapter,
19
+ ralphy: ralphyAdapter,
20
+ };
21
+ //# sourceMappingURL=index.js.map
@@ -0,0 +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"}
@@ -0,0 +1 @@
1
+ export declare const kimiAdapter: import("./types.js").EngineAdapter;
@@ -0,0 +1,10 @@
1
+ import { createCliAdapter } from './cli-adapter.js';
2
+ export const kimiAdapter = createCliAdapter({
3
+ name: 'kimi',
4
+ commandName: 'kimi',
5
+ hasNativeSwarm: true,
6
+ buildArgs: (_task, prompt) => [prompt],
7
+ unavailableHint: 'Install Kimi CLI and ensure it is on PATH.',
8
+ failureHint: 'Ensure Kimi CLI is authenticated.',
9
+ });
10
+ //# sourceMappingURL=kimi.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kimi.js","sourceRoot":"","sources":["../../src/engines/kimi.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpD,MAAM,CAAC,MAAM,WAAW,GAAG,gBAAgB,CAAC;IAC1C,IAAI,EAAE,MAAM;IACZ,WAAW,EAAE,MAAM;IACnB,cAAc,EAAE,IAAI;IACpB,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC;IACtC,eAAe,EAAE,4CAA4C;IAC7D,WAAW,EAAE,mCAAmC;CACjD,CAAC,CAAC"}
@@ -0,0 +1 @@
1
+ export declare const opencodeAdapter: import("./types.js").EngineAdapter;
@@ -0,0 +1,10 @@
1
+ import { createCliAdapter } from './cli-adapter.js';
2
+ export const opencodeAdapter = createCliAdapter({
3
+ name: 'opencode',
4
+ commandName: 'ralphy',
5
+ hasNativeSwarm: false,
6
+ buildArgs: (_task, prompt) => ['--opencode', '--max-iterations', '1', prompt],
7
+ unavailableHint: 'Install ralphy and ensure it is on PATH.',
8
+ failureHint: 'Ensure OpenCode integration is configured in ralphy.',
9
+ });
10
+ //# sourceMappingURL=opencode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opencode.js","sourceRoot":"","sources":["../../src/engines/opencode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpD,MAAM,CAAC,MAAM,eAAe,GAAG,gBAAgB,CAAC;IAC9C,IAAI,EAAE,UAAU;IAChB,WAAW,EAAE,QAAQ;IACrB,cAAc,EAAE,KAAK;IACrB,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC,YAAY,EAAE,kBAAkB,EAAE,GAAG,EAAE,MAAM,CAAC;IAC7E,eAAe,EAAE,0CAA0C;IAC3D,WAAW,EAAE,sDAAsD;CACpE,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { EngineTask } from './types.js';
2
+ export declare function renderTaskPrompt(projectRoot: string, task: EngineTask): Promise<string>;
@@ -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 @@
1
+ export declare const qwenAdapter: import("./types.js").EngineAdapter;
@@ -0,0 +1,10 @@
1
+ import { createCliAdapter } from './cli-adapter.js';
2
+ export const qwenAdapter = createCliAdapter({
3
+ name: 'qwen',
4
+ commandName: 'ralphy',
5
+ hasNativeSwarm: false,
6
+ buildArgs: (_task, prompt) => ['--qwen', '--max-iterations', '1', prompt],
7
+ unavailableHint: 'Install ralphy and ensure it is on PATH.',
8
+ failureHint: 'Ensure Qwen integration is configured in ralphy.',
9
+ });
10
+ //# sourceMappingURL=qwen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qwen.js","sourceRoot":"","sources":["../../src/engines/qwen.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpD,MAAM,CAAC,MAAM,WAAW,GAAG,gBAAgB,CAAC;IAC1C,IAAI,EAAE,MAAM;IACZ,WAAW,EAAE,QAAQ;IACrB,cAAc,EAAE,KAAK;IACrB,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC,QAAQ,EAAE,kBAAkB,EAAE,GAAG,EAAE,MAAM,CAAC;IACzE,eAAe,EAAE,0CAA0C;IAC3D,WAAW,EAAE,kDAAkD;CAChE,CAAC,CAAC"}
@@ -0,0 +1 @@
1
+ export declare const ralphyAdapter: import("./types.js").EngineAdapter;
@@ -0,0 +1,10 @@
1
+ import { createCliAdapter } from './cli-adapter.js';
2
+ export const ralphyAdapter = createCliAdapter({
3
+ name: 'ralphy',
4
+ commandName: 'ralphy',
5
+ hasNativeSwarm: false,
6
+ buildArgs: (_task, prompt) => ['--max-iterations', '1', prompt],
7
+ unavailableHint: 'Install ralphy and ensure it is on PATH.',
8
+ failureHint: 'Ensure ralphy is initialized and authenticated.',
9
+ });
10
+ //# sourceMappingURL=ralphy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ralphy.js","sourceRoot":"","sources":["../../src/engines/ralphy.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,CAAC,CAAC,kBAAkB,EAAE,GAAG,EAAE,MAAM,CAAC;IAC/D,eAAe,EAAE,0CAA0C;IAC3D,WAAW,EAAE,iDAAiD;CAC/D,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { EngineAdapter } from './types.js';
2
+ export declare function createStubAdapter(name: string, hasNativeSwarm: boolean, permissionFlags?: string[], commandName?: string): EngineAdapter;
@@ -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,21 @@
1
+ export type EngineTask = {
2
+ id: string;
3
+ title: string;
4
+ description?: string;
5
+ };
6
+ export type ExecuteOptions = {
7
+ cwd?: string;
8
+ dryRun?: boolean;
9
+ };
10
+ export type TaskResult = {
11
+ status: 'success' | 'failed' | 'skipped';
12
+ output?: string;
13
+ error?: string;
14
+ };
15
+ export interface EngineAdapter {
16
+ name: string;
17
+ hasNativeSwarm: boolean;
18
+ permissionFlags: string[];
19
+ checkAvailable(): Promise<boolean>;
20
+ execute(task: EngineTask, options: ExecuteOptions): Promise<TaskResult>;
21
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map