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
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export declare function main(argv: string[]): Promise<void>;
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AA0CA,wBAAsB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAKxD"}
package/dist/cli.js ADDED
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from "commander";
3
+ import { readFileSync, realpathSync } from "fs";
4
+ import { fileURLToPath } from "url";
5
+ import { dirname, join } from "path";
6
+ import { runCommand } from "./commands/run.js";
7
+ import { onceCommand } from "./commands/once.js";
8
+ import { loopCommand } from "./commands/loop.js";
9
+ import { statusCommand } from "./commands/status.js";
10
+ import { logsCommand } from "./commands/logs.js";
11
+ import { initCommand } from "./commands/init.js";
12
+ import { doctorCommand } from "./commands/doctor.js";
13
+ import { taskCommand } from "./commands/task.js";
14
+ const __dirname = dirname(fileURLToPath(import.meta.url));
15
+ const pkg = JSON.parse(readFileSync(join(__dirname, "..", "package.json"), "utf-8"));
16
+ const program = new Command();
17
+ program
18
+ .name("ralph-cursor")
19
+ .description("Ralph Wiggum: autonomous development loop for Cursor")
20
+ .version(pkg.version, "-V, --version")
21
+ .option("-v, --verbose", "Extra debug output");
22
+ program.addCommand(runCommand());
23
+ program.addCommand(onceCommand());
24
+ program.addCommand(loopCommand());
25
+ program.addCommand(statusCommand());
26
+ program.addCommand(logsCommand());
27
+ program.addCommand(initCommand());
28
+ program.addCommand(doctorCommand());
29
+ program.addCommand(taskCommand());
30
+ // Default: run (interactive) when no subcommand
31
+ program.action(async () => {
32
+ await program.parseAsync(process.argv.slice(0, 2).concat(["run"]));
33
+ });
34
+ export async function main(argv) {
35
+ if (argv.includes("-v") || argv.includes("--verbose")) {
36
+ process.env.RALPH_VERBOSE = "1";
37
+ }
38
+ await program.parseAsync(argv);
39
+ }
40
+ // Run when this file is the entry script (handles symlinks e.g. npm global bin)
41
+ const modulePath = fileURLToPath(import.meta.url);
42
+ const firstArg = process.argv[1];
43
+ let isMain = false;
44
+ if (firstArg) {
45
+ try {
46
+ isMain =
47
+ modulePath === firstArg ||
48
+ realpathSync(modulePath) === realpathSync(firstArg);
49
+ }
50
+ catch {
51
+ isMain = modulePath === firstArg;
52
+ }
53
+ }
54
+ if (isMain) {
55
+ main(process.argv).catch((err) => {
56
+ console.error(err);
57
+ process.exit(1);
58
+ });
59
+ }
60
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare function doctorCommand(): Command;
3
+ //# sourceMappingURL=doctor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAwCpC,wBAAgB,aAAa,IAAI,OAAO,CA+BvC"}
@@ -0,0 +1,69 @@
1
+ import { Command } from "commander";
2
+ import { existsSync, appendFileSync, mkdirSync, unlinkSync } from "fs";
3
+ import { join } from "path";
4
+ import { execSync } from "child_process";
5
+ import { getRalphDir } from "../lib/ralph-dir.js";
6
+ import { getTaskFilePath } from "../task-parser/index.js";
7
+ function checkCursorAgent() {
8
+ try {
9
+ execSync("which cursor-agent", { stdio: "pipe" });
10
+ return true;
11
+ }
12
+ catch {
13
+ return false;
14
+ }
15
+ }
16
+ function checkGit(workspace) {
17
+ try {
18
+ execSync("git rev-parse --git-dir", { cwd: workspace, stdio: "pipe" });
19
+ return true;
20
+ }
21
+ catch {
22
+ return false;
23
+ }
24
+ }
25
+ function checkRalphWritable(workspace) {
26
+ const ralphDir = getRalphDir(workspace);
27
+ try {
28
+ const testFile = join(ralphDir, ".ralph-write-test");
29
+ if (!existsSync(ralphDir)) {
30
+ mkdirSync(ralphDir, { recursive: true });
31
+ }
32
+ appendFileSync(testFile, "test");
33
+ unlinkSync(testFile);
34
+ return true;
35
+ }
36
+ catch {
37
+ return false;
38
+ }
39
+ }
40
+ export function doctorCommand() {
41
+ return new Command("doctor")
42
+ .description("Check environment: cursor-agent, git, task file, .ralph writable")
43
+ .option("--task <path>", "Path to task file")
44
+ .action(async (opts) => {
45
+ const workspace = process.cwd();
46
+ const taskPath = getTaskFilePath(workspace, opts.task);
47
+ const issues = [];
48
+ if (!checkCursorAgent()) {
49
+ issues.push("cursor-agent not found in PATH (install: curl https://cursor.com/install -fsS | bash)");
50
+ }
51
+ if (!checkGit(workspace)) {
52
+ issues.push("Not a git repository (run: git init)");
53
+ }
54
+ if (!existsSync(taskPath)) {
55
+ issues.push(`Task file not found: ${taskPath} (run: ralph-cursor init)`);
56
+ }
57
+ if (!checkRalphWritable(workspace)) {
58
+ issues.push(".ralph/ directory not writable");
59
+ }
60
+ if (issues.length === 0) {
61
+ console.log("✓ All checks passed.");
62
+ process.exit(0);
63
+ }
64
+ console.error("Issues found:");
65
+ issues.forEach((i) => console.error(" -", i));
66
+ process.exit(2);
67
+ });
68
+ }
69
+ //# sourceMappingURL=doctor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare function initCommand(): Command;
3
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAyEpC,wBAAgB,WAAW,IAAI,OAAO,CAsGrC"}
@@ -0,0 +1,162 @@
1
+ import { Command } from "commander";
2
+ import { existsSync, writeFileSync, readFileSync, appendFileSync, mkdirSync } from "fs";
3
+ import { join } from "path";
4
+ import { execSync } from "child_process";
5
+ import { ensureRalphDir, getRalphDir } from "../lib/ralph-dir.js";
6
+ const GUARDRAILS_TEMPLATE = `# Ralph Guardrails (Signs)
7
+
8
+ > Lessons learned from past failures. READ THESE BEFORE ACTING.
9
+
10
+ ## Core Signs
11
+
12
+ ### Sign: Read Before Writing
13
+ - **Trigger**: Before modifying any file
14
+ - **Instruction**: Always read the existing file first
15
+ - **Added after**: Core principle
16
+
17
+ ### Sign: Test After Changes
18
+ - **Trigger**: After any code change
19
+ - **Instruction**: Run tests to verify nothing broke
20
+ - **Added after**: Core principle
21
+
22
+ ### Sign: Commit Checkpoints
23
+ - **Trigger**: Before risky changes
24
+ - **Instruction**: Commit current working state first
25
+ - **Added after**: Core principle
26
+
27
+ ---
28
+
29
+ ## Learned Signs
30
+
31
+ (Signs added from observed failures will appear below)
32
+ `;
33
+ const PROGRESS_TEMPLATE = `# Progress Log
34
+
35
+ > Updated by the agent after significant work.
36
+
37
+ ## Summary
38
+
39
+ - Iterations completed: 0
40
+ - Current status: Initialized
41
+
42
+ ## How This Works
43
+
44
+ Progress is tracked in THIS FILE, not in LLM context.
45
+ When context is rotated (fresh agent), the new agent reads this file.
46
+ This is how Ralph maintains continuity across iterations.
47
+
48
+ ## Session History
49
+ `;
50
+ /** Default task template when assets/RALPH_TASK_TEMPLATE.md is not present. */
51
+ const RALPH_TASK_TEMPLATE = `---
52
+ task: Your task description here
53
+ test_command: "pnpm test"
54
+ ---
55
+
56
+ # Task
57
+
58
+ Describe what you want to accomplish.
59
+
60
+ ## Success Criteria
61
+
62
+ 1. [ ] First thing to complete
63
+ 2. [ ] Second thing to complete
64
+ 3. [ ] Third thing to complete
65
+
66
+ ## Context
67
+
68
+ Any additional context the agent should know.
69
+ `;
70
+ export function initCommand() {
71
+ return new Command("init")
72
+ .description("Create .ralph/ and optional RALPH_TASK.md template")
73
+ .action(async () => {
74
+ const workspace = process.cwd();
75
+ console.log("═══════════════════════════════════════════════════════════════════");
76
+ console.log("🐛 Ralph Wiggum Initialization");
77
+ console.log("═══════════════════════════════════════════════════════════════════");
78
+ console.log("");
79
+ try {
80
+ execSync("git rev-parse --git-dir", { cwd: workspace, stdio: "pipe" });
81
+ }
82
+ catch {
83
+ console.log("⚠️ Warning: Not in a git repository.");
84
+ console.log(" Ralph works best with git for state persistence.");
85
+ console.log("");
86
+ const readline = await import("readline");
87
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
88
+ const answer = await new Promise((resolve) => {
89
+ rl.question("Continue anyway? [y/N] ", (a) => resolve(a.trim()));
90
+ });
91
+ rl.close();
92
+ if (answer.toLowerCase() !== "y" && answer.toLowerCase() !== "yes") {
93
+ process.exit(1);
94
+ }
95
+ }
96
+ try {
97
+ execSync("which cursor-agent", { stdio: "pipe" });
98
+ }
99
+ catch {
100
+ console.log("⚠️ Warning: cursor-agent CLI not found.");
101
+ console.log(" Install via: curl https://cursor.com/install -fsS | bash");
102
+ console.log("");
103
+ }
104
+ ensureRalphDir(workspace);
105
+ const ralphDir = getRalphDir(workspace);
106
+ writeFileSync(join(ralphDir, "guardrails.md"), GUARDRAILS_TEMPLATE);
107
+ writeFileSync(join(ralphDir, "progress.md"), PROGRESS_TEMPLATE);
108
+ writeFileSync(join(ralphDir, "errors.log"), "# Error Log\n\n> Failures detected by stream-parser. Use to update guardrails.\n\n");
109
+ writeFileSync(join(ralphDir, "activity.log"), "# Activity Log\n\n> Real-time tool call logging from stream-parser.\n\n");
110
+ writeFileSync(join(ralphDir, ".iteration"), "0");
111
+ const cursorScriptsDir = join(workspace, ".cursor", "ralph-scripts");
112
+ if (!existsSync(cursorScriptsDir)) {
113
+ mkdirSync(cursorScriptsDir, { recursive: true });
114
+ }
115
+ console.log("📁 Initializing .ralph/ directory...");
116
+ console.log("✓ .ralph/ initialized");
117
+ const taskPath = join(workspace, "RALPH_TASK.md");
118
+ if (!existsSync(taskPath)) {
119
+ console.log("📝 Creating RALPH_TASK.md template...");
120
+ writeFileSync(taskPath, RALPH_TASK_TEMPLATE);
121
+ console.log(" Edit RALPH_TASK.md to define your task.");
122
+ }
123
+ else {
124
+ console.log("✓ RALPH_TASK.md already exists (not overwritten)");
125
+ }
126
+ const gitignorePath = join(workspace, ".gitignore");
127
+ const ralphConfigLine = ".cursor/ralph-config.json";
128
+ if (existsSync(gitignorePath)) {
129
+ const content = readFileSync(gitignorePath, "utf-8");
130
+ if (!content.includes("ralph-config.json")) {
131
+ appendFileSync(gitignorePath, "\n# Ralph config (may contain API keys)\n" + ralphConfigLine + "\n");
132
+ console.log("✓ Updated .gitignore");
133
+ }
134
+ }
135
+ else {
136
+ writeFileSync(gitignorePath, "# Ralph config (may contain API keys)\n" + ralphConfigLine + "\n");
137
+ console.log("✓ Created .gitignore");
138
+ }
139
+ console.log("");
140
+ console.log("═══════════════════════════════════════════════════════════════════");
141
+ console.log("✅ Ralph initialized!");
142
+ console.log("═══════════════════════════════════════════════════════════════════");
143
+ console.log("");
144
+ console.log("Files created:");
145
+ console.log(" • RALPH_TASK.md - Define your task here");
146
+ console.log(" • .ralph/guardrails.md - Lessons learned (agent updates this)");
147
+ console.log(" • .ralph/progress.md - Progress log (agent updates this)");
148
+ console.log(" • .ralph/activity.log - Tool call log (parser updates this)");
149
+ console.log(" • .ralph/errors.log - Failure log (parser updates this)");
150
+ console.log("");
151
+ console.log("Next steps:");
152
+ console.log(" 1. Edit RALPH_TASK.md to define your task and criteria");
153
+ console.log(" 2. Run: ralph-cursor run (or ralph-cursor loop for non-interactive)");
154
+ console.log("");
155
+ console.log("The agent will work autonomously, rotating context as needed.");
156
+ console.log("Monitor progress: tail -f .ralph/activity.log");
157
+ console.log("");
158
+ console.log("Learn more: https://ghuntley.com/ralph/");
159
+ console.log("═══════════════════════════════════════════════════════════════════");
160
+ });
161
+ }
162
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare function logsCommand(): Command;
3
+ //# sourceMappingURL=logs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../../src/commands/logs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,wBAAgB,WAAW,IAAI,OAAO,CAuBrC"}
@@ -0,0 +1,28 @@
1
+ import { Command } from "commander";
2
+ import { join } from "path";
3
+ import { getRalphDir } from "../lib/ralph-dir.js";
4
+ import { existsSync } from "fs";
5
+ import { tailFile } from "../lib/tail.js";
6
+ export function logsCommand() {
7
+ return new Command("logs")
8
+ .description("Tail activity.log (or errors.log with --errors)")
9
+ .option("--errors", "Tail errors.log instead of activity.log")
10
+ .option("-n, --lines <n>", "Number of lines to show initially", "50")
11
+ .option("--no-follow", "Do not follow; only print last N lines")
12
+ .action((opts) => {
13
+ const workspace = process.cwd();
14
+ const ralphDir = getRalphDir(workspace);
15
+ const logFile = opts.errors ? "errors.log" : "activity.log";
16
+ const logPath = join(ralphDir, logFile);
17
+ if (!existsSync(logPath)) {
18
+ console.error(".ralph/ not initialized. Run: ralph-cursor init");
19
+ process.exit(2);
20
+ }
21
+ const lines = parseInt(opts.lines ?? "50", 10) || 50;
22
+ tailFile(logPath, {
23
+ follow: opts.follow !== false,
24
+ lines,
25
+ });
26
+ });
27
+ }
28
+ //# sourceMappingURL=logs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logs.js","sourceRoot":"","sources":["../../src/commands/logs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C,MAAM,UAAU,WAAW;IACzB,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;SACvB,WAAW,CAAC,iDAAiD,CAAC;SAC9D,MAAM,CAAC,UAAU,EAAE,yCAAyC,CAAC;SAC7D,MAAM,CAAC,iBAAiB,EAAE,mCAAmC,EAAE,IAAI,CAAC;SACpE,MAAM,CAAC,aAAa,EAAE,wCAAwC,CAAC;SAC/D,MAAM,CAAC,CAAC,IAA4D,EAAE,EAAE;QACvE,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;QAChC,MAAM,QAAQ,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC;QACxC,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,cAAc,CAAC;QAC5D,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAExC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACzB,OAAO,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC;YACjE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC;QACrD,QAAQ,CAAC,OAAO,EAAE;YAChB,MAAM,EAAE,IAAI,CAAC,MAAM,KAAK,KAAK;YAC7B,KAAK;SACN,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare function loopCommand(): Command;
3
+ //# sourceMappingURL=loop.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loop.d.ts","sourceRoot":"","sources":["../../src/commands/loop.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA+DpC,wBAAgB,WAAW,IAAI,OAAO,CA0IrC"}
@@ -0,0 +1,186 @@
1
+ import { Command } from "commander";
2
+ import { resolve } from "path";
3
+ import { existsSync, readFileSync } from "fs";
4
+ import { execSync } from "child_process";
5
+ import { runRalphLoop } from "../loop/index.js";
6
+ import { runParallelTasks } from "../parallel/run.js";
7
+ import { ensureRalphDir } from "../lib/ralph-dir.js";
8
+ import { checkTaskComplete, getTaskFilePath, getProgress, countRemaining } from "../task-parser/index.js";
9
+ import { loadConfig } from "../lib/config.js";
10
+ /** Prerequisite checks: cursor-agent, git, task file, .ralph writable. Returns false on first failure. */
11
+ function checkPrerequisites(workspace, taskFilePath) {
12
+ if (!existsSync(taskFilePath)) {
13
+ console.error(`❌ No RALPH_TASK.md found in ${workspace}`);
14
+ console.error("");
15
+ console.error("Create a task file first:");
16
+ console.error(" cat > RALPH_TASK.md << 'EOF'");
17
+ console.error(" ---");
18
+ console.error(" task: Your task description");
19
+ console.error(" test_command: \"pnpm test\"");
20
+ console.error(" ---");
21
+ console.error(" # Task");
22
+ console.error(" ## Success Criteria");
23
+ console.error(" 1. [ ] First thing to do");
24
+ console.error(" 2. [ ] Second thing to do");
25
+ console.error(" EOF");
26
+ return false;
27
+ }
28
+ try {
29
+ execSync("which cursor-agent", { stdio: "pipe" });
30
+ }
31
+ catch {
32
+ console.error("❌ cursor-agent CLI not found");
33
+ console.error("");
34
+ console.error("Install via:");
35
+ console.error(" curl https://cursor.com/install -fsS | bash");
36
+ return false;
37
+ }
38
+ try {
39
+ execSync("git rev-parse --git-dir", { cwd: workspace, stdio: "pipe" });
40
+ }
41
+ catch {
42
+ console.error("❌ Not a git repository");
43
+ console.error(" Ralph requires git for state persistence.");
44
+ return false;
45
+ }
46
+ return true;
47
+ }
48
+ function showTaskSummary(workspace, taskPath) {
49
+ const path = getTaskFilePath(workspace, taskPath);
50
+ if (!existsSync(path))
51
+ return;
52
+ const content = readFileSync(path, "utf-8");
53
+ const lines = content.split("\n").slice(0, 30);
54
+ console.log("📋 Task Summary:");
55
+ console.log("─────────────────────────────────────────────────────────────────");
56
+ console.log(lines.join("\n"));
57
+ console.log("─────────────────────────────────────────────────────────────────");
58
+ console.log("");
59
+ const progress = getProgress(workspace, taskPath);
60
+ const [done, total] = progress.split(":").map(Number);
61
+ const remaining = countRemaining(workspace, taskPath);
62
+ console.log(`Progress: ${done} / ${total} criteria complete (${remaining} remaining)`);
63
+ }
64
+ export function loopCommand() {
65
+ return new Command("loop")
66
+ .description("Non-interactive loop with flags")
67
+ .argument("[workspace]", "Project directory (default: current)")
68
+ .option("-n, --iterations <n>", "Max iterations", "20")
69
+ .option("-m, --model <model>", "Model to use")
70
+ .option("--branch <name>", "Branch name")
71
+ .option("--pr", "Open PR when complete")
72
+ .option("--task <path>", "Path to task file")
73
+ .option("--parallel", "Run in parallel mode")
74
+ .option("--max-parallel <n>", "Max parallel agents", "3")
75
+ .option("--no-merge", "Skip auto-merge in parallel mode")
76
+ .option("-y, --yes", "Skip confirmation")
77
+ .action(async (workspaceArg, opts) => {
78
+ const workspace = workspaceArg ? resolve(process.cwd(), workspaceArg) : process.cwd();
79
+ if (!existsSync(workspace)) {
80
+ console.error("Workspace not found:", workspace);
81
+ process.exit(2);
82
+ }
83
+ const sep = "═══════════════════════════════════════════════════════════════════";
84
+ console.log(sep);
85
+ console.log("🐛 Ralph Wiggum: Autonomous Development Loop");
86
+ console.log(sep);
87
+ console.log("");
88
+ console.log(" \"That's the beauty of Ralph - the technique is deterministically");
89
+ console.log(" bad in an undeterministic world.\"");
90
+ console.log("");
91
+ console.log(sep);
92
+ console.log("");
93
+ const taskFile = getTaskFilePath(workspace, opts.task);
94
+ if (!checkPrerequisites(workspace, taskFile)) {
95
+ process.exit(1);
96
+ }
97
+ if (opts.pr && !opts.branch) {
98
+ console.error("--pr requires --branch (sequential mode)");
99
+ console.error(" Example: ralph-cursor loop --branch feature/foo --pr");
100
+ process.exit(2);
101
+ }
102
+ ensureRalphDir(workspace);
103
+ const config = loadConfig(workspace);
104
+ const model = opts.model ?? config.default_model;
105
+ const maxIterations = parseInt(opts.iterations ?? String(config.max_iterations), 10);
106
+ console.log("Workspace:", workspace);
107
+ console.log("Task: ", taskFile);
108
+ console.log("");
109
+ showTaskSummary(workspace, opts.task);
110
+ console.log("Model: ", model);
111
+ console.log("Max iter: ", maxIterations);
112
+ if (opts.branch)
113
+ console.log("Branch: ", opts.branch);
114
+ if (opts.pr)
115
+ console.log("Open PR: Yes");
116
+ if (opts.parallel)
117
+ console.log("Parallel: Yes (" + (opts.maxParallel ?? "3") + " agents)");
118
+ if (opts.parallel && opts.merge === false)
119
+ console.log("Merge: Skipped");
120
+ console.log("");
121
+ const taskStatus = checkTaskComplete(workspace, opts.task);
122
+ if (taskStatus === "COMPLETE") {
123
+ console.log("🎉 Task already complete! All criteria are checked.");
124
+ process.exit(0);
125
+ }
126
+ if (opts.parallel) {
127
+ if (!opts.yes) {
128
+ const readline = await import("readline");
129
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
130
+ const answer = await new Promise((resolve) => {
131
+ rl.question("Start Ralph parallel execution? [y/N] ", (a) => resolve(a.trim()));
132
+ });
133
+ rl.close();
134
+ if (answer.toLowerCase() !== "y" && answer.toLowerCase() !== "yes") {
135
+ console.log("Aborted.");
136
+ process.exit(0);
137
+ }
138
+ }
139
+ const maxParallel = parseInt(opts.maxParallel ?? "3", 10) || 3;
140
+ const result = await runParallelTasks(workspace, {
141
+ maxParallel,
142
+ model,
143
+ baseBranch: undefined,
144
+ integrationBranch: opts.branch ?? undefined,
145
+ skipMerge: opts.merge === false,
146
+ createPr: opts.pr ?? false,
147
+ taskFilePath: opts.task,
148
+ });
149
+ process.exit(result.success ? 0 : 1);
150
+ }
151
+ if (!opts.yes) {
152
+ console.log("This will run cursor-agent locally to work on this task.");
153
+ console.log("The agent will be rotated when context fills up (~80k tokens).");
154
+ console.log("");
155
+ console.log("Tip: Use -y flag to skip this prompt.");
156
+ console.log("");
157
+ const readline = await import("readline");
158
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
159
+ const answer = await new Promise((resolve) => {
160
+ rl.question("Start Ralph loop? [y/N] ", (a) => resolve(a.trim()));
161
+ });
162
+ rl.close();
163
+ if (answer.toLowerCase() !== "y" && answer.toLowerCase() !== "yes") {
164
+ console.log("Aborted.");
165
+ process.exit(0);
166
+ }
167
+ }
168
+ const result = await runRalphLoop({
169
+ workspace,
170
+ model,
171
+ maxIterations,
172
+ useBranch: opts.branch,
173
+ openPr: opts.pr,
174
+ taskFilePath: opts.task,
175
+ warnThreshold: config.warn_threshold,
176
+ rotateThreshold: config.rotate_threshold,
177
+ });
178
+ if (result.success) {
179
+ console.log("\nRALPH COMPLETE! Iterations:", result.iterations);
180
+ process.exit(0);
181
+ }
182
+ console.error("\nLoop ended without completion.");
183
+ process.exit(1);
184
+ });
185
+ }
186
+ //# sourceMappingURL=loop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loop.js","sourceRoot":"","sources":["../../src/commands/loop.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare function onceCommand(): Command;
3
+ //# sourceMappingURL=once.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"once.d.ts","sourceRoot":"","sources":["../../src/commands/once.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA+DpC,wBAAgB,WAAW,IAAI,OAAO,CAiIrC"}