rlph-cli 0.1.0 → 1.0.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 (71) hide show
  1. package/README.md +79 -40
  2. package/dist/agents/claude-events.d.ts +45 -0
  3. package/dist/agents/claude-events.d.ts.map +1 -0
  4. package/dist/agents/claude-events.js +2 -0
  5. package/dist/agents/claude-events.js.map +1 -0
  6. package/dist/agents/claude-formatter.d.ts +3 -0
  7. package/dist/agents/claude-formatter.d.ts.map +1 -0
  8. package/dist/agents/claude-formatter.js +45 -0
  9. package/dist/agents/claude-formatter.js.map +1 -0
  10. package/dist/agents/claude.d.ts.map +1 -1
  11. package/dist/agents/claude.js +27 -40
  12. package/dist/agents/claude.js.map +1 -1
  13. package/dist/commands/prd-add.d.ts +5 -0
  14. package/dist/commands/prd-add.d.ts.map +1 -0
  15. package/dist/commands/prd-add.js +72 -0
  16. package/dist/commands/prd-add.js.map +1 -0
  17. package/dist/commands/prd-list.d.ts +2 -0
  18. package/dist/commands/prd-list.d.ts.map +1 -0
  19. package/dist/commands/prd-list.js +47 -0
  20. package/dist/commands/prd-list.js.map +1 -0
  21. package/dist/commands/run.d.ts +1 -2
  22. package/dist/commands/run.d.ts.map +1 -1
  23. package/dist/commands/run.js +43 -23
  24. package/dist/commands/run.js.map +1 -1
  25. package/dist/index.js +13 -2
  26. package/dist/index.js.map +1 -1
  27. package/dist/prd/index.d.ts +3 -0
  28. package/dist/prd/index.d.ts.map +1 -0
  29. package/dist/prd/index.js +3 -0
  30. package/dist/prd/index.js.map +1 -0
  31. package/dist/prd/manager.d.ts +9 -0
  32. package/dist/prd/manager.d.ts.map +1 -0
  33. package/dist/prd/manager.js +68 -0
  34. package/dist/prd/manager.js.map +1 -0
  35. package/dist/prd/types.d.ts +25 -0
  36. package/dist/prd/types.d.ts.map +1 -0
  37. package/dist/prd/types.js +2 -0
  38. package/dist/prd/types.js.map +1 -0
  39. package/dist/templates/index.d.ts +2 -0
  40. package/dist/templates/index.d.ts.map +1 -0
  41. package/dist/templates/index.js +2 -0
  42. package/dist/templates/index.js.map +1 -0
  43. package/dist/templates/templates.d.ts +6 -0
  44. package/dist/templates/templates.d.ts.map +1 -0
  45. package/dist/templates/templates.js +47 -0
  46. package/dist/templates/templates.js.map +1 -0
  47. package/dist/utils/index.d.ts +1 -1
  48. package/dist/utils/index.d.ts.map +1 -1
  49. package/dist/utils/index.js +1 -1
  50. package/dist/utils/index.js.map +1 -1
  51. package/dist/utils/ndjson.d.ts +12 -0
  52. package/dist/utils/ndjson.d.ts.map +1 -0
  53. package/dist/utils/ndjson.js +43 -0
  54. package/dist/utils/ndjson.js.map +1 -0
  55. package/package.json +11 -2
  56. package/dist/session/index.d.ts +0 -3
  57. package/dist/session/index.d.ts.map +0 -1
  58. package/dist/session/index.js +0 -3
  59. package/dist/session/index.js.map +0 -1
  60. package/dist/session/logger.d.ts +0 -10
  61. package/dist/session/logger.d.ts.map +0 -1
  62. package/dist/session/logger.js +0 -17
  63. package/dist/session/logger.js.map +0 -1
  64. package/dist/session/manager.d.ts +0 -18
  65. package/dist/session/manager.d.ts.map +0 -1
  66. package/dist/session/manager.js +0 -29
  67. package/dist/session/manager.js.map +0 -1
  68. package/dist/utils/files.d.ts +0 -4
  69. package/dist/utils/files.d.ts.map +0 -1
  70. package/dist/utils/files.js +0 -39
  71. package/dist/utils/files.js.map +0 -1
@@ -1,8 +1,11 @@
1
1
  import chalk from 'chalk';
2
+ import { mkdir, writeFile } from 'node:fs/promises';
3
+ import { join } from 'node:path';
2
4
  import { getAgent, isValidAgent } from '../agents/index.js';
3
- import { createSession, writeLog, getSessionDir } from '../session/index.js';
4
- import { buildPrompt, COMPLETION_MARKER } from '../utils/index.js';
5
- export async function run(opts) {
5
+ import { getPrd, getPrdDir, prdExists } from '../prd/index.js';
6
+ import { ensureTemplates, loadTemplate, substituteVars } from '../templates/index.js';
7
+ const TASKS_COMPLETE_MARKER = '<tasks>COMPLETE</tasks>';
8
+ export async function run(prdName, opts) {
6
9
  // Validate agent
7
10
  if (!isValidAgent(opts.agent)) {
8
11
  console.error(chalk.red(`Unknown agent: ${opts.agent}`));
@@ -15,25 +18,30 @@ export async function run(opts) {
15
18
  console.error(chalk.red(`Iterations must be a positive number, got: ${opts.iterations}`));
16
19
  process.exit(1);
17
20
  }
18
- const agent = getAgent(opts.agent);
19
- // Build prompt with completion instructions
20
- let prompt;
21
- try {
22
- prompt = await buildPrompt(opts.prompt);
23
- }
24
- catch (err) {
25
- const message = err instanceof Error ? err.message : String(err);
26
- console.error(chalk.red(`Failed to read prompt files: ${message}`));
21
+ // Validate PRD exists
22
+ if (!(await prdExists(prdName))) {
23
+ console.error(chalk.red(`PRD not found: ${prdName}`));
27
24
  process.exit(1);
28
25
  }
29
- // Create session
30
- const sessionId = await createSession({
31
- promptFiles: opts.prompt,
32
- agent: opts.agent,
33
- iterations,
26
+ const prd = await getPrd(prdName);
27
+ const prdDir = getPrdDir(prdName);
28
+ const prdJsonPath = join(prdDir, 'prd.json');
29
+ const iterationsDir = join(prdDir, 'iterations');
30
+ // Create iterations directory
31
+ await mkdir(iterationsDir, { recursive: true });
32
+ // Load and substitute template
33
+ await ensureTemplates();
34
+ const template = await loadTemplate('complete-next-task');
35
+ const prompt = substituteVars(template, {
36
+ PRD_NAME: prdName,
37
+ PRD_PATH: prdJsonPath,
38
+ CWD: process.cwd(),
34
39
  });
35
- console.log(chalk.blue(`Session: ${sessionId}`));
40
+ const agent = getAgent(opts.agent);
41
+ const pendingTasks = prd.tasks.filter((t) => !t.passes).length;
42
+ console.log(chalk.blue(`PRD: ${prdName}`));
36
43
  console.log(chalk.gray(`Agent: ${agent.name}`));
44
+ console.log(chalk.gray(`Pending tasks: ${pendingTasks}/${prd.tasks.length}`));
37
45
  console.log(chalk.gray(`Iterations: ${iterations}`));
38
46
  console.log();
39
47
  // Run loop
@@ -47,7 +55,7 @@ export async function run(opts) {
47
55
  onOutput: (chunk) => process.stdout.write(chunk),
48
56
  });
49
57
  console.log();
50
- await writeLog(sessionId, i, result);
58
+ await writeIterationLog(iterationsDir, i, result);
51
59
  if (result.exitCode !== 0) {
52
60
  console.log(chalk.red(` Exit code: ${result.exitCode}`));
53
61
  }
@@ -55,19 +63,31 @@ export async function run(opts) {
55
63
  console.log(chalk.green(` Done (${result.duration}ms)`));
56
64
  }
57
65
  // Check for completion marker
58
- if (result.output.includes(COMPLETION_MARKER)) {
59
- console.log(chalk.cyan(` Agent signaled task complete`));
66
+ if (result.output.includes(TASKS_COMPLETE_MARKER)) {
67
+ console.log(chalk.cyan(` All tasks complete`));
60
68
  completed = true;
61
69
  break;
62
70
  }
63
71
  }
64
72
  console.log();
65
73
  if (completed) {
66
- console.log(chalk.green(`Task completed after ${actualIterations} iteration(s)`));
74
+ console.log(chalk.green(`PRD completed after ${actualIterations} iteration(s)`));
67
75
  }
68
76
  else {
69
77
  console.log(chalk.yellow(`Reached max iterations (${iterations})`));
70
78
  }
71
- console.log(chalk.gray(`Logs: ${getSessionDir(sessionId)}`));
79
+ console.log(chalk.gray(`Logs: ${iterationsDir}`));
80
+ }
81
+ async function writeIterationLog(iterationsDir, iteration, result) {
82
+ const logPath = join(iterationsDir, `${iteration}.log`);
83
+ const header = [
84
+ `# Iteration ${iteration}`,
85
+ `Timestamp: ${new Date().toISOString()}`,
86
+ `Duration: ${result.duration}ms`,
87
+ `Exit Code: ${result.exitCode}`,
88
+ '---',
89
+ '',
90
+ ].join('\n');
91
+ await writeFile(logPath, header + result.output);
72
92
  }
73
93
  //# sourceMappingURL=run.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAC3D,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAC5E,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAQlE,MAAM,CAAC,KAAK,UAAU,GAAG,CAAC,IAAgB;IACxC,iBAAiB;IACjB,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC9B,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,kBAAkB,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAA;QACxD,OAAO,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAA;QACzC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,sBAAsB;IACtB,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC,CAAA;IAChD,IAAI,KAAK,CAAC,UAAU,CAAC,IAAI,UAAU,IAAI,CAAC,EAAE,CAAC;QACzC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,8CAA8C,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAA;QACzF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IAElC,4CAA4C;IAC5C,IAAI,MAAc,CAAA;IAClB,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IACzC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QAChE,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,gCAAgC,OAAO,EAAE,CAAC,CAAC,CAAA;QACnE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,iBAAiB;IACjB,MAAM,SAAS,GAAG,MAAM,aAAa,CAAC;QACpC,WAAW,EAAE,IAAI,CAAC,MAAM;QACxB,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,UAAU;KACX,CAAC,CAAA;IAEF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,SAAS,EAAE,CAAC,CAAC,CAAA;IAChD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA;IAC/C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,eAAe,UAAU,EAAE,CAAC,CAAC,CAAA;IACpD,OAAO,CAAC,GAAG,EAAE,CAAA;IAEb,WAAW;IACX,IAAI,SAAS,GAAG,KAAK,CAAA;IACrB,IAAI,gBAAgB,GAAG,CAAC,CAAA;IAExB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC;QACpC,gBAAgB,EAAE,CAAA;QAClB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,UAAU,aAAa,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,CAAA;QAC9E,OAAO,CAAC,GAAG,EAAE,CAAA;QAEb,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE;YACxD,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC;SACjD,CAAC,CAAA;QAEF,OAAO,CAAC,GAAG,EAAE,CAAA;QACb,MAAM,QAAQ,CAAC,SAAS,EAAE,CAAC,EAAE,MAAM,CAAC,CAAA;QAEpC,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,gBAAgB,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAA;QAC3D,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,WAAW,MAAM,CAAC,QAAQ,KAAK,CAAC,CAAC,CAAA;QAC3D,CAAC;QAED,8BAA8B;QAC9B,IAAI,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC;YAC9C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC,CAAA;YACzD,SAAS,GAAG,IAAI,CAAA;YAChB,MAAK;QACP,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,EAAE,CAAA;IACb,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,wBAAwB,gBAAgB,eAAe,CAAC,CAAC,CAAA;IACnF,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,2BAA2B,UAAU,GAAG,CAAC,CAAC,CAAA;IACrE,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,aAAa,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAA;AAC9D,CAAC"}
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,16 +1,27 @@
1
1
  #!/usr/bin/env node
2
2
  import { program } from 'commander';
3
3
  import { run } from './commands/run.js';
4
+ import { prdAdd } from './commands/prd-add.js';
5
+ import { prdList } from './commands/prd-list.js';
4
6
  program
5
7
  .name('ralph')
6
8
  .description('Loop coding agent CLI - run agents headlessly in a loop')
7
9
  .version('0.1.0');
8
10
  program
9
11
  .command('run')
10
- .description('Run an agent in a loop')
11
- .requiredOption('-p, --prompt <files...>', 'Prompt files to pass to agent')
12
+ .description('Run PRD tasks in a loop')
13
+ .argument('<prd-name>', 'Name of PRD to run')
12
14
  .option('-a, --agent <agent>', 'Agent type', 'claude')
13
15
  .option('-i, --iterations <n>', 'Number of loop iterations', '4')
14
16
  .action(run);
17
+ const prd = program.command('prd').description('Manage PRDs');
18
+ prd
19
+ .command('add')
20
+ .description('Add a new PRD from markdown file')
21
+ .argument('<path>', 'Path to PRD markdown file')
22
+ .argument('<name>', 'Name for the PRD')
23
+ .option('-a, --agent <agent>', 'Agent type', 'claude')
24
+ .action(prdAdd);
25
+ prd.command('list').description('List all PRDs').action(prdList);
15
26
  program.parse();
16
27
  //# 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":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAA;AAEvC,OAAO;KACJ,IAAI,CAAC,OAAO,CAAC;KACb,WAAW,CAAC,yDAAyD,CAAC;KACtE,OAAO,CAAC,OAAO,CAAC,CAAA;AAEnB,OAAO;KACJ,OAAO,CAAC,KAAK,CAAC;KACd,WAAW,CAAC,wBAAwB,CAAC;KACrC,cAAc,CAAC,yBAAyB,EAAE,+BAA+B,CAAC;KAC1E,MAAM,CAAC,qBAAqB,EAAE,YAAY,EAAE,QAAQ,CAAC;KACrD,MAAM,CAAC,sBAAsB,EAAE,2BAA2B,EAAE,GAAG,CAAC;KAChE,MAAM,CAAC,GAAG,CAAC,CAAA;AAEd,OAAO,CAAC,KAAK,EAAE,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAA;AACvC,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAA;AAEhD,OAAO;KACJ,IAAI,CAAC,OAAO,CAAC;KACb,WAAW,CAAC,yDAAyD,CAAC;KACtE,OAAO,CAAC,OAAO,CAAC,CAAA;AAEnB,OAAO;KACJ,OAAO,CAAC,KAAK,CAAC;KACd,WAAW,CAAC,yBAAyB,CAAC;KACtC,QAAQ,CAAC,YAAY,EAAE,oBAAoB,CAAC;KAC5C,MAAM,CAAC,qBAAqB,EAAE,YAAY,EAAE,QAAQ,CAAC;KACrD,MAAM,CAAC,sBAAsB,EAAE,2BAA2B,EAAE,GAAG,CAAC;KAChE,MAAM,CAAC,GAAG,CAAC,CAAA;AAEd,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,aAAa,CAAC,CAAA;AAE7D,GAAG;KACA,OAAO,CAAC,KAAK,CAAC;KACd,WAAW,CAAC,kCAAkC,CAAC;KAC/C,QAAQ,CAAC,QAAQ,EAAE,2BAA2B,CAAC;KAC/C,QAAQ,CAAC,QAAQ,EAAE,kBAAkB,CAAC;KACtC,MAAM,CAAC,qBAAqB,EAAE,YAAY,EAAE,QAAQ,CAAC;KACrD,MAAM,CAAC,MAAM,CAAC,CAAA;AAEjB,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;AAEhE,OAAO,CAAC,KAAK,EAAE,CAAA"}
@@ -0,0 +1,3 @@
1
+ export * from './types.js';
2
+ export * from './manager.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/prd/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,cAAc,cAAc,CAAA"}
@@ -0,0 +1,3 @@
1
+ export * from './types.js';
2
+ export * from './manager.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/prd/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,cAAc,cAAc,CAAA"}
@@ -0,0 +1,9 @@
1
+ import type { PrdJson, PrdStatus } from './types.js';
2
+ export declare function getPrdsDir(): string;
3
+ export declare function getPrdDir(name: string): string;
4
+ export declare function prdExists(name: string): Promise<boolean>;
5
+ export declare function createPrdFolder(name: string): Promise<void>;
6
+ export declare function copyMarkdown(src: string, name: string): Promise<void>;
7
+ export declare function getPrd(name: string): Promise<PrdJson>;
8
+ export declare function listPrds(): Promise<PrdStatus[]>;
9
+ //# sourceMappingURL=manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/prd/manager.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAiB,MAAM,YAAY,CAAA;AAEnE,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAO9D;AAED,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEjE;AAED,wBAAsB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG3E;AAED,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAI3D;AASD,wBAAsB,QAAQ,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC,CA+BrD"}
@@ -0,0 +1,68 @@
1
+ import { access, copyFile, mkdir, readdir, readFile } from 'node:fs/promises';
2
+ import { homedir } from 'node:os';
3
+ import { join } from 'node:path';
4
+ export function getPrdsDir() {
5
+ return join(homedir(), '.ralph', 'prd');
6
+ }
7
+ export function getPrdDir(name) {
8
+ return join(getPrdsDir(), name);
9
+ }
10
+ export async function prdExists(name) {
11
+ try {
12
+ await access(getPrdDir(name));
13
+ return true;
14
+ }
15
+ catch {
16
+ return false;
17
+ }
18
+ }
19
+ export async function createPrdFolder(name) {
20
+ await mkdir(getPrdDir(name), { recursive: true });
21
+ }
22
+ export async function copyMarkdown(src, name) {
23
+ const dest = join(getPrdDir(name), 'prd.md');
24
+ await copyFile(src, dest);
25
+ }
26
+ export async function getPrd(name) {
27
+ const prdPath = join(getPrdDir(name), 'prd.json');
28
+ const content = await readFile(prdPath, 'utf-8');
29
+ return JSON.parse(content);
30
+ }
31
+ function computeStatus(prd) {
32
+ const completed = prd.tasks.filter((t) => t.passes).length;
33
+ if (completed === 0)
34
+ return 'pending';
35
+ if (completed === prd.tasks.length)
36
+ return 'completed';
37
+ return 'in_progress';
38
+ }
39
+ export async function listPrds() {
40
+ const prdsDir = getPrdsDir();
41
+ let entries;
42
+ try {
43
+ entries = await readdir(prdsDir);
44
+ }
45
+ catch {
46
+ return [];
47
+ }
48
+ const results = [];
49
+ for (const entry of entries) {
50
+ try {
51
+ const prd = await getPrd(entry);
52
+ const status = computeStatus(prd);
53
+ const tasksCompleted = prd.tasks.filter((t) => t.passes).length;
54
+ results.push({
55
+ name: prd.prdName,
56
+ description: prd.tasks[0]?.description ?? '',
57
+ status,
58
+ tasksTotal: prd.tasks.length,
59
+ tasksCompleted,
60
+ });
61
+ }
62
+ catch {
63
+ // Skip invalid PRD folders
64
+ }
65
+ }
66
+ return results;
67
+ }
68
+ //# sourceMappingURL=manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/prd/manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ export interface PrdTask {
2
+ id: string;
3
+ category: string;
4
+ description: string;
5
+ steps: string[];
6
+ passes: boolean;
7
+ }
8
+ export interface PrdJson {
9
+ prdName: string;
10
+ tasks: PrdTask[];
11
+ context?: {
12
+ patterns?: string[];
13
+ keyFiles?: string[];
14
+ nonGoals?: string[];
15
+ };
16
+ }
17
+ export type PrdStatusType = 'pending' | 'in_progress' | 'completed';
18
+ export interface PrdStatus {
19
+ name: string;
20
+ description: string;
21
+ status: PrdStatusType;
22
+ tasksTotal: number;
23
+ tasksCompleted: number;
24
+ }
25
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/prd/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAA;IACV,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;IACnB,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,MAAM,EAAE,OAAO,CAAA;CAChB;AAED,MAAM,WAAW,OAAO;IACtB,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,OAAO,EAAE,CAAA;IAChB,OAAO,CAAC,EAAE;QACR,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;QACnB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;QACnB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;KACpB,CAAA;CACF;AAED,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,aAAa,GAAG,WAAW,CAAA;AAEnE,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,aAAa,CAAA;IACrB,UAAU,EAAE,MAAM,CAAA;IAClB,cAAc,EAAE,MAAM,CAAA;CACvB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/prd/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export * from './templates.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/templates/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAA"}
@@ -0,0 +1,2 @@
1
+ export * from './templates.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/templates/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAA"}
@@ -0,0 +1,6 @@
1
+ export declare function getTemplatesDir(): string;
2
+ export declare function getBundledTemplatesDir(): string;
3
+ export declare function ensureTemplates(): Promise<void>;
4
+ export declare function loadTemplate(name: string): Promise<string>;
5
+ export declare function substituteVars(template: string, vars: Record<string, string>): string;
6
+ //# sourceMappingURL=templates.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/templates/templates.ts"],"names":[],"mappings":"AAOA,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,wBAAgB,sBAAsB,IAAI,MAAM,CAE/C;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAwBrD;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAGhE;AAED,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC3B,MAAM,CAMR"}
@@ -0,0 +1,47 @@
1
+ import { readFile, mkdir, copyFile, readdir } from 'node:fs/promises';
2
+ import { join, dirname } from 'node:path';
3
+ import { homedir } from 'node:os';
4
+ import { fileURLToPath } from 'node:url';
5
+ const __dirname = dirname(fileURLToPath(import.meta.url));
6
+ export function getTemplatesDir() {
7
+ return join(homedir(), '.ralph', 'templates');
8
+ }
9
+ export function getBundledTemplatesDir() {
10
+ return join(__dirname, '..', '..', 'templates');
11
+ }
12
+ export async function ensureTemplates() {
13
+ const userDir = getTemplatesDir();
14
+ const bundledDir = getBundledTemplatesDir();
15
+ await mkdir(userDir, { recursive: true });
16
+ let files;
17
+ try {
18
+ files = await readdir(bundledDir);
19
+ }
20
+ catch {
21
+ return;
22
+ }
23
+ for (const file of files) {
24
+ if (file.endsWith('.md')) {
25
+ const src = join(bundledDir, file);
26
+ const dest = join(userDir, file);
27
+ try {
28
+ await copyFile(src, dest);
29
+ }
30
+ catch {
31
+ // ignore copy errors
32
+ }
33
+ }
34
+ }
35
+ }
36
+ export async function loadTemplate(name) {
37
+ const templatePath = join(getTemplatesDir(), `${name}.md`);
38
+ return readFile(templatePath, 'utf-8');
39
+ }
40
+ export function substituteVars(template, vars) {
41
+ let result = template;
42
+ for (const [key, value] of Object.entries(vars)) {
43
+ result = result.replaceAll(`$${key}`, value);
44
+ }
45
+ return result;
46
+ }
47
+ //# sourceMappingURL=templates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templates.js","sourceRoot":"","sources":["../../src/templates/templates.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AACrE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAExC,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;AAEzD,MAAM,UAAU,eAAe;IAC7B,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAA;AAC/C,CAAC;AAED,MAAM,UAAU,sBAAsB;IACpC,OAAO,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,CAAC,CAAA;AACjD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,MAAM,OAAO,GAAG,eAAe,EAAE,CAAA;IACjC,MAAM,UAAU,GAAG,sBAAsB,EAAE,CAAA;IAE3C,MAAM,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAEzC,IAAI,KAAe,CAAA;IACnB,IAAI,CAAC;QACH,KAAK,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,CAAA;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,OAAM;IACR,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YACzB,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAA;YAClC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;YAChC,IAAI,CAAC;gBACH,MAAM,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;YAC3B,CAAC;YAAC,MAAM,CAAC;gBACP,qBAAqB;YACvB,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAY;IAC7C,MAAM,YAAY,GAAG,IAAI,CAAC,eAAe,EAAE,EAAE,GAAG,IAAI,KAAK,CAAC,CAAA;IAC1D,OAAO,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAA;AACxC,CAAC;AAED,MAAM,UAAU,cAAc,CAC5B,QAAgB,EAChB,IAA4B;IAE5B,IAAI,MAAM,GAAG,QAAQ,CAAA;IACrB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAChD,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,GAAG,EAAE,EAAE,KAAK,CAAC,CAAA;IAC9C,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC"}
@@ -1,2 +1,2 @@
1
- export * from './files.js';
1
+ export * from './ndjson.js';
2
2
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA"}
@@ -1,2 +1,2 @@
1
- export * from './files.js';
1
+ export * from './ndjson.js';
2
2
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Handles streaming NDJSON parsing with line buffering
3
+ */
4
+ export declare class NDJSONParser<T> {
5
+ private buffer;
6
+ private onEvent;
7
+ private onError;
8
+ constructor(onEvent: (event: T) => void, onError?: (error: Error, line: string) => void);
9
+ push(chunk: string): void;
10
+ flush(): void;
11
+ }
12
+ //# sourceMappingURL=ndjson.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ndjson.d.ts","sourceRoot":"","sources":["../../src/utils/ndjson.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,YAAY,CAAC,CAAC;IACzB,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,OAAO,CAAoB;IACnC,OAAO,CAAC,OAAO,CAAsC;gBAGnD,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,EAC3B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI;IAMhD,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAoBzB,KAAK,IAAI,IAAI;CAWd"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Handles streaming NDJSON parsing with line buffering
3
+ */
4
+ export class NDJSONParser {
5
+ buffer = '';
6
+ onEvent;
7
+ onError;
8
+ constructor(onEvent, onError) {
9
+ this.onEvent = onEvent;
10
+ this.onError = onError ?? (() => { });
11
+ }
12
+ push(chunk) {
13
+ this.buffer += chunk;
14
+ const lines = this.buffer.split('\n');
15
+ // Keep incomplete last line in buffer
16
+ this.buffer = lines.pop() ?? '';
17
+ for (const line of lines) {
18
+ const trimmed = line.trim();
19
+ if (!trimmed)
20
+ continue;
21
+ try {
22
+ const event = JSON.parse(trimmed);
23
+ this.onEvent(event);
24
+ }
25
+ catch (err) {
26
+ this.onError(err instanceof Error ? err : new Error(String(err)), trimmed);
27
+ }
28
+ }
29
+ }
30
+ flush() {
31
+ if (this.buffer.trim()) {
32
+ try {
33
+ const event = JSON.parse(this.buffer.trim());
34
+ this.onEvent(event);
35
+ }
36
+ catch (err) {
37
+ this.onError(err instanceof Error ? err : new Error(String(err)), this.buffer);
38
+ }
39
+ }
40
+ this.buffer = '';
41
+ }
42
+ }
43
+ //# sourceMappingURL=ndjson.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ndjson.js","sourceRoot":"","sources":["../../src/utils/ndjson.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,OAAO,YAAY;IACf,MAAM,GAAG,EAAE,CAAA;IACX,OAAO,CAAoB;IAC3B,OAAO,CAAsC;IAErD,YACE,OAA2B,EAC3B,OAA8C;QAE9C,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;QACtB,IAAI,CAAC,OAAO,GAAG,OAAO,IAAI,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;IACtC,CAAC;IAED,IAAI,CAAC,KAAa;QAChB,IAAI,CAAC,MAAM,IAAI,KAAK,CAAA;QACpB,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QAErC,sCAAsC;QACtC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,CAAA;QAE/B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAA;YAC3B,IAAI,CAAC,OAAO;gBAAE,SAAQ;YAEtB,IAAI,CAAC;gBACH,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAM,CAAA;gBACtC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;YACrB,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,CAAC,OAAO,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,CAAA;YAC5E,CAAC;QACH,CAAC;IACH,CAAC;IAED,KAAK;QACH,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;YACvB,IAAI,CAAC;gBACH,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAM,CAAA;gBACjD,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;YACrB,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,CAAC,OAAO,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;YAChF,CAAC;QACH,CAAC;QACD,IAAI,CAAC,MAAM,GAAG,EAAE,CAAA;IAClB,CAAC;CACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rlph-cli",
3
- "version": "0.1.0",
3
+ "version": "1.0.0",
4
4
  "description": "Loop coding agent CLI - run agents headlessly in a loop",
5
5
  "type": "module",
6
6
  "bin": {
@@ -18,7 +18,8 @@
18
18
  "test": "vitest run",
19
19
  "test:watch": "vitest",
20
20
  "test:coverage": "vitest run --coverage",
21
- "prepublishOnly": "bun run build"
21
+ "prepublishOnly": "bun run build",
22
+ "release": "semantic-release"
22
23
  },
23
24
  "keywords": [
24
25
  "cli",
@@ -38,8 +39,16 @@
38
39
  "nanoid": "^5.0.9"
39
40
  },
40
41
  "devDependencies": {
42
+ "@semantic-release/changelog": "^6.0.3",
43
+ "@semantic-release/commit-analyzer": "^13.0.1",
44
+ "@semantic-release/git": "^10.0.1",
45
+ "@semantic-release/github": "^12.0.2",
46
+ "@semantic-release/npm": "^13.1.3",
47
+ "@semantic-release/release-notes-generator": "^14.1.0",
41
48
  "@types/node": "^22.10.5",
42
49
  "@vitest/coverage-v8": "^2.1.8",
50
+ "conventional-changelog-conventionalcommits": "^9.1.0",
51
+ "semantic-release": "^25.0.2",
43
52
  "typescript": "^5.7.3",
44
53
  "vitest": "^2.1.8"
45
54
  }
@@ -1,3 +0,0 @@
1
- export * from './manager.js';
2
- export * from './logger.js';
3
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/session/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA"}
@@ -1,3 +0,0 @@
1
- export * from './manager.js';
2
- export * from './logger.js';
3
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/session/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA"}
@@ -1,10 +0,0 @@
1
- import type { AgentResult } from '../agents/base.js';
2
- export interface LogEntry {
3
- iteration: number;
4
- timestamp: string;
5
- duration: number;
6
- exitCode: number;
7
- output: string;
8
- }
9
- export declare function writeLog(sessionId: string, iteration: number, result: AgentResult): Promise<void>;
10
- //# sourceMappingURL=logger.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/session/logger.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAGpD,MAAM,WAAW,QAAQ;IACvB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;CACf;AAED,wBAAsB,QAAQ,CAC5B,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,IAAI,CAAC,CAcf"}
@@ -1,17 +0,0 @@
1
- import { writeFile } from 'node:fs/promises';
2
- import { join } from 'node:path';
3
- import { getSessionDir } from './manager.js';
4
- export async function writeLog(sessionId, iteration, result) {
5
- const sessionDir = getSessionDir(sessionId);
6
- const logPath = join(sessionDir, `${iteration}.log`);
7
- const header = [
8
- `# Iteration ${iteration}`,
9
- `Timestamp: ${new Date().toISOString()}`,
10
- `Duration: ${result.duration}ms`,
11
- `Exit Code: ${result.exitCode}`,
12
- '---',
13
- '',
14
- ].join('\n');
15
- await writeFile(logPath, header + result.output);
16
- }
17
- //# sourceMappingURL=logger.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/session/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAEhC,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAU5C,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,SAAiB,EACjB,SAAiB,EACjB,MAAmB;IAEnB,MAAM,UAAU,GAAG,aAAa,CAAC,SAAS,CAAC,CAAA;IAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE,GAAG,SAAS,MAAM,CAAC,CAAA;IAEpD,MAAM,MAAM,GAAG;QACb,eAAe,SAAS,EAAE;QAC1B,cAAc,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE;QACxC,aAAa,MAAM,CAAC,QAAQ,IAAI;QAChC,cAAc,MAAM,CAAC,QAAQ,EAAE;QAC/B,KAAK;QACL,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAEZ,MAAM,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAA;AAClD,CAAC"}
@@ -1,18 +0,0 @@
1
- export interface SessionMeta {
2
- id: string;
3
- promptFiles: string[];
4
- agent: string;
5
- cwd: string;
6
- iterations: number;
7
- startTime: string;
8
- }
9
- export declare function getRalphDir(): string;
10
- export declare function getSessionsDir(): string;
11
- export declare function getSessionDir(sessionId: string): string;
12
- export interface CreateSessionOpts {
13
- promptFiles: string[];
14
- agent: string;
15
- iterations: number;
16
- }
17
- export declare function createSession(opts: CreateSessionOpts): Promise<string>;
18
- //# sourceMappingURL=manager.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/session/manager.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,WAAW,EAAE,MAAM,EAAE,CAAA;IACrB,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,MAAM,CAAA;IACX,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAED,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,MAAM,EAAE,CAAA;IACrB,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CAkB5E"}
@@ -1,29 +0,0 @@
1
- import { mkdir, writeFile } from 'node:fs/promises';
2
- import { homedir } from 'node:os';
3
- import { join } from 'node:path';
4
- import { nanoid } from 'nanoid';
5
- export function getRalphDir() {
6
- return join(homedir(), '.ralph');
7
- }
8
- export function getSessionsDir() {
9
- return join(getRalphDir(), 'sessions');
10
- }
11
- export function getSessionDir(sessionId) {
12
- return join(getSessionsDir(), sessionId);
13
- }
14
- export async function createSession(opts) {
15
- const sessionId = nanoid(10);
16
- const sessionDir = getSessionDir(sessionId);
17
- await mkdir(sessionDir, { recursive: true });
18
- const meta = {
19
- id: sessionId,
20
- promptFiles: opts.promptFiles,
21
- agent: opts.agent,
22
- cwd: process.cwd(),
23
- iterations: opts.iterations,
24
- startTime: new Date().toISOString(),
25
- };
26
- await writeFile(join(sessionDir, 'meta.json'), JSON.stringify(meta, null, 2));
27
- return sessionId;
28
- }
29
- //# sourceMappingURL=manager.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/session/manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAW/B,MAAM,UAAU,WAAW;IACzB,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC,CAAA;AAClC,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,OAAO,IAAI,CAAC,WAAW,EAAE,EAAE,UAAU,CAAC,CAAA;AACxC,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,SAAiB;IAC7C,OAAO,IAAI,CAAC,cAAc,EAAE,EAAE,SAAS,CAAC,CAAA;AAC1C,CAAC;AAQD,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAuB;IACzD,MAAM,SAAS,GAAG,MAAM,CAAC,EAAE,CAAC,CAAA;IAC5B,MAAM,UAAU,GAAG,aAAa,CAAC,SAAS,CAAC,CAAA;IAE3C,MAAM,KAAK,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAE5C,MAAM,IAAI,GAAgB;QACxB,EAAE,EAAE,SAAS;QACb,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE;QAClB,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACpC,CAAA;IAED,MAAM,SAAS,CAAC,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;IAE7E,OAAO,SAAS,CAAA;AAClB,CAAC"}