@beremaran/ralphie 0.0.0-stage → 0.2.1
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/CHANGELOG.md +843 -0
- package/LICENSE +21 -0
- package/README.md +53 -2
- package/dist/ralphie.js +33689 -0
- package/docs/README.md +71 -0
- package/docs/architecture.md +159 -0
- package/docs/cli-reference.md +126 -0
- package/docs/configuration.md +269 -0
- package/docs/development.md +249 -0
- package/docs/getting-started.md +134 -0
- package/docs/operations-and-recovery.md +328 -0
- package/docs/safety.md +189 -0
- package/docs/workflows.md +411 -0
- package/package.json +83 -3
- package/vendor/mattpocock-skills/LICENSE +21 -0
- package/vendor/mattpocock-skills/code-review/SKILL.md +87 -0
- package/vendor/mattpocock-skills/code-review/agents/openai.yaml +3 -0
- package/vendor/mattpocock-skills/codebase-design/DEEPENING.md +37 -0
- package/vendor/mattpocock-skills/codebase-design/DESIGN-IT-TWICE.md +44 -0
- package/vendor/mattpocock-skills/codebase-design/SKILL.md +114 -0
- package/vendor/mattpocock-skills/codebase-design/agents/openai.yaml +3 -0
- package/vendor/mattpocock-skills/diagnosing-bugs/SKILL.md +138 -0
- package/vendor/mattpocock-skills/diagnosing-bugs/agents/openai.yaml +3 -0
- package/vendor/mattpocock-skills/diagnosing-bugs/scripts/hitl-loop.template.sh +44 -0
- package/vendor/mattpocock-skills/implement/SKILL.md +15 -0
- package/vendor/mattpocock-skills/implement/agents/openai.yaml +5 -0
- package/vendor/mattpocock-skills/lock.json +37 -0
- package/vendor/mattpocock-skills/tdd/SKILL.md +38 -0
- package/vendor/mattpocock-skills/tdd/agents/openai.yaml +3 -0
- package/vendor/mattpocock-skills/tdd/mocking.md +59 -0
- package/vendor/mattpocock-skills/tdd/tests.md +77 -0
- package/vendor/mattpocock-skills/to-tickets/SKILL.md +105 -0
- package/vendor/mattpocock-skills/to-tickets/agents/openai.yaml +5 -0
- package/vendor/mattpocock-skills/triage/AGENT-BRIEF.md +207 -0
- package/vendor/mattpocock-skills/triage/OUT-OF-SCOPE.md +105 -0
- package/vendor/mattpocock-skills/triage/SKILL.md +112 -0
- package/vendor/mattpocock-skills/triage/agents/openai.yaml +5 -0
package/docs/README.md
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Ralphie documentation
|
|
2
|
+
|
|
3
|
+
This directory is the detailed documentation set for Ralphie. The [root
|
|
4
|
+
README](../README.md) is the concise product overview and first-run guide;
|
|
5
|
+
these pages are the authoritative home for contracts that should not be
|
|
6
|
+
buried in a landing page.
|
|
7
|
+
|
|
8
|
+
## Suggested reading paths
|
|
9
|
+
|
|
10
|
+
### New user
|
|
11
|
+
|
|
12
|
+
1. [Getting started](getting-started.md): prerequisites, installation,
|
|
13
|
+
authentication, verification, and a safe first run.
|
|
14
|
+
2. [Safety](safety.md): understand what a mutation-enabled run can change.
|
|
15
|
+
3. [Workflows](workflows.md): see how issues are routed and delivered.
|
|
16
|
+
4. [Configuration](configuration.md): write the config file.
|
|
17
|
+
5. [CLI reference](cli-reference.md): choose options and adapt the recipes.
|
|
18
|
+
|
|
19
|
+
### Operator
|
|
20
|
+
|
|
21
|
+
1. [Safety](safety.md): review direct-push defaults, invariants, and workspace
|
|
22
|
+
risks before operating on a real repository.
|
|
23
|
+
2. [Configuration](configuration.md) and [CLI reference](cli-reference.md) -
|
|
24
|
+
settings, invocation, output, and environment variables.
|
|
25
|
+
3. [Operations and recovery](operations-and-recovery.md): interpret output,
|
|
26
|
+
inspect artifacts, and understand what remains after interruption.
|
|
27
|
+
4. [Workflows](workflows.md): understand implementation, decomposition, and
|
|
28
|
+
direct-push delivery.
|
|
29
|
+
|
|
30
|
+
### Contributor
|
|
31
|
+
|
|
32
|
+
1. [Development](development.md): local setup, checks, tests, and contribution
|
|
33
|
+
expectations.
|
|
34
|
+
2. [Architecture](architecture.md): runtime assembly and domain boundaries.
|
|
35
|
+
3. [Workflows](workflows.md): behavior and mutation boundaries to preserve.
|
|
36
|
+
4. [Operations and recovery](operations-and-recovery.md): state and recovery
|
|
37
|
+
contracts that changes must not break.
|
|
38
|
+
|
|
39
|
+
### Release maintainer
|
|
40
|
+
|
|
41
|
+
1. [Getting started](getting-started.md): the installation contract
|
|
42
|
+
(`bunx @beremaran/ralphie`) and first run.
|
|
43
|
+
2. [Development](development.md): build, package smoke, and the tag-triggered
|
|
44
|
+
npm publish flow.
|
|
45
|
+
3. [Operations and recovery](operations-and-recovery.md): operational state and
|
|
46
|
+
cleanup behavior.
|
|
47
|
+
|
|
48
|
+
## Page map
|
|
49
|
+
|
|
50
|
+
| Page | Purpose |
|
|
51
|
+
| --- | --- |
|
|
52
|
+
| [Getting started](getting-started.md) | Install Ralphie, configure credentials, verify it, and run the first run. |
|
|
53
|
+
| [Workflows](workflows.md) | Explain issue routing, implementation, decomposition, and direct-push delivery. |
|
|
54
|
+
| [Safety](safety.md) | Define deterministic Git/GitHub safety checks and destructive workspace behavior. |
|
|
55
|
+
| [Configuration](configuration.md) | Define the YAML config file, every key and default, repository overrides, and `--set`. |
|
|
56
|
+
| [CLI reference](cli-reference.md) | Record the command syntax, remaining options, environment variables, and recipes. |
|
|
57
|
+
| [Operations and recovery](operations-and-recovery.md) | Document progress, artifacts, state, cancellation, failure, and cleanup. |
|
|
58
|
+
| [Architecture](architecture.md) | Map runtime, orchestrator, domain services, and source locations. |
|
|
59
|
+
| [Development](development.md) | Explain local development, test commands, optional registry checks, the vendored skills sync, and contribution rules. |
|
|
60
|
+
|
|
61
|
+
## Keeping documentation current
|
|
62
|
+
|
|
63
|
+
Keep each contract authoritative on one page. Put new settings in
|
|
64
|
+
[Configuration](configuration.md), new CLI options in the [CLI
|
|
65
|
+
reference](cli-reference.md), workflow behavior in [Workflows](workflows.md),
|
|
66
|
+
recovery behavior in [Operations and recovery](operations-and-recovery.md),
|
|
67
|
+
component changes in [Architecture](architecture.md), and release changes in
|
|
68
|
+
[Development](development.md)'s publishing section. Summaries elsewhere should
|
|
69
|
+
link here rather than copy sections that can drift. Keep safety warnings
|
|
70
|
+
visible before mutation-enabled commands and use relative links so pages work
|
|
71
|
+
on GitHub and in a checkout.
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# Architecture
|
|
2
|
+
|
|
3
|
+
This page is for contributors and maintainers who need the runtime and domain
|
|
4
|
+
boundaries, component map, or source locations. It is the authoritative
|
|
5
|
+
architecture overview. Return to the [documentation index](README.md).
|
|
6
|
+
|
|
7
|
+
## Runtime boundaries
|
|
8
|
+
|
|
9
|
+
Ralphie uses Bun's built-in argument parser and native promises. Services are
|
|
10
|
+
assembled as an explicit dependency object, which keeps the runtime small and
|
|
11
|
+
makes tests straightforward without a framework-specific execution model.
|
|
12
|
+
|
|
13
|
+
```mermaid
|
|
14
|
+
flowchart LR
|
|
15
|
+
U[Operator] --> CLI["Inbound adapter<br/>command.ts / cli.ts / options.ts"]
|
|
16
|
+
CLI --> CTX["Bounded contexts<br/>agent · config · git · github · harness · issues<br/>process · progress · run · workflow · workspace"]
|
|
17
|
+
CTX --> PORTS["<context>/ports.ts + /domain"]
|
|
18
|
+
PORTS -. implemented by .-> AD["<context>/adapters/"]
|
|
19
|
+
AD --> GH[GitHub API]
|
|
20
|
+
AD --> REPO[Workspace checkout]
|
|
21
|
+
AD --> LLM[Harness CLIs]
|
|
22
|
+
AD --> DISK[State, artifacts, diagnostics]
|
|
23
|
+
AD --> TERM[Terminal or JSON Lines]
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Each bounded context owns its contract, domain model, and adapters together:
|
|
27
|
+
`<context>/ports.ts` (and `issues/domain/`) declares the core-owned types,
|
|
28
|
+
`<context>/adapters/` implements them, and application logic lives beside them
|
|
29
|
+
(`issues/app/`, `agent/`, `workflow/`). `src/runtime.ts` is the composition root
|
|
30
|
+
that binds concrete adapters into the runtime bundle.
|
|
31
|
+
|
|
32
|
+
| Context | Location | Responsibility |
|
|
33
|
+
| --- | --- | --- |
|
|
34
|
+
| `agent` | `src/agent/` | Prompts, structured-output and text-task helpers, and the role-to-session mapping (access mode, timeouts) over the harness port. Kept apart from `harness` on purpose: `agent` holds Ralphie's own prompts and role policy, while `harness` stays provider-neutral session plumbing that knows nothing about issues. |
|
|
35
|
+
| `config` | `src/config/` | YAML configuration: the zod schema (`settings.ts`), layering and `--set` overrides (`load.ts`, `overrides.ts`), and the file-reader port with its Bun YAML adapter. |
|
|
36
|
+
| `harness` | `src/harness/` | Provider-neutral harness port (session request, events, typed failures, structured results), the service that runs sessions and repairs invalid results, and one CLI adapter per harness (Claude Code, Codex, pi and OpenCode). Every workflow session runs through it, wrapped by session isolation, the read-only fingerprint guard and skill injection; `app/roles.ts` resolves the configured role assignments. The vendored skills live in `vendor/mattpocock-skills/` (see [Development](development.md#vendored-skills)). |
|
|
37
|
+
| `github` | `src/github/` | Issue value objects, repository slug parsing, and the Octokit/`gh` adapters. |
|
|
38
|
+
| `git` | `src/git/` | Checkout preparation, checkpoints, issue operations, invariants, and remote-safety adapters. |
|
|
39
|
+
| `issues` | `src/issues/` | Domain (`domain/`), executors and artifact/recovery logic (`app/`), filesystem adapters (`adapters/`). |
|
|
40
|
+
| `progress` | `src/progress/` | `ports.ts` contract plus the OpenTUI interactive adapter and the plain/JSON adapters. It renders only harness-neutral session events and imports nothing from `agent` or a harness adapter. |
|
|
41
|
+
| `run` | `src/run/` | Versioned run-state schemas, the state/event-log ports, and their adapters. |
|
|
42
|
+
| `process` | `src/process/` | Bounded command runner port (timeout, abort, stdin, streamed stdout lines), the helper, and its adapter. |
|
|
43
|
+
| `workspace` | `src/workspace/` | Path expansion, the workspace port, and the protected-removal adapter. |
|
|
44
|
+
| `workflow` | `src/workflow/` | Issue-workflow orchestration, the runtime bundle port, and exit-code policy. |
|
|
45
|
+
| Inbound adapter | `src/command.ts`, `src/cli.ts`, `src/options.ts` | CLI parsing, terminal detection, and the top-level error boundary. |
|
|
46
|
+
| Composition root | `src/runtime.ts` | Builds concrete adapters and exposes them as the workflow runtime bundle. |
|
|
47
|
+
| Shared kernel | `src/shared/` | Errors and terminal-control sanitization used by every context. |
|
|
48
|
+
|
|
49
|
+
Dependency direction is one-way. Contexts import each other's `ports.ts`,
|
|
50
|
+
domain modules and pure `app/` helpers (no I/O, no process or vendor imports),
|
|
51
|
+
never another context's `adapters/`; only the composition root
|
|
52
|
+
(`runtime.ts`, `command.ts`) instantiates adapters. Non-adapter code imports no
|
|
53
|
+
`node:fs`, `node:child_process`, vendor SDK, or process stream. The `issues`
|
|
54
|
+
context defines its file-system ports (`IssueArtifactFileSystem`,
|
|
55
|
+
`RecoveryFileSystem`) in `issues/app/` and its node implementations live in
|
|
56
|
+
`issues/adapters/`, so the atomic-write and diagnostic logic never touches
|
|
57
|
+
`node:fs`. Adapters receive their dependencies instead of constructing them:
|
|
58
|
+
the GitHub capability adapters share one adapter-owned session, git adapters
|
|
59
|
+
receive the command runner, and the run receives a composition-resolved
|
|
60
|
+
`RunLayout` plus injected `Clock` and `IdGenerator`, so no application code
|
|
61
|
+
reads the clock, generates ids, or composes workspace paths itself.
|
|
62
|
+
Cross-cutting composed services such as parent completion and issue
|
|
63
|
+
preparation live in `issues/app/`, and `workflow/ports.ts` exposes the
|
|
64
|
+
driving `IssueWorkflow` port that the CLI invokes.
|
|
65
|
+
|
|
66
|
+
The progress contract lives in `src/progress/ports.ts`; `src/progress/adapters/`
|
|
67
|
+
implements it and is imported only by the composition root. `src/command.ts`
|
|
68
|
+
owns the terminal decision and passes one shared `RunEventLog` to the
|
|
69
|
+
coordinator (for persistence) and the runtime (the run closes it before
|
|
70
|
+
removing the workspace). `tests/architecture.test.ts` enforces the adapter
|
|
71
|
+
import rules, the no-I/O rule for non-adapter code, the Octokit confinement
|
|
72
|
+
(the `github` context is the only place the SDK appears), composition-root
|
|
73
|
+
isolation, and process-stream ownership. `tests/contracts/` holds the shared
|
|
74
|
+
behavioral suites that both the in-memory fakes and the live adapters pass: the
|
|
75
|
+
`RunEventLog` and `IssueArtifactStore` suites, the harness adapter suite that
|
|
76
|
+
every `HarnessAdapter` must pass (`harness-adapter.contract.ts`), and the
|
|
77
|
+
harness service suite (`harness-service.contract.ts`).
|
|
78
|
+
|
|
79
|
+
## Skill injection
|
|
80
|
+
|
|
81
|
+
For each session, skill injection copies the pinned skills into the harness's
|
|
82
|
+
project skills location (`SKILL_SUPPORT` in `src/harness/app/skill-injection.ts`),
|
|
83
|
+
shadows any same-named repository skill until the session ends, and adds the
|
|
84
|
+
copies to `.git/info/exclude`. The spec also allows a per-invocation skills
|
|
85
|
+
option where a harness has one. Of the four, only pi does (`--skill <path>`).
|
|
86
|
+
Claude Code's `--plugin-dir` would load the skills as a plugin and rename them
|
|
87
|
+
`plugin:name`, and Codex and OpenCode have no such flag. Ralphie therefore uses
|
|
88
|
+
the project location for every harness, so shadowing and exclusion live in one
|
|
89
|
+
place. A new harness adds one `SKILL_SUPPORT` entry, its location and invocation
|
|
90
|
+
syntax together.
|
|
91
|
+
|
|
92
|
+
## OpenCode adapter findings
|
|
93
|
+
|
|
94
|
+
Spike against OpenCode v2.0.22 (the published docs mostly describe v1). The recorded streams live in `tests/harness/fixtures/opencode/`.
|
|
95
|
+
|
|
96
|
+
- **Invocation**: `opencode run --standalone --format json`, prompt on stdin (with no message it prints an `error` event, "You must provide a message"). `--standalone` starts a private server, so the invocation's working directory and environment apply; the background service is shared and is never used.
|
|
97
|
+
- **Events**: one JSON object per line: `step_start`, `text` (whole block), `tool_use` (one event with input and output once the tool finished; `state.status` is `completed` or `error`, and a tool can report failure through `metadata.metadata.error` while `completed`), `step_finish` (`tokens` and `cost` per step) and `error` (`error.type` such as `provider.no-route` or `provider.quota`). There is no terminal result event, so a run succeeded when it exited 0, printed no `error` event and produced text. An error makes the process exit 1.
|
|
98
|
+
- **Usage**: the adapter sums every `step_finish` into one usage event per turn. `cost` is 0 for the recorded runs, so `costUsd` is omitted then. There is no budget cap flag.
|
|
99
|
+
- **Sessions**: `--session <id>` resumes, or creates the session when it does not exist. Session ids look like `ses_...`.
|
|
100
|
+
- **Model and effort**: `--model provider/model#variant`; the variant plays the part of effort and is only applied together with a model.
|
|
101
|
+
- **Access**: there is no sandbox. Read-only uses `--agent plan`, which denies edit tools but still allows shell commands, so it is not a hard guarantee. `--auto` approves every permission that is not denied and is the only editing mode; `safe` is refused with an `access` failure before anything runs. Without `--auto` a headless run cannot answer approval prompts.
|
|
102
|
+
- **Structured output**: none native. The service falls back to the fenced JSON block protocol.
|
|
103
|
+
- **Skills**: a skill under `.opencode/skills/<name>/` is loaded headlessly through the `skill` tool (recorded in `skill.jsonl`). Skills hidden from the model (user-only) were not tested.
|
|
104
|
+
- **Not verified live**: the spike had no usable model credits, so a successful read-only `--agent plan` run, resuming with `--session`, and user-only skills headlessly are untested against the real CLI. The recorded success streams come from earlier notes; only the error streams were recorded fresh. Until that run passes, startup refuses OpenCode unless the configuration sets `harnesses.opencode.experimental: true` (`UNVERIFIED_HARNESSES` in `src/harness/ports.ts`). Run [the live smoke script](development.md#live-smoke-script) with `--harness opencode` to verify it, and drop it from that list once it passes. The smoke script opts in on its own.
|
|
105
|
+
|
|
106
|
+
## Dependency and side-effect rules
|
|
107
|
+
|
|
108
|
+
Agents own reasoning and edits within their permitted tool boundary. They do not
|
|
109
|
+
own commits, pushes, issue mutations, or delivery sequencing. Deterministic
|
|
110
|
+
services under `src/git/adapters/` and `src/github/adapters/` perform those side
|
|
111
|
+
effects and verify their invariants. The explicit runtime object makes these
|
|
112
|
+
boundaries testable without a framework-specific execution model.
|
|
113
|
+
|
|
114
|
+
The `GitRepositoryFactsService` port in `src/git/ports.ts` reads HEAD, branch, status, recent log, and tracked files so read-only prompts, whose sessions have no shell, receive them as a `<repository-facts>` block.
|
|
115
|
+
|
|
116
|
+
Agent configuration is separate from persistent workspace state: the
|
|
117
|
+
`harnesses` and `roles` configuration keys choose the harness, model, and
|
|
118
|
+
effort per role, and each harness CLI keeps its own login and credentials.
|
|
119
|
+
Ralphie never stores agent configuration under the
|
|
120
|
+
workspace; run state and recovery artifacts belong under the workspace's
|
|
121
|
+
`.ralphie` directory.
|
|
122
|
+
|
|
123
|
+
For workflow behavior and the agent/deterministic boundary, see [Workflows](workflows.md)
|
|
124
|
+
and [Safety](safety.md). For state transitions and retained diagnostics, see
|
|
125
|
+
[Operations and recovery](operations-and-recovery.md).
|
|
126
|
+
|
|
127
|
+
## Distribution boundary
|
|
128
|
+
|
|
129
|
+
Ralphie's only distribution channel is the published npm package (see
|
|
130
|
+
[Getting started](getting-started.md#published-package)); the former native
|
|
131
|
+
binary, installer, Homebrew, and container distribution machinery was removed.
|
|
132
|
+
|
|
133
|
+
The package boundary is the bundled `dist/ralphie.js` CLI reached from
|
|
134
|
+
`index.ts` through `src/cli.ts`, `src/command.ts`, and runtime assembly. Tests
|
|
135
|
+
and helper probes are verification-only consumers. In particular, a type-only
|
|
136
|
+
import can document or check a contract but does not make a module runtime
|
|
137
|
+
reachable. The deterministic source audit is described in
|
|
138
|
+
[Development](development.md#source-reachability-boundary) and runs as part of
|
|
139
|
+
the normal check gate.
|
|
140
|
+
|
|
141
|
+
## Source map
|
|
142
|
+
|
|
143
|
+
| Concern | Primary source |
|
|
144
|
+
| --- | --- |
|
|
145
|
+
| Configuration schema, layering, and file loading | `src/config/` |
|
|
146
|
+
| Public trigger and flags | `index.ts`, `src/cli.ts`, `src/command.ts`, `src/options.ts` |
|
|
147
|
+
| Runtime dependency assembly | `src/runtime.ts` |
|
|
148
|
+
| Run orchestration, queue, state transitions | `src/workflow/workflow.ts`, `src/issues/domain/queue.ts` |
|
|
149
|
+
| Pre-flight routing | `src/issues/app/issue-routing.ts`, `src/issues/app/execution-model.ts` (outcomes and execution context), `src/issues/app/preflight.ts` |
|
|
150
|
+
| Hand-offs | `src/issues/domain/hand-off.ts`, `src/issues/app/hand-off.ts`, `src/github/adapters/hand-off.ts` |
|
|
151
|
+
| AFK triage | `src/workflow/triage-phase.ts`, `src/issues/app/triage.ts`, `src/github/adapters/triage.ts` |
|
|
152
|
+
| Implementation/review/delivery | `src/issues/app/implementation-executor.ts` (attempts and delivery), `src/issues/app/implementation-attempt.ts` (prompt, result, retry policy), `src/issues/app/candidate-review.ts` (candidate commits and the two-axis review gate), `src/issues/app/verification.ts`, `src/git/adapters/issue-operations.ts`, `src/git/adapters/remote-safety.ts` |
|
|
153
|
+
| Decomposition and GitHub mutations | `src/issues/app/decomposition-executor.ts`, `src/github/adapters/issue-mutations.ts`, `src/github/adapters/issue-relationships.ts` |
|
|
154
|
+
| Role assignments, session requests, and structured results | `src/harness/app/roles.ts`, `src/agent/` |
|
|
155
|
+
| Harness sessions, structured results, and the harness adapters | `src/harness/ports.ts`, `src/harness/app/`, `src/harness/adapters/` |
|
|
156
|
+
| Git checkpoints, safety, and branches | `src/git/` |
|
|
157
|
+
| Durable run state, artifacts, diagnostics, and event audit | `src/issues/app/artifacts.ts`, `src/issues/app/recovery.ts`, `src/run/`, `src/issues/adapters/` |
|
|
158
|
+
| Driving port and runtime bundle | `src/workflow/ports.ts`, `src/runtime.ts` |
|
|
159
|
+
| Execution contracts, presentation, and exit semantics | `src/*/ports.ts`, `src/progress/adapters/` (OpenTUI, plain, JSON), `src/workflow/exit-code.ts` |
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# CLI reference
|
|
2
|
+
|
|
3
|
+
This page is for operators automating Ralphie. It is the authoritative
|
|
4
|
+
reference for invocation syntax, command-line options, environment variables,
|
|
5
|
+
and common recipes. Settings live in the [configuration file](configuration.md). Return to the
|
|
6
|
+
[documentation index](README.md) for suggested reading paths.
|
|
7
|
+
|
|
8
|
+
## Invocation
|
|
9
|
+
|
|
10
|
+
```text
|
|
11
|
+
bunx @beremaran/ralphie [owner/]repository [options]
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
`[owner/]repository` is required. It accepts an `owner/name` slug, a GitHub
|
|
15
|
+
HTTPS/SSH clone URL, or a bare repository name whose owner comes from
|
|
16
|
+
`defaultOwner` or the authenticated `gh` login (see
|
|
17
|
+
[Configuration](configuration.md#choosing-a-repository)). Nothing is inferred
|
|
18
|
+
from the current directory. Extra positional arguments are rejected. When
|
|
19
|
+
running from a source checkout, replace the package runner with
|
|
20
|
+
`bun run index.ts`.
|
|
21
|
+
|
|
22
|
+
Run `bunx @beremaran/ralphie --help` for the help generated from the current
|
|
23
|
+
command schema.
|
|
24
|
+
|
|
25
|
+
> [!CAUTION]
|
|
26
|
+
> Ralphie commits and pushes directly to the selected branch. Test against a
|
|
27
|
+
> repository you control, and read the [safety model](safety.md) before
|
|
28
|
+
> running it.
|
|
29
|
+
|
|
30
|
+
## `init`
|
|
31
|
+
|
|
32
|
+
```text
|
|
33
|
+
bunx @beremaran/ralphie init [--config <path>]
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Detects the harnesses on PATH and writes a commented starter config at
|
|
37
|
+
`--config` or the default location. It never overwrites an existing file and
|
|
38
|
+
fails when no supported harness is found. See
|
|
39
|
+
[Getting started](getting-started.md#create-the-config-file).
|
|
40
|
+
|
|
41
|
+
## Options
|
|
42
|
+
|
|
43
|
+
All behavior settings live in the [configuration file](configuration.md).
|
|
44
|
+
These options remain on the command line:
|
|
45
|
+
|
|
46
|
+
| Option | Default | Description |
|
|
47
|
+
| --- | --- | --- |
|
|
48
|
+
| `--config <path>` | `$XDG_CONFIG_HOME/ralphie/config.yaml`, else `~/.config/ralphie/config.yaml` | Read configuration from this file. A missing file is an error. |
|
|
49
|
+
| `--set <path=value>` | none | Override one configuration key for this run; repeatable. The path is dotted, a key containing a slash is double-quoted (`repos."owner/repo".branch=develop`), and the value is YAML. Applied after the file and the matching `repos` entry. |
|
|
50
|
+
| `--output <mode>` | `default` | Output mode: `default` renders the full-screen TUI on a terminal and plain append-only lines when piped or in CI; `json` writes JSON Lines on stdout. |
|
|
51
|
+
|
|
52
|
+
The short aliases are `-h` for `--help` and `-v` for `--version`. Former flags
|
|
53
|
+
fail with an error naming the configuration key that replaces them; the
|
|
54
|
+
mapping is in [Configuration](configuration.md#removed-flags).
|
|
55
|
+
|
|
56
|
+
Every run processes the entire matching open-issue queue, sequentially, in the
|
|
57
|
+
order set by `intake.sort`.
|
|
58
|
+
|
|
59
|
+
## Environment variables
|
|
60
|
+
|
|
61
|
+
Ralphie also reads these environment variables:
|
|
62
|
+
|
|
63
|
+
| Variable | Purpose |
|
|
64
|
+
| --- | --- |
|
|
65
|
+
| `GH_TOKEN` | GitHub.com token for noninteractive `gh` authentication (preferred). |
|
|
66
|
+
| `GITHUB_TOKEN` | Fallback GitHub.com token alias for `gh`. |
|
|
67
|
+
|
|
68
|
+
For interactive `github.com` use, authenticate with `gh auth login` and verify
|
|
69
|
+
with `gh auth status`. For unattended use, provide `GH_TOKEN` (preferred) or
|
|
70
|
+
`GITHUB_TOKEN` as an environment input; it does not need to be printed or
|
|
71
|
+
exposed. A mounted GitHub CLI profile is not required when an environment token
|
|
72
|
+
is provided. This authentication contract covers `github.com` only. See
|
|
73
|
+
[Getting started](getting-started.md) for the first-run setup.
|
|
74
|
+
|
|
75
|
+
## Common recipes
|
|
76
|
+
|
|
77
|
+
Run the issue queue with settings from the default config file:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
bunx @beremaran/ralphie owner/repository
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Use a different config file and a bare repository name:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
bunx @beremaran/ralphie repository --config ./ralphie.yaml
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Override settings for one run:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
bunx @beremaran/ralphie owner/repository \
|
|
93
|
+
--set 'intake.requireLabels=[bug]' \
|
|
94
|
+
--set 'repos."owner/repository".branch=develop'
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Choose a model and effort for one run with `--set` (see
|
|
98
|
+
[Configuration](configuration.md#harnesses-and-roles)):
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
bunx @beremaran/ralphie owner/repository \
|
|
102
|
+
--set harnesses.claude.model=opus \
|
|
103
|
+
--set harnesses.claude.effort=high
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Write machine-readable progress to stdout:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
bunx @beremaran/ralphie owner/repository --output json > ralphie.jsonl
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
The workflow commits and pushes directly to the selected branch. It is not a
|
|
113
|
+
wait-for-human-review mode: approved work is committed, the remote head is
|
|
114
|
+
revalidated, and the commit is pushed without force before the source issue is
|
|
115
|
+
closed. Read [Workflows](workflows.md) and [Safety](safety.md) before running
|
|
116
|
+
it; the workspace is deleted, so read [Workspace risk](safety.md#workspace-risk)
|
|
117
|
+
first.
|
|
118
|
+
|
|
119
|
+
## Version and help
|
|
120
|
+
|
|
121
|
+
`ralphie --version` prints only the release version. For automation,
|
|
122
|
+
`ralphie --version --output json` prints a stable object containing `version`
|
|
123
|
+
and `commitSha`. Both forms work without a repository, GitHub credentials, or
|
|
124
|
+
a model provider. Release builds embed the immutable commit SHA supplied by
|
|
125
|
+
the build entry point; local builds use the documented `local` commit sentinel
|
|
126
|
+
when no release SHA is supplied.
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
# Configuration
|
|
2
|
+
|
|
3
|
+
Ralphie reads its settings from a YAML file instead of command-line flags. This
|
|
4
|
+
page is the authoritative reference for the file location, every key, its
|
|
5
|
+
default, and how settings are layered. Return to the
|
|
6
|
+
[documentation index](README.md) for reading paths, and see the
|
|
7
|
+
[CLI reference](cli-reference.md) for the few options that remain on the
|
|
8
|
+
command line.
|
|
9
|
+
|
|
10
|
+
## File location
|
|
11
|
+
|
|
12
|
+
Ralphie loads the first of these that applies:
|
|
13
|
+
|
|
14
|
+
1. The path given with `--config <path>`. A missing file is an error.
|
|
15
|
+
2. `$XDG_CONFIG_HOME/ralphie/config.yaml`, when `XDG_CONFIG_HOME` is an
|
|
16
|
+
absolute path.
|
|
17
|
+
3. `~/.config/ralphie/config.yaml`.
|
|
18
|
+
|
|
19
|
+
There is no built-in fallback: when no file exists, Ralphie stops at startup,
|
|
20
|
+
names the path it looked for, and points at `ralphie init`, which writes a
|
|
21
|
+
starter file. An empty file is valid and means "all
|
|
22
|
+
defaults".
|
|
23
|
+
|
|
24
|
+
The file is validated with a strict schema before anything else runs. Unknown
|
|
25
|
+
keys, wrong types, and unknown values fail with the offending path, for
|
|
26
|
+
example `limits.reviewRounds: Invalid input: expected number, received string`. Errors caused
|
|
27
|
+
by a `--set` override are marked `(from --set)`.
|
|
28
|
+
|
|
29
|
+
## Choosing a repository
|
|
30
|
+
|
|
31
|
+
Ralphie is invoked as `ralphie [owner/]repo`. Nothing is inferred from the
|
|
32
|
+
current directory.
|
|
33
|
+
|
|
34
|
+
| Argument | Resolved to |
|
|
35
|
+
| --- | --- |
|
|
36
|
+
| `owner/repo` or a GitHub HTTPS/SSH clone URL | Used as given. |
|
|
37
|
+
| `repo` | `defaultOwner/repo`, else the login `gh` is authenticated as (`gh api user`, honoring `GH_TOKEN`/`GITHUB_TOKEN`). |
|
|
38
|
+
|
|
39
|
+
## Layering
|
|
40
|
+
|
|
41
|
+
For the selected repository, settings are layered from lowest to highest
|
|
42
|
+
precedence:
|
|
43
|
+
|
|
44
|
+
1. Built-in defaults.
|
|
45
|
+
2. Top-level settings in the file.
|
|
46
|
+
3. The matching `repos."owner/repo"` entry. Repository keys match
|
|
47
|
+
case-insensitively.
|
|
48
|
+
4. `--set path=value` overrides, in command-line order.
|
|
49
|
+
|
|
50
|
+
Mappings merge key by key. Lists and scalars replace the lower layer
|
|
51
|
+
entirely: a `repos` entry that sets `intake.requireLabels` does not add to the
|
|
52
|
+
top-level list.
|
|
53
|
+
|
|
54
|
+
### `--set path=value`
|
|
55
|
+
|
|
56
|
+
`--set` is repeatable. The path is dotted; a key containing dots or a slash
|
|
57
|
+
is double-quoted, and the value is read as YAML:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
ralphie acme/api \
|
|
61
|
+
--set limits.reviewRounds=3 \
|
|
62
|
+
--set 'intake.requireLabels=[bug, backend]' \
|
|
63
|
+
--set 'repos."acme/api".branch=develop'
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
A `--set` path under `repos."owner/repo"` applies to that repository like
|
|
67
|
+
any file entry. Quote the whole argument for your shell when the value
|
|
68
|
+
contains spaces or brackets.
|
|
69
|
+
|
|
70
|
+
## Keys
|
|
71
|
+
|
|
72
|
+
```yaml
|
|
73
|
+
defaultOwner: acme
|
|
74
|
+
workspace: ~/.ralphie
|
|
75
|
+
approval: safe
|
|
76
|
+
harnesses:
|
|
77
|
+
claude:
|
|
78
|
+
model: opus
|
|
79
|
+
effort: high
|
|
80
|
+
approval: safe
|
|
81
|
+
roles:
|
|
82
|
+
default: claude
|
|
83
|
+
reviewer:
|
|
84
|
+
harness: claude
|
|
85
|
+
model: sonnet
|
|
86
|
+
intake:
|
|
87
|
+
requireLabels: [bug]
|
|
88
|
+
sort: created:asc
|
|
89
|
+
triage:
|
|
90
|
+
enabled: false
|
|
91
|
+
labels:
|
|
92
|
+
needs-triage: needs-triage
|
|
93
|
+
needs-info: needs-info
|
|
94
|
+
ready-for-agent: ready-for-agent
|
|
95
|
+
ready-for-human: ready-for-human
|
|
96
|
+
wontfix: wontfix
|
|
97
|
+
skills:
|
|
98
|
+
dir: ./my-skills
|
|
99
|
+
limits:
|
|
100
|
+
implementationAttempts: 3
|
|
101
|
+
reviewRounds: 5
|
|
102
|
+
verificationFixes: 5
|
|
103
|
+
maxDecompositionDepth: 3
|
|
104
|
+
sessionTimeoutMinutes:
|
|
105
|
+
edit: 60
|
|
106
|
+
readOnly: 15
|
|
107
|
+
maxBudgetUsd: 5
|
|
108
|
+
repos:
|
|
109
|
+
acme/api:
|
|
110
|
+
branch: develop
|
|
111
|
+
verify:
|
|
112
|
+
- bun run check
|
|
113
|
+
intake:
|
|
114
|
+
requireLabels: [bug, backend]
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Every key is optional. The values above are the defaults, except
|
|
118
|
+
`defaultOwner`, `branch`, `verify`, `skills.dir`, and `limits.maxBudgetUsd`, which have none.
|
|
119
|
+
|
|
120
|
+
### Top level
|
|
121
|
+
|
|
122
|
+
| Key | Default | Description |
|
|
123
|
+
| --- | --- | --- |
|
|
124
|
+
| `defaultOwner` | none | Owner added to a bare `repo` argument. Top level only. |
|
|
125
|
+
| `approval` | `safe` | Approval mode of the editing roles (`implementer`, `fixer`): `safe` or `yolo`. Overridable per repository and per harness. See [Approval modes](safety.md#approval-modes). |
|
|
126
|
+
| `workspace` | `~/.ralphie` | Root directory for repository checkouts and run artifacts. Ralphie deletes this directory; use a path dedicated to Ralphie (see [Workspace risk](safety.md#workspace-risk)). Overridable per repository. |
|
|
127
|
+
| `repos` | none | Per-repository overrides, keyed by `owner/repo`. Top level only. |
|
|
128
|
+
|
|
129
|
+
### `harnesses` and `roles`
|
|
130
|
+
|
|
131
|
+
Every agent session runs as a role on a harness. The harnesses are `claude`
|
|
132
|
+
(Claude Code), `codex`, `pi`, and `opencode`. Sessions run through the
|
|
133
|
+
harness's own command-line program, which brings its own login and
|
|
134
|
+
credentials; Ralphie stores none.
|
|
135
|
+
|
|
136
|
+
`harnesses.<name>` sets the defaults for sessions on that harness:
|
|
137
|
+
|
|
138
|
+
| Key | Default | Description |
|
|
139
|
+
| --- | --- | --- |
|
|
140
|
+
| `harnesses.<name>.model` | harness default | Model passed to the harness. |
|
|
141
|
+
| `harnesses.<name>.effort` | harness default | Reasoning effort passed to the harness. |
|
|
142
|
+
| `harnesses.<name>.approval` | top-level `approval` | Approval mode for editing roles that run on this harness. |
|
|
143
|
+
| `harnesses.<name>.experimental` | `false` | Opt in to a harness whose adapter has not been verified against a live model. Currently only `opencode` needs it: startup refuses any role assigned to OpenCode until `harnesses.opencode.experimental: true` is set. Other harnesses ignore it. |
|
|
144
|
+
|
|
145
|
+
`roles` assigns a harness to each role. A value is a harness name, or a
|
|
146
|
+
mapping `{ harness, model, effort }` whose `model` and `effort` override the
|
|
147
|
+
harness defaults for that role.
|
|
148
|
+
|
|
149
|
+
| Key | Default | Description |
|
|
150
|
+
| --- | --- | --- |
|
|
151
|
+
| `roles.default` | `claude` | Harness for every role without its own assignment. |
|
|
152
|
+
| `roles.reviewer` | `roles.default` | Assignment both `standards-reviewer` and `spec-reviewer` inherit. |
|
|
153
|
+
| `roles.triager`, `preflight`, `implementer`, `resolution-verifier`, `decomposer` | `roles.default` | Per-role assignment. |
|
|
154
|
+
| `roles.standards-reviewer`, `roles.spec-reviewer` | `roles.reviewer`, else `roles.default` | Per-role assignment. |
|
|
155
|
+
| `roles.fixer` | the resolved `implementer` | Per-role assignment. |
|
|
156
|
+
|
|
157
|
+
The sessions map onto the roles as follows: AFK triage is the `triager`; the
|
|
158
|
+
pre-flight session and hand-off confirmation are the `preflight`;
|
|
159
|
+
implementation is the `implementer` (it also writes the commit message);
|
|
160
|
+
repair sessions are the `fixer`; the review gate runs the `standards-reviewer`
|
|
161
|
+
and the `spec-reviewer`; issue-resolution checks are the `resolution-verifier`;
|
|
162
|
+
and decomposition is the `decomposer`.
|
|
163
|
+
|
|
164
|
+
Startup checks each assigned harness (the `triager` only when
|
|
165
|
+
`triage.enabled` is true) by running its `--version`. A harness older than the
|
|
166
|
+
minimum below stops the run with an error naming the harness and the version it
|
|
167
|
+
needs. Output that contains no readable version only produces a warning.
|
|
168
|
+
|
|
169
|
+
| Harness | Minimum version |
|
|
170
|
+
| --- | --- |
|
|
171
|
+
| Claude Code (`claude`) | 2.1.289 |
|
|
172
|
+
| Codex (`codex`) | 0.160.0 |
|
|
173
|
+
| OpenCode (`opencode`) | 2.0.22 |
|
|
174
|
+
| pi (`pi`) | 1.0.2 |
|
|
175
|
+
|
|
176
|
+
Only the editing roles (`implementer`, `fixer`) may edit the checkout; the
|
|
177
|
+
others run read-only. How the editing roles are approved is described under
|
|
178
|
+
[Approval modes](safety.md#approval-modes), and each session's time limit is
|
|
179
|
+
under `limits.sessionTimeoutMinutes`. `pi` and `opencode` editing roles need
|
|
180
|
+
`approval: yolo`.
|
|
181
|
+
|
|
182
|
+
### `intake`
|
|
183
|
+
|
|
184
|
+
| Key | Default | Description |
|
|
185
|
+
| --- | --- | --- |
|
|
186
|
+
| `intake.requireLabels` | `[]` | An issue must carry every listed label to enter the queue (AND filter). Added to the mandatory `labels.ready-for-agent` label. Children created by decomposition inherit the parent's labels listed here, plus the agent-ready label (see [Decomposition](workflows.md#decomposition-workflow)). |
|
|
187
|
+
| `intake.sort` | `created:asc` | Queue order: `created`, `updated`, or `comments`, optionally suffixed `:asc` or `:desc`. Without a suffix the order is ascending. |
|
|
188
|
+
|
|
189
|
+
### `triage`
|
|
190
|
+
|
|
191
|
+
| Key | Default | Description |
|
|
192
|
+
| --- | --- | --- |
|
|
193
|
+
| `triage.enabled` | `false` | Run AFK triage before the queue. See [AFK triage](workflows.md#afk-triage). |
|
|
194
|
+
|
|
195
|
+
### `labels`
|
|
196
|
+
|
|
197
|
+
Maps Matt Pocock's five canonical triage roles to the label names used in the
|
|
198
|
+
tracker. Each value is a non-empty label name and defaults to the role's own
|
|
199
|
+
name. Two roles may not share one label (compared case-insensitively).
|
|
200
|
+
|
|
201
|
+
| Key | Default |
|
|
202
|
+
| --- | --- |
|
|
203
|
+
| `labels.needs-triage` | `needs-triage` |
|
|
204
|
+
| `labels.needs-info` | `needs-info` |
|
|
205
|
+
| `labels.ready-for-agent` | `ready-for-agent` |
|
|
206
|
+
| `labels.ready-for-human` | `ready-for-human` |
|
|
207
|
+
| `labels.wontfix` | `wontfix` |
|
|
208
|
+
|
|
209
|
+
### `skills`
|
|
210
|
+
|
|
211
|
+
| Key | Default | Description |
|
|
212
|
+
| --- | --- | --- |
|
|
213
|
+
| `skills.dir` | the skills bundled with Ralphie | Directory whose subdirectories are skills (each holds a `SKILL.md`). Relative paths resolve against the current directory. |
|
|
214
|
+
|
|
215
|
+
Before each session Ralphie copies these skills into the harness's project
|
|
216
|
+
skills directory (`.claude/skills`, `.agents/skills` for Codex, `.pi/skills`,
|
|
217
|
+
`.opencode/skills`). A repository skill with the same name is set aside for the
|
|
218
|
+
session and restored afterwards, so Ralphie's copy wins while other repository
|
|
219
|
+
skills stay available. Everything injected is added to the checkout's
|
|
220
|
+
`.git/info/exclude`, and is removed again when the session ends. Sessions that
|
|
221
|
+
overlap in one working directory (the parallel reviewers) share one injection:
|
|
222
|
+
the first prepares the checkout, and the last to finish restores it. If the
|
|
223
|
+
repository has no `docs/agents/issue-tracker.md` or
|
|
224
|
+
`docs/agents/triage-labels.md`, Ralphie generates them for the session: the
|
|
225
|
+
label table comes from `labels`, and the tracker doc says issue content is in
|
|
226
|
+
the prompt and sessions must not use `gh`. Committed versions always win.
|
|
227
|
+
|
|
228
|
+
### `limits`
|
|
229
|
+
|
|
230
|
+
All limits are positive; counts are integers.
|
|
231
|
+
|
|
232
|
+
| Key | Default | Description |
|
|
233
|
+
| --- | --- | --- |
|
|
234
|
+
| `limits.implementationAttempts` | `3` | Implementation attempts allowed when sessions leave an unresolved empty diff or an implementer session times out. After the last attempt the issue is handed off `ready-for-human`. |
|
|
235
|
+
| `limits.reviewRounds` | `5` | Review rounds before the issue escalates to decomposition. At most `20`. |
|
|
236
|
+
| `limits.verificationFixes` | `5` | Repair attempts allowed after a failing `verify` command. |
|
|
237
|
+
| `limits.sessionTimeoutMinutes.edit` | `60` | Wall-clock limit of one session in an editing role. Exceeding it kills the session's process group and counts as a failed attempt. |
|
|
238
|
+
| `limits.sessionTimeoutMinutes.readOnly` | `15` | The same limit for read-only roles. |
|
|
239
|
+
| `limits.maxBudgetUsd` | none | Spend cap in US dollars for each session. Only Claude Code enforces it; Codex, pi and OpenCode ignore it, and startup warns for every assigned harness that cannot. |
|
|
240
|
+
| `limits.maxDecompositionDepth` | `3` | Maximum generated-child lineage depth. Reaching it hands the issue off as `ready-for-human` and continues independent work. |
|
|
241
|
+
|
|
242
|
+
### Repository entries
|
|
243
|
+
|
|
244
|
+
Each `repos."owner/repo"` entry accepts `workspace`, `approval`, `harnesses`, `roles`,
|
|
245
|
+
`intake`, `triage`, `labels`, `skills`, and `limits` (overriding the top level for that repository
|
|
246
|
+
only) plus two keys that exist only here:
|
|
247
|
+
|
|
248
|
+
| Key | Default | Description |
|
|
249
|
+
| --- | --- | --- |
|
|
250
|
+
| `branch` | `main`, otherwise `master` | Base branch that verified work is pushed to directly. |
|
|
251
|
+
| `verify` | `[]` | Deterministic gate commands run in order after changes are staged, each under a 30-minute deadline. When empty, the gate is skipped and review proceeds on the staged diff alone. |
|
|
252
|
+
|
|
253
|
+
## Removed flags
|
|
254
|
+
|
|
255
|
+
Each former flag now fails with an error naming its replacement.
|
|
256
|
+
|
|
257
|
+
| Former flag | Config key |
|
|
258
|
+
| --- | --- |
|
|
259
|
+
| `-b`, `--branch` | `repos."owner/repo".branch` |
|
|
260
|
+
| `--verify-command` | `repos."owner/repo".verify` |
|
|
261
|
+
| `--issue-label` | `intake.requireLabels` |
|
|
262
|
+
| `--issue-sort` | `intake.sort` |
|
|
263
|
+
| `--implementation-attempts` | `limits.implementationAttempts` |
|
|
264
|
+
| `--max-decomposition-depth` | `limits.maxDecompositionDepth` |
|
|
265
|
+
| `--workspace` | `workspace` |
|
|
266
|
+
| `--model` | `harnesses.<harness>.model` or `roles.<role>.model` |
|
|
267
|
+
| `--thinking` | `harnesses.<harness>.effort` or `roles.<role>.effort` |
|
|
268
|
+
| `--notify-needs-attention` | none: hand-offs are always on |
|
|
269
|
+
| `--needs-attention-label` | `labels.ready-for-human` |
|