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.
- package/README.md +79 -40
- package/dist/agents/claude-events.d.ts +45 -0
- package/dist/agents/claude-events.d.ts.map +1 -0
- package/dist/agents/claude-events.js +2 -0
- package/dist/agents/claude-events.js.map +1 -0
- package/dist/agents/claude-formatter.d.ts +3 -0
- package/dist/agents/claude-formatter.d.ts.map +1 -0
- package/dist/agents/claude-formatter.js +45 -0
- package/dist/agents/claude-formatter.js.map +1 -0
- package/dist/agents/claude.d.ts.map +1 -1
- package/dist/agents/claude.js +27 -40
- package/dist/agents/claude.js.map +1 -1
- package/dist/commands/prd-add.d.ts +5 -0
- package/dist/commands/prd-add.d.ts.map +1 -0
- package/dist/commands/prd-add.js +72 -0
- package/dist/commands/prd-add.js.map +1 -0
- package/dist/commands/prd-list.d.ts +2 -0
- package/dist/commands/prd-list.d.ts.map +1 -0
- package/dist/commands/prd-list.js +47 -0
- package/dist/commands/prd-list.js.map +1 -0
- package/dist/commands/run.d.ts +1 -2
- package/dist/commands/run.d.ts.map +1 -1
- package/dist/commands/run.js +43 -23
- package/dist/commands/run.js.map +1 -1
- package/dist/index.js +13 -2
- package/dist/index.js.map +1 -1
- package/dist/prd/index.d.ts +3 -0
- package/dist/prd/index.d.ts.map +1 -0
- package/dist/prd/index.js +3 -0
- package/dist/prd/index.js.map +1 -0
- package/dist/prd/manager.d.ts +9 -0
- package/dist/prd/manager.d.ts.map +1 -0
- package/dist/prd/manager.js +68 -0
- package/dist/prd/manager.js.map +1 -0
- package/dist/prd/types.d.ts +25 -0
- package/dist/prd/types.d.ts.map +1 -0
- package/dist/prd/types.js +2 -0
- package/dist/prd/types.js.map +1 -0
- package/dist/templates/index.d.ts +2 -0
- package/dist/templates/index.d.ts.map +1 -0
- package/dist/templates/index.js +2 -0
- package/dist/templates/index.js.map +1 -0
- package/dist/templates/templates.d.ts +6 -0
- package/dist/templates/templates.d.ts.map +1 -0
- package/dist/templates/templates.js +47 -0
- package/dist/templates/templates.js.map +1 -0
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -1
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/ndjson.d.ts +12 -0
- package/dist/utils/ndjson.d.ts.map +1 -0
- package/dist/utils/ndjson.js +43 -0
- package/dist/utils/ndjson.js.map +1 -0
- package/package.json +11 -2
- package/dist/session/index.d.ts +0 -3
- package/dist/session/index.d.ts.map +0 -1
- package/dist/session/index.js +0 -3
- package/dist/session/index.js.map +0 -1
- package/dist/session/logger.d.ts +0 -10
- package/dist/session/logger.d.ts.map +0 -1
- package/dist/session/logger.js +0 -17
- package/dist/session/logger.js.map +0 -1
- package/dist/session/manager.d.ts +0 -18
- package/dist/session/manager.d.ts.map +0 -1
- package/dist/session/manager.js +0 -29
- package/dist/session/manager.js.map +0 -1
- package/dist/utils/files.d.ts +0 -4
- package/dist/utils/files.d.ts.map +0 -1
- package/dist/utils/files.js +0 -39
- package/dist/utils/files.js.map +0 -1
package/dist/commands/run.js
CHANGED
|
@@ -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 {
|
|
4
|
-
import {
|
|
5
|
-
|
|
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
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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
|
-
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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
|
-
|
|
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
|
|
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(
|
|
59
|
-
console.log(chalk.cyan(`
|
|
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(`
|
|
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: ${
|
|
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
|
package/dist/commands/run.js.map
CHANGED
|
@@ -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,
|
|
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
|
|
11
|
-
.
|
|
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;
|
|
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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/prd/types.ts"],"names":[],"mappings":""}
|
|
@@ -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 @@
|
|
|
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"}
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from './
|
|
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,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA"}
|
package/dist/utils/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from './
|
|
1
|
+
export * from './ndjson.js';
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/utils/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,
|
|
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": "
|
|
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
|
}
|
package/dist/session/index.d.ts
DELETED
|
@@ -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"}
|
package/dist/session/index.js
DELETED
|
@@ -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"}
|
package/dist/session/logger.d.ts
DELETED
|
@@ -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"}
|
package/dist/session/logger.js
DELETED
|
@@ -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"}
|
package/dist/session/manager.js
DELETED
|
@@ -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"}
|