ralph-cursor 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.
- package/README.md +724 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +60 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/doctor.d.ts +3 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +69 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/init.d.ts +3 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +162 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/logs.d.ts +3 -0
- package/dist/commands/logs.d.ts.map +1 -0
- package/dist/commands/logs.js +28 -0
- package/dist/commands/logs.js.map +1 -0
- package/dist/commands/loop.d.ts +3 -0
- package/dist/commands/loop.d.ts.map +1 -0
- package/dist/commands/loop.js +186 -0
- package/dist/commands/loop.js.map +1 -0
- package/dist/commands/once.d.ts +3 -0
- package/dist/commands/once.d.ts.map +1 -0
- package/dist/commands/once.js +187 -0
- package/dist/commands/once.js.map +1 -0
- package/dist/commands/run.d.ts +3 -0
- package/dist/commands/run.d.ts.map +1 -0
- package/dist/commands/run.js +328 -0
- package/dist/commands/run.js.map +1 -0
- package/dist/commands/status.d.ts +3 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +33 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/task.d.ts +3 -0
- package/dist/commands/task.d.ts.map +1 -0
- package/dist/commands/task.js +161 -0
- package/dist/commands/task.js.map +1 -0
- package/dist/lib/config.d.ts +8 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +48 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/last-run.d.ts +12 -0
- package/dist/lib/last-run.d.ts.map +1 -0
- package/dist/lib/last-run.js +33 -0
- package/dist/lib/last-run.js.map +1 -0
- package/dist/lib/ralph-dir.d.ts +6 -0
- package/dist/lib/ralph-dir.d.ts.map +1 -0
- package/dist/lib/ralph-dir.js +96 -0
- package/dist/lib/ralph-dir.js.map +1 -0
- package/dist/lib/spawn.d.ts +11 -0
- package/dist/lib/spawn.d.ts.map +1 -0
- package/dist/lib/spawn.js +29 -0
- package/dist/lib/spawn.js.map +1 -0
- package/dist/lib/tail.d.ts +9 -0
- package/dist/lib/tail.d.ts.map +1 -0
- package/dist/lib/tail.js +58 -0
- package/dist/lib/tail.js.map +1 -0
- package/dist/loop/index.d.ts +32 -0
- package/dist/loop/index.d.ts.map +1 -0
- package/dist/loop/index.js +165 -0
- package/dist/loop/index.js.map +1 -0
- package/dist/loop/prompt.d.ts +5 -0
- package/dist/loop/prompt.d.ts.map +1 -0
- package/dist/loop/prompt.js +77 -0
- package/dist/loop/prompt.js.map +1 -0
- package/dist/loop/retry.d.ts +22 -0
- package/dist/loop/retry.d.ts.map +1 -0
- package/dist/loop/retry.js +65 -0
- package/dist/loop/retry.js.map +1 -0
- package/dist/parallel/lock.d.ts +7 -0
- package/dist/parallel/lock.d.ts.map +1 -0
- package/dist/parallel/lock.js +110 -0
- package/dist/parallel/lock.js.map +1 -0
- package/dist/parallel/merge.d.ts +5 -0
- package/dist/parallel/merge.d.ts.map +1 -0
- package/dist/parallel/merge.js +39 -0
- package/dist/parallel/merge.js.map +1 -0
- package/dist/parallel/run.d.ts +18 -0
- package/dist/parallel/run.d.ts.map +1 -0
- package/dist/parallel/run.js +407 -0
- package/dist/parallel/run.js.map +1 -0
- package/dist/parallel/worktree.d.ts +12 -0
- package/dist/parallel/worktree.d.ts.map +1 -0
- package/dist/parallel/worktree.js +69 -0
- package/dist/parallel/worktree.js.map +1 -0
- package/dist/stream-parser/index.d.ts +18 -0
- package/dist/stream-parser/index.d.ts.map +1 -0
- package/dist/stream-parser/index.js +248 -0
- package/dist/stream-parser/index.js.map +1 -0
- package/dist/task-parser/index.d.ts +21 -0
- package/dist/task-parser/index.d.ts.map +1 -0
- package/dist/task-parser/index.js +195 -0
- package/dist/task-parser/index.js.map +1 -0
- package/package.json +44 -0
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { resolve } from "path";
|
|
3
|
+
import { existsSync, readFileSync } from "fs";
|
|
4
|
+
import { join } from "path";
|
|
5
|
+
import { getTaskFilePath, getAllTasks, getNextTask, getProgress, markTaskComplete, markTaskIncomplete, checkTaskComplete, parseTasks, } from "../task-parser/index.js";
|
|
6
|
+
import { ensureRalphDir, getRalphDir } from "../lib/ralph-dir.js";
|
|
7
|
+
export function taskCommand() {
|
|
8
|
+
const task = new Command("task")
|
|
9
|
+
.description("Task operations: list, next, complete, incomplete, parse, export");
|
|
10
|
+
task
|
|
11
|
+
.command("list")
|
|
12
|
+
.description("List all tasks (id, status, description)")
|
|
13
|
+
.argument("[workspace]", "Project directory (default: current)")
|
|
14
|
+
.option("--task <path>", "Path to task file")
|
|
15
|
+
.action((workspaceArg, opts) => {
|
|
16
|
+
const workspace = workspaceArg ? resolve(process.cwd(), workspaceArg) : process.cwd();
|
|
17
|
+
if (!existsSync(workspace)) {
|
|
18
|
+
console.error("Workspace not found:", workspace);
|
|
19
|
+
process.exit(2);
|
|
20
|
+
}
|
|
21
|
+
ensureRalphDir(workspace);
|
|
22
|
+
const path = getTaskFilePath(workspace, opts.task);
|
|
23
|
+
if (!existsSync(path)) {
|
|
24
|
+
console.error("No task file. Run: ralph-cursor init");
|
|
25
|
+
process.exit(2);
|
|
26
|
+
}
|
|
27
|
+
const tasks = getAllTasks(workspace, opts.task);
|
|
28
|
+
const progress = getProgress(workspace, opts.task);
|
|
29
|
+
console.log(`Tasks (${progress} done/total):\n`);
|
|
30
|
+
for (const t of tasks) {
|
|
31
|
+
const mark = t.status === "completed" ? "[x]" : "[ ]";
|
|
32
|
+
console.log(` ${t.id} ${mark} ${t.description}`);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
task
|
|
36
|
+
.command("next")
|
|
37
|
+
.description("Print the next incomplete task (id and description)")
|
|
38
|
+
.argument("[workspace]", "Project directory (default: current)")
|
|
39
|
+
.option("--task <path>", "Path to task file")
|
|
40
|
+
.action((workspaceArg, opts) => {
|
|
41
|
+
const workspace = workspaceArg ? resolve(process.cwd(), workspaceArg) : process.cwd();
|
|
42
|
+
if (!existsSync(workspace)) {
|
|
43
|
+
console.error("Workspace not found:", workspace);
|
|
44
|
+
process.exit(2);
|
|
45
|
+
}
|
|
46
|
+
ensureRalphDir(workspace);
|
|
47
|
+
if (checkTaskComplete(workspace, opts.task) === "NO_TASK_FILE") {
|
|
48
|
+
console.error("No task file. Run: ralph-cursor init");
|
|
49
|
+
process.exit(2);
|
|
50
|
+
}
|
|
51
|
+
const next = getNextTask(workspace, opts.task);
|
|
52
|
+
if (!next) {
|
|
53
|
+
console.log("All tasks complete.");
|
|
54
|
+
process.exit(0);
|
|
55
|
+
}
|
|
56
|
+
console.log(`${next.id}|${next.status}|${next.description}`);
|
|
57
|
+
});
|
|
58
|
+
task
|
|
59
|
+
.command("complete <id>")
|
|
60
|
+
.description("Mark a task complete by id (e.g. line_5)")
|
|
61
|
+
.argument("[workspace]", "Project directory (default: current)")
|
|
62
|
+
.option("--task <path>", "Path to task file")
|
|
63
|
+
.action((taskId, workspaceArg, opts) => {
|
|
64
|
+
const workspace = workspaceArg ? resolve(process.cwd(), workspaceArg) : process.cwd();
|
|
65
|
+
if (!existsSync(workspace)) {
|
|
66
|
+
console.error("Workspace not found:", workspace);
|
|
67
|
+
process.exit(2);
|
|
68
|
+
}
|
|
69
|
+
ensureRalphDir(workspace);
|
|
70
|
+
if (checkTaskComplete(workspace, opts.task) === "NO_TASK_FILE") {
|
|
71
|
+
console.error("No task file. Run: ralph-cursor init");
|
|
72
|
+
process.exit(2);
|
|
73
|
+
}
|
|
74
|
+
try {
|
|
75
|
+
markTaskComplete(workspace, taskId, opts.task);
|
|
76
|
+
console.log(`Marked ${taskId} complete.`);
|
|
77
|
+
}
|
|
78
|
+
catch (err) {
|
|
79
|
+
console.error(err instanceof Error ? err.message : err);
|
|
80
|
+
process.exit(1);
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
task
|
|
84
|
+
.command("incomplete <id>")
|
|
85
|
+
.description("Mark a task incomplete by id (e.g. line_5)")
|
|
86
|
+
.argument("[workspace]", "Project directory (default: current)")
|
|
87
|
+
.option("--task <path>", "Path to task file")
|
|
88
|
+
.action((taskId, workspaceArg, opts) => {
|
|
89
|
+
const workspace = workspaceArg ? resolve(process.cwd(), workspaceArg) : process.cwd();
|
|
90
|
+
if (!existsSync(workspace)) {
|
|
91
|
+
console.error("Workspace not found:", workspace);
|
|
92
|
+
process.exit(2);
|
|
93
|
+
}
|
|
94
|
+
ensureRalphDir(workspace);
|
|
95
|
+
if (checkTaskComplete(workspace, opts.task) === "NO_TASK_FILE") {
|
|
96
|
+
console.error("No task file. Run: ralph-cursor init");
|
|
97
|
+
process.exit(2);
|
|
98
|
+
}
|
|
99
|
+
try {
|
|
100
|
+
markTaskIncomplete(workspace, taskId, opts.task);
|
|
101
|
+
console.log(`Marked ${taskId} incomplete.`);
|
|
102
|
+
}
|
|
103
|
+
catch (err) {
|
|
104
|
+
console.error(err instanceof Error ? err.message : err);
|
|
105
|
+
process.exit(1);
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
task
|
|
109
|
+
.command("parse")
|
|
110
|
+
.description("Parse task file and update cache (.ralph/tasks.yaml)")
|
|
111
|
+
.argument("[workspace]", "Project directory (default: current)")
|
|
112
|
+
.option("--task <path>", "Path to task file")
|
|
113
|
+
.action((workspaceArg, opts) => {
|
|
114
|
+
const workspace = workspaceArg ? resolve(process.cwd(), workspaceArg) : process.cwd();
|
|
115
|
+
if (!existsSync(workspace)) {
|
|
116
|
+
console.error("Workspace not found:", workspace);
|
|
117
|
+
process.exit(2);
|
|
118
|
+
}
|
|
119
|
+
ensureRalphDir(workspace);
|
|
120
|
+
const path = getTaskFilePath(workspace, opts.task);
|
|
121
|
+
if (!existsSync(path)) {
|
|
122
|
+
console.error("No task file. Run: ralph-cursor init");
|
|
123
|
+
process.exit(2);
|
|
124
|
+
}
|
|
125
|
+
try {
|
|
126
|
+
parseTasks(workspace, opts.task);
|
|
127
|
+
console.log("Cache updated.");
|
|
128
|
+
}
|
|
129
|
+
catch (err) {
|
|
130
|
+
console.error(err instanceof Error ? err.message : err);
|
|
131
|
+
process.exit(1);
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
task
|
|
135
|
+
.command("export")
|
|
136
|
+
.description("Print task cache as YAML (same as .ralph/tasks.yaml)")
|
|
137
|
+
.argument("[workspace]", "Project directory (default: current)")
|
|
138
|
+
.option("--task <path>", "Path to task file")
|
|
139
|
+
.action((workspaceArg, opts) => {
|
|
140
|
+
const workspace = workspaceArg ? resolve(process.cwd(), workspaceArg) : process.cwd();
|
|
141
|
+
if (!existsSync(workspace)) {
|
|
142
|
+
console.error("Workspace not found:", workspace);
|
|
143
|
+
process.exit(2);
|
|
144
|
+
}
|
|
145
|
+
ensureRalphDir(workspace);
|
|
146
|
+
const path = getTaskFilePath(workspace, opts.task);
|
|
147
|
+
if (!existsSync(path)) {
|
|
148
|
+
console.error("No task file. Run: ralph-cursor init");
|
|
149
|
+
process.exit(2);
|
|
150
|
+
}
|
|
151
|
+
getAllTasks(workspace, opts.task);
|
|
152
|
+
const yamlPath = join(getRalphDir(workspace), "tasks.yaml");
|
|
153
|
+
if (!existsSync(yamlPath)) {
|
|
154
|
+
console.error("Cache not found. Run: ralph-cursor task parse");
|
|
155
|
+
process.exit(1);
|
|
156
|
+
}
|
|
157
|
+
console.log(readFileSync(yamlPath, "utf-8"));
|
|
158
|
+
});
|
|
159
|
+
return task;
|
|
160
|
+
}
|
|
161
|
+
//# sourceMappingURL=task.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task.js","sourceRoot":"","sources":["../../src/commands/task.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,WAAW;IAC1B,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;CACxB;AASD,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,WAAW,CA+BzD"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { readFileSync, existsSync } from "fs";
|
|
2
|
+
import { join } from "path";
|
|
3
|
+
import { getRalphDir } from "./ralph-dir.js";
|
|
4
|
+
const DEFAULTS = {
|
|
5
|
+
warn_threshold: 70_000,
|
|
6
|
+
rotate_threshold: 80_000,
|
|
7
|
+
default_model: "opus-4.5-thinking",
|
|
8
|
+
max_iterations: 20,
|
|
9
|
+
};
|
|
10
|
+
export function loadConfig(workspace) {
|
|
11
|
+
const configPath = join(getRalphDir(workspace), "config.json");
|
|
12
|
+
const out = { ...DEFAULTS };
|
|
13
|
+
if (existsSync(configPath)) {
|
|
14
|
+
try {
|
|
15
|
+
const data = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
16
|
+
if (typeof data.warn_threshold === "number")
|
|
17
|
+
out.warn_threshold = data.warn_threshold;
|
|
18
|
+
if (typeof data.rotate_threshold === "number")
|
|
19
|
+
out.rotate_threshold = data.rotate_threshold;
|
|
20
|
+
if (typeof data.default_model === "string")
|
|
21
|
+
out.default_model = data.default_model;
|
|
22
|
+
if (typeof data.max_iterations === "number")
|
|
23
|
+
out.max_iterations = data.max_iterations;
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
// ignore invalid config
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
if (process.env.RALPH_WARN_THRESHOLD ?? process.env.WARN_THRESHOLD) {
|
|
30
|
+
const n = parseInt(String(process.env.RALPH_WARN_THRESHOLD ?? process.env.WARN_THRESHOLD), 10);
|
|
31
|
+
if (!isNaN(n))
|
|
32
|
+
out.warn_threshold = n;
|
|
33
|
+
}
|
|
34
|
+
if (process.env.RALPH_ROTATE_THRESHOLD ?? process.env.ROTATE_THRESHOLD) {
|
|
35
|
+
const n = parseInt(String(process.env.RALPH_ROTATE_THRESHOLD ?? process.env.ROTATE_THRESHOLD), 10);
|
|
36
|
+
if (!isNaN(n))
|
|
37
|
+
out.rotate_threshold = n;
|
|
38
|
+
}
|
|
39
|
+
if (process.env.RALPH_MODEL)
|
|
40
|
+
out.default_model = process.env.RALPH_MODEL;
|
|
41
|
+
if (process.env.MAX_ITERATIONS) {
|
|
42
|
+
const n = parseInt(process.env.MAX_ITERATIONS, 10);
|
|
43
|
+
if (!isNaN(n))
|
|
44
|
+
out.max_iterations = n;
|
|
45
|
+
}
|
|
46
|
+
return out;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAC9C,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAS7C,MAAM,QAAQ,GAAgB;IAC5B,cAAc,EAAE,MAAM;IACtB,gBAAgB,EAAE,MAAM;IACxB,aAAa,EAAE,mBAAmB;IAClC,cAAc,EAAE,EAAE;CACnB,CAAC;AAEF,MAAM,UAAU,UAAU,CAAC,SAAiB;IAC1C,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,EAAE,aAAa,CAAC,CAAC;IAC/D,MAAM,GAAG,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;IAE5B,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC3B,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAyB,CAAC;YACnF,IAAI,OAAO,IAAI,CAAC,cAAc,KAAK,QAAQ;gBAAE,GAAG,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC;YACtF,IAAI,OAAO,IAAI,CAAC,gBAAgB,KAAK,QAAQ;gBAAE,GAAG,CAAC,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,CAAC;YAC5F,IAAI,OAAO,IAAI,CAAC,aAAa,KAAK,QAAQ;gBAAE,GAAG,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC;YACnF,IAAI,OAAO,IAAI,CAAC,cAAc,KAAK,QAAQ;gBAAE,GAAG,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC;QACxF,CAAC;QAAC,MAAM,CAAC;YACP,wBAAwB;QAC1B,CAAC;IACH,CAAC;IAED,IAAI,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC;QACnE,MAAM,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,EAAE,CAAC,CAAC;QAC/F,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;YAAE,GAAG,CAAC,cAAc,GAAG,CAAC,CAAC;IACxC,CAAC;IACD,IAAI,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QACvE,MAAM,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,EAAE,EAAE,CAAC,CAAC;QACnG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;YAAE,GAAG,CAAC,gBAAgB,GAAG,CAAC,CAAC;IAC1C,CAAC;IACD,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW;QAAE,GAAG,CAAC,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;IACzE,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC;QAC/B,MAAM,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;QACnD,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;YAAE,GAAG,CAAC,cAAc,GAAG,CAAC,CAAC;IACxC,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface LastRunOptions {
|
|
2
|
+
model: string;
|
|
3
|
+
max_iterations: number;
|
|
4
|
+
use_branch: string;
|
|
5
|
+
open_pr: boolean;
|
|
6
|
+
parallel: boolean;
|
|
7
|
+
max_parallel: number;
|
|
8
|
+
}
|
|
9
|
+
export declare function getLastRunPath(workspace: string): string;
|
|
10
|
+
export declare function readLastRun(workspace: string): LastRunOptions | null;
|
|
11
|
+
export declare function writeLastRun(workspace: string, options: Partial<LastRunOptions>): void;
|
|
12
|
+
//# sourceMappingURL=last-run.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"last-run.d.ts","sourceRoot":"","sources":["../../src/lib/last-run.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;CACtB;AAWD,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CASpE;AAED,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,IAAI,CAKtF"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync, existsSync } from "fs";
|
|
2
|
+
import { join } from "path";
|
|
3
|
+
import { getRalphDir } from "./ralph-dir.js";
|
|
4
|
+
const DEFAULT_LAST_RUN = {
|
|
5
|
+
model: "opus-4.5-thinking",
|
|
6
|
+
max_iterations: 20,
|
|
7
|
+
use_branch: "",
|
|
8
|
+
open_pr: false,
|
|
9
|
+
parallel: false,
|
|
10
|
+
max_parallel: 3,
|
|
11
|
+
};
|
|
12
|
+
export function getLastRunPath(workspace) {
|
|
13
|
+
return join(getRalphDir(workspace), "last-run.json");
|
|
14
|
+
}
|
|
15
|
+
export function readLastRun(workspace) {
|
|
16
|
+
const path = getLastRunPath(workspace);
|
|
17
|
+
if (!existsSync(path))
|
|
18
|
+
return null;
|
|
19
|
+
try {
|
|
20
|
+
const data = JSON.parse(readFileSync(path, "utf-8"));
|
|
21
|
+
return { ...DEFAULT_LAST_RUN, ...data };
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
export function writeLastRun(workspace, options) {
|
|
28
|
+
const path = getLastRunPath(workspace);
|
|
29
|
+
const current = readLastRun(workspace) ?? DEFAULT_LAST_RUN;
|
|
30
|
+
const merged = { ...current, ...options };
|
|
31
|
+
writeFileSync(path, JSON.stringify(merged, null, 2));
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=last-run.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"last-run.js","sourceRoot":"","sources":["../../src/lib/last-run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAC7D,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAW7C,MAAM,gBAAgB,GAAmB;IACvC,KAAK,EAAE,mBAAmB;IAC1B,cAAc,EAAE,EAAE;IAClB,UAAU,EAAE,EAAE;IACd,OAAO,EAAE,KAAK;IACd,QAAQ,EAAE,KAAK;IACf,YAAY,EAAE,CAAC;CAChB,CAAC;AAEF,MAAM,UAAU,cAAc,CAAC,SAAiB;IAC9C,OAAO,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,EAAE,eAAe,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,SAAiB;IAC3C,MAAM,IAAI,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC;IACvC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACnC,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;QACrD,OAAO,EAAE,GAAG,gBAAgB,EAAE,GAAG,IAAI,EAAE,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,SAAiB,EAAE,OAAgC;IAC9E,MAAM,IAAI,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC;IACvC,MAAM,OAAO,GAAG,WAAW,CAAC,SAAS,CAAC,IAAI,gBAAgB,CAAC;IAC3D,MAAM,MAAM,GAAG,EAAE,GAAG,OAAO,EAAE,GAAG,OAAO,EAAE,CAAC;IAC1C,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AACvD,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare function getRalphDir(workspace: string): string;
|
|
2
|
+
export declare function ensureRalphDir(workspace: string): void;
|
|
3
|
+
export declare function getIteration(workspace: string): number;
|
|
4
|
+
export declare function setIteration(workspace: string, iteration: number): void;
|
|
5
|
+
export declare function logProgress(workspace: string, message: string): void;
|
|
6
|
+
//# sourceMappingURL=ralph-dir.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ralph-dir.d.ts","sourceRoot":"","sources":["../../src/lib/ralph-dir.ts"],"names":[],"mappings":"AAUA,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAuEtD;AAED,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAKtD;AAED,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAIvE;AAED,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAKpE"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { appendFileSync, mkdirSync, readFileSync, writeFileSync, existsSync } from "fs";
|
|
2
|
+
import { join } from "path";
|
|
3
|
+
const RALPH_DIR = ".ralph";
|
|
4
|
+
const ITERATION_FILE = ".iteration";
|
|
5
|
+
const PROGRESS_FILE = "progress.md";
|
|
6
|
+
const GUARDRAILS_FILE = "guardrails.md";
|
|
7
|
+
const ERRORS_FILE = "errors.log";
|
|
8
|
+
const ACTIVITY_FILE = "activity.log";
|
|
9
|
+
export function getRalphDir(workspace) {
|
|
10
|
+
return join(workspace, RALPH_DIR);
|
|
11
|
+
}
|
|
12
|
+
export function ensureRalphDir(workspace) {
|
|
13
|
+
const ralphDir = getRalphDir(workspace);
|
|
14
|
+
if (!existsSync(ralphDir)) {
|
|
15
|
+
mkdirSync(ralphDir, { recursive: true });
|
|
16
|
+
}
|
|
17
|
+
const progressPath = join(ralphDir, PROGRESS_FILE);
|
|
18
|
+
if (!existsSync(progressPath)) {
|
|
19
|
+
writeFileSync(progressPath, `# Progress Log
|
|
20
|
+
|
|
21
|
+
> Updated by the agent after significant work.
|
|
22
|
+
|
|
23
|
+
## Summary
|
|
24
|
+
|
|
25
|
+
- Iterations completed: 0
|
|
26
|
+
- Current status: Initialized
|
|
27
|
+
|
|
28
|
+
## How This Works
|
|
29
|
+
|
|
30
|
+
Progress is tracked in THIS FILE, not in LLM context.
|
|
31
|
+
When context is rotated (fresh agent), the new agent reads this file.
|
|
32
|
+
This is how Ralph maintains continuity across iterations.
|
|
33
|
+
|
|
34
|
+
## Session History
|
|
35
|
+
|
|
36
|
+
`);
|
|
37
|
+
}
|
|
38
|
+
const guardrailsPath = join(ralphDir, GUARDRAILS_FILE);
|
|
39
|
+
if (!existsSync(guardrailsPath)) {
|
|
40
|
+
writeFileSync(guardrailsPath, `# Ralph Guardrails (Signs)
|
|
41
|
+
|
|
42
|
+
> Lessons learned from past failures. READ THESE BEFORE ACTING.
|
|
43
|
+
|
|
44
|
+
## Core Signs
|
|
45
|
+
|
|
46
|
+
### Sign: Read Before Writing
|
|
47
|
+
- **Trigger**: Before modifying any file
|
|
48
|
+
- **Instruction**: Always read the existing file first
|
|
49
|
+
- **Added after**: Core principle
|
|
50
|
+
|
|
51
|
+
### Sign: Test After Changes
|
|
52
|
+
- **Trigger**: After any code change
|
|
53
|
+
- **Instruction**: Run tests to verify nothing broke
|
|
54
|
+
- **Added after**: Core principle
|
|
55
|
+
|
|
56
|
+
### Sign: Commit Checkpoints
|
|
57
|
+
- **Trigger**: Before risky changes
|
|
58
|
+
- **Instruction**: Commit current working state first
|
|
59
|
+
- **Added after**: Core principle
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Learned Signs
|
|
64
|
+
|
|
65
|
+
(Signs added from observed failures will appear below)
|
|
66
|
+
|
|
67
|
+
`);
|
|
68
|
+
}
|
|
69
|
+
const errorsPath = join(ralphDir, ERRORS_FILE);
|
|
70
|
+
if (!existsSync(errorsPath)) {
|
|
71
|
+
writeFileSync(errorsPath, "# Error Log\n\n");
|
|
72
|
+
}
|
|
73
|
+
const activityPath = join(ralphDir, ACTIVITY_FILE);
|
|
74
|
+
if (!existsSync(activityPath)) {
|
|
75
|
+
writeFileSync(activityPath, "# Activity Log\n\n");
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
export function getIteration(workspace) {
|
|
79
|
+
const path = join(getRalphDir(workspace), ITERATION_FILE);
|
|
80
|
+
if (!existsSync(path))
|
|
81
|
+
return 0;
|
|
82
|
+
const n = parseInt(readFileSync(path, "utf-8").trim(), 10);
|
|
83
|
+
return isNaN(n) ? 0 : n;
|
|
84
|
+
}
|
|
85
|
+
export function setIteration(workspace, iteration) {
|
|
86
|
+
ensureRalphDir(workspace);
|
|
87
|
+
const path = join(getRalphDir(workspace), ITERATION_FILE);
|
|
88
|
+
writeFileSync(path, String(iteration));
|
|
89
|
+
}
|
|
90
|
+
export function logProgress(workspace, message) {
|
|
91
|
+
ensureRalphDir(workspace);
|
|
92
|
+
const path = join(getRalphDir(workspace), PROGRESS_FILE);
|
|
93
|
+
const ts = new Date().toISOString().replace("T", " ").slice(0, 19);
|
|
94
|
+
appendFileSync(path, `\n### ${ts}\n${message}\n`);
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=ralph-dir.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ralph-dir.js","sourceRoot":"","sources":["../../src/lib/ralph-dir.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type ChildProcess } from "child_process";
|
|
2
|
+
export interface SpawnOptions {
|
|
3
|
+
model: string;
|
|
4
|
+
sessionId?: string;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Spawn cursor-agent with the given prompt. Returns the child process.
|
|
8
|
+
* Caller should wire stdout to the stream parser and write prompt to stdin.
|
|
9
|
+
*/
|
|
10
|
+
export declare function spawnCursorAgent(prompt: string, options: SpawnOptions): ChildProcess;
|
|
11
|
+
//# sourceMappingURL=spawn.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spawn.d.ts","sourceRoot":"","sources":["../../src/lib/spawn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAEzD,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,YAAY,GACpB,YAAY,CAsBd"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { spawn } from "child_process";
|
|
2
|
+
/**
|
|
3
|
+
* Spawn cursor-agent with the given prompt. Returns the child process.
|
|
4
|
+
* Caller should wire stdout to the stream parser and write prompt to stdin.
|
|
5
|
+
*/
|
|
6
|
+
export function spawnCursorAgent(prompt, options) {
|
|
7
|
+
const args = [
|
|
8
|
+
"-p",
|
|
9
|
+
"--force",
|
|
10
|
+
"--output-format",
|
|
11
|
+
"stream-json",
|
|
12
|
+
"--model",
|
|
13
|
+
options.model,
|
|
14
|
+
];
|
|
15
|
+
if (options.sessionId) {
|
|
16
|
+
args.push("--resume", options.sessionId);
|
|
17
|
+
}
|
|
18
|
+
const child = spawn("cursor-agent", args, {
|
|
19
|
+
stdio: ["pipe", "pipe", "inherit"],
|
|
20
|
+
shell: false,
|
|
21
|
+
});
|
|
22
|
+
if (child.stdin) {
|
|
23
|
+
child.stdin.write(prompt, "utf-8", () => {
|
|
24
|
+
child.stdin?.end();
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
return child;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=spawn.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spawn.js","sourceRoot":"","sources":["../../src/lib/spawn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAqB,MAAM,eAAe,CAAC;AAOzD;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAC9B,MAAc,EACd,OAAqB;IAErB,MAAM,IAAI,GAAG;QACX,IAAI;QACJ,SAAS;QACT,iBAAiB;QACjB,aAAa;QACb,SAAS;QACT,OAAO,CAAC,KAAK;KACd,CAAC;IACF,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;QACtB,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IAC3C,CAAC;IACD,MAAM,KAAK,GAAG,KAAK,CAAC,cAAc,EAAE,IAAI,EAAE;QACxC,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC;QAClC,KAAK,EAAE,KAAK;KACb,CAAC,CAAC;IACH,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE;YACtC,KAAK,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC;QACrB,CAAC,CAAC,CAAC;IACL,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stream last N lines of a file, then follow new content (like tail -f).
|
|
3
|
+
* Cross-platform: no dependency on the `tail` command.
|
|
4
|
+
*/
|
|
5
|
+
export declare function tailFile(filePath: string, options?: {
|
|
6
|
+
follow?: boolean;
|
|
7
|
+
lines?: number;
|
|
8
|
+
}): void;
|
|
9
|
+
//# sourceMappingURL=tail.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tail.d.ts","sourceRoot":"","sources":["../../src/lib/tail.ts"],"names":[],"mappings":"AAKA;;;GAGG;AACH,wBAAgB,QAAQ,CACtB,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GACjD,IAAI,CAoDN"}
|
package/dist/lib/tail.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { createReadStream, readFileSync, watch } from "fs";
|
|
2
|
+
import { createInterface } from "readline";
|
|
3
|
+
const DEFAULT_LINES = 50;
|
|
4
|
+
/**
|
|
5
|
+
* Stream last N lines of a file, then follow new content (like tail -f).
|
|
6
|
+
* Cross-platform: no dependency on the `tail` command.
|
|
7
|
+
*/
|
|
8
|
+
export function tailFile(filePath, options = {}) {
|
|
9
|
+
const { follow = true, lines = DEFAULT_LINES } = options;
|
|
10
|
+
const buffer = [];
|
|
11
|
+
const stream = createReadStream(filePath, { encoding: "utf-8" });
|
|
12
|
+
const rl = createInterface({ input: stream, crlfDelay: Infinity });
|
|
13
|
+
rl.on("line", (line) => {
|
|
14
|
+
buffer.push(line);
|
|
15
|
+
if (buffer.length > lines)
|
|
16
|
+
buffer.shift();
|
|
17
|
+
});
|
|
18
|
+
rl.on("close", () => {
|
|
19
|
+
buffer.forEach((l) => console.log(l));
|
|
20
|
+
if (!follow) {
|
|
21
|
+
process.exit(0);
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
let lastOffset = 0;
|
|
25
|
+
try {
|
|
26
|
+
const content = readFileSync(filePath, "utf-8");
|
|
27
|
+
lastOffset = content.length;
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
lastOffset = 0;
|
|
31
|
+
}
|
|
32
|
+
const watcher = watch(filePath, { persistent: true }, () => {
|
|
33
|
+
try {
|
|
34
|
+
const content = readFileSync(filePath, "utf-8");
|
|
35
|
+
if (content.length > lastOffset) {
|
|
36
|
+
const newPart = content.slice(lastOffset);
|
|
37
|
+
newPart.split("\n").forEach((l) => {
|
|
38
|
+
if (l.length > 0)
|
|
39
|
+
console.log(l);
|
|
40
|
+
});
|
|
41
|
+
lastOffset = content.length;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
// file may be rotated or deleted
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
process.on("SIGINT", () => {
|
|
49
|
+
watcher.close();
|
|
50
|
+
process.exit(0);
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
stream.on("error", (err) => {
|
|
54
|
+
console.error(err);
|
|
55
|
+
process.exit(1);
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=tail.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tail.js","sourceRoot":"","sources":["../../src/lib/tail.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,IAAI,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAE3C,MAAM,aAAa,GAAG,EAAE,CAAC;AAEzB;;;GAGG;AACH,MAAM,UAAU,QAAQ,CACtB,QAAgB,EAChB,UAAgD,EAAE;IAElD,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,KAAK,GAAG,aAAa,EAAE,GAAG,OAAO,CAAC;IACzD,MAAM,MAAM,GAAa,EAAE,CAAC;IAE5B,MAAM,MAAM,GAAG,gBAAgB,CAAC,QAAQ,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;IACjE,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC;IAEnE,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;QAC7B,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClB,IAAI,MAAM,CAAC,MAAM,GAAG,KAAK;YAAE,MAAM,CAAC,KAAK,EAAE,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;QAClB,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACtC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAChB,OAAO;QACT,CAAC;QAED,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAChD,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC;QAC9B,CAAC;QAAC,MAAM,CAAC;YACP,UAAU,GAAG,CAAC,CAAC;QACjB,CAAC;QAED,MAAM,OAAO,GAAG,KAAK,CAAC,QAAQ,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE;YACzD,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;gBAChD,IAAI,OAAO,CAAC,MAAM,GAAG,UAAU,EAAE,CAAC;oBAChC,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;oBAC1C,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;wBAChC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC;4BAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;oBACnC,CAAC,CAAC,CAAC;oBACH,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC;gBAC9B,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,iCAAiC;YACnC,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;YACxB,OAAO,CAAC,KAAK,EAAE,CAAC;YAChB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;QACzB,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACnB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export type RalphSignal = "ROTATE" | "WARN" | "GUTTER" | "COMPLETE" | "DEFER";
|
|
2
|
+
export interface RunIterationOptions {
|
|
3
|
+
workspace: string;
|
|
4
|
+
iteration: number;
|
|
5
|
+
model: string;
|
|
6
|
+
sessionId?: string;
|
|
7
|
+
warnThreshold?: number;
|
|
8
|
+
rotateThreshold?: number;
|
|
9
|
+
taskFilePath?: string;
|
|
10
|
+
}
|
|
11
|
+
export interface RunLoopOptions {
|
|
12
|
+
workspace: string;
|
|
13
|
+
model: string;
|
|
14
|
+
maxIterations: number;
|
|
15
|
+
useBranch?: string;
|
|
16
|
+
openPr?: boolean;
|
|
17
|
+
taskFilePath?: string;
|
|
18
|
+
warnThreshold?: number;
|
|
19
|
+
rotateThreshold?: number;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Run a single agent iteration. Returns the signal (ROTATE, GUTTER, COMPLETE, DEFER) or null when agent exits without signal.
|
|
23
|
+
*/
|
|
24
|
+
export declare function runIteration(options: RunIterationOptions): Promise<RalphSignal | null>;
|
|
25
|
+
/**
|
|
26
|
+
* Run the main Ralph loop until COMPLETE, GUTTER, or max iterations.
|
|
27
|
+
*/
|
|
28
|
+
export declare function runRalphLoop(options: RunLoopOptions): Promise<{
|
|
29
|
+
success: boolean;
|
|
30
|
+
iterations: number;
|
|
31
|
+
}>;
|
|
32
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/loop/index.ts"],"names":[],"mappings":"AASA,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,UAAU,GAAG,OAAO,CAAC;AAE9E,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAmBD;;GAEG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAgE5F;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,CA0F7G"}
|