ralphy-spec 0.3.0 → 0.3.1
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/CHANGELOG.md +5 -0
- package/README.md +9 -0
- package/dist/core/backends/cursor.d.ts.map +1 -1
- package/dist/core/backends/cursor.js +31 -8
- package/dist/core/backends/cursor.js.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -30,3 +30,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
30
30
|
- `ralphy-spec run` now supports `worktree` mode and real backend selection (`cursor|opencode|claude-code|noop`).
|
|
31
31
|
- Docs + README (all languages) updated to reflect the new artifacts and CLI.
|
|
32
32
|
|
|
33
|
+
## [0.3.1] - 2026-01-23
|
|
34
|
+
|
|
35
|
+
### Fixed
|
|
36
|
+
- `--backend cursor` now invokes **Cursor Agent** (`cursor agent --print ...`) instead of the editor CLI, and provides a clear error when Cursor Agent authentication is missing.
|
|
37
|
+
|
package/README.md
CHANGED
|
@@ -34,6 +34,15 @@ Then use the commands for your AI tool:
|
|
|
34
34
|
| `/ralphy-validate` | Verify acceptance criteria |
|
|
35
35
|
| `/ralphy-archive` | Complete and archive |
|
|
36
36
|
|
|
37
|
+
If you want to run the full workflow from a terminal with Cursor as the backend (no IDE slash commands), you must authenticate Cursor Agent first:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
cursor agent login
|
|
41
|
+
# or set CURSOR_API_KEY in your environment
|
|
42
|
+
|
|
43
|
+
ralphy-spec run --backend cursor
|
|
44
|
+
```
|
|
45
|
+
|
|
37
46
|
### Claude Code
|
|
38
47
|
|
|
39
48
|
| Command | What it does |
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cursor.d.ts","sourceRoot":"","sources":["../../../src/core/backends/cursor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE1F;;;;;GAKG;AACH,qBAAa,aAAc,YAAW,aAAa;IAGrC,OAAO,CAAC,QAAQ,CAAC,IAAI;IAFjC,QAAQ,CAAC,EAAE,YAAY;gBAEM,IAAI,GAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAO;IAExD,SAAS,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"cursor.d.ts","sourceRoot":"","sources":["../../../src/core/backends/cursor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE1F;;;;;GAKG;AACH,qBAAa,aAAc,YAAW,aAAa;IAGrC,OAAO,CAAC,QAAQ,CAAC,IAAI;IAFjC,QAAQ,CAAC,EAAE,YAAY;gBAEM,IAAI,GAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAO;IAExD,SAAS,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC;IAqEjF,OAAO,CAAC,WAAW;CAsCpB"}
|
|
@@ -16,27 +16,41 @@ class CursorBackend {
|
|
|
16
16
|
}
|
|
17
17
|
async implement(env, input) {
|
|
18
18
|
const { task, iteration, repairNotes } = input;
|
|
19
|
-
// Build the prompt to send to Cursor
|
|
19
|
+
// Build the prompt to send to Cursor Agent
|
|
20
20
|
const prompt = this.buildPrompt(task, iteration, repairNotes);
|
|
21
21
|
try {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
/**
|
|
23
|
+
* Cursor 2.x CLI provides `cursor agent` (headless) which is suitable for this backend.
|
|
24
|
+
*
|
|
25
|
+
* Notes:
|
|
26
|
+
* - Requires authentication: `cursor agent login` OR `CURSOR_API_KEY`.
|
|
27
|
+
* - `--print` makes it usable from scripts/non-interactive terminals.
|
|
28
|
+
* - `--workspace` ensures the agent operates on the task working directory.
|
|
29
|
+
*/
|
|
30
|
+
const result = await (0, execa_1.execa)("cursor", ["agent", "--print", "--output-format", "text", "--workspace", env.cwd, prompt], {
|
|
25
31
|
cwd: env.cwd,
|
|
26
32
|
timeout: this.opts.timeoutMs ?? 600_000, // 10 min default
|
|
27
33
|
reject: false,
|
|
28
34
|
stdio: "pipe",
|
|
29
35
|
});
|
|
36
|
+
const combined = [result.stdout, result.stderr].filter(Boolean).join("\n").trim();
|
|
37
|
+
// Cursor Agent auth failures (common on first run)
|
|
38
|
+
if (result.exitCode !== 0 && /(not logged in|authentication required)/i.test(combined)) {
|
|
39
|
+
return {
|
|
40
|
+
ok: false,
|
|
41
|
+
message: "Cursor Agent is not authenticated. Run `cursor agent login` (interactive) or set CURSOR_API_KEY, then retry.",
|
|
42
|
+
};
|
|
43
|
+
}
|
|
30
44
|
if (result.exitCode === 0) {
|
|
31
45
|
return {
|
|
32
46
|
ok: true,
|
|
33
|
-
message: `Cursor completed task "${task.id}" (iteration ${iteration})`,
|
|
47
|
+
message: `Cursor Agent completed task "${task.id}" (iteration ${iteration})`,
|
|
34
48
|
};
|
|
35
49
|
}
|
|
36
50
|
// Non-zero exit code
|
|
37
51
|
return {
|
|
38
52
|
ok: false,
|
|
39
|
-
message: `Cursor exited with code ${result.exitCode}: ${
|
|
53
|
+
message: `Cursor Agent exited with code ${result.exitCode}: ${combined || "(no output)"}`.slice(0, 2000),
|
|
40
54
|
};
|
|
41
55
|
}
|
|
42
56
|
catch (err) {
|
|
@@ -44,7 +58,7 @@ class CursorBackend {
|
|
|
44
58
|
if (err?.code === "ENOENT") {
|
|
45
59
|
return {
|
|
46
60
|
ok: false,
|
|
47
|
-
message: "Cursor CLI not found.
|
|
61
|
+
message: "Cursor CLI not found. Install Cursor and enable its shell command so `cursor` is in PATH.",
|
|
48
62
|
};
|
|
49
63
|
}
|
|
50
64
|
return {
|
|
@@ -62,12 +76,21 @@ class CursorBackend {
|
|
|
62
76
|
lines.push(task.goal);
|
|
63
77
|
lines.push(``);
|
|
64
78
|
}
|
|
79
|
+
lines.push(`## Where to read context`);
|
|
80
|
+
lines.push([
|
|
81
|
+
`- Read OpenSpec: \`openspec/project.yml\` and any relevant files under \`openspec/specs/**\`.`,
|
|
82
|
+
`- Read task context: \`ralphy-spec/tasks/${task.id}/CONTEXT.md\`.`,
|
|
83
|
+
`- If present, read repair notes: \`ralphy-spec/tasks/${task.id}/REPAIR.md\`.`,
|
|
84
|
+
].join("\n"));
|
|
85
|
+
lines.push(``);
|
|
65
86
|
if (repairNotes) {
|
|
66
87
|
lines.push(`## Repair Notes (iteration ${iteration})`);
|
|
67
88
|
lines.push(repairNotes);
|
|
68
89
|
lines.push(``);
|
|
69
90
|
}
|
|
70
|
-
lines.push(`
|
|
91
|
+
lines.push(`## Instructions`);
|
|
92
|
+
lines.push(`- Implement the task in this workspace and ensure all configured validators pass.`);
|
|
93
|
+
lines.push(`- Keep changes within the task file contract / scope guard constraints.`);
|
|
71
94
|
return lines.join("\n");
|
|
72
95
|
}
|
|
73
96
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cursor.js","sourceRoot":"","sources":["../../../src/core/backends/cursor.ts"],"names":[],"mappings":";;;AAAA,iCAA8B;AAG9B;;;;;GAKG;AACH,MAAa,aAAa;IAGK;IAFpB,EAAE,GAAG,QAAQ,CAAC;IAEvB,YAA6B,OAA+B,EAAE;QAAjC,SAAI,GAAJ,IAAI,CAA6B;IAAG,CAAC;IAElE,KAAK,CAAC,SAAS,CAAC,GAAe,EAAE,KAAqB;QACpD,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,GAAG,KAAK,CAAC;QAE/C,
|
|
1
|
+
{"version":3,"file":"cursor.js","sourceRoot":"","sources":["../../../src/core/backends/cursor.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -15,7 +15,7 @@ function buildProgram() {
|
|
|
15
15
|
program
|
|
16
16
|
.name("ralphy-spec")
|
|
17
17
|
.description("One-command setup for Ralph loop + OpenSpec workflows across Cursor, OpenCode, and Claude Code.")
|
|
18
|
-
.version("0.3.
|
|
18
|
+
.version("0.3.1");
|
|
19
19
|
(0, init_1.registerInitCommand)(program);
|
|
20
20
|
(0, validate_1.registerValidateCommand)(program);
|
|
21
21
|
(0, update_1.registerUpdateCommand)(program);
|
package/package.json
CHANGED