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.
Files changed (94) hide show
  1. package/README.md +724 -0
  2. package/dist/cli.d.ts +3 -0
  3. package/dist/cli.d.ts.map +1 -0
  4. package/dist/cli.js +60 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/commands/doctor.d.ts +3 -0
  7. package/dist/commands/doctor.d.ts.map +1 -0
  8. package/dist/commands/doctor.js +69 -0
  9. package/dist/commands/doctor.js.map +1 -0
  10. package/dist/commands/init.d.ts +3 -0
  11. package/dist/commands/init.d.ts.map +1 -0
  12. package/dist/commands/init.js +162 -0
  13. package/dist/commands/init.js.map +1 -0
  14. package/dist/commands/logs.d.ts +3 -0
  15. package/dist/commands/logs.d.ts.map +1 -0
  16. package/dist/commands/logs.js +28 -0
  17. package/dist/commands/logs.js.map +1 -0
  18. package/dist/commands/loop.d.ts +3 -0
  19. package/dist/commands/loop.d.ts.map +1 -0
  20. package/dist/commands/loop.js +186 -0
  21. package/dist/commands/loop.js.map +1 -0
  22. package/dist/commands/once.d.ts +3 -0
  23. package/dist/commands/once.d.ts.map +1 -0
  24. package/dist/commands/once.js +187 -0
  25. package/dist/commands/once.js.map +1 -0
  26. package/dist/commands/run.d.ts +3 -0
  27. package/dist/commands/run.d.ts.map +1 -0
  28. package/dist/commands/run.js +328 -0
  29. package/dist/commands/run.js.map +1 -0
  30. package/dist/commands/status.d.ts +3 -0
  31. package/dist/commands/status.d.ts.map +1 -0
  32. package/dist/commands/status.js +33 -0
  33. package/dist/commands/status.js.map +1 -0
  34. package/dist/commands/task.d.ts +3 -0
  35. package/dist/commands/task.d.ts.map +1 -0
  36. package/dist/commands/task.js +161 -0
  37. package/dist/commands/task.js.map +1 -0
  38. package/dist/lib/config.d.ts +8 -0
  39. package/dist/lib/config.d.ts.map +1 -0
  40. package/dist/lib/config.js +48 -0
  41. package/dist/lib/config.js.map +1 -0
  42. package/dist/lib/last-run.d.ts +12 -0
  43. package/dist/lib/last-run.d.ts.map +1 -0
  44. package/dist/lib/last-run.js +33 -0
  45. package/dist/lib/last-run.js.map +1 -0
  46. package/dist/lib/ralph-dir.d.ts +6 -0
  47. package/dist/lib/ralph-dir.d.ts.map +1 -0
  48. package/dist/lib/ralph-dir.js +96 -0
  49. package/dist/lib/ralph-dir.js.map +1 -0
  50. package/dist/lib/spawn.d.ts +11 -0
  51. package/dist/lib/spawn.d.ts.map +1 -0
  52. package/dist/lib/spawn.js +29 -0
  53. package/dist/lib/spawn.js.map +1 -0
  54. package/dist/lib/tail.d.ts +9 -0
  55. package/dist/lib/tail.d.ts.map +1 -0
  56. package/dist/lib/tail.js +58 -0
  57. package/dist/lib/tail.js.map +1 -0
  58. package/dist/loop/index.d.ts +32 -0
  59. package/dist/loop/index.d.ts.map +1 -0
  60. package/dist/loop/index.js +165 -0
  61. package/dist/loop/index.js.map +1 -0
  62. package/dist/loop/prompt.d.ts +5 -0
  63. package/dist/loop/prompt.d.ts.map +1 -0
  64. package/dist/loop/prompt.js +77 -0
  65. package/dist/loop/prompt.js.map +1 -0
  66. package/dist/loop/retry.d.ts +22 -0
  67. package/dist/loop/retry.d.ts.map +1 -0
  68. package/dist/loop/retry.js +65 -0
  69. package/dist/loop/retry.js.map +1 -0
  70. package/dist/parallel/lock.d.ts +7 -0
  71. package/dist/parallel/lock.d.ts.map +1 -0
  72. package/dist/parallel/lock.js +110 -0
  73. package/dist/parallel/lock.js.map +1 -0
  74. package/dist/parallel/merge.d.ts +5 -0
  75. package/dist/parallel/merge.d.ts.map +1 -0
  76. package/dist/parallel/merge.js +39 -0
  77. package/dist/parallel/merge.js.map +1 -0
  78. package/dist/parallel/run.d.ts +18 -0
  79. package/dist/parallel/run.d.ts.map +1 -0
  80. package/dist/parallel/run.js +407 -0
  81. package/dist/parallel/run.js.map +1 -0
  82. package/dist/parallel/worktree.d.ts +12 -0
  83. package/dist/parallel/worktree.d.ts.map +1 -0
  84. package/dist/parallel/worktree.js +69 -0
  85. package/dist/parallel/worktree.js.map +1 -0
  86. package/dist/stream-parser/index.d.ts +18 -0
  87. package/dist/stream-parser/index.d.ts.map +1 -0
  88. package/dist/stream-parser/index.js +248 -0
  89. package/dist/stream-parser/index.js.map +1 -0
  90. package/dist/task-parser/index.d.ts +21 -0
  91. package/dist/task-parser/index.d.ts.map +1 -0
  92. package/dist/task-parser/index.js +195 -0
  93. package/dist/task-parser/index.js.map +1 -0
  94. 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,8 @@
1
+ export interface RalphConfig {
2
+ warn_threshold: number;
3
+ rotate_threshold: number;
4
+ default_model: string;
5
+ max_iterations: number;
6
+ }
7
+ export declare function loadConfig(workspace: string): RalphConfig;
8
+ //# sourceMappingURL=config.d.ts.map
@@ -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"}
@@ -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"}