@wavilikhin/ralph-wiggum 0.1.14 → 0.1.15
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 +76 -306
- package/package.json +1 -1
- package/src/cli.js +4 -3
- package/templates/ralph-loop.sh +45 -15
package/README.md
CHANGED
|
@@ -1,182 +1,69 @@
|
|
|
1
1
|
# Ralph Wiggum
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/@wavilikhin/ralph-wiggum)
|
|
4
|
-
[](https://github.com/wavilikhin/ralph-wiggum/actions/workflows/publish.yml)
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
____ _ _ __ ___
|
|
8
|
-
| _ \ __ _| |_ __ | |__ \ \ / (_) __ _ _ _ _ _ _ __
|
|
9
|
-
| |_) / _` | | '_ \| '_ \ \ \ /\ / /| |/ _` | | | | | | | '_ \
|
|
10
|
-
| _ < (_| | | |_) | | | | \ V V / | | (_| | |_| | |_| | | | |
|
|
11
|
-
|_| \_\__,_|_| .__/|_| |_| \_/\_/ |_|\__, |\__,_|\__,_|_| |_|
|
|
12
|
-
|_| |___/
|
|
13
|
-
```
|
|
6
|
+
Ralph Wiggum is a tiny wrapper around the “autonomous loop” pattern: run an AI coding agent repeatedly, but keep each iteration small and strict.
|
|
14
7
|
|
|
15
|
-
|
|
8
|
+
Each iteration:
|
|
9
|
+
- starts with fresh context (new process)
|
|
10
|
+
- completes exactly one plan item
|
|
11
|
+
- runs your repo’s validation commands
|
|
12
|
+
- creates exactly one local git commit
|
|
16
13
|
|
|
17
|
-
|
|
18
|
-
# npm
|
|
19
|
-
npx @wavilikhin/ralph-wiggum init
|
|
14
|
+
This keeps context focused and your history clean.
|
|
20
15
|
|
|
21
|
-
|
|
22
|
-
bunx @wavilikhin/ralph-wiggum init
|
|
23
|
-
```
|
|
16
|
+
## Install
|
|
24
17
|
|
|
25
|
-
|
|
18
|
+
No global install needed:
|
|
26
19
|
|
|
27
20
|
```bash
|
|
28
|
-
|
|
29
|
-
npm install -g @wavilikhin/ralph-wiggum
|
|
30
|
-
|
|
31
|
-
# bun
|
|
32
|
-
bun install -g @wavilikhin/ralph-wiggum
|
|
21
|
+
npx @wavilikhin/ralph-wiggum init
|
|
33
22
|
```
|
|
34
23
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
This is a near-vanilla implementation of the [Ralph Wiggum autonomous loop](https://ghuntley.com/ralph/) pattern by Geoffrey Huntley. The core idea: run an AI coding agent in a loop where each iteration gets fresh context, picks exactly one task, implements it, validates it passes all checks, commits, and repeats until done. This produces clean atomic commits and avoids context window bloat.
|
|
38
|
-
|
|
39
|
-
Built for [OpenCode](https://opencode.ai), but should work with any CLI-based coding agent that can read files and run commands.
|
|
40
|
-
|
|
41
|
-
**Additions to the original pattern:**
|
|
42
|
-
- `npx` initialization that scaffolds everything into a `.ralph/` directory
|
|
43
|
-
- Structured logging with timestamps (`.ralph/logs/ralph.log`)
|
|
44
|
-
- `--verbose` flag to preserve full agent output per iteration
|
|
45
|
-
- Enforces exactly one commit per iteration (fails if zero or multiple)
|
|
46
|
-
- Verifies clean working tree after each iteration
|
|
47
|
-
- Phases-based `IMPLEMENTATION_PLAN.md` template
|
|
48
|
-
|
|
49
|
-
---
|
|
50
|
-
|
|
51
|
-
## What is this?
|
|
52
|
-
|
|
53
|
-
Ralph Wiggum runs your coding agent in a loop, where each iteration:
|
|
54
|
-
|
|
55
|
-
1. Starts with **fresh context** (new process, no memory of previous iterations)
|
|
56
|
-
2. Picks **exactly one task** from your implementation plan
|
|
57
|
-
3. Implements it and runs **validation gates** (lint, test, build)
|
|
58
|
-
4. Creates **exactly one commit** (local only, no push)
|
|
59
|
-
5. Repeats until all tasks are complete
|
|
24
|
+
(Inside an existing git repo.)
|
|
60
25
|
|
|
61
|
-
|
|
26
|
+
## Quick start
|
|
62
27
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
> **Warning**: Ralph Wiggum requires the latest generation of AI models to work reliably.
|
|
66
|
-
>
|
|
67
|
-
> The autonomous loop requires models capable of:
|
|
68
|
-
> - Following complex multi-step instructions precisely
|
|
69
|
-
> - Making exactly one commit per iteration
|
|
70
|
-
> - Running validation commands and fixing failures
|
|
71
|
-
> - Updating state files accurately
|
|
72
|
-
>
|
|
73
|
-
> **Recommended models:**
|
|
74
|
-
> - `anthropic/claude-opus-4-20250514`
|
|
75
|
-
> - `openai/gpt-5.2`
|
|
76
|
-
>
|
|
77
|
-
> Using older or less capable models will likely result in failed iterations.
|
|
78
|
-
|
|
79
|
-
## Prerequisites
|
|
80
|
-
|
|
81
|
-
- [OpenCode CLI](https://opencode.ai) installed and configured (or another CLI agent)
|
|
28
|
+
1) Ensure you have prerequisites:
|
|
82
29
|
- Node.js 18+
|
|
83
|
-
-
|
|
84
|
-
-
|
|
85
|
-
|
|
86
|
-
```bash
|
|
87
|
-
# Verify opencode is working
|
|
88
|
-
opencode --version
|
|
89
|
-
|
|
90
|
-
# List available models
|
|
91
|
-
opencode models
|
|
92
|
-
```
|
|
30
|
+
- `opencode` installed and configured (or another CLI agent)
|
|
31
|
+
- a repo-root `AGENTS.md` that lists your validation commands
|
|
93
32
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
Ralph Wiggum expects your repository to have a well-configured `AGENTS.md` file at the root. This file tells the AI agent how to validate changes in your project.
|
|
97
|
-
|
|
98
|
-
Your `AGENTS.md` must include:
|
|
99
|
-
|
|
100
|
-
1. **Validation commands** - How to run formatting, linting, type checking, and tests
|
|
101
|
-
2. **Project structure** - Overview of your codebase layout
|
|
102
|
-
3. **Coding standards** - Any conventions the agent should follow
|
|
103
|
-
|
|
104
|
-
Example minimal `AGENTS.md`:
|
|
105
|
-
|
|
106
|
-
```markdown
|
|
107
|
-
## Validation Commands
|
|
108
|
-
|
|
109
|
-
Run these commands to validate changes:
|
|
110
|
-
|
|
111
|
-
1. Format: `npm run format`
|
|
112
|
-
2. Lint: `npm run lint`
|
|
113
|
-
3. Typecheck: `npm run typecheck`
|
|
114
|
-
4. Test: `npm test`
|
|
115
|
-
|
|
116
|
-
## Project Structure
|
|
117
|
-
|
|
118
|
-
- `src/` - Source code
|
|
119
|
-
- `tests/` - Test files
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
See [OpenCode AGENTS.md documentation](https://opencode.ai/docs/agents-md) for best practices.
|
|
123
|
-
|
|
124
|
-
## Quick Start
|
|
125
|
-
|
|
126
|
-
### 1. Initialize in your repo
|
|
33
|
+
2) Scaffold `.ralph/`:
|
|
127
34
|
|
|
128
35
|
```bash
|
|
129
|
-
cd your-project
|
|
130
36
|
npx @wavilikhin/ralph-wiggum init
|
|
131
37
|
```
|
|
132
38
|
|
|
133
|
-
|
|
134
|
-
-
|
|
135
|
-
-
|
|
136
|
-
- `run.sh` - The loop runner
|
|
137
|
-
- `logs/` - Directory for iteration logs
|
|
39
|
+
3) Fill in tasks:
|
|
40
|
+
- Edit `.ralph/IMPLEMENTATION_PLAN.md`
|
|
41
|
+
- Use checkboxes (`- [ ]`, `- [x]`)
|
|
138
42
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
Edit `.ralph/IMPLEMENTATION_PLAN.md` with your tasks:
|
|
142
|
-
|
|
143
|
-
```markdown
|
|
144
|
-
## Phase 1: Foundation
|
|
145
|
-
|
|
146
|
-
- [ ] Set up project structure with src/ and tests/ directories
|
|
147
|
-
- [ ] Add TypeScript configuration
|
|
148
|
-
- [ ] Create initial CI pipeline
|
|
149
|
-
|
|
150
|
-
## Phase 2: Core Implementation
|
|
151
|
-
|
|
152
|
-
- [ ] Implement user authentication module
|
|
153
|
-
- [ ] Add database connection layer
|
|
154
|
-
- [ ] Create REST API endpoints
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
Use the checkbox format (`- [ ]` / `- [x]`) - the agent marks tasks complete as it works.
|
|
158
|
-
|
|
159
|
-
### 3. Run the loop
|
|
43
|
+
4) Run the loop:
|
|
160
44
|
|
|
161
45
|
```bash
|
|
162
46
|
.ralph/run.sh --max-iterations 20 --model anthropic/claude-opus-4-20250514
|
|
163
47
|
```
|
|
164
48
|
|
|
165
|
-
The loop
|
|
166
|
-
-
|
|
167
|
-
-
|
|
168
|
-
-
|
|
49
|
+
The loop stops when either:
|
|
50
|
+
- all tasks are checked off and the agent outputs `<promise>COMPLETE</promise>`
|
|
51
|
+
- `--max-iterations` is reached
|
|
52
|
+
- you press Ctrl+C
|
|
53
|
+
|
|
54
|
+
## Flags
|
|
169
55
|
|
|
170
|
-
|
|
56
|
+
`ralph-wiggum init` scaffolds files. The loop itself is controlled via `.ralph/run.sh`:
|
|
171
57
|
|
|
172
58
|
```bash
|
|
173
59
|
.ralph/run.sh [options]
|
|
174
60
|
|
|
175
61
|
Options:
|
|
176
|
-
--max-iterations N Maximum iterations (default: 50)
|
|
62
|
+
--max-iterations N Maximum iterations before stopping (default: 50)
|
|
177
63
|
--model MODEL Model to use (default: anthropic/claude-opus-4-20250514)
|
|
178
|
-
--variant NAME Optional variant name
|
|
179
|
-
--verbose
|
|
64
|
+
--variant NAME Optional variant name passed to opencode
|
|
65
|
+
--verbose Keep per-iteration logs (.ralph/logs/ralph_iter_N.log)
|
|
66
|
+
--live Stream opencode output (requires --verbose)
|
|
180
67
|
--help Show help
|
|
181
68
|
|
|
182
69
|
Environment variables:
|
|
@@ -184,193 +71,76 @@ Environment variables:
|
|
|
184
71
|
RALPH_MODEL Default model
|
|
185
72
|
```
|
|
186
73
|
|
|
187
|
-
##
|
|
74
|
+
## What gets created
|
|
188
75
|
|
|
189
|
-
|
|
76
|
+
`init` creates a `.ralph/` directory:
|
|
77
|
+
- `.ralph/PROMPT.md` – instructions the agent reads every iteration
|
|
78
|
+
- `.ralph/IMPLEMENTATION_PLAN.md` – your checklist of tasks
|
|
79
|
+
- `.ralph/run.sh` – the loop runner
|
|
80
|
+
- `.ralph/logs/` – log directory (ignored via `.gitignore`)
|
|
190
81
|
|
|
191
|
-
|
|
82
|
+
## Logs
|
|
192
83
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
```
|
|
196
|
-
[2025-01-19 14:30:15] [ITER] === Iteration 1/20 STARTED ===
|
|
197
|
-
[2025-01-19 14:32:47] [ITER] === Iteration 1 FINISHED: SUCCESS (152s) - feat: add user auth module ===
|
|
198
|
-
[2025-01-19 14:32:48] [ITER] === Iteration 2/20 STARTED ===
|
|
199
|
-
```
|
|
84
|
+
- `.ralph/logs/ralph.log` is always written (timestamps + iteration status).
|
|
85
|
+
- `.ralph/logs/ralph_iter_N.log` is kept only with `--verbose` (or on failures).
|
|
200
86
|
|
|
201
|
-
|
|
87
|
+
Watch progress:
|
|
202
88
|
|
|
203
89
|
```bash
|
|
204
|
-
# Watch progress in real-time
|
|
205
90
|
tail -f .ralph/logs/ralph.log
|
|
206
91
|
```
|
|
207
92
|
|
|
208
|
-
|
|
93
|
+
## Safety
|
|
209
94
|
|
|
210
|
-
|
|
95
|
+
- Never pushes: commits are local only.
|
|
96
|
+
- Enforces one commit per iteration.
|
|
97
|
+
- Requires a clean working tree after each iteration.
|
|
211
98
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
```
|
|
215
|
-
|
|
216
|
-
On failure, the iteration log is always preserved for debugging.
|
|
217
|
-
|
|
218
|
-
## Examples
|
|
219
|
-
|
|
220
|
-
### Run with Claude Opus 4
|
|
221
|
-
|
|
222
|
-
```bash
|
|
223
|
-
.ralph/run.sh --max-iterations 10 --model anthropic/claude-opus-4-20250514
|
|
224
|
-
```
|
|
99
|
+
<details>
|
|
100
|
+
<summary><strong>AI agent appendix (full detail)</strong></summary>
|
|
225
101
|
|
|
226
|
-
###
|
|
102
|
+
### Model requirements
|
|
227
103
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
104
|
+
This loop is strict and works best with high-end models that can follow multistep instructions reliably:
|
|
105
|
+
- `anthropic/claude-opus-4-20250514`
|
|
106
|
+
- `openai/gpt-5.2`
|
|
231
107
|
|
|
232
|
-
###
|
|
108
|
+
### `AGENTS.md` (repo root) is required
|
|
233
109
|
|
|
234
|
-
|
|
235
|
-
export RALPH_MODEL="anthropic/claude-opus-4-20250514"
|
|
236
|
-
export RALPH_MAX_ITERATIONS=30
|
|
237
|
-
.ralph/run.sh
|
|
238
|
-
```
|
|
110
|
+
Ralph Wiggum expects a repo-root `AGENTS.md` that tells the agent how to validate changes.
|
|
239
111
|
|
|
240
|
-
|
|
112
|
+
At minimum, include:
|
|
113
|
+
- formatting command
|
|
114
|
+
- lint command
|
|
115
|
+
- typecheck command (if applicable)
|
|
116
|
+
- test command
|
|
241
117
|
|
|
242
|
-
|
|
243
|
-
.ralph/run.sh --max-iterations 1
|
|
244
|
-
```
|
|
245
|
-
|
|
246
|
-
### Debug mode (verbose + single iteration)
|
|
247
|
-
|
|
248
|
-
```bash
|
|
249
|
-
.ralph/run.sh --verbose --max-iterations 1
|
|
250
|
-
```
|
|
251
|
-
|
|
252
|
-
## How It Works
|
|
253
|
-
|
|
254
|
-
```
|
|
255
|
-
.ralph/run.sh
|
|
256
|
-
|
|
|
257
|
-
v
|
|
258
|
-
+---------------------------------------+
|
|
259
|
-
| Iteration N |
|
|
260
|
-
| +----------------------------------+ |
|
|
261
|
-
| | 1. Record git HEAD | |
|
|
262
|
-
| | 2. Run: opencode run ... | |
|
|
263
|
-
| | 3. Agent reads PROMPT.md | |
|
|
264
|
-
| | 4. Agent picks ONE task | |
|
|
265
|
-
| | 5. Agent implements + validates | |
|
|
266
|
-
| | 6. Agent commits (local only) | |
|
|
267
|
-
| | 7. Check: exactly 1 commit? | |
|
|
268
|
-
| | 8. Check: working tree clean? | |
|
|
269
|
-
| | 9. Check: COMPLETE marker? | |
|
|
270
|
-
| +----------------------------------+ |
|
|
271
|
-
+---------------------------------------+
|
|
272
|
-
|
|
|
273
|
-
+------------+------------+
|
|
274
|
-
v v
|
|
275
|
-
[COMPLETE] [Continue]
|
|
276
|
-
Exit 0 Iteration N+1
|
|
277
|
-
```
|
|
278
|
-
|
|
279
|
-
Each iteration is a fresh `opencode run` process, so the agent:
|
|
280
|
-
- Has no memory of previous iterations
|
|
281
|
-
- Must re-read PROMPT.md, AGENTS.md, IMPLEMENTATION_PLAN.md
|
|
282
|
-
- Stays focused on one task at a time
|
|
283
|
-
|
|
284
|
-
## File Structure
|
|
285
|
-
|
|
286
|
-
After initialization, your repo will have:
|
|
287
|
-
|
|
288
|
-
```
|
|
289
|
-
your-project/
|
|
290
|
-
├── .ralph/
|
|
291
|
-
│ ├── PROMPT.md # Agent instructions (edit [CUSTOMIZABLE] sections)
|
|
292
|
-
│ ├── IMPLEMENTATION_PLAN.md # Your task list (fill this in)
|
|
293
|
-
│ ├── run.sh # Loop runner script
|
|
294
|
-
│ └── logs/
|
|
295
|
-
│ ├── ralph.log # Iteration status log
|
|
296
|
-
│ └── ralph_iter_N.log # Per-iteration logs (verbose/error only)
|
|
297
|
-
├── AGENTS.md # Your validation commands (required, you create this)
|
|
298
|
-
└── .gitignore # Updated to ignore .ralph/logs/
|
|
299
|
-
```
|
|
300
|
-
|
|
301
|
-
### .ralph/PROMPT.md
|
|
302
|
-
|
|
303
|
-
Contains instructions the agent follows each iteration. Has two types of sections:
|
|
304
|
-
|
|
305
|
-
- **[MANDATORY] sections**: Core loop mechanics - don't modify these
|
|
306
|
-
- **[CUSTOMIZABLE] sections**: Add project-specific context, quality standards
|
|
307
|
-
|
|
308
|
-
### .ralph/IMPLEMENTATION_PLAN.md
|
|
309
|
-
|
|
310
|
-
Your task list. Structure it in phases:
|
|
118
|
+
Example (minimal):
|
|
311
119
|
|
|
312
120
|
```markdown
|
|
313
|
-
##
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
- [ ] Task 3
|
|
319
|
-
|
|
320
|
-
## Discovered Tasks
|
|
321
|
-
<!-- Agent adds tasks here as it finds them -->
|
|
322
|
-
```
|
|
323
|
-
|
|
324
|
-
### AGENTS.md (your file, repo root)
|
|
325
|
-
|
|
326
|
-
Your project's agent configuration. Must exist in repo root before running.
|
|
327
|
-
|
|
328
|
-
## Safety Features
|
|
329
|
-
|
|
330
|
-
- **Local only**: Never pushes to remote
|
|
331
|
-
- **One commit per iteration**: Enforced by the loop
|
|
332
|
-
- **Clean working tree**: Verified after each iteration
|
|
333
|
-
- **Max iterations**: Hard stop to prevent runaway loops
|
|
334
|
-
- **Validation gates**: All must pass before commit
|
|
335
|
-
|
|
336
|
-
## Troubleshooting
|
|
337
|
-
|
|
338
|
-
### "opencode CLI not found"
|
|
339
|
-
|
|
340
|
-
Install OpenCode:
|
|
341
|
-
```bash
|
|
342
|
-
npm install -g opencode
|
|
121
|
+
## Validation Commands
|
|
122
|
+
1. Format: `npm run format`
|
|
123
|
+
2. Lint: `npm run lint`
|
|
124
|
+
3. Typecheck: `npm run typecheck`
|
|
125
|
+
4. Test: `npm test`
|
|
343
126
|
```
|
|
344
127
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
Create an `AGENTS.md` file in your repo root with validation commands. See the [AGENTS.md Requirement](#agentsmd-requirement) section.
|
|
348
|
-
|
|
349
|
-
### "No commit was created"
|
|
350
|
-
|
|
351
|
-
The agent must create exactly one commit per iteration. Check `.ralph/logs/ralph_iter_N.log` to see what happened. Common causes:
|
|
352
|
-
- Validation gates failed
|
|
353
|
-
- Agent got stuck on a complex task
|
|
354
|
-
- Task was already complete
|
|
355
|
-
- Model not capable enough (try a more advanced model)
|
|
356
|
-
|
|
357
|
-
### "Working tree is not clean"
|
|
128
|
+
OpenCode docs: https://opencode.ai/docs/agents-md
|
|
358
129
|
|
|
359
|
-
|
|
130
|
+
### What happens each iteration
|
|
360
131
|
|
|
361
|
-
|
|
132
|
+
- A fresh `opencode run` process starts (no memory).
|
|
133
|
+
- The agent reads (at least) `.ralph/PROMPT.md`, `.ralph/IMPLEMENTATION_PLAN.md`, and `AGENTS.md`.
|
|
134
|
+
- The agent must pick exactly one unchecked task, implement it, run all validation gates, update the plan, and make exactly one commit.
|
|
135
|
+
- When every task is complete, the agent must output exactly `<promise>COMPLETE</promise>`.
|
|
362
136
|
|
|
363
|
-
|
|
364
|
-
- Ensure validation commands in AGENTS.md are correct
|
|
365
|
-
- Try running with `--verbose --max-iterations 1` to debug a single iteration
|
|
366
|
-
- Consider using a more capable model
|
|
137
|
+
### Templates
|
|
367
138
|
|
|
368
|
-
|
|
139
|
+
Scaffolded from:
|
|
140
|
+
- `templates/PROMPT.md`
|
|
141
|
+
- `templates/IMPLEMENTATION_PLAN.md`
|
|
369
142
|
|
|
370
|
-
|
|
371
|
-
- Using `anthropic/claude-opus-4-20250514` or `openai/gpt-5.2`
|
|
372
|
-
- Simplifying tasks in IMPLEMENTATION_PLAN.md
|
|
373
|
-
- Adding more context to AGENTS.md
|
|
143
|
+
</details>
|
|
374
144
|
|
|
375
145
|
## Credits
|
|
376
146
|
|
package/package.json
CHANGED
package/src/cli.js
CHANGED
|
@@ -74,10 +74,11 @@ ${YELLOW}Available loop options:${RESET}
|
|
|
74
74
|
--max-iterations N Maximum iterations before stopping (default: 50)
|
|
75
75
|
--model provider/m Model to use (default: anthropic/claude-opus-4-20250514)
|
|
76
76
|
--variant name Optional variant name passed to opencode
|
|
77
|
-
--verbose
|
|
77
|
+
--verbose Save per-iteration logs (.ralph/logs/ralph_iter_N.log)
|
|
78
|
+
--live Stream opencode output to terminal (requires --verbose)
|
|
78
79
|
|
|
79
|
-
${DIM}Logs are written to ${CYAN}.ralph/logs/ralph.log${RESET}${DIM} (iteration status)${RESET}
|
|
80
|
-
${DIM}Verbose logs: ${CYAN}.ralph/logs/ralph_iter_N.log${RESET}${DIM} (full output per iteration)${RESET}
|
|
80
|
+
${DIM}Logs are written to ${CYAN}.ralph/logs/ralph.log${RESET}${DIM} (iteration status + timings)${RESET}
|
|
81
|
+
${DIM}Verbose logs: ${CYAN}.ralph/logs/ralph_iter_N.log${RESET}${DIM} (full output per iteration, --verbose only)${RESET}
|
|
81
82
|
|
|
82
83
|
${DIM}The loop stops automatically when all tasks are complete (<promise>COMPLETE</promise>)${RESET}
|
|
83
84
|
`);
|
package/templates/ralph-loop.sh
CHANGED
|
@@ -17,6 +17,7 @@ MAX_ITERATIONS="${RALPH_MAX_ITERATIONS:-50}"
|
|
|
17
17
|
MODEL="${RALPH_MODEL:-anthropic/claude-opus-4-20250514}"
|
|
18
18
|
VARIANT=""
|
|
19
19
|
VERBOSE=false
|
|
20
|
+
LIVE=false
|
|
20
21
|
|
|
21
22
|
# All ralph files are in .ralph/
|
|
22
23
|
RALPH_DIR="$SCRIPT_DIR"
|
|
@@ -83,8 +84,11 @@ log_iteration_end() {
|
|
|
83
84
|
local iter="$1"
|
|
84
85
|
local status="$2"
|
|
85
86
|
local commit_msg="$3"
|
|
86
|
-
local
|
|
87
|
-
|
|
87
|
+
local iter_duration="$4"
|
|
88
|
+
local opencode_duration="$5"
|
|
89
|
+
log_to_file "ITER" "=== Iteration $iter FINISHED: $status (iter=${iter_duration}s, opencode=${opencode_duration}s) - $commit_msg ==="
|
|
90
|
+
echo ""
|
|
91
|
+
echo -e "${DIM}Timing: opencode=${opencode_duration}s, iteration=${iter_duration}s${NC}"
|
|
88
92
|
}
|
|
89
93
|
|
|
90
94
|
#=============================================================================
|
|
@@ -111,7 +115,8 @@ print_usage() {
|
|
|
111
115
|
echo " --max-iterations N Maximum iterations (default: $MAX_ITERATIONS)"
|
|
112
116
|
echo " --model MODEL Model to use (default: $MODEL)"
|
|
113
117
|
echo " --variant NAME Variant name for opencode"
|
|
114
|
-
echo " --verbose
|
|
118
|
+
echo " --verbose Save per-iteration logs (.ralph/logs/ralph_iter_N.log)"
|
|
119
|
+
echo " --live Stream opencode output to terminal (requires --verbose)"
|
|
115
120
|
echo " --help Show this help"
|
|
116
121
|
echo ""
|
|
117
122
|
echo "Environment variables:"
|
|
@@ -119,11 +124,11 @@ print_usage() {
|
|
|
119
124
|
echo " RALPH_MODEL Default model"
|
|
120
125
|
echo ""
|
|
121
126
|
echo "Logs:"
|
|
122
|
-
echo " .ralph/logs/ralph.log Iteration status (always written)"
|
|
123
|
-
echo " .ralph/logs/ralph_iter_N.log Full opencode output (verbose
|
|
127
|
+
echo " .ralph/logs/ralph.log Iteration status + timings (always written)"
|
|
128
|
+
echo " .ralph/logs/ralph_iter_N.log Full opencode output (--verbose only)"
|
|
124
129
|
echo ""
|
|
125
130
|
echo "Example:"
|
|
126
|
-
echo " $0 --max-iterations 10 --
|
|
131
|
+
echo " $0 --max-iterations 10 --verbose --live"
|
|
127
132
|
}
|
|
128
133
|
|
|
129
134
|
check_prerequisites() {
|
|
@@ -201,6 +206,10 @@ while [[ $# -gt 0 ]]; do
|
|
|
201
206
|
VERBOSE=true
|
|
202
207
|
shift
|
|
203
208
|
;;
|
|
209
|
+
--live)
|
|
210
|
+
LIVE=true
|
|
211
|
+
shift
|
|
212
|
+
;;
|
|
204
213
|
--help|-h)
|
|
205
214
|
print_usage
|
|
206
215
|
exit 0
|
|
@@ -223,10 +232,17 @@ log_info "Configuration:"
|
|
|
223
232
|
echo -e " ${DIM}Max iterations:${NC} $MAX_ITERATIONS"
|
|
224
233
|
echo -e " ${DIM}Model:${NC} $MODEL"
|
|
225
234
|
echo -e " ${DIM}Verbose:${NC} $VERBOSE"
|
|
235
|
+
echo -e " ${DIM}Live output:${NC} $LIVE"
|
|
226
236
|
echo -e " ${DIM}Repo root:${NC} $REPO_ROOT"
|
|
227
237
|
[[ -n "$VARIANT" ]] && echo -e " ${DIM}Variant:${NC} $VARIANT"
|
|
228
238
|
echo ""
|
|
229
239
|
|
|
240
|
+
# Validate --live requires --verbose
|
|
241
|
+
if [[ "$LIVE" == true && "$VERBOSE" != true ]]; then
|
|
242
|
+
log_error "--live requires --verbose flag"
|
|
243
|
+
exit 1
|
|
244
|
+
fi
|
|
245
|
+
|
|
230
246
|
check_prerequisites
|
|
231
247
|
|
|
232
248
|
mkdir -p "$LOGS_DIR"
|
|
@@ -270,23 +286,37 @@ for i in $(seq 1 "$MAX_ITERATIONS"); do
|
|
|
270
286
|
|
|
271
287
|
log_info "Running opencode..."
|
|
272
288
|
|
|
289
|
+
OPENCODE_START=$(date +%s)
|
|
290
|
+
|
|
273
291
|
set +e
|
|
274
|
-
if [[ "$
|
|
275
|
-
|
|
292
|
+
if [[ "$LIVE" == true ]]; then
|
|
293
|
+
# Stream to terminal AND write to log file
|
|
294
|
+
"${OPENCODE_CMD[@]}" 2>&1 | tee "$ITER_LOG_FILE"
|
|
295
|
+
EXIT_CODE=${PIPESTATUS[0]}
|
|
296
|
+
OUTPUT=$(cat "$ITER_LOG_FILE")
|
|
297
|
+
elif [[ "$VERBOSE" == true ]]; then
|
|
298
|
+
# Write to log file only (no terminal stream)
|
|
299
|
+
"${OPENCODE_CMD[@]}" > "$ITER_LOG_FILE" 2>&1
|
|
300
|
+
EXIT_CODE=$?
|
|
301
|
+
OUTPUT=$(cat "$ITER_LOG_FILE")
|
|
276
302
|
else
|
|
303
|
+
# Capture output, write temp file for error inspection
|
|
277
304
|
OUTPUT=$("${OPENCODE_CMD[@]}" 2>&1)
|
|
305
|
+
EXIT_CODE=$?
|
|
278
306
|
echo "$OUTPUT" > "$ITER_LOG_FILE"
|
|
279
307
|
fi
|
|
280
|
-
EXIT_CODE=$?
|
|
281
308
|
set -e
|
|
282
309
|
|
|
310
|
+
OPENCODE_END=$(date +%s)
|
|
311
|
+
OPENCODE_DURATION=$((OPENCODE_END - OPENCODE_START))
|
|
312
|
+
|
|
283
313
|
ITER_END=$(date +%s)
|
|
284
314
|
ITER_DURATION=$((ITER_END - ITER_START))
|
|
285
315
|
|
|
286
316
|
if [[ $EXIT_CODE -ne 0 ]]; then
|
|
287
317
|
log_error "opencode exited with code $EXIT_CODE"
|
|
288
318
|
log_error "Check log: $ITER_LOG_FILE"
|
|
289
|
-
log_iteration_end "$i" "FAILED" "opencode error" "$ITER_DURATION"
|
|
319
|
+
log_iteration_end "$i" "FAILED" "opencode error" "$ITER_DURATION" "$OPENCODE_DURATION"
|
|
290
320
|
exit 1
|
|
291
321
|
fi
|
|
292
322
|
|
|
@@ -295,7 +325,7 @@ for i in $(seq 1 "$MAX_ITERATIONS"); do
|
|
|
295
325
|
log_success "All tasks complete!"
|
|
296
326
|
echo ""
|
|
297
327
|
echo -e "${GREEN}${BOLD}Loop finished successfully after $i iteration(s)${NC}"
|
|
298
|
-
log_iteration_end "$i" "COMPLETE" "all tasks done" "$ITER_DURATION"
|
|
328
|
+
log_iteration_end "$i" "COMPLETE" "all tasks done" "$ITER_DURATION" "$OPENCODE_DURATION"
|
|
299
329
|
log_to_file "INFO" "=== LOOP COMPLETED SUCCESSFULLY ==="
|
|
300
330
|
exit 0
|
|
301
331
|
fi
|
|
@@ -307,14 +337,14 @@ for i in $(seq 1 "$MAX_ITERATIONS"); do
|
|
|
307
337
|
log_error "No commit was created in this iteration!"
|
|
308
338
|
log_error "The agent must create exactly one commit per iteration."
|
|
309
339
|
log_error "Check log: $ITER_LOG_FILE"
|
|
310
|
-
log_iteration_end "$i" "FAILED" "no commit created" "$ITER_DURATION"
|
|
340
|
+
log_iteration_end "$i" "FAILED" "no commit created" "$ITER_DURATION" "$OPENCODE_DURATION"
|
|
311
341
|
exit 1
|
|
312
342
|
fi
|
|
313
343
|
|
|
314
344
|
COMMIT_COUNT=$(git rev-list --count "$BEFORE_HEAD".."$AFTER_HEAD")
|
|
315
345
|
if [[ "$COMMIT_COUNT" -ne 1 ]]; then
|
|
316
346
|
log_error "Expected 1 commit, but $COMMIT_COUNT were created!"
|
|
317
|
-
log_iteration_end "$i" "FAILED" "multiple commits" "$ITER_DURATION"
|
|
347
|
+
log_iteration_end "$i" "FAILED" "multiple commits" "$ITER_DURATION" "$OPENCODE_DURATION"
|
|
318
348
|
exit 1
|
|
319
349
|
fi
|
|
320
350
|
|
|
@@ -322,13 +352,13 @@ for i in $(seq 1 "$MAX_ITERATIONS"); do
|
|
|
322
352
|
log_error "Working tree is not clean after iteration!"
|
|
323
353
|
echo ""
|
|
324
354
|
git status --short
|
|
325
|
-
log_iteration_end "$i" "FAILED" "dirty working tree" "$ITER_DURATION"
|
|
355
|
+
log_iteration_end "$i" "FAILED" "dirty working tree" "$ITER_DURATION" "$OPENCODE_DURATION"
|
|
326
356
|
exit 1
|
|
327
357
|
fi
|
|
328
358
|
|
|
329
359
|
COMMIT_MSG=$(git log -1 --format='%s')
|
|
330
360
|
log_success "Commit created: $COMMIT_MSG"
|
|
331
|
-
log_iteration_end "$i" "SUCCESS" "$COMMIT_MSG" "$ITER_DURATION"
|
|
361
|
+
log_iteration_end "$i" "SUCCESS" "$COMMIT_MSG" "$ITER_DURATION" "$OPENCODE_DURATION"
|
|
332
362
|
|
|
333
363
|
if [[ "$VERBOSE" != true ]]; then
|
|
334
364
|
rm -f "$ITER_LOG_FILE"
|