@wavilikhin/ralph-wiggum 0.1.14 → 0.1.16

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  # Ralph Wiggum
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/@wavilikhin/ralph-wiggum.svg)](https://www.npmjs.com/package/@wavilikhin/ralph-wiggum)
4
- [![npm publish](https://github.com/wavilikhin/ralph-wiggum/actions/workflows/publish.yml/badge.svg?event=push)](https://github.com/wavilikhin/ralph-wiggum/actions/workflows/publish.yml)
4
+ [![npm publish](https://github.com/wavilikhin/ralph-wiggum/actions/workflows/publish.yml/badge.svg)](https://github.com/wavilikhin/ralph-wiggum/actions/workflows/publish.yml)
5
5
 
6
6
  ```
7
7
  ____ _ _ __ ___
@@ -12,171 +12,71 @@
12
12
  |_| |___/
13
13
  ```
14
14
 
15
- ## Installation
15
+ Ralph Wiggum is a tiny wrapper around the “autonomous loop” pattern: run an AI coding agent repeatedly, but keep each iteration small and strict.
16
16
 
17
- ```bash
18
- # npm
19
- npx @wavilikhin/ralph-wiggum init
20
-
21
- # bun
22
- bunx @wavilikhin/ralph-wiggum init
23
- ```
24
-
25
- Or install globally:
26
-
27
- ```bash
28
- # npm
29
- npm install -g @wavilikhin/ralph-wiggum
30
-
31
- # bun
32
- bun install -g @wavilikhin/ralph-wiggum
33
- ```
34
-
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
- ---
17
+ Origin: the [Ralph Wiggum autonomous loop](https://ghuntley.com/ralph/) pattern by Geoffrey Huntley.
50
18
 
51
- ## What is this?
19
+ Each iteration:
20
+ - starts with fresh context (new process)
21
+ - completes exactly one plan item
22
+ - runs your repo’s validation commands
23
+ - creates exactly one local git commit
52
24
 
53
- Ralph Wiggum runs your coding agent in a loop, where each iteration:
25
+ This keeps context focused and your history clean.
54
26
 
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
27
+ ## Install
60
28
 
61
- This approach keeps context focused and produces clean, atomic commits.
62
-
63
- ## Model Requirements
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)
82
- - Node.js 18+
83
- - Git repository
84
- - **AGENTS.md file in your repo root** (see below)
29
+ No global install needed:
85
30
 
86
31
  ```bash
87
- # Verify opencode is working
88
- opencode --version
89
-
90
- # List available models
91
- opencode models
32
+ npx @wavilikhin/ralph-wiggum init
92
33
  ```
93
34
 
94
- ### AGENTS.md Requirement
35
+ (Inside an existing git repo.)
95
36
 
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
37
+ ## Quick start
108
38
 
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
39
+ 1) Ensure you have prerequisites:
40
+ - Node.js 18+
41
+ - `opencode` installed and configured (or another CLI agent)
42
+ - a repo-root `AGENTS.md` that lists your validation commands
125
43
 
126
- ### 1. Initialize in your repo
44
+ 2) Scaffold `.ralph/`:
127
45
 
128
46
  ```bash
129
- cd your-project
130
47
  npx @wavilikhin/ralph-wiggum init
131
48
  ```
132
49
 
133
- This creates a `.ralph/` directory with:
134
- - `PROMPT.md` - Instructions for the AI agent (has mandatory + customizable sections)
135
- - `IMPLEMENTATION_PLAN.md` - Your task list template
136
- - `run.sh` - The loop runner
137
- - `logs/` - Directory for iteration logs
138
-
139
- ### 2. Fill in your implementation plan
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.
50
+ 3) Fill in tasks:
51
+ - Edit `.ralph/IMPLEMENTATION_PLAN.md`
52
+ - Use checkboxes (`- [ ]`, `- [x]`)
158
53
 
159
- ### 3. Run the loop
54
+ 4) Run the loop:
160
55
 
161
56
  ```bash
162
57
  .ralph/run.sh --max-iterations 20 --model anthropic/claude-opus-4-20250514
163
58
  ```
164
59
 
165
- The loop runs until:
166
- - All tasks are complete (agent outputs `<promise>COMPLETE</promise>`)
167
- - Max iterations reached
168
- - You press Ctrl+C
60
+ The loop stops when either:
61
+ - all tasks are checked off and the agent outputs `<promise>COMPLETE</promise>`
62
+ - `--max-iterations` is reached
63
+ - you press Ctrl+C
169
64
 
170
- ## CLI Options
65
+ ## Flags
66
+
67
+ `ralph-wiggum init` scaffolds files. The loop itself is controlled via `.ralph/run.sh`.
68
+
69
+ Any additional flags are forwarded to `opencode run`.
171
70
 
172
71
  ```bash
173
72
  .ralph/run.sh [options]
174
73
 
175
74
  Options:
176
- --max-iterations N Maximum iterations (default: 50)
75
+ --max-iterations N Maximum iterations before stopping (default: 50)
177
76
  --model MODEL Model to use (default: anthropic/claude-opus-4-20250514)
178
- --variant NAME Optional variant name for opencode
179
- --verbose Enable verbose logging (keeps full opencode output)
77
+ --variant NAME Optional variant name passed to opencode
78
+ --verbose Keep per-iteration logs (.ralph/logs/ralph_iter_N.log)
79
+ --live Stream opencode output (requires --verbose)
180
80
  --help Show help
181
81
 
182
82
  Environment variables:
@@ -184,193 +84,76 @@ Environment variables:
184
84
  RALPH_MODEL Default model
185
85
  ```
186
86
 
187
- ## Logging
188
-
189
- Ralph Wiggum maintains two types of logs in `.ralph/logs/`:
87
+ ## What gets created
190
88
 
191
- ### Status Log (`.ralph/logs/ralph.log`)
89
+ `init` creates a `.ralph/` directory:
90
+ - `.ralph/PROMPT.md` – instructions the agent reads every iteration
91
+ - `.ralph/IMPLEMENTATION_PLAN.md` – your checklist of tasks
92
+ - `.ralph/run.sh` – the loop runner
93
+ - `.ralph/logs/` – log directory (ignored via `.gitignore`)
192
94
 
193
- Always written. Contains iteration status with timestamps:
95
+ ## Logs
194
96
 
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
- ```
97
+ - `.ralph/logs/ralph.log` is always written (timestamps + iteration status).
98
+ - `.ralph/logs/ralph_iter_N.log` is kept only with `--verbose` (or on failures).
200
99
 
201
- Use this to monitor progress:
100
+ Watch progress:
202
101
 
203
102
  ```bash
204
- # Watch progress in real-time
205
103
  tail -f .ralph/logs/ralph.log
206
104
  ```
207
105
 
208
- ### Verbose Logs (`.ralph/logs/ralph_iter_N.log`)
106
+ ## Safety
209
107
 
210
- Full opencode output per iteration. By default, these are deleted after successful iterations. Use `--verbose` to keep them:
108
+ - Never pushes: commits are local only.
109
+ - Enforces one commit per iteration.
110
+ - Requires a clean working tree after each iteration.
211
111
 
212
- ```bash
213
- .ralph/run.sh --verbose --max-iterations 10
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
- ```
225
-
226
- ### Run with GPT-5.2
227
-
228
- ```bash
229
- .ralph/run.sh --max-iterations 10 --model openai/gpt-5.2
230
- ```
231
-
232
- ### Run with environment variables
233
-
234
- ```bash
235
- export RALPH_MODEL="anthropic/claude-opus-4-20250514"
236
- export RALPH_MAX_ITERATIONS=30
237
- .ralph/run.sh
238
- ```
239
-
240
- ### Dry run (single iteration)
241
-
242
- ```bash
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
112
+ <details>
113
+ <summary><strong>AI agent appendix (full detail)</strong></summary>
283
114
 
284
- ## File Structure
115
+ ### Model requirements
285
116
 
286
- After initialization, your repo will have:
117
+ This loop is strict and works best with high-end models that can follow multistep instructions reliably:
118
+ - `anthropic/claude-opus-4-20250514`
119
+ - `openai/gpt-5.2`
287
120
 
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
- ```
121
+ ### `AGENTS.md` (repo root) is required
300
122
 
301
- ### .ralph/PROMPT.md
123
+ Ralph Wiggum expects a repo-root `AGENTS.md` that tells the agent how to validate changes.
302
124
 
303
- Contains instructions the agent follows each iteration. Has two types of sections:
125
+ At minimum, include:
126
+ - formatting command
127
+ - lint command
128
+ - typecheck command (if applicable)
129
+ - test command
304
130
 
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:
131
+ Example (minimal):
311
132
 
312
133
  ```markdown
313
- ## Phase 1: Foundation
314
- - [ ] Task 1
315
- - [x] Task 2 (completed)
316
-
317
- ## Phase 2: Core
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
134
+ ## Validation Commands
135
+ 1. Format: `npm run format`
136
+ 2. Lint: `npm run lint`
137
+ 3. Typecheck: `npm run typecheck`
138
+ 4. Test: `npm test`
343
139
  ```
344
140
 
345
- ### "AGENTS.md not found"
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"
141
+ OpenCode docs: https://opencode.ai/docs/agents-md
358
142
 
359
- The agent left uncommitted changes. This usually means validation failed. Check the log and fix manually, then restart.
143
+ ### What happens each iteration
360
144
 
361
- ### Loop never completes
145
+ - A fresh `opencode run` process starts (no memory).
146
+ - The agent reads (at least) `.ralph/PROMPT.md`, `.ralph/IMPLEMENTATION_PLAN.md`, and `AGENTS.md`.
147
+ - The agent must pick exactly one unchecked task, implement it, run all validation gates, update the plan, and make exactly one commit.
148
+ - When every task is complete, the agent must output exactly `<promise>COMPLETE</promise>`.
362
149
 
363
- - Check if tasks in `.ralph/IMPLEMENTATION_PLAN.md` are achievable
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
150
+ ### Templates
367
151
 
368
- ### Iterations failing consistently
152
+ Scaffolded from:
153
+ - `templates/PROMPT.md`
154
+ - `templates/IMPLEMENTATION_PLAN.md`
369
155
 
370
- This often indicates the model isn't capable enough for autonomous operation. Try:
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
156
+ </details>
374
157
 
375
158
  ## Credits
376
159
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wavilikhin/ralph-wiggum",
3
- "version": "0.1.14",
3
+ "version": "0.1.16",
4
4
  "description": "Autonomous coding loop for OpenCode - one task, one commit, fresh context per iteration",
5
5
  "type": "module",
6
6
  "bin": {
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 Enable verbose logging (full opencode output)
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
  `);
@@ -17,6 +17,8 @@ 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
21
+ OPENCODE_ARGS=()
20
22
 
21
23
  # All ralph files are in .ralph/
22
24
  RALPH_DIR="$SCRIPT_DIR"
@@ -83,8 +85,11 @@ log_iteration_end() {
83
85
  local iter="$1"
84
86
  local status="$2"
85
87
  local commit_msg="$3"
86
- local duration="$4"
87
- log_to_file "ITER" "=== Iteration $iter FINISHED: $status (${duration}s) - $commit_msg ==="
88
+ local iter_duration="$4"
89
+ local opencode_duration="$5"
90
+ log_to_file "ITER" "=== Iteration $iter FINISHED: $status (iter=${iter_duration}s, opencode=${opencode_duration}s) - $commit_msg ==="
91
+ echo ""
92
+ echo -e "${DIM}Timing: opencode=${opencode_duration}s, iteration=${iter_duration}s${NC}"
88
93
  }
89
94
 
90
95
  #=============================================================================
@@ -111,7 +116,8 @@ print_usage() {
111
116
  echo " --max-iterations N Maximum iterations (default: $MAX_ITERATIONS)"
112
117
  echo " --model MODEL Model to use (default: $MODEL)"
113
118
  echo " --variant NAME Variant name for opencode"
114
- echo " --verbose Enable verbose logging (full opencode output)"
119
+ echo " --verbose Save per-iteration logs (.ralph/logs/ralph_iter_N.log)"
120
+ echo " --live Stream opencode output to terminal (requires --verbose)"
115
121
  echo " --help Show this help"
116
122
  echo ""
117
123
  echo "Environment variables:"
@@ -119,11 +125,11 @@ print_usage() {
119
125
  echo " RALPH_MODEL Default model"
120
126
  echo ""
121
127
  echo "Logs:"
122
- echo " .ralph/logs/ralph.log Iteration status (always written)"
123
- echo " .ralph/logs/ralph_iter_N.log Full opencode output (verbose mode or on error)"
128
+ echo " .ralph/logs/ralph.log Iteration status + timings (always written)"
129
+ echo " .ralph/logs/ralph_iter_N.log Full opencode output (--verbose only)"
124
130
  echo ""
125
131
  echo "Example:"
126
- echo " $0 --max-iterations 10 --model anthropic/claude-opus-4-20250514"
132
+ echo " $0 --max-iterations 10 --verbose --live"
127
133
  }
128
134
 
129
135
  check_prerequisites() {
@@ -201,14 +207,27 @@ while [[ $# -gt 0 ]]; do
201
207
  VERBOSE=true
202
208
  shift
203
209
  ;;
210
+ --live)
211
+ LIVE=true
212
+ shift
213
+ ;;
204
214
  --help|-h)
205
215
  print_usage
206
216
  exit 0
207
217
  ;;
218
+ --)
219
+ shift
220
+ OPENCODE_ARGS+=("$@")
221
+ break
222
+ ;;
208
223
  *)
209
- log_error "Unknown option: $1"
210
- print_usage
211
- exit 1
224
+ if [[ $# -ge 2 && "$2" != -* ]]; then
225
+ OPENCODE_ARGS+=("$1" "$2")
226
+ shift 2
227
+ else
228
+ OPENCODE_ARGS+=("$1")
229
+ shift
230
+ fi
212
231
  ;;
213
232
  esac
214
233
  done
@@ -223,10 +242,17 @@ log_info "Configuration:"
223
242
  echo -e " ${DIM}Max iterations:${NC} $MAX_ITERATIONS"
224
243
  echo -e " ${DIM}Model:${NC} $MODEL"
225
244
  echo -e " ${DIM}Verbose:${NC} $VERBOSE"
245
+ echo -e " ${DIM}Live output:${NC} $LIVE"
226
246
  echo -e " ${DIM}Repo root:${NC} $REPO_ROOT"
227
247
  [[ -n "$VARIANT" ]] && echo -e " ${DIM}Variant:${NC} $VARIANT"
228
248
  echo ""
229
249
 
250
+ # Validate --live requires --verbose
251
+ if [[ "$LIVE" == true && "$VERBOSE" != true ]]; then
252
+ log_error "--live requires --verbose flag"
253
+ exit 1
254
+ fi
255
+
230
256
  check_prerequisites
231
257
 
232
258
  mkdir -p "$LOGS_DIR"
@@ -249,6 +275,7 @@ cd "$REPO_ROOT"
249
275
  for i in $(seq 1 "$MAX_ITERATIONS"); do
250
276
  ITER_START=$(date +%s)
251
277
  ITER_LOG_FILE="$LOGS_DIR/ralph_iter_${i}.log"
278
+ LIVE_PREFIX=" ${DIM}[LIVE ${i}/${MAX_ITERATIONS}]${NC} "
252
279
 
253
280
  log_iteration_start "$i" "$MAX_ITERATIONS"
254
281
 
@@ -265,28 +292,47 @@ for i in $(seq 1 "$MAX_ITERATIONS"); do
265
292
  if [[ -n "$VARIANT" ]]; then
266
293
  OPENCODE_CMD+=(--variant "$VARIANT")
267
294
  fi
295
+
296
+ if [[ ${#OPENCODE_ARGS[@]} -gt 0 ]]; then
297
+ OPENCODE_CMD+=("${OPENCODE_ARGS[@]}")
298
+ fi
268
299
 
269
300
  OPENCODE_CMD+=("Follow the attached PROMPT.md. Use AGENTS.md for validation commands and IMPLEMENTATION_PLAN.md for task selection. Do exactly one task and one commit.")
270
301
 
271
302
  log_info "Running opencode..."
272
303
 
304
+ OPENCODE_START=$(date +%s)
305
+
273
306
  set +e
274
- if [[ "$VERBOSE" == true ]]; then
275
- OUTPUT=$("${OPENCODE_CMD[@]}" 2>&1 | tee "$ITER_LOG_FILE")
307
+ if [[ "$LIVE" == true ]]; then
308
+ # Stream to terminal AND write to log file
309
+ # Prefix each opencode line so it doesn't visually clash with ralph logs.
310
+ "${OPENCODE_CMD[@]}" 2>&1 | while IFS= read -r line; do printf '%b%s\n' "$LIVE_PREFIX" "$line"; done | tee "$ITER_LOG_FILE"
311
+ EXIT_CODE=${PIPESTATUS[0]}
312
+ OUTPUT=$(cat "$ITER_LOG_FILE")
313
+ elif [[ "$VERBOSE" == true ]]; then
314
+ # Write to log file only (no terminal stream)
315
+ "${OPENCODE_CMD[@]}" > "$ITER_LOG_FILE" 2>&1
316
+ EXIT_CODE=$?
317
+ OUTPUT=$(cat "$ITER_LOG_FILE")
276
318
  else
319
+ # Capture output, write temp file for error inspection
277
320
  OUTPUT=$("${OPENCODE_CMD[@]}" 2>&1)
321
+ EXIT_CODE=$?
278
322
  echo "$OUTPUT" > "$ITER_LOG_FILE"
279
323
  fi
280
- EXIT_CODE=$?
281
324
  set -e
282
325
 
326
+ OPENCODE_END=$(date +%s)
327
+ OPENCODE_DURATION=$((OPENCODE_END - OPENCODE_START))
328
+
283
329
  ITER_END=$(date +%s)
284
330
  ITER_DURATION=$((ITER_END - ITER_START))
285
331
 
286
332
  if [[ $EXIT_CODE -ne 0 ]]; then
287
333
  log_error "opencode exited with code $EXIT_CODE"
288
334
  log_error "Check log: $ITER_LOG_FILE"
289
- log_iteration_end "$i" "FAILED" "opencode error" "$ITER_DURATION"
335
+ log_iteration_end "$i" "FAILED" "opencode error" "$ITER_DURATION" "$OPENCODE_DURATION"
290
336
  exit 1
291
337
  fi
292
338
 
@@ -295,7 +341,7 @@ for i in $(seq 1 "$MAX_ITERATIONS"); do
295
341
  log_success "All tasks complete!"
296
342
  echo ""
297
343
  echo -e "${GREEN}${BOLD}Loop finished successfully after $i iteration(s)${NC}"
298
- log_iteration_end "$i" "COMPLETE" "all tasks done" "$ITER_DURATION"
344
+ log_iteration_end "$i" "COMPLETE" "all tasks done" "$ITER_DURATION" "$OPENCODE_DURATION"
299
345
  log_to_file "INFO" "=== LOOP COMPLETED SUCCESSFULLY ==="
300
346
  exit 0
301
347
  fi
@@ -307,14 +353,14 @@ for i in $(seq 1 "$MAX_ITERATIONS"); do
307
353
  log_error "No commit was created in this iteration!"
308
354
  log_error "The agent must create exactly one commit per iteration."
309
355
  log_error "Check log: $ITER_LOG_FILE"
310
- log_iteration_end "$i" "FAILED" "no commit created" "$ITER_DURATION"
356
+ log_iteration_end "$i" "FAILED" "no commit created" "$ITER_DURATION" "$OPENCODE_DURATION"
311
357
  exit 1
312
358
  fi
313
359
 
314
360
  COMMIT_COUNT=$(git rev-list --count "$BEFORE_HEAD".."$AFTER_HEAD")
315
361
  if [[ "$COMMIT_COUNT" -ne 1 ]]; then
316
362
  log_error "Expected 1 commit, but $COMMIT_COUNT were created!"
317
- log_iteration_end "$i" "FAILED" "multiple commits" "$ITER_DURATION"
363
+ log_iteration_end "$i" "FAILED" "multiple commits" "$ITER_DURATION" "$OPENCODE_DURATION"
318
364
  exit 1
319
365
  fi
320
366
 
@@ -322,13 +368,13 @@ for i in $(seq 1 "$MAX_ITERATIONS"); do
322
368
  log_error "Working tree is not clean after iteration!"
323
369
  echo ""
324
370
  git status --short
325
- log_iteration_end "$i" "FAILED" "dirty working tree" "$ITER_DURATION"
371
+ log_iteration_end "$i" "FAILED" "dirty working tree" "$ITER_DURATION" "$OPENCODE_DURATION"
326
372
  exit 1
327
373
  fi
328
374
 
329
375
  COMMIT_MSG=$(git log -1 --format='%s')
330
376
  log_success "Commit created: $COMMIT_MSG"
331
- log_iteration_end "$i" "SUCCESS" "$COMMIT_MSG" "$ITER_DURATION"
377
+ log_iteration_end "$i" "SUCCESS" "$COMMIT_MSG" "$ITER_DURATION" "$OPENCODE_DURATION"
332
378
 
333
379
  if [[ "$VERBOSE" != true ]]; then
334
380
  rm -f "$ITER_LOG_FILE"