ralphctl 0.17.1 → 0.19.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
@@ -8,6 +8,7 @@
8
8
  [![Claude Code](https://img.shields.io/badge/Claude_Code-supported-191919?style=flat&logo=anthropic&logoColor=white)](https://docs.anthropic.com/en/docs/claude-code)
9
9
  [![GitHub Copilot CLI](https://img.shields.io/badge/GitHub_Copilot_CLI-supported-000?style=flat&logo=githubcopilot&logoColor=white)](https://docs.github.com/en/copilot/github-copilot-in-the-cli)
10
10
  [![OpenAI Codex CLI](https://img.shields.io/badge/OpenAI_Codex_CLI-supported-412991?style=flat&logo=openai&logoColor=white)](https://github.com/openai/codex)
11
+ [![OpenCode](https://img.shields.io/badge/OpenCode-supported-f59e0b?style=flat&logo=opencollective&logoColor=white)](https://opencode.ai/)
11
12
  [![Built with Donuts](https://img.shields.io/badge/%F0%9F%8D%A9-Built_with_Donuts-ff6f00?style=flat)](https://github.com/lukas-grigis/ralphctl)
12
13
 
13
14
  <p align="center">
@@ -18,18 +19,15 @@
18
19
 
19
20
  **A ralph harness for long-running AI coding tasks — a hardened ralph loop that drives your coding agent of choice
20
21
  ([Claude Code](https://docs.anthropic.com/en/docs/claude-code),
21
- [GitHub Copilot CLI](https://docs.github.com/en/copilot/github-copilot-in-the-cli), or
22
- [OpenAI Codex CLI](https://github.com/openai/codex)) across one or more repositories.**
22
+ [GitHub Copilot CLI](https://docs.github.com/en/copilot/github-copilot-in-the-cli),
23
+ [OpenAI Codex CLI](https://github.com/openai/codex), or [OpenCode](https://opencode.ai/)) across one or more
24
+ repositories.**
23
25
 
24
26
  > _"I'm helping!"_ — Ralph Wiggum
25
27
 
26
28
  > [!NOTE]
27
- > **Active development.** New features and polish ship regularly. All three providers — Claude Code,
28
- > GitHub Copilot CLI, and OpenAI Codex CLI — are supported; pick one per flow or mix them, in one command,
29
- > from a preset matrix of 20 presets across five families (`standard`, `economic`, `strong-gate`, `fast`,
30
- > `frontier`), each in `mixed` / `claude-only` / `copilot-only` / `codex-only` variants.
31
- > Upgrades are best-effort: install the latest version, redo your config, proceed.
32
- > See [Upgrading](#upgrading) and [CHANGELOG](./CHANGELOG.md).
29
+ > **Active development.** New features and polish ship regularly. Upgrades are best-effort: install the
30
+ > latest version, redo your config, proceed. See [Upgrading](#upgrading) and [CHANGELOG](./CHANGELOG.md).
33
31
 
34
32
  ---
35
33
 
@@ -50,7 +48,7 @@ plan → generate → evaluate → verify loop turns one-shot prompting into a r
50
48
 
51
49
  AI coding agents are powerful but lose context on long tasks, need babysitting when things break, and have no way to
52
50
  coordinate changes across multiple repositories. ralphctl wraps your chosen AI CLI — Claude Code, GitHub Copilot CLI,
53
- or OpenAI Codex CLI — in a
51
+ OpenAI Codex CLI, or OpenCode — in a
54
52
  structured harness that decomposes your work into dependency-ordered tasks, drives each one through
55
53
  a [generator-evaluator loop](https://www.anthropic.com/engineering/harness-design-long-running-apps) that catches issues
56
54
  before moving on, and persists context across sessions so nothing gets lost.
@@ -67,9 +65,16 @@ npm install -g ralphctl
67
65
 
68
66
  > Needs [Node.js](https://nodejs.org/) ≥ 24 — `mise use node@24` or `nvm install 24`.
69
67
 
70
- Install one of the supported CLIs — [Claude Code](https://docs.anthropic.com/en/docs/claude-code),
71
- [GitHub Copilot CLI](https://docs.github.com/en/copilot/github-copilot-in-the-cli), or
72
- [OpenAI Codex CLI](https://github.com/openai/codex) — and authenticate it, then confirm ralphctl can see it:
68
+ Install one of the supported CLIs and authenticate it:
69
+
70
+ | CLI | Install | Auth |
71
+ | ---------------------------------------------------------------------------------- | ------------------------------------ | --------------------- |
72
+ | [Claude Code](https://docs.anthropic.com/en/docs/claude-code) | `npm i -g @anthropic-ai/claude-code` | Anthropic account |
73
+ | [GitHub Copilot CLI](https://docs.github.com/en/copilot/github-copilot-in-the-cli) | `npm i -g @github/copilot` | GitHub Copilot seat |
74
+ | [OpenAI Codex CLI](https://github.com/openai/codex) | `npm i -g @openai/codex` | ChatGPT / OpenAI |
75
+ | [OpenCode](https://opencode.ai/) | `npm i -g opencode-ai` | your own key, or none |
76
+
77
+ Then confirm ralphctl can see it:
73
78
 
74
79
  ```bash
75
80
  ralphctl doctor # verifies your provider CLI is installed + authenticated — the #1 first-run failure
@@ -87,7 +92,7 @@ flow (refine / plan / implement / readiness / …), or open the Sprints submenu
87
92
  or create a sprint. No commands to memorize.
88
93
 
89
94
  **Requirements:** [Node.js](https://nodejs.org/) ≥ 24, [Git](https://git-scm.com/), and one supported AI CLI in `PATH`
90
- and authenticated.
95
+ and authenticated (OpenCode takes your own keys, or runs on its free tier with none).
91
96
 
92
97
  <details>
93
98
  <summary>Prefer the CLI for inspection + one-shot operations?</summary>
@@ -120,7 +125,7 @@ ralphctl export-context --sprint <id> --project <id> --output <path>
120
125
 
121
126
  # Settings
122
127
  ralphctl settings show
123
- ralphctl settings apply-preset claude-only # or mixed / copilot-only / codex-only / *-economic / *-strong-gate / *-fast / *-frontier
128
+ ralphctl settings apply-preset claude-only # or mixed / copilot-only / codex-only / opencode-only / *-economic / *-strong-gate / *-fast / *-frontier
124
129
  ralphctl settings set ai.implement.generator.provider claude-code
125
130
  ralphctl settings set ai.implement.generator.model <model-id>
126
131
  ralphctl settings set ai.implement.generator.effort high
@@ -134,19 +139,21 @@ ralphctl settings set ai.implement.evaluator.model <model-id>
134
139
 
135
140
  ## How It Works
136
141
 
137
- ```
138
- You describe what to build ralphctl drives it to done
139
- ───────────────────────── ────────────────────────────────────────────
140
- ┌──────────┐ ┌──────────┐ ┌────────┐ ┌──────┐ ┌───────────┐ ┌────────┐
141
- │ Create │──>│ Add │───────>│ Refine │──>│ Plan │──>│ Implement │──>│ Review │──> done
142
- │ Sprint │ │ Tickets │ │ (WHAT) │ │(HOW) │ │ Loop │ │ Loop │
143
- └──────────┘ └──────────┘ └────────┘ └──────┘ └───────────┘ └────────┘
144
- │ │ │ │
145
- AI clarifies AI builds AI implements you steer
146
- requirements the task + AI reviews revisions,
147
- with you graph each task close to done
142
+ ```mermaid
143
+ flowchart LR
144
+ A[Create sprint] --> B[Add tickets] --> C[Refine] --> D[Plan] --> E[Implement] --> F[Review] --> G[Done]
145
+
146
+ classDef you fill:#eef2ff,stroke:#6366f1,color:#1e1b4b
147
+ classDef ai fill:#ecfdf5,stroke:#10b981,color:#052e16
148
+ classDef end_ fill:#f1f5f9,stroke:#94a3b8,color:#0f172a
149
+ class A,B you
150
+ class C,D,E,F ai
151
+ class G end_
148
152
  ```
149
153
 
154
+ The first two steps are yours (blue); from **Refine** onward ralphctl drives (green), with approval gates where
155
+ your judgement matters.
156
+
150
157
  **Refine** is implementation-agnostic: the AI clarifies requirements with you, ticket by ticket, and flips each one from
151
158
  `pending` to `approved`. **Plan** requires every ticket approved — the AI explores the affected repos and generates a
152
159
  dependency-ordered task graph. **Implement** drives those tasks in dependency order through a generator-evaluator cycle:
@@ -156,13 +163,41 @@ loop — once every task lands, the sprint enters `review` and you run human-ste
156
163
  the AI revises, and the sprint flips to `done` when you're satisfied. Opening a PR (`ralphctl create-pr`) is separate
157
164
  and optional.
158
165
 
166
+ The loop inside **Implement** is what separates a ralph harness from a bare `while` loop — every task passes an
167
+ independent reviewer before the harness moves on:
168
+
169
+ ```mermaid
170
+ flowchart LR
171
+ T[Next task] --> G[Generator] --> E{Evaluator}
172
+ E -->|pass| V{Verify}
173
+ E -->|fail| R[Retry]
174
+ V -->|green| D[Done]
175
+ V -->|red| R
176
+ R --> G
177
+ R -.->|attempts exhausted| B[Blocked]
178
+
179
+ classDef work fill:#ecfdf5,stroke:#10b981,color:#052e16
180
+ classDef gate fill:#fefce8,stroke:#eab308,color:#422006
181
+ classDef ok fill:#f1f5f9,stroke:#94a3b8,color:#0f172a
182
+ classDef bad fill:#fef2f2,stroke:#ef4444,color:#450a0a
183
+ class T,G,R work
184
+ class E,V gate
185
+ class D ok
186
+ class B bad
187
+ ```
188
+
189
+ Both gates send the task back, but they spend different budgets: a failed review re-runs the generator
190
+ _within_ the same attempt (up to `harness.maxTurns` turns), while a red verify fails the attempt outright and
191
+ opens a fresh one (up to `harness.maxAttempts`, after which the task is flagged `blocked`).
192
+
159
193
  Key properties:
160
194
 
161
195
  - **Dependency-ordered execution** — tasks run in topological order; no task starts until its blockers are done.
162
196
  Opt-in parallelism (`concurrency.maxParallelTasks` > 1) runs independent tasks within a dependency wave concurrently,
163
197
  each in its own git worktree folded onto one branch — default stays serial
164
198
  - **Generator-evaluator cycle** — an independent AI reviewer checks each task; if it fails, the generator gets the
165
- critique and iterates (up to `harness.maxAttempts` tries before the task is flagged `blocked`)
199
+ critique and iterates (up to `harness.maxTurns` turns per attempt, across at most `harness.maxAttempts`
200
+ attempts before the task is flagged `blocked`)
166
201
  - **Context persistence** — sprint state, branch, progress history, and per-task context survive across sessions;
167
202
  interrupted runs resume automatically
168
203
  - **Multi-repo support** — one sprint can span several repositories with per-repo setup and verify scripts
@@ -174,26 +209,45 @@ For the full architectural picture see [`.claude/docs/ARCHITECTURE.md`](./.claud
174
209
 
175
210
  ## Providers
176
211
 
177
- ralphctl drives three AI coding CLIs. Choose one per flow — or mix them, say plan with one and implement with
178
- another — through a [preset](#configuration) or per-row settings. All three are supported and in everyday use.
212
+ ralphctl drives four AI coding CLIs. All four run every flow and are supported first-class. Pick one per
213
+ flow — or mix them, say plan with one and implement with another — through a [preset](#configuration) or
214
+ per-row settings.
215
+
216
+ | Provider | CLI | Install | Auth | Context file |
217
+ | ----------------------------------------- | ---------- | ------------------------------------ | --------------------- | --------------------------------- |
218
+ | **Claude Code** (`claude-code`) | `claude` | `npm i -g @anthropic-ai/claude-code` | Anthropic account | `CLAUDE.md` |
219
+ | **GitHub Copilot CLI** (`github-copilot`) | `copilot` | `npm i -g @github/copilot` | GitHub Copilot seat | `.github/copilot-instructions.md` |
220
+ | **OpenAI Codex CLI** (`openai-codex`) | `codex` | `npm i -g @openai/codex` | ChatGPT / OpenAI | `AGENTS.md` |
221
+ | **OpenCode** (`opencode`) | `opencode` | `npm i -g opencode-ai` | your own key, or none | `AGENTS.md` |
222
+
223
+ **Which one?**
224
+
225
+ - **Claude Code** — read-only flows deny the edit, shell and network tools at the CLI level, the finest-grained
226
+ gate of the four.
227
+ - **GitHub Copilot CLI** — no extra billing relationship if you already have a seat. Read-only flows deny the
228
+ shell tool; file writes stay open, bounded by path scope.
229
+ - **OpenAI Codex CLI** — a natural fit inside the ChatGPT/OpenAI ecosystem. Its sandbox has two modes only,
230
+ so path scope is the fine-grained safety envelope.
231
+ - **OpenCode** — vendor-neutral: it fronts 75+ providers and local runtimes on a bring-your-own-key model, so
232
+ you can run a specific model, a local model, or no account at all.
233
+
234
+ On every backend the `Write` tool stays open by design — the harness's `signals.json` lands through it — so
235
+ path scope (cwd + mounted roots) is always part of the safety envelope. See the
236
+ [provider reference](./docs/providers.md#permission-model-per-backend) for the exact mapping.
237
+
238
+ Bundled skill injection and forensic capture work on all four; only the on-disk skills directory differs
239
+ (`.claude/` / `.github/` / `.agents/` / `.opencode/`). Parallel execution is provider-agnostic. Claude Code
240
+ has the most real-world mileage simply because it came first — the others are equally supported, with
241
+ correspondingly less of it.
179
242
 
180
- | Provider | CLI | Headless permission mapping | Native context file |
181
- | ----------------------------------------- | --------- | ----------------------------------------------------------------------------------------------- | --------------------------------- |
182
- | **Claude Code** (`claude-code`) | `claude` | `--permission-mode bypassPermissions` + per-tool deny list | `CLAUDE.md` at repo root |
183
- | **GitHub Copilot CLI** (`github-copilot`) | `copilot` | `--autopilot --max-autopilot-continues=200` + `--allow-all` (per-tool deny list when read-only) | `.github/copilot-instructions.md` |
184
- | **OpenAI Codex CLI** (`openai-codex`) | `codex` | `-s workspace-write` (topology-scoped) | `AGENTS.md` |
243
+ 📖 **[Full provider reference →](./docs/providers.md)** — permission mapping per backend, per-provider setup,
244
+ model ids, mixing backends, and known limitations.
185
245
 
186
- Claude Code has the most end-to-end mileage inside the harness — it's the most battle-tested of the three — but Copilot
187
- and Codex run every flow and are supported first-class. Two small differences worth knowing: bundled skill injection
188
- and `bodyFile` forensic artifacts currently no-op on Copilot and Codex, and Codex's sandbox has only two modes
189
- (read-only / workspace-write), so path scope (cwd + `--add-dir`) is its fine-grained safety envelope rather than a
190
- per-tool deny list. Parallel execution is provider-agnostic — it works with whichever provider each implement role is
191
- configured to use. Hit a rough edge with any provider? Please [open an
192
- issue](https://github.com/lukas-grigis/ralphctl/issues).
246
+ Hit a rough edge with any provider? Please [open an issue](https://github.com/lukas-grigis/ralphctl/issues).
193
247
 
194
- One-shot configuration for any provider: `ralphctl settings apply-preset <name>` where `<name>` is one of
195
- 20 presets across five families — `standard`, `economic`, `strong-gate`, `fast`, and `frontier`, each in
196
- `mixed` / `claude-only` / `copilot-only` / `codex-only` variants.
248
+ One-shot configuration: `ralphctl settings apply-preset <name>` where `<name>` is one of 21 presets —
249
+ `standard`, `economic`, `strong-gate`, `fast`, and `frontier` families, each in `mixed` / `claude-only` /
250
+ `copilot-only` / `codex-only` variants, plus `opencode-only`.
197
251
 
198
252
  ---
199
253
 
@@ -215,6 +269,8 @@ One-shot configuration for any provider: `ralphctl settings apply-preset <name>`
215
269
  first — the crashed attempt is settled as aborted (kept in history) and a fresh attempt opens automatically
216
270
  - **Pair or let it run** — work alongside your AI agent interactively, or let it execute unattended
217
271
  - **Zero-memorization start** — run `ralphctl` with no args for a guided menu
272
+ - **Bring your own model** — four backends to choose from, one of which (OpenCode) is vendor-neutral, so the
273
+ harness reaches hosted, aggregated, and local models alike
218
274
 
219
275
  ---
220
276
 
@@ -226,7 +282,7 @@ Configure via the TUI `Settings` view or one-shot CLI commands.
226
282
  `apply-preset`.
227
283
 
228
284
  <details>
229
- <summary>All 20 presets across five families</summary>
285
+ <summary>All 21 presets</summary>
230
286
 
231
287
  ```bash
232
288
  # Standard — flagship model per flow
@@ -234,6 +290,7 @@ ralphctl settings apply-preset mixed # best-fit provider per flow
234
290
  ralphctl settings apply-preset claude-only # every flow on Claude Code
235
291
  ralphctl settings apply-preset copilot-only # every flow on GitHub Copilot CLI
236
292
  ralphctl settings apply-preset codex-only # every flow on OpenAI Codex CLI
293
+ ralphctl settings apply-preset opencode-only # every flow on OpenCode's free tier (no auth)
237
294
 
238
295
  # Economic — implement starts one tier below flagship; escalation ladder climbs only on plateau
239
296
  ralphctl settings apply-preset mixed-economic
@@ -260,7 +317,9 @@ ralphctl settings apply-preset copilot-frontier
260
317
  ralphctl settings apply-preset codex-frontier
261
318
  ```
262
319
 
263
- Twenty presets across five families ship, all equally first-class — none is marked default. Applying a
320
+ Twenty-one presets ship, all equally first-class — none is marked default. `opencode-only` sits outside the
321
+ five-family grid on purpose: every free-tier model is at the same (zero) price point, so `economic` / `frontier`
322
+ variants of it would differ in name only. Applying a
264
323
  preset stamps the entire `ai` section plus `harness.escalateOnPlateau` in one transaction (`fast` stamps it
265
324
  `false` so a plateau settles; all others stamp it `true`). On a fresh install the welcome view silently
266
325
  auto-seeds a preset based on which provider CLIs it detects on `PATH`.
@@ -360,14 +419,14 @@ readiness / create sprint) stay TUI-only by design. The CLI exposes inspection +
360
419
 
361
420
  ### Getting Started
362
421
 
363
- | Command | Description |
364
- | --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
365
- | `ralphctl` | Interactive TUI (primary surface) |
366
- | `ralphctl doctor` | Check environment health |
367
- | `ralphctl settings show` | Print current settings |
368
- | `ralphctl settings set <key> <value>` | Set a single settings key |
369
- | `ralphctl settings apply-preset <name>` | Stamp the entire `ai` section — 20 presets across five families: `standard` / `economic` / `strong-gate` / `fast` / `frontier`, each in `mixed` / `*-only` / `*-economic` / `*-strong-gate` / `*-fast` / `*-frontier` variants |
370
- | `ralphctl completion <shell>` | Print shell tab-completion script |
422
+ | Command | Description |
423
+ | --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
424
+ | `ralphctl` | Interactive TUI (primary surface) |
425
+ | `ralphctl doctor` | Check environment health |
426
+ | `ralphctl settings show` | Print current settings |
427
+ | `ralphctl settings set <key> <value>` | Set a single settings key |
428
+ | `ralphctl settings apply-preset <name>` | Stamp the entire `ai` section — 21 presets: `standard` / `economic` / `strong-gate` / `fast` / `frontier` families, each in `mixed` / `*-only` variants, plus `opencode-only` |
429
+ | `ralphctl completion <shell>` | Print shell tab-completion script |
371
430
 
372
431
  ### Project & Sprint Inspection
373
432
 
@@ -420,6 +479,7 @@ Run `ralphctl <command> --help` for flag-level detail.
420
479
  | Resource | Description |
421
480
  | ------------------------------------------------ | -------------------------------------------------------- |
422
481
  | [Architecture](./ARCHITECTURE.md) | Data models, harness loop, file storage, error reference |
482
+ | [Providers](./docs/providers.md) | Per-backend setup, permission mapping, model ids, limits |
423
483
  | [Adding a provider](./docs/adding-a-provider.md) | Extension guide: wire a new AI CLI into the harness |
424
484
  | [Requirements](./.claude/docs/REQUIREMENTS.md) | Acceptance criteria and feature checklist |
425
485
  | [Contributing](./CONTRIBUTING.md) | Dev setup, code style, PR process |