cralph 1.0.0-beta.5 → 1.0.0-beta.7
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 +13 -4
- package/package.json +1 -1
- package/src/prompt.ts +10 -20
- package/src/runner.ts +46 -7
package/README.md
CHANGED
|
@@ -62,8 +62,9 @@ cralph --yes
|
|
|
62
62
|
2. Looks for `.ralph/` in current directory only (not subdirectories)
|
|
63
63
|
3. Loads config from `.ralph/paths.json` or creates starter structure
|
|
64
64
|
4. Runs `claude -p --dangerously-skip-permissions` in a loop
|
|
65
|
-
5. Claude
|
|
66
|
-
6.
|
|
65
|
+
5. Claude completes **ONE task per iteration**, marks it done, then stops
|
|
66
|
+
6. Auto-commits progress after each iteration (fails gracefully if no git)
|
|
67
|
+
7. Stops when Claude outputs `<promise>COMPLETE</promise>`
|
|
67
68
|
|
|
68
69
|
## Config
|
|
69
70
|
|
|
@@ -90,7 +91,7 @@ Save as `.ralph/paths.json`. Refs are optional reference material (read-only).
|
|
|
90
91
|
|
|
91
92
|
### TODO Format
|
|
92
93
|
|
|
93
|
-
Claude maintains this structure:
|
|
94
|
+
Claude maintains this structure (one task per iteration):
|
|
94
95
|
|
|
95
96
|
```markdown
|
|
96
97
|
# Tasks
|
|
@@ -98,9 +99,17 @@ Claude maintains this structure:
|
|
|
98
99
|
- [ ] Pending task
|
|
99
100
|
- [x] Completed task
|
|
100
101
|
|
|
102
|
+
---
|
|
103
|
+
|
|
101
104
|
# Notes
|
|
102
105
|
|
|
103
|
-
|
|
106
|
+
## Task 1 - Done
|
|
107
|
+
- What was implemented
|
|
108
|
+
- Files changed
|
|
109
|
+
- Learnings: patterns discovered, gotchas encountered
|
|
110
|
+
|
|
111
|
+
## Task 2 - Done
|
|
112
|
+
- ...
|
|
104
113
|
```
|
|
105
114
|
|
|
106
115
|
## First Run (No .ralph/ in cwd)
|
package/package.json
CHANGED
package/src/prompt.ts
CHANGED
|
@@ -8,19 +8,19 @@ const BASE_PROMPT = `You are an autonomous coding agent running in a loop.
|
|
|
8
8
|
|
|
9
9
|
FIRST: Read and internalize the rules provided below.
|
|
10
10
|
|
|
11
|
-
## Your Task
|
|
11
|
+
## Your Task This Iteration
|
|
12
12
|
|
|
13
|
-
1. Read the TODO file
|
|
13
|
+
1. Read the TODO file
|
|
14
14
|
2. Pick the FIRST uncompleted task (marked with [ ])
|
|
15
15
|
3. Implement that SINGLE task
|
|
16
16
|
4. Run quality checks (typecheck, lint, test - whatever the project requires)
|
|
17
17
|
5. If checks pass, mark the task [x] complete
|
|
18
|
-
6. Append your progress
|
|
19
|
-
7.
|
|
18
|
+
6. Append your progress to the Notes section
|
|
19
|
+
7. **STOP** - End your response. Another iteration will handle the next task.
|
|
20
20
|
|
|
21
21
|
## Critical Rules
|
|
22
22
|
|
|
23
|
-
- **ONE task per iteration** - Do
|
|
23
|
+
- **ONE task per iteration** - Complete exactly ONE task, then STOP. Do NOT continue to the next task.
|
|
24
24
|
- **Quality first** - Do NOT mark a task complete if tests/typecheck fail
|
|
25
25
|
- **Keep changes focused** - Minimal, targeted changes only
|
|
26
26
|
- **Follow existing patterns** - Match the codebase style
|
|
@@ -38,31 +38,21 @@ After completing a task, APPEND to the Notes section:
|
|
|
38
38
|
- Gotchas encountered
|
|
39
39
|
\`\`\`
|
|
40
40
|
|
|
41
|
-
## Consolidate Patterns
|
|
42
|
-
|
|
43
|
-
If you discover a REUSABLE pattern, add it to the **# Patterns** section at the TOP of the TODO file:
|
|
44
|
-
|
|
45
|
-
\`\`\`
|
|
46
|
-
# Patterns
|
|
47
|
-
- Example: Use \`sql<number>\` template for aggregations
|
|
48
|
-
- Example: Always update X when changing Y
|
|
49
|
-
\`\`\`
|
|
50
|
-
|
|
51
|
-
Only add patterns that are general and reusable, not task-specific details.
|
|
52
|
-
|
|
53
41
|
## Refs (Read-Only)
|
|
54
42
|
|
|
55
43
|
If refs paths are provided, they are READ-ONLY reference material. Never modify files in refs.
|
|
56
44
|
|
|
57
45
|
## Stop Condition
|
|
58
46
|
|
|
59
|
-
After completing
|
|
47
|
+
After completing ONE task, check the TODO file:
|
|
48
|
+
|
|
49
|
+
- If there are still tasks marked [ ] (pending): **END your response normally.** Another iteration will pick up the next task.
|
|
60
50
|
|
|
61
|
-
If ALL tasks are
|
|
51
|
+
- If ALL tasks are marked [x] (complete): Output exactly:
|
|
62
52
|
|
|
63
53
|
<promise>COMPLETE</promise>
|
|
64
54
|
|
|
65
|
-
|
|
55
|
+
**IMPORTANT:** Do NOT continue to the next task. Complete ONE task, then STOP.`;
|
|
66
56
|
|
|
67
57
|
/**
|
|
68
58
|
* Build the complete prompt with config and rules injected
|
package/src/runner.ts
CHANGED
|
@@ -9,13 +9,7 @@ import { setCurrentProcess, throwIfCancelled } from "./state";
|
|
|
9
9
|
const COMPLETION_SIGNAL = "<promise>COMPLETE</promise>";
|
|
10
10
|
const AUTH_CACHE_TTL_MS = 6 * 60 * 60 * 1000; // 6 hours
|
|
11
11
|
|
|
12
|
-
const INITIAL_TODO_CONTENT = `#
|
|
13
|
-
|
|
14
|
-
_None yet - add reusable patterns discovered during work_
|
|
15
|
-
|
|
16
|
-
---
|
|
17
|
-
|
|
18
|
-
# Tasks
|
|
12
|
+
const INITIAL_TODO_CONTENT = `# Tasks
|
|
19
13
|
|
|
20
14
|
- [ ] Task 1
|
|
21
15
|
- [ ] Task 2
|
|
@@ -186,6 +180,48 @@ async function log(state: RunnerState, message: string): Promise<void> {
|
|
|
186
180
|
await Bun.write(state.logFile, existing + logLine);
|
|
187
181
|
}
|
|
188
182
|
|
|
183
|
+
/**
|
|
184
|
+
* Try to commit progress after each iteration
|
|
185
|
+
* Fails gracefully - logs warning and continues if commit fails
|
|
186
|
+
*/
|
|
187
|
+
async function tryCommitProgress(state: RunnerState, cwd: string): Promise<void> {
|
|
188
|
+
try {
|
|
189
|
+
// Stage all changes
|
|
190
|
+
const addProc = Bun.spawn(["git", "add", "-A"], {
|
|
191
|
+
cwd,
|
|
192
|
+
stdout: "pipe",
|
|
193
|
+
stderr: "pipe",
|
|
194
|
+
});
|
|
195
|
+
await addProc.exited;
|
|
196
|
+
|
|
197
|
+
// Commit with iteration number
|
|
198
|
+
const commitMessage = `chore(ralph): iteration ${state.iteration} progress`;
|
|
199
|
+
const commitProc = Bun.spawn(
|
|
200
|
+
["git", "commit", "-m", commitMessage, "--no-verify"],
|
|
201
|
+
{
|
|
202
|
+
cwd,
|
|
203
|
+
stdout: "pipe",
|
|
204
|
+
stderr: "pipe",
|
|
205
|
+
}
|
|
206
|
+
);
|
|
207
|
+
|
|
208
|
+
const exitCode = await commitProc.exited;
|
|
209
|
+
|
|
210
|
+
if (exitCode === 0) {
|
|
211
|
+
consola.info(`Committed iteration ${state.iteration} progress`);
|
|
212
|
+
await log(state, `Committed: ${commitMessage}`);
|
|
213
|
+
} else {
|
|
214
|
+
// Exit code 1 usually means nothing to commit
|
|
215
|
+
await log(state, `No changes to commit for iteration ${state.iteration}`);
|
|
216
|
+
}
|
|
217
|
+
} catch (error) {
|
|
218
|
+
// Gracefully fail - just log and continue
|
|
219
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
220
|
+
consola.warn(`Could not commit progress: ${errorMsg}`);
|
|
221
|
+
await log(state, `Commit failed: ${errorMsg}`);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
189
225
|
/**
|
|
190
226
|
* Run a single Claude iteration
|
|
191
227
|
*/
|
|
@@ -268,6 +304,9 @@ export async function run(config: RalphConfig): Promise<void> {
|
|
|
268
304
|
|
|
269
305
|
const result = await runIteration(prompt, state, cwd);
|
|
270
306
|
|
|
307
|
+
// Try to commit progress after each iteration (fails gracefully)
|
|
308
|
+
await tryCommitProgress(state, cwd);
|
|
309
|
+
|
|
271
310
|
if (result.isComplete) {
|
|
272
311
|
break;
|
|
273
312
|
}
|