@lnilluv/pi-ralph-loop 1.2.0 → 1.3.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.
package/README.md CHANGED
@@ -1,25 +1,108 @@
1
- # pi-ralph
2
- Autonomous coding loops for pi with task folders, editable drafts, durable state, and per-iteration supervision.
1
+ # pi-ralph-loop
3
2
 
4
- ## Why use it
5
- - Keep work in a task folder instead of a single chat turn.
6
- - Re-run commands each iteration and feed the output back into the prompt.
7
- - Keep short rolling memory in `RALPH_PROGRESS.md`.
8
- - Store durable loop state in `.ralph-runner/`.
9
- - Draft from plain language, then review before starting.
3
+ Autonomous coding loops for [pi](https://github.com/mariozechner/pi-coding-agent).
4
+
5
+ Describe what you want done. The loop runs your agent, re-reads the task, feeds fresh command output every iteration, and stops when the work is finished or when you tell it to stop.
6
+
7
+ ```
8
+ /ralph "fix the flaky auth tests"
9
+ ```
10
+
11
+ ## Why loops
12
+
13
+ A single agent run can fix a bug. But the real leverage is **sustained, autonomous work** — campaigns that run for hours, making progress one commit at a time while you do something else.
14
+
15
+ | Without a loop | With a loop |
16
+ |---|---|
17
+ | Run an agent once, hope it finishes | Re-run until the work is done |
18
+ | Copy-paste test output back into chat | Commands feed fresh evidence each iteration |
19
+ | Watch the terminal and Ctrl+C when bored | Completion gating stops when the goal is met |
20
+ | One long context that gets stale | Fresh context every iteration |
21
+ | No guardrails — agent can push to main or delete secrets | Block commands, protect files, confine paths |
22
+
23
+ People use ralph loops for:
24
+
25
+ | Task | How the loop helps |
26
+ |---|---|
27
+ | Grow test coverage | Run the suite each iteration, only commit when coverage increases |
28
+ | Fix flaky tests | Run tests, find failures, fix, verify, repeat |
29
+ | Migrate a codebase | Transform one module per iteration, keep the build green |
30
+ | Write documentation | Check for doc build warnings, fix them, commit |
31
+ | Security audit | Scan for vulnerabilities, fix them, verify |
32
+ | Deep research | Write findings to files, iterate until the report is complete |
10
33
 
11
34
  ## Install
35
+
12
36
  ```bash
13
37
  pi install npm:@lnilluv/pi-ralph-loop
14
38
  ```
15
39
 
16
40
  ## Quick start
17
- 1. Create `work/RALPH.md`.
18
- 2. Run `/ralph --path work --arg owner="Ada Lovelace"`.
19
- 3. If you want a draft first, use `/ralph-draft fix flaky auth tests`.
20
41
 
21
- ## Concise `RALPH.md`
22
- ```md
42
+ ### From plain language
43
+
44
+ Draft and run in one command:
45
+
46
+ ```
47
+ /ralph "fix the failing auth tests"
48
+ ```
49
+
50
+ The extension creates a `RALPH.md` draft and shows it for review. Edit, start, or cancel.
51
+
52
+ ### With an existing task folder
53
+
54
+ ```
55
+ /ralph --path ./my-task --arg owner="Ada"
56
+ ```
57
+
58
+ ### From a scaffold
59
+
60
+ ```
61
+ /ralph-scaffold my-task
62
+ ```
63
+
64
+ Creates `my-task/RALPH.md` with a starter template — edit it, then run with `/ralph --path my-task`.
65
+
66
+ ### What a run looks like
67
+
68
+ ```
69
+ ▶ Ralph loop started: my-task (max 20 iterations)
70
+
71
+ ── Iteration 1 ──
72
+ Commands: 2 ran (tests, verify)
73
+ ✗ auth/login.test.ts — 2 failures
74
+ ✓ Iteration 1 completed (48.2s)
75
+
76
+ ── Iteration 2 ──
77
+ Commands: 2 ran
78
+ ✓ All tests passing
79
+ ✓ Iteration 2 completed (23.1s)
80
+
81
+ Ralph loop complete: completion promise matched on iteration 2 (71s total)
82
+ ```
83
+
84
+ ## The task folder
85
+
86
+ ```
87
+ my-task/
88
+ ├── RALPH.md ← the prompt (required)
89
+ ├── check-coverage.sh ← helper script (optional)
90
+ ├── testing-conventions.md ← reference doc (optional)
91
+ ├── RALPH_PROGRESS.md ← rolling memory (auto-managed)
92
+ └── .ralph-runner/ ← run state (auto-managed)
93
+ ├── status.json
94
+ ├── iterations.jsonl
95
+ ├── events.jsonl
96
+ └── transcripts/
97
+ ```
98
+
99
+ Put scripts, reference docs, and data files alongside `RALPH.md`. The agent can read them every iteration. `RALPH_PROGRESS.md` is injected as rolling memory — the loop reads and writes it between iterations.
100
+
101
+ ## RALPH.md format
102
+
103
+ YAML header (configuration) + Markdown body (the prompt). The header uses `snake_case` keys.
104
+
105
+ ```yaml
23
106
  ---
24
107
  args:
25
108
  - owner
@@ -30,52 +113,276 @@ commands:
30
113
  - name: verify
31
114
  run: ./scripts/verify.sh
32
115
  timeout: 60
33
- max_iterations: 25
34
- timeout: 300
116
+ max_iterations: 20
117
+ timeout: 120
35
118
  completion_promise: DONE
119
+ required_outputs:
120
+ - AUTH_FIXES.md
121
+ stop_on_error: false
122
+ guardrails:
123
+ block_commands:
124
+ - 'git\s+push'
125
+ protected_files:
126
+ - '.env*'
127
+ - 'policy:secret-bearing-paths'
36
128
  ---
129
+
37
130
  Fix the failing auth tests for {{ args.owner }}.
38
131
 
39
- Use {{ commands.tests }} and {{ commands.verify }} as evidence.
40
- Stop with <promise>DONE</promise> only when the gate passes.
132
+ ## Current test results
133
+
134
+ {{ commands.tests }}
135
+
136
+ ## Verification
137
+
138
+ {{ commands.verify }}
139
+
140
+ Stop with <promise>DONE</promise> only when all tests pass and AUTH_FIXES.md exists.
41
141
  ```
42
142
 
43
- ## Key features
44
- - `/ralph` runs an existing task folder or `RALPH.md`, or drafts a new loop from plain language.
45
- - `/ralph-draft` saves the draft without starting the loop.
46
- - `/ralph-stop` writes a stop flag under `.ralph-runner/` so the loop exits after the current iteration.
47
- - Frontmatter can declare `args` and `{{ args.name }}` placeholders; `--arg name=value` fills them when you run an existing task folder with `/ralph --path`.
48
- - Commands that start with `./` run from the task directory, so checked-in helper scripts work.
49
- - `RALPH_PROGRESS.md` is injected as short rolling memory and excluded from progress snapshots.
50
- - The runner stores status, iteration records, events, transcripts, and stop signals in `.ralph-runner/`.
51
- - Completion gating only stops early when the promise is seen and the readiness checks pass; a clear no-progress result will not trigger early stop.
52
- - The loop can use a selected model and thinking level; if interactive draft strengthening has no authenticated model, it falls back to the deterministic draft path.
143
+ ### Frontmatter reference
144
+
145
+ | YAML key | Type | Default | Description |
146
+ |---|---|---|---|
147
+ | `commands` | CommandDef[] | `[]` | Shell commands run each iteration. Each: `name`, `run`, `timeout` (1–300s, default 60) |
148
+ | `args` | string[] | `[]` | Declared runtime parameters for `--arg name=value` |
149
+ | `max_iterations` | integer | `50` | 1–50 |
150
+ | `inter_iteration_delay` | integer | `0` | Seconds between iterations |
151
+ | `timeout` | integer | `300` | 1–300 seconds per iteration |
152
+ | `completion_promise` | string | | Done marker. Single line, no `<>` or line breaks |
153
+ | `required_outputs` | string[] | `[]` | Relative file paths that must exist for early stop |
154
+ | `stop_on_error` | boolean | `true` | `false` continues past RPC errors and timeouts |
155
+ | `guardrails.block_commands` | string[] | `[]` | Regex patterns; matching bash commands are blocked |
156
+ | `guardrails.protected_files` | string[] | `[]` | Glob patterns + `policy:secret-bearing-paths` |
157
+
158
+ ### Body placeholders
159
+
160
+ | Placeholder | Resolves to |
161
+ |---|---|
162
+ | `{{ commands.NAME }}` | Output of the named command |
163
+ | `{{ args.NAME }}` | Value of the named runtime arg |
164
+ | `{{ ralph.iteration }}` | Current iteration number |
165
+ | `{{ ralph.name }}` | Task directory basename |
166
+ | `{{ ralph.max_iterations }}` | Current max iterations |
167
+
168
+ Commands starting with `./` run from the task directory. Others run from the project root. Blocked commands produce `[blocked by guardrail: PATTERN]`. Timed-out commands produce `[timed out after Ns]`.
53
169
 
54
170
  ## Commands
55
- | Command | Use |
171
+
172
+ | Command | What it does |
173
+ |---|---|
174
+ | `/ralph [path-or-task]` | Start or draft+start a loop |
175
+ | `/ralph-draft [path-or-task]` | Create or edit a draft without starting |
176
+ | `/ralph-stop [path-or-task]` | Finish current iteration, then stop |
177
+ | `/ralph-cancel [path-or-task]` | Kill the current iteration immediately |
178
+ | `/ralph-scaffold <name-or-path>` | Create a starter `RALPH.md` template |
179
+ | `/ralph-logs [--path] [--dest]` | Export run artifacts to a directory |
180
+
181
+ ### Argument passing
182
+
183
+ `--arg name=value` is only valid with `--path` to an existing `RALPH.md`:
184
+
185
+ ```
186
+ /ralph --path ./my-task --arg owner="Ada" --arg env=staging
187
+ ```
188
+
189
+ `/ralph-draft`, `/ralph-stop`, and `/ralph-cancel` reject `--arg`. Names must match `^\w[\w-]*$` and be declared in `args`.
190
+
191
+ ### Stopping
192
+
193
+ | Action | Behavior |
194
+ |---|---|
195
+ | `/ralph-stop` | Finish current iteration, then stop |
196
+ | `/ralph-cancel` | Kill the current iteration immediately |
197
+ | Completion promise + gate | Stop when `<promise>DONE</promise>` appears and all `required_outputs` exist |
198
+ | Max iterations reached | Stop after the last iteration |
199
+ | No progress for all iterations | Stop with `no-progress-exhaustion` |
200
+
201
+ ## Completion gating
202
+
203
+ Completion requires **both** conditions:
204
+
205
+ 1. The agent emits `<promise>DONE</promise>` (or whatever marker you set)
206
+ 2. Every file in `required_outputs` exists on disk
207
+
208
+ If the promise is seen but files are missing, the loop continues — the next iteration gets a rejection notice telling the agent what's still missing.
209
+
210
+ `RALPH_PROGRESS.md` is injected as rolling memory (max 4096 chars) and excluded from the `required_outputs` gate.
211
+
212
+ ## Guardrails
213
+
214
+ ### Block commands
215
+
216
+ Regex patterns matched against the full bash command. If any pattern matches, the command is blocked:
217
+
218
+ ```yaml
219
+ guardrails:
220
+ block_commands:
221
+ - 'git\s+push'
222
+ - 'rm\s+-rf\s+/'
223
+ ```
224
+
225
+ ### Protect files
226
+
227
+ Glob patterns matched against file paths. Blocks `write` and `edit` tool calls:
228
+
229
+ ```yaml
230
+ guardrails:
231
+ protected_files:
232
+ - '.env*'
233
+ - '*.pem'
234
+ - 'policy:secret-bearing-paths'
235
+ ```
236
+
237
+ `policy:secret-bearing-paths` is a built-in policy that blocks `.aws/`, `.ssh/`, `secrets/`, `.npmrc`, `.pem`, `.key`, and other secret-bearing paths.
238
+
239
+ ## Common patterns
240
+
241
+ ### Minimal loop
242
+
243
+ ```yaml
244
+ ---
245
+ max_iterations: 10
246
+ ---
247
+ Read TODO.md and implement the next task. Commit when done.
248
+ ```
249
+
250
+ ### Self-healing with test feedback
251
+
252
+ ```yaml
253
+ ---
254
+ commands:
255
+ - name: tests
256
+ run: npm test
257
+ timeout: 60
258
+ max_iterations: 20
259
+ completion_promise: DONE
260
+ ---
261
+
262
+ {{ commands.tests }}
263
+
264
+ Fix failing tests before starting new work.
265
+ Read TODO.md and implement the next task.
266
+ Stop with <promise>DONE</promise> when all tests pass.
267
+ ```
268
+
269
+ ### Parameterized multi-env loop
270
+
271
+ ```yaml
272
+ ---
273
+ args:
274
+ - env
275
+ - focus
276
+ commands:
277
+ - name: tests
278
+ run: npm test -- --env={{ args.env }}
279
+ timeout: 120
280
+ max_iterations: 15
281
+ guardrails:
282
+ protected_files:
283
+ - 'policy:secret-bearing-paths'
284
+ ---
285
+
286
+ Environment: {{ args.env }}
287
+ Focus: {{ args.focus }}
288
+
289
+ {{ commands.tests }}
290
+ ```
291
+
292
+ Run: `/ralph --path my-task --arg env=staging --arg focus="auth"`
293
+
294
+ ### Incremental migration
295
+
296
+ ```yaml
297
+ ---
298
+ commands:
299
+ - name: build
300
+ run: npm run build
301
+ timeout: 60
302
+ - name: tests
303
+ run: npm test
304
+ timeout: 120
305
+ required_outputs:
306
+ - MIGRATION_NOTES.md
307
+ stop_on_error: false
308
+ max_iterations: 30
309
+ completion_promise: DONE
310
+ ---
311
+
312
+ Migrate one module per iteration from the legacy API to the new one.
313
+
314
+ Build output:
315
+ {{ commands.build }}
316
+
317
+ Test results:
318
+ {{ commands.tests }}
319
+
320
+ Stop with <promise>DONE</promise> when MIGRATION_NOTES.md exists and all tests pass.
321
+ ```
322
+
323
+ ## Run state
324
+
325
+ `.ralph-runner/` is auto-created in the task directory. Everything the loop needs to resume, inspect, or export:
326
+
327
+ | File | Purpose |
56
328
  |---|---|
57
- | `/ralph [path-or-task]` | Run an existing task folder or `RALPH.md`, or draft a new loop from a task description. |
58
- | `/ralph-draft [path-or-task]` | Draft or edit a loop without starting it. |
59
- | `/ralph-stop [path-or-task]` | Request a graceful stop after the current iteration. |
60
- | `/ralph-cancel [path-or-task]` | Cancel the active iteration immediately. |
61
- | `/ralph-scaffold <name-or-path>` | Create a non-interactive RALPH.md starter template. |
62
- | `/ralph-logs [--path <task>] [--dest <dir>]` | Export run logs to an external directory. |
63
-
64
- ## Config reference
65
- | Field | Purpose |
329
+ | `status.json` | Current loop state (status, iteration, guardrails, timing) |
330
+ | `iterations.jsonl` | Append-only iteration records |
331
+ | `events.jsonl` | Append-only runner events (progress, gates, starts, finishes) |
332
+ | `transcripts/` | Per-iteration markdown transcripts |
333
+ | `active-loops/` | Registry of running loops (pruned after 30 minutes) |
334
+
335
+ ### Log export
336
+
337
+ `/ralph-logs` copies `status.json`, `iterations.jsonl`, `events.jsonl`, and `transcripts/` to a destination directory. Skips symlinks and excludes control files. Default destination: `./ralph-logs-<ISO-timestamp>`.
338
+
339
+ ## Termination statuses
340
+
341
+ | Status | Meaning |
66
342
  |---|---|
67
- | `commands` | Shell commands to run each iteration. |
68
- | `args` | Declared runtime parameters for `--arg`. |
69
- | `max_iterations` | Maximum iterations, from 1 to 50. |
70
- | `inter_iteration_delay` | Delay between iterations, in seconds. |
71
- | `timeout` | Per-iteration timeout, up to 300 seconds. |
72
- | `completion_promise` | Early-stop marker such as `DONE`. |
73
- | `required_outputs` | Files that must exist before early stop. |
74
- | `guardrails.block_commands` | Regexes blocked in bash commands. |
75
- | `guardrails.protected_files` | File globs protected from `write` and `edit`. |
76
- | Model selection | Use a selected model and optional thinking level; the runner applies it before the prompt. |
77
-
78
- Advanced behavior, validation, and edge cases live in `src/runner.ts`, `src/runner-state.ts`, `src/runner-rpc.ts`, `src/ralph.ts`, and `tests/`.
343
+ | `complete` | Completion promise seen and gate passed |
344
+ | `max-iterations` | Reached `max_iterations` without completion |
345
+ | `no-progress-exhaustion` | No durable progress in any iteration |
346
+ | `stopped` | `/ralph-stop` observed |
347
+ | `timeout` | An iteration exceeded the `timeout` limit |
348
+ | `error` | Structural failure (parse error, missing file) |
349
+ | `cancelled` | `/ralph-cancel` observed |
350
+
351
+ ## Draft workflow
352
+
353
+ `/ralph-draft` and `/ralph` without a path produce a draft:
354
+
355
+ 1. Task text is classified as `analysis`, `fix`, `migration`, or `general`
356
+ 2. A deterministic draft is generated from repo signals (package manager, test/lint commands)
357
+ 3. If an authenticated model is available, the draft may be strengthened by LLM review
358
+ 4. The draft is presented for interactive review — edit, start, or cancel
359
+ 5. Guardrails and `required_outputs` from the baseline are preserved during strengthening
360
+
361
+ Drafts include a metadata comment (`<!-- pi-ralph-loop: ... -->`) used for re-validation on edits.
362
+
363
+ ## Scaffold
364
+
365
+ `/ralph-scaffold <name-or-path>` creates a starter template:
366
+
367
+ ```yaml
368
+ ---
369
+ max_iterations: 10
370
+ timeout: 120
371
+ commands: []
372
+ ---
373
+ # {{ ralph.name }}
374
+
375
+ Describe the task here.
376
+
377
+ ## Evidence
378
+ Use {{ commands.* }} outputs as evidence.
379
+
380
+ ## Completion
381
+ Stop with <promise>DONE</promise> when finished.
382
+ ```
383
+
384
+ Refuses to overwrite an existing `RALPH.md` or write outside the current working directory.
79
385
 
80
386
  ## License
81
- MIT
387
+
388
+ MIT
package/package.json CHANGED
@@ -1,11 +1,14 @@
1
1
  {
2
2
  "name": "@lnilluv/pi-ralph-loop",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "Pi-native ralph loop — autonomous coding iterations with mid-turn supervision",
5
5
  "type": "module",
6
6
  "pi": {
7
7
  "extensions": [
8
8
  "./src/index.ts"
9
+ ],
10
+ "skills": [
11
+ "./skills"
9
12
  ]
10
13
  },
11
14
  "engines": {