opencode-ralph-rlm 0.1.5 → 0.1.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.
Files changed (3) hide show
  1. package/README.md +158 -8
  2. package/dist/ralph-rlm.js +1102 -52
  3. package/package.json +2 -1
package/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  An [OpenCode](https://opencode.ai) plugin that turns an AI coding session into a persistent, self-correcting loop. Describe a goal, walk away, and come back to working code.
4
4
 
5
+ New here? Start with [`GETTINGSTARTEDGUIDE.md`](GETTINGSTARTEDGUIDE.md).
6
+
5
7
  Two techniques combine to make this work:
6
8
 
7
9
  - **Ralph** — a strategist session spawned fresh per attempt. It reviews what failed, adjusts the plan and instructions, then delegates coding to a worker. It never writes code itself.
@@ -144,7 +146,7 @@ Sub-agents follow the same discipline as workers: one pass, file-first, fresh co
144
146
 
145
147
  Spawned sessions (Ralph and workers) can communicate back to the main conversation at runtime:
146
148
 
147
- - `ralph_report()` — fire-and-forget progress updates, appended to `SUPERVISOR_LOG.md` and posted to the main conversation
149
+ - `ralph_report()` — fire-and-forget progress updates, appended to `SUPERVISOR_LOG.md` and `CONVERSATION.md`, and posted to the main conversation
148
150
  - `ralph_ask()` — blocks the session until you respond via `ralph_respond()`, enabling interactive decision points mid-loop (e.g., "should I rewrite auth.ts or patch it?")
149
151
 
150
152
  This is implemented via file-based IPC (`.opencode/pending_input.json`) so responses survive across any session boundary.
@@ -187,9 +189,12 @@ Create `.opencode/ralph.json`. All fields are optional — the plugin runs with
187
189
  ```json
188
190
  {
189
191
  "enabled": true,
192
+ "autoStartOnMainIdle": false,
193
+ "statusVerbosity": "normal",
190
194
  "maxAttempts": 25,
195
+ "heartbeatMinutes": 15,
191
196
  "verify": {
192
- "command": ["bun", "test"],
197
+ "command": ["bun", "run", "verify"],
193
198
  "cwd": "."
194
199
  },
195
200
  "gateDestructiveToolsUntilContextLoaded": true,
@@ -198,6 +203,13 @@ Create `.opencode/ralph.json`. All fields are optional — the plugin runs with
198
203
  "grepRequiredThresholdLines": 120,
199
204
  "subAgentEnabled": true,
200
205
  "maxSubAgents": 5,
206
+ "maxConversationLines": 1200,
207
+ "conversationArchiveCount": 3,
208
+ "reviewerEnabled": false,
209
+ "reviewerRequireExplicitReady": true,
210
+ "reviewerMaxRunsPerAttempt": 1,
211
+ "reviewerOutputDir": ".opencode/reviews",
212
+ "reviewerPostToConversation": true,
201
213
  "agentMdPath": "AGENT.md"
202
214
  }
203
215
  ```
@@ -205,8 +217,11 @@ Create `.opencode/ralph.json`. All fields are optional — the plugin runs with
205
217
  | Field | Default | Description |
206
218
  |---|---|---|
207
219
  | `enabled` | `true` | Set to `false` to disable the outer loop without removing the plugin. |
220
+ | `autoStartOnMainIdle` | `false` | Automatically start attempt 1 when the main session goes idle. Set `true` to enable auto-start, or keep `false` for manual starts via `ralph_create_supervisor_session()`. |
221
+ | `statusVerbosity` | `"normal"` | Supervisor status emission level: `minimal` (warnings/errors), `normal`, or `verbose`. |
208
222
  | `maxAttempts` | `20` | Hard stop after this many failed verify attempts. |
209
- | `verify.command` | | Shell command to run as an array, e.g. `["bun", "test"]`. If omitted, verify always returns `unknown`. |
223
+ | `heartbeatMinutes` | `15` | Warn if active strategist/worker has no progress for this many minutes. |
224
+ | `verify.command` | — | Shell command to run as an array, e.g. `["bun", "run", "verify"]`. If omitted, verify always returns `unknown`. |
210
225
  | `verify.cwd` | `"."` | Working directory for the verify command, relative to the repo root. |
211
226
  | `gateDestructiveToolsUntilContextLoaded` | `true` | Block `write`, `edit`, `bash`, etc. until `ralph_load_context()` has been called in the current attempt. |
212
227
  | `maxRlmSliceLines` | `200` | Maximum lines a single `rlm_slice` call may return. |
@@ -214,11 +229,19 @@ Create `.opencode/ralph.json`. All fields are optional — the plugin runs with
214
229
  | `grepRequiredThresholdLines` | `120` | Line threshold above which grep-first is required. |
215
230
  | `subAgentEnabled` | `true` | Allow `subagent_spawn`. |
216
231
  | `maxSubAgents` | `5` | Maximum concurrently running sub-agents per session. |
232
+ | `maxConversationLines` | `1200` | Rotate `CONVERSATION.md` when it grows beyond this many lines. |
233
+ | `conversationArchiveCount` | `3` | Number of rotated archives to keep (`CONVERSATION.1.md`, etc.). |
234
+ | `reviewerEnabled` | `false` | Enable optional reviewer sub-agent tooling. |
235
+ | `reviewerRequireExplicitReady` | `true` | Require explicit `ralph_request_review()` before reviewer runs. |
236
+ | `reviewerMaxRunsPerAttempt` | `1` | Max reviewer runs per attempt unless forced. |
237
+ | `reviewerOutputDir` | `".opencode/reviews"` | Directory for reviewer report files. |
238
+ | `reviewerPostToConversation` | `true` | Post reviewer lifecycle updates to main conversation feed. |
217
239
  | `agentMdPath` | `"AGENT.md"` | Path (relative to repo root) to the project AGENT.md. Read by `ralph_load_context()` and included in the context payload. Set to `""` to disable. |
218
240
 
219
241
  ### verify command examples
220
242
 
221
243
  ```json
244
+ { "command": ["bun", "run", "verify"] }
222
245
  { "command": ["bun", "test"] }
223
246
  { "command": ["npm", "test"] }
224
247
  { "command": ["cargo", "test"] }
@@ -227,8 +250,43 @@ Create `.opencode/ralph.json`. All fields are optional — the plugin runs with
227
250
  { "command": ["./scripts/verify.sh"] }
228
251
  ```
229
252
 
253
+ If your repo has no test files yet, avoid `bun test` as a verify command because Bun exits non-zero when no tests match. Use a command that reflects your current quality gate (for example `bun run verify` with typecheck + build).
254
+
230
255
  The verify command is the loop's exit condition. It should be as comprehensive as you want the output to be. A verify that runs tests + typecheck + lint will produce code that passes all three; a verify that only checks syntax will produce syntactically valid code that may be logically broken.
231
256
 
257
+ ## Quick start (recommended)
258
+
259
+ If you are setting up a repo from scratch, use this sequence:
260
+
261
+ 1. Run `ralph_quickstart_wizard(...)` for one-call setup, or use `ralph_doctor(autofix=true)` + `ralph_bootstrap_plan(...)` manually.
262
+ 2. Validate plan quality with `ralph_validate_plan()`.
263
+ 3. Start the loop with `ralph_create_supervisor_session()` (or enable auto-start if desired).
264
+ 4. Monitor progress in `SUPERVISOR_LOG.md` (structured) and `CONVERSATION.md` (readable timeline).
265
+
266
+ If setup is incomplete, auto-start is skipped and the plugin emits a warning with next actions.
267
+
268
+ ## Recommended OpenCode agent setup
269
+
270
+ The plugin already manages the core loop roles (`main` / `ralph` / `worker` / `subagent`).
271
+ Use OpenCode agents to control posture and delegation, not to replace loop orchestration.
272
+
273
+ Recommended split:
274
+
275
+ - `supervisor` (primary): your default top-level operator for safe orchestration.
276
+ - built-in `plan` (primary): dry analysis/planning without edits.
277
+ - built-in `build` (primary): full manual implementation when needed.
278
+ - project subagents (optional): focused review/docs/security helpers.
279
+
280
+ This repo now includes project-local agent files under `.opencode/agents/`:
281
+
282
+ - `.opencode/agents/supervisor.md`
283
+ - `.opencode/agents/ralph-reviewer.md`
284
+ - `.opencode/agents/docs-writer.md`
285
+ - `.opencode/agents/security-auditor.md`
286
+
287
+ These profiles intentionally keep loop ownership in `ralph-rlm`.
288
+ Do not model Ralph strategist/worker as OpenCode primary/subagent replacements.
289
+
232
290
 
233
291
  ## Protocol files
234
292
 
@@ -245,6 +303,7 @@ The plugin bootstraps these files on first run if they do not exist. They are th
245
303
  | `NOTES_AND_LEARNINGS.md` | Append-only log of durable insights. Survives all context resets. |
246
304
  | `TODOS.md` | Optional lightweight task list. |
247
305
  | `SUPERVISOR_LOG.md` | Append-only feed of all `ralph_report()` entries across all attempts and sessions. |
306
+ | `CONVERSATION.md` | Append-only human-readable timeline of supervisor updates, loop events, questions, and responses. |
248
307
 
249
308
  Sub-agent state lives under `.opencode/agents/<name>/` with the same structure.
250
309
 
@@ -354,6 +413,60 @@ This injects the file on every turn rather than only when `ralph_load_context()`
354
413
 
355
414
  ## Tools
356
415
 
416
+ ### Setup and supervisor bootstrap
417
+
418
+ #### `ralph_doctor(autofix?)`
419
+
420
+ Check whether the repository is ready for Ralph/RLM execution. It validates core setup (verify command, baseline files, placeholders) and returns structured diagnostics.
421
+
422
+ With `autofix: true`, it applies safe bootstrap fixes such as creating `.opencode/ralph.json` defaults and a baseline `AGENT.md` when missing.
423
+
424
+ #### `ralph_bootstrap_plan(goal, requirements?, stopping_conditions?, features?, steps?, todos?, overwrite_plan?, overwrite_todos?)`
425
+
426
+ Generate `PLAN.md` and `TODOS.md` from explicit project requirements. This is the fastest way to turn a rough prompt into a concrete execution plan.
427
+
428
+ #### `ralph_create_supervisor_session(start_loop?, force_rebind?, restart_if_done?)`
429
+
430
+ Bind the current session as the supervisor and optionally start attempt 1 immediately.
431
+
432
+ - Use this when `autoStartOnMainIdle` is disabled.
433
+ - Use `force_rebind: true` to move supervision to a different session.
434
+ - Use `restart_if_done: true` to start a new run after completion or manual stop.
435
+
436
+ #### `ralph_end_supervision(reason?, clear_binding?)`
437
+
438
+ Stop supervision for the current process. This prevents further auto-loop orchestration until restarted.
439
+
440
+ - Use this when you want to pause/stop Ralph from spawning more sessions.
441
+ - Resume later with `ralph_create_supervisor_session(restart_if_done=true)`.
442
+
443
+ #### `ralph_supervision_status()`
444
+
445
+ Return current supervision state: bound session, attempt number, active strategist/worker session IDs, and done status.
446
+
447
+ #### `ralph_pause_supervision(reason?)`
448
+
449
+ Pause automatic loop orchestration without ending supervision state.
450
+
451
+ #### `ralph_resume_supervision(start_loop?)`
452
+
453
+ Resume from pause. Optionally start the loop immediately.
454
+
455
+ #### `ralph_reset_state(scope, confirm, preserve_logs?)`
456
+
457
+ Reset protocol/runtime state. Requires `confirm: "RESET_RALPH_STATE"`.
458
+
459
+ - `scope: "attempt"` resets scratch files.
460
+ - `scope: "full"` resets scratch + baseline protocol scaffolding.
461
+
462
+ #### `ralph_validate_plan()`
463
+
464
+ Validate `PLAN.md` structure (goal, requirements, stopping conditions, milestones/checklists) before long runs.
465
+
466
+ #### `ralph_quickstart_wizard(...)`
467
+
468
+ One-call setup helper: applies basic setup, writes `PLAN.md`/`TODOS.md`, validates plan, and can optionally start the loop.
469
+
357
470
  ### Context loading
358
471
 
359
472
  #### `ralph_load_context()`
@@ -400,6 +513,8 @@ Run the configured verify command. Returns `{ verdict: "pass"|"fail"|"unknown",
400
513
 
401
514
  **Ralph strategist sessions only.** Spawn a fresh RLM worker session for this attempt. Call this after reviewing protocol files and optionally updating `PLAN.md` / `RLM_INSTRUCTIONS.md`. Then stop — the plugin handles verification and spawns the next Ralph session if needed.
402
515
 
516
+ If you call this from the main conversation you will get: `ralph_spawn_worker() can only be called from a Ralph strategist session.` In normal operation the plugin creates strategist sessions automatically on `session.idle`.
517
+
403
518
  ### Sub-agents
404
519
 
405
520
  #### `subagent_spawn(name, goal, context?)`
@@ -420,11 +535,35 @@ List all sub-agents registered in the current session with their name, goal, sta
420
535
 
421
536
  ### Supervisor communication
422
537
 
423
- These tools let spawned sessions (Ralph strategist, RLM worker) communicate back to the main conversation at runtime. State is carried in `.opencode/pending_input.json` for question/response pairs and `SUPERVISOR_LOG.md` for the progress feed.
538
+ These tools let spawned sessions (Ralph strategist, RLM worker) communicate back to the main conversation at runtime. State is carried in `.opencode/pending_input.json` for question/response pairs, `SUPERVISOR_LOG.md` for structured status entries, and `CONVERSATION.md` for the readable event timeline.
539
+
540
+ User answers to `ralph_ask()` are persisted too: when you reply via `ralph_respond()`, the response is appended to `CONVERSATION.md`.
541
+
542
+ #### `ralph_set_status(status, note?, post_to_conversation?)`
543
+
544
+ Optionally publish explicit attempt status (`running`, `blocked`, `done`, `error`) for the current session. This improves observability and handoffs.
545
+
546
+ If an inner session does not call `ralph_set_status()`, the loop still works: idle + verify events continue with implicit status handling.
547
+
548
+ #### `ralph_request_review(note?)`
549
+
550
+ Mark the current attempt as review-ready. This is the recommended gate before running the reviewer so it does not execute too often.
551
+
552
+ #### `ralph_run_reviewer(force?, wait?, timeout_minutes?, output_path?)`
553
+
554
+ Run an optional reviewer sub-agent and write the review report to a file (default: `.opencode/reviews/review-attempt-N.md`).
555
+
556
+ - Honors `reviewerRequireExplicitReady` and `reviewerMaxRunsPerAttempt` unless `force=true`.
557
+ - Use `wait=true` (default) to block until review completion.
558
+ - Reviewer gate/runtime state is persisted in `.opencode/reviewer_state.json` so restarts can resume tracking.
559
+
560
+ #### `ralph_review_status()`
561
+
562
+ Show reviewer gate state: active reviewer, review requests, and runs per attempt.
424
563
 
425
564
  #### `ralph_report(message, level?, post_to_conversation?)`
426
565
 
427
- Fire-and-forget progress report. Appends a timestamped entry to `SUPERVISOR_LOG.md`, shows a toast, and optionally posts into the main conversation so you can see what's happening without opening a separate session.
566
+ Fire-and-forget progress report. Appends a timestamped entry to `SUPERVISOR_LOG.md` and `CONVERSATION.md`, shows a toast, and optionally posts into the main conversation so you can see what's happening without opening a separate session.
428
567
 
429
568
  ```
430
569
  args:
@@ -540,7 +679,7 @@ Set `maxAttempts` high (25–50), write a detailed `PLAN.md` with a precise defi
540
679
  3. On failure: roll state, spawn Ralph to diagnose and adjust, spawn the next worker.
541
680
  4. Repeat until it passes or hits `maxAttempts`.
542
681
 
543
- In the morning, check `SUPERVISOR_LOG.md` for the progress feed, `NOTES_AND_LEARNINGS.md` for what the loop learned, and `AGENT_CONTEXT_FOR_NEXT_RALPH.md` for where it stopped.
682
+ In the morning, check `SUPERVISOR_LOG.md` and `CONVERSATION.md` for the progress feed, `NOTES_AND_LEARNINGS.md` for what the loop learned, and `AGENT_CONTEXT_FOR_NEXT_RALPH.md` for where it stopped.
544
683
 
545
684
  ### Supervisory check-in
546
685
 
@@ -556,6 +695,16 @@ Worker:
556
695
 
557
696
  You stay in the loop for decisions that require human judgment. Everything else runs unattended.
558
697
 
698
+ ### Optional reviewer pass (gated)
699
+
700
+ To avoid over-running reviews, use explicit readiness:
701
+
702
+ 1. Worker marks readiness with `ralph_request_review("ready for correctness review")`.
703
+ 2. Supervisor runs `ralph_run_reviewer()`.
704
+ 3. Review report is written to `.opencode/reviews/review-attempt-N.md` (or configured output path).
705
+
706
+ Reviewer execution is gated by `reviewerRequireExplicitReady` and `reviewerMaxRunsPerAttempt` unless forced.
707
+
559
708
  ### Parallel decomposition with sub-agents
560
709
 
561
710
  ```
@@ -581,11 +730,12 @@ The instructions file is the primary lever for improving loop performance. If th
581
730
 
582
731
  | Hook | What it does |
583
732
  |---|---|
584
- | `event: session.idle` | Routes idle events: **worker** → `handleWorkerIdle` (verify + continue loop); **ralph** → `handleRalphSessionIdle` (warn if no worker spawned); **main/other** → `handleMainIdle` (kick off attempt 1). |
733
+ | `event: session.idle` | Routes idle events: **worker** → `handleWorkerIdle` (verify + continue loop); **ralph** → `handleRalphSessionIdle` (warn if no worker spawned); **main/other** → `handleMainIdle` (kick off attempt 1). Also emits heartbeat/staleness warnings and supervisor status updates to `SUPERVISOR_LOG.md` and `CONVERSATION.md`. |
585
734
  | `event: session.created` | Pre-allocates session state for known worker/ralph sessions. |
735
+ | `event: session.status` | Refreshes heartbeat/progress timestamps for active sessions and surfaces explicit session error statuses to the supervisor feed. |
586
736
  | `experimental.chat.system.transform` | Three-way routing: **worker** → RLM file-first prompt; **ralph** → Ralph strategist prompt; **main/other** → supervisor prompt. |
587
737
  | `experimental.session.compacting` | Injects protocol file pointers into compaction context so state survives context compression. |
588
- | `tool.execute.before` | Blocks destructive tools (`write`, `edit`, `bash`, `delete`, `move`, `rename`) in **worker sessions** until `ralph_load_context()` has been called. Ralph strategist sessions are not gated. |
738
+ | `tool.execute.before` | Blocks destructive tools (`write`, `edit`, `bash`, `delete`, `move`, `rename`) in **worker and sub-agent sessions** until `ralph_load_context()` has been called. Ralph strategist sessions are not gated. |
589
739
 
590
740
 
591
741
  ## Background