ralph-cli-sandboxed 0.6.3 → 0.6.4
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 +9 -5
- package/dist/commands/docker.js +20 -11
- package/dist/commands/init.js +6 -0
- package/dist/commands/once.js +4 -0
- package/dist/commands/run.js +7 -3
- package/dist/config/cli-providers.json +18 -0
- package/dist/tui/components/SectionNav.js +6 -0
- package/dist/utils/config.d.ts +1 -0
- package/docs/BRANCHING.md +22 -29
- package/docs/CHAT-CLIENTS.md +13 -17
- package/docs/CHAT-RESPONDERS.md +3 -3
- package/docs/DEVELOPMENT.md +45 -7
- package/docs/DOCKER.md +5 -4
- package/docs/FAQ.md +125 -0
- package/docs/HOW-TO-WRITE-PRDs.md +5 -8
- package/docs/MACOS-DEVELOPMENT.md +3 -3
- package/docs/PRD-GENERATOR.md +9 -12
- package/docs/RALPH-SETUP-TEMPLATE.md +56 -24
- package/docs/SECURITY.md +4 -2
- package/docs/SKILLS.md +3 -3
- package/docs/chat-architecture.md +37 -30
- package/docs/run-state-machine.md +13 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -42,8 +42,10 @@ ralph docker run
|
|
|
42
42
|
| `ralph status` | Show PRD completion status |
|
|
43
43
|
| `ralph toggle <n>` | Toggle passes status for entry n |
|
|
44
44
|
| `ralph clean` | Remove all passing entries from PRD |
|
|
45
|
+
| `ralph reset` | Reset all PRD entries to passes: false |
|
|
45
46
|
| `ralph fix-prd [opts]` | Validate and recover corrupted PRD file |
|
|
46
47
|
| `ralph prompt [opts]` | Display resolved prompt |
|
|
48
|
+
| `ralph progress <sub>` | Manage progress file (summarize) |
|
|
47
49
|
| `ralph branch <sub>` | Manage PRD branches (list, merge, pr, delete) |
|
|
48
50
|
| `ralph docker <sub>` | Manage Docker sandbox environment |
|
|
49
51
|
| `ralph daemon <sub>` | Manage host daemon for sandbox notifications |
|
|
@@ -233,10 +235,10 @@ Ralph supports 18 programming languages with pre-configured build/test commands:
|
|
|
233
235
|
| Java | `mvn compile` | `mvn test` |
|
|
234
236
|
| Kotlin | `gradle build` | `gradle test` |
|
|
235
237
|
| C#/.NET | `dotnet build` | `dotnet test` |
|
|
236
|
-
| Ruby | `bundle exec rubocop` | `bundle exec rspec` |
|
|
237
|
-
| PHP | `composer validate` | `vendor/bin/phpunit` |
|
|
238
|
+
| Ruby | `bundle exec rubocop --fail-level error` | `bundle exec rspec` |
|
|
239
|
+
| PHP | `composer validate && php -l` | `vendor/bin/phpunit` |
|
|
238
240
|
| Swift | `swift build` | `swift test` |
|
|
239
|
-
| Elixir | `mix compile` | `mix test` |
|
|
241
|
+
| Elixir | `mix compile --warnings-as-errors` | `mix test` |
|
|
240
242
|
| Scala | `sbt compile` | `sbt test` |
|
|
241
243
|
| Zig | `zig build` | `zig build test` |
|
|
242
244
|
| Haskell | `stack build` | `stack test` |
|
|
@@ -255,6 +257,7 @@ Ralph supports multiple AI CLI tools. Select your provider during `ralph init`:
|
|
|
255
257
|
| [OpenCode](https://github.com/anomalyco/opencode) | Working | `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, `GOOGLE_GENERATIVE_AI_API_KEY` | No autonomous/yolo mode yet. Requires [PR #9073](https://github.com/anomalyco/opencode/pull/9073) |
|
|
256
258
|
| [Aider](https://github.com/paul-gauthier/aider) | Working | `OPENAI_API_KEY`, `ANTHROPIC_API_KEY` | |
|
|
257
259
|
| [Goose](https://github.com/block/goose) | Working | `OPENAI_API_KEY`, `ANTHROPIC_API_KEY` | Block's AI coding agent |
|
|
260
|
+
| [Ollama](https://ollama.com/) | Working | (none) | Local LLM server |
|
|
258
261
|
| [Codex CLI](https://github.com/openai/codex) | Testers wanted | `OPENAI_API_KEY` | Sponsors welcome |
|
|
259
262
|
| [AMP](https://ampcode.com/) | Testers wanted | `ANTHROPIC_API_KEY`, `OPENAI_API_KEY` | Sponsors welcome |
|
|
260
263
|
| Custom | - | User-defined | Configure your own CLI |
|
|
@@ -353,6 +356,7 @@ Not all CLI providers support stream-json output. Here's the compatibility matri
|
|
|
353
356
|
| Goose | ✅ Yes | `--output-format stream-json` |
|
|
354
357
|
| Aider | ❌ No | - |
|
|
355
358
|
| AMP | ❌ No | - |
|
|
359
|
+
| Ollama | ❌ No | - |
|
|
356
360
|
| Custom | ❌ No* | *Add `streamJsonArgs` to your custom config |
|
|
357
361
|
|
|
358
362
|
Each provider uses different command-line arguments and output formats. Ralph automatically selects the correct parser based on your configured provider.
|
|
@@ -426,7 +430,7 @@ The PRD (`prd.json`) is an array of requirements:
|
|
|
426
430
|
]
|
|
427
431
|
```
|
|
428
432
|
|
|
429
|
-
Categories: `
|
|
433
|
+
Categories: `ui`, `feature`, `bugfix`, `setup`, `development`, `testing`, `docs`
|
|
430
434
|
|
|
431
435
|
### Branching
|
|
432
436
|
|
|
@@ -499,7 +503,7 @@ ralph fix-prd backup.json # Restore from a specific backup file
|
|
|
499
503
|
|
|
500
504
|
### Dynamic Iteration Limits
|
|
501
505
|
|
|
502
|
-
To prevent runaway loops, `ralph run`
|
|
506
|
+
To prevent runaway loops, `ralph run` stops after 3 consecutive iterations without progress (no tasks completed and no new tasks added). It also stops after 3 consecutive failures with the same exit code.
|
|
503
507
|
|
|
504
508
|
## Docker Sandbox
|
|
505
509
|
|
package/dist/commands/docker.js
CHANGED
|
@@ -17,6 +17,7 @@ function computeConfigHash(config) {
|
|
|
17
17
|
cliProvider: config.cliProvider,
|
|
18
18
|
docker: config.docker,
|
|
19
19
|
claude: config.claude,
|
|
20
|
+
cliModel: config.cli?.model,
|
|
20
21
|
};
|
|
21
22
|
const content = JSON.stringify(relevantConfig, null, 2);
|
|
22
23
|
return createHash("sha256").update(content).digest("hex").substring(0, 16);
|
|
@@ -71,9 +72,15 @@ function getCliProviderSnippet(cliProvider) {
|
|
|
71
72
|
}
|
|
72
73
|
return provider.docker.install;
|
|
73
74
|
}
|
|
74
|
-
function generateDockerfile(language, javaVersion, cliProvider, dockerConfig) {
|
|
75
|
+
function generateDockerfile(language, javaVersion, cliProvider, dockerConfig, cliModel) {
|
|
75
76
|
const languageSnippet = getLanguageSnippet(language, javaVersion);
|
|
76
77
|
const cliSnippet = getCliProviderSnippet(cliProvider);
|
|
78
|
+
// Ollama model pull: when provider is ollama and a model is configured,
|
|
79
|
+
// start the server briefly and pull the model during the Docker build
|
|
80
|
+
let ollamaModelPull = "";
|
|
81
|
+
if (cliProvider === "ollama" && cliModel) {
|
|
82
|
+
ollamaModelPull = `\n# Pull Ollama model during build\nRUN ollama serve & sleep 2 && ollama pull ${cliModel}\n`;
|
|
83
|
+
}
|
|
77
84
|
// Build custom packages section
|
|
78
85
|
let customPackages = "";
|
|
79
86
|
if (dockerConfig?.packages && dockerConfig.packages.length > 0) {
|
|
@@ -206,14 +213,14 @@ if [ -z "$RALPH_BANNER_SHOWN" ]; then
|
|
|
206
213
|
echo "\\033[38;2;253;216;53m██╔══██╗██╔══██║██║ ██╔═══╝ ██╔══██║ ██║ ██║ ██║\\033[0m"
|
|
207
214
|
echo "\\033[38;2;251;192;45m██║ ██║██║ ██║███████╗██║ ██║ ██║ ╚██████╗███████╗██║\\033[0m"
|
|
208
215
|
echo "\\033[38;2;249;168;37m╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝ ╚═╝ ╚═════╝╚══════╝╚═╝\\033[0m"
|
|
209
|
-
RALPH_VERSION=$(ralph --version 2>/dev/null |
|
|
210
|
-
echo "\\033[38;5;
|
|
216
|
+
RALPH_VERSION=$(ralph --version 2>/dev/null | awk '{print $NF}' || echo "unknown")
|
|
217
|
+
echo "\\033[38;5;248m$RALPH_VERSION\\033[0m"
|
|
211
218
|
echo ""
|
|
212
219
|
fi
|
|
213
220
|
RALPH_BANNER
|
|
214
221
|
|
|
215
222
|
${cliSnippet}
|
|
216
|
-
|
|
223
|
+
${ollamaModelPull}
|
|
217
224
|
# Install ralph-cli-sandboxed from npm registry
|
|
218
225
|
RUN npm install -g ralph-cli-sandboxed
|
|
219
226
|
RUN ralph logo
|
|
@@ -654,7 +661,7 @@ function generateClaudeSettings() {
|
|
|
654
661
|
};
|
|
655
662
|
return JSON.stringify(settings, null, 2) + "\n";
|
|
656
663
|
}
|
|
657
|
-
async function generateFiles(ralphDir, language, imageName, force = false, javaVersion, cliProvider, dockerConfig, claudeConfig) {
|
|
664
|
+
async function generateFiles(ralphDir, language, imageName, force = false, javaVersion, cliProvider, dockerConfig, claudeConfig, cliModel) {
|
|
658
665
|
const dockerDir = join(ralphDir, DOCKER_DIR);
|
|
659
666
|
// Create docker directory
|
|
660
667
|
if (!existsSync(dockerDir)) {
|
|
@@ -665,7 +672,7 @@ async function generateFiles(ralphDir, language, imageName, force = false, javaV
|
|
|
665
672
|
const files = [
|
|
666
673
|
{
|
|
667
674
|
name: "Dockerfile",
|
|
668
|
-
content: generateDockerfile(language, javaVersion, cliProvider, dockerConfig),
|
|
675
|
+
content: generateDockerfile(language, javaVersion, cliProvider, dockerConfig, cliModel),
|
|
669
676
|
},
|
|
670
677
|
{ name: "init-firewall.sh", content: generateFirewallScript(customDomains) },
|
|
671
678
|
{ name: "docker-compose.yml", content: generateDockerCompose(imageName, dockerConfig) },
|
|
@@ -797,6 +804,7 @@ async function generateFiles(ralphDir, language, imageName, force = false, javaV
|
|
|
797
804
|
cliProvider,
|
|
798
805
|
docker: dockerConfig,
|
|
799
806
|
claude: claudeConfig,
|
|
807
|
+
cli: cliModel ? { command: "", model: cliModel } : undefined,
|
|
800
808
|
};
|
|
801
809
|
const hash = computeConfigHash(configForHash);
|
|
802
810
|
saveConfigHash(dockerDir, hash);
|
|
@@ -816,7 +824,7 @@ async function buildImage(ralphDir) {
|
|
|
816
824
|
await generateFiles(ralphDir, config.language, config.imageName ||
|
|
817
825
|
`ralph-${basename(process.cwd())
|
|
818
826
|
.toLowerCase()
|
|
819
|
-
.replace(/[^a-z0-9-]/g, "-")}`, true, config.javaVersion, config.cliProvider, config.docker, config.claude);
|
|
827
|
+
.replace(/[^a-z0-9-]/g, "-")}`, true, config.javaVersion, config.cliProvider, config.docker, config.claude, config.cli?.model);
|
|
820
828
|
console.log("");
|
|
821
829
|
}
|
|
822
830
|
}
|
|
@@ -957,11 +965,12 @@ async function runContainer(ralphDir, imageName, language, javaVersion, cliProvi
|
|
|
957
965
|
cliProvider,
|
|
958
966
|
docker: dockerConfig,
|
|
959
967
|
claude: claudeConfig,
|
|
968
|
+
cli: fullConfig?.cli?.model ? { command: "", model: fullConfig.cli.model } : undefined,
|
|
960
969
|
};
|
|
961
970
|
if (hasConfigChanged(ralphDir, configForHash)) {
|
|
962
971
|
const regenerate = await promptConfirm("Config has changed since last docker init. Regenerate Docker files?");
|
|
963
972
|
if (regenerate) {
|
|
964
|
-
await generateFiles(ralphDir, language, imageName, true, javaVersion, cliProvider, dockerConfig, claudeConfig);
|
|
973
|
+
await generateFiles(ralphDir, language, imageName, true, javaVersion, cliProvider, dockerConfig, claudeConfig, fullConfig?.cli?.model);
|
|
965
974
|
console.log("");
|
|
966
975
|
}
|
|
967
976
|
}
|
|
@@ -970,7 +979,7 @@ async function runContainer(ralphDir, imageName, language, javaVersion, cliProvi
|
|
|
970
979
|
if (!dockerfileExists || !hasImage) {
|
|
971
980
|
if (!dockerfileExists) {
|
|
972
981
|
console.log("Docker folder not found. Initializing docker setup...\n");
|
|
973
|
-
await generateFiles(ralphDir, language, imageName, true, javaVersion, cliProvider, dockerConfig, claudeConfig);
|
|
982
|
+
await generateFiles(ralphDir, language, imageName, true, javaVersion, cliProvider, dockerConfig, claudeConfig, fullConfig?.cli?.model);
|
|
974
983
|
console.log("");
|
|
975
984
|
}
|
|
976
985
|
if (!hasImage) {
|
|
@@ -1249,7 +1258,7 @@ export async function dockerInit(silent = false) {
|
|
|
1249
1258
|
console.log(`CLI provider: ${config.cliProvider}`);
|
|
1250
1259
|
}
|
|
1251
1260
|
console.log(`Image name: ${imageName}\n`);
|
|
1252
|
-
await generateFiles(ralphDir, config.language, imageName, true, config.javaVersion, config.cliProvider, config.docker, config.claude);
|
|
1261
|
+
await generateFiles(ralphDir, config.language, imageName, true, config.javaVersion, config.cliProvider, config.docker, config.claude, config.cli?.model);
|
|
1253
1262
|
if (!silent) {
|
|
1254
1263
|
console.log(`
|
|
1255
1264
|
Docker files generated in .ralph/docker/
|
|
@@ -1367,7 +1376,7 @@ INSTALLING PACKAGES (works with Docker & Podman):
|
|
|
1367
1376
|
console.log(`CLI provider: ${config.cliProvider}`);
|
|
1368
1377
|
}
|
|
1369
1378
|
console.log(`Image name: ${imageName}\n`);
|
|
1370
|
-
await generateFiles(ralphDir, config.language, imageName, force, config.javaVersion, config.cliProvider, config.docker, config.claude);
|
|
1379
|
+
await generateFiles(ralphDir, config.language, imageName, force, config.javaVersion, config.cliProvider, config.docker, config.claude, config.cli?.model);
|
|
1371
1380
|
console.log(`
|
|
1372
1381
|
Docker files generated in .ralph/docker/
|
|
1373
1382
|
|
package/dist/commands/init.js
CHANGED
|
@@ -98,6 +98,11 @@ export async function init(args) {
|
|
|
98
98
|
};
|
|
99
99
|
}
|
|
100
100
|
console.log(`\nSelected CLI provider: ${CLI_PROVIDERS[selectedCliProviderKey].name}`);
|
|
101
|
+
// Optional: specify default model
|
|
102
|
+
const modelInput = await promptInput("Enter default model name (optional, press Enter to skip): ");
|
|
103
|
+
if (modelInput.trim()) {
|
|
104
|
+
cliConfig.model = modelInput.trim();
|
|
105
|
+
}
|
|
101
106
|
// Step 2: Select language (second)
|
|
102
107
|
const languageKeys = Object.keys(LANGUAGES);
|
|
103
108
|
const languageNames = languageKeys.map((k) => `${LANGUAGES[k].name} - ${LANGUAGES[k].description}`);
|
|
@@ -369,6 +374,7 @@ config.json
|
|
|
369
374
|
# Runtime state files
|
|
370
375
|
messages.json
|
|
371
376
|
chat-state.json
|
|
377
|
+
prd-tasks.json
|
|
372
378
|
|
|
373
379
|
# Service logs
|
|
374
380
|
daemon.log
|
package/dist/commands/once.js
CHANGED
|
@@ -36,6 +36,10 @@ export async function once(args) {
|
|
|
36
36
|
});
|
|
37
37
|
const paths = getPaths();
|
|
38
38
|
const cliConfig = getCliConfig(config);
|
|
39
|
+
// Use config model as fallback when --model flag is not provided
|
|
40
|
+
if (!model && cliConfig.model) {
|
|
41
|
+
model = cliConfig.model;
|
|
42
|
+
}
|
|
39
43
|
// Check if stream-json output is enabled
|
|
40
44
|
const streamJsonConfig = config.docker?.asciinema?.streamJson;
|
|
41
45
|
const streamJsonEnabled = streamJsonConfig?.enabled ?? false;
|
package/dist/commands/run.js
CHANGED
|
@@ -3,7 +3,7 @@ import { existsSync, readFileSync, writeFileSync, unlinkSync, appendFileSync, mk
|
|
|
3
3
|
import { extname, join } from "path";
|
|
4
4
|
import { checkFilesExist, loadConfig, loadPrompt, getPaths, getCliConfig, requireContainer, saveBranchState, loadBranchState, clearBranchState, getProjectName, } from "../utils/config.js";
|
|
5
5
|
import { resolvePromptVariables, getCliProviders, GEMINI_MD } from "../templates/prompts.js";
|
|
6
|
-
import { validatePrd, smartMerge, readPrdFile,
|
|
6
|
+
import { validatePrd, smartMerge, readPrdFile, writePrdAuto, expandPrdFileReferences, } from "../utils/prd-validator.js";
|
|
7
7
|
import { getStreamJsonParser } from "../utils/stream-json.js";
|
|
8
8
|
import { sendNotificationWithDaemonEvents } from "../utils/notification.js";
|
|
9
9
|
const CATEGORIES = ["ui", "feature", "bugfix", "setup", "development", "testing", "docs"];
|
|
@@ -485,7 +485,7 @@ function validateAndRecoverPrd(prdPath, validPrd) {
|
|
|
485
485
|
if (!parsed) {
|
|
486
486
|
console.log("\nNote: PRD corrupted (invalid JSON) - restored from memory.");
|
|
487
487
|
const mergedPrd = [...validPrd, ...newItems];
|
|
488
|
-
|
|
488
|
+
writePrdAuto(prdPath, mergedPrd);
|
|
489
489
|
if (newItems.length > 0) {
|
|
490
490
|
console.log(`Preserved ${newItems.length} newly-added item(s).`);
|
|
491
491
|
}
|
|
@@ -503,7 +503,7 @@ function validateAndRecoverPrd(prdPath, validPrd) {
|
|
|
503
503
|
// Add any newly-added items
|
|
504
504
|
const mergedPrd = [...mergeResult.merged, ...newItems];
|
|
505
505
|
// Write the valid structure back (with new items)
|
|
506
|
-
|
|
506
|
+
writePrdAuto(prdPath, mergedPrd);
|
|
507
507
|
if (mergeResult.itemsUpdated > 0) {
|
|
508
508
|
console.log(`Recovered: merged ${mergeResult.itemsUpdated} passes flag(s) into valid PRD structure.`);
|
|
509
509
|
}
|
|
@@ -610,6 +610,10 @@ export async function run(args) {
|
|
|
610
610
|
});
|
|
611
611
|
const paths = getPaths();
|
|
612
612
|
const cliConfig = getCliConfig(config);
|
|
613
|
+
// Use config model as fallback when --model flag is not provided
|
|
614
|
+
if (!model && cliConfig.model) {
|
|
615
|
+
model = cliConfig.model;
|
|
616
|
+
}
|
|
613
617
|
// Check if stream-json output is enabled
|
|
614
618
|
const streamJsonConfig = config.docker?.asciinema?.streamJson;
|
|
615
619
|
// Get provider-specific streamJsonArgs, falling back to Claude's defaults
|
|
@@ -135,6 +135,24 @@
|
|
|
135
135
|
},
|
|
136
136
|
"modelArgs": ["--model"]
|
|
137
137
|
},
|
|
138
|
+
"ollama": {
|
|
139
|
+
"name": "Ollama",
|
|
140
|
+
"description": "Local LLM server with CLI interface",
|
|
141
|
+
"command": "ollama",
|
|
142
|
+
"defaultArgs": [],
|
|
143
|
+
"yoloArgs": [],
|
|
144
|
+
"promptArgs": ["run"],
|
|
145
|
+
"docker": {
|
|
146
|
+
"install": "# Install zstd (required for Ollama model layers)\nRUN apt-get update && apt-get install -y zstd && rm -rf /var/lib/apt/lists/*\n\n# Install Ollama\nRUN curl -fsSL https://ollama.com/install.sh | sh",
|
|
147
|
+
"note": "After building, Ollama needs a model pulled. Set cli.model in config.json and rebuild, or pull manually inside the container with: ollama pull <model>"
|
|
148
|
+
},
|
|
149
|
+
"envVars": [],
|
|
150
|
+
"credentialMount": null,
|
|
151
|
+
"modelConfig": {
|
|
152
|
+
"note": "Set cli.model in config.json (e.g., \"qwen3:1.7b\") to auto-pull during docker build. Or pull manually: ollama pull <model>"
|
|
153
|
+
},
|
|
154
|
+
"modelArgs": []
|
|
155
|
+
},
|
|
138
156
|
"custom": {
|
|
139
157
|
"name": "Custom CLI",
|
|
140
158
|
"description": "Configure your own AI CLI tool",
|
|
@@ -12,6 +12,12 @@ export const CONFIG_SECTIONS = [
|
|
|
12
12
|
icon: "⚙",
|
|
13
13
|
fields: ["language", "checkCommand", "testCommand", "imageName", "technologies", "javaVersion"],
|
|
14
14
|
},
|
|
15
|
+
{
|
|
16
|
+
id: "cli",
|
|
17
|
+
label: "CLI",
|
|
18
|
+
icon: "⌨",
|
|
19
|
+
fields: ["cliProvider", "cli.command", "cli.args", "cli.model", "cli.yoloArgs", "cli.promptArgs", "cli.modelArgs", "cli.fileArgs"],
|
|
20
|
+
},
|
|
15
21
|
{
|
|
16
22
|
id: "docker",
|
|
17
23
|
label: "Docker",
|
package/dist/utils/config.d.ts
CHANGED
package/docs/BRANCHING.md
CHANGED
|
@@ -177,18 +177,18 @@ The branch state is cleaned up from config after the group completes.
|
|
|
177
177
|
|
|
178
178
|
### `ralph branch list`
|
|
179
179
|
|
|
180
|
-
Shows all branches referenced in
|
|
180
|
+
Shows all branches referenced in the PRD with status:
|
|
181
181
|
|
|
182
182
|
```
|
|
183
183
|
Branches:
|
|
184
184
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
* = currently active
|
|
185
|
+
○ feat/auth 2/3 [worktree] ◀ active
|
|
186
|
+
○ feat/ui 0/1
|
|
187
|
+
○ (no branch) 1/2
|
|
190
188
|
```
|
|
191
189
|
|
|
190
|
+
Each branch shows a pass/total count, a `[worktree]` indicator if the worktree directory exists on disk, and `◀ active` if it's the branch currently being worked on.
|
|
191
|
+
|
|
192
192
|
### `ralph branch merge <name>`
|
|
193
193
|
|
|
194
194
|
Merges a completed branch back into the base branch:
|
|
@@ -199,33 +199,25 @@ ralph branch merge feat/auth
|
|
|
199
199
|
|
|
200
200
|
1. Asks for confirmation
|
|
201
201
|
2. Merges `feat/auth` into the base branch (in `/workspace`)
|
|
202
|
-
3. Removes the worktree with `git worktree remove`
|
|
203
|
-
4. Cleans up the worktree directory from the host
|
|
202
|
+
3. Removes the worktree with `git worktree remove` (if it exists)
|
|
204
203
|
|
|
205
204
|
If there are merge conflicts, ralph aborts the merge, lists the conflicting files, and suggests resolving manually or creating a PRD item for the AI to resolve.
|
|
206
205
|
|
|
207
206
|
### `ralph branch pr <name>`
|
|
208
207
|
|
|
209
|
-
Creates a
|
|
208
|
+
Creates a GitHub pull request for the branch using the `gh` CLI:
|
|
210
209
|
|
|
211
210
|
```bash
|
|
212
211
|
ralph branch pr feat/auth
|
|
213
212
|
```
|
|
214
213
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
branch: feat/auth
|
|
221
|
-
steps:
|
|
222
|
-
- Push feat/auth to the remote repository
|
|
223
|
-
- Create a pull request from feat/auth into main using `gh pr create`
|
|
224
|
-
- Include a summary of changes in the PR description
|
|
225
|
-
passes: false
|
|
226
|
-
```
|
|
214
|
+
1. Verifies `gh` is installed and authenticated
|
|
215
|
+
2. Pushes the branch to the remote if it has no upstream tracking
|
|
216
|
+
3. Generates a PR body with PRD item checklist and commit log
|
|
217
|
+
4. Asks for confirmation
|
|
218
|
+
5. Creates the PR via `gh pr create`
|
|
227
219
|
|
|
228
|
-
|
|
220
|
+
Requires the [GitHub CLI](https://cli.github.com/) (`gh`) to be installed and authenticated.
|
|
229
221
|
|
|
230
222
|
### `ralph branch delete <name>`
|
|
231
223
|
|
|
@@ -245,17 +237,18 @@ ralph branch delete feat/old-feature
|
|
|
245
237
|
When `ralph branch merge` detects conflicts:
|
|
246
238
|
|
|
247
239
|
```
|
|
248
|
-
Merge conflict detected
|
|
240
|
+
Merge conflict detected!
|
|
249
241
|
|
|
250
242
|
Conflicting files:
|
|
251
|
-
|
|
252
|
-
|
|
243
|
+
src/components/App.tsx
|
|
244
|
+
src/utils/config.ts
|
|
253
245
|
|
|
254
|
-
|
|
246
|
+
Merge aborted.
|
|
255
247
|
|
|
256
|
-
|
|
257
|
-
1. Resolve manually
|
|
258
|
-
2.
|
|
248
|
+
To resolve:
|
|
249
|
+
1. Resolve conflicts manually and merge again
|
|
250
|
+
2. Or add a PRD item to resolve the conflicts:
|
|
251
|
+
ralph prd add # describe the conflict resolution needed
|
|
259
252
|
```
|
|
260
253
|
|
|
261
254
|
Conflicts are a normal part of branching. They occur when both the branch and the base branch modify the same lines. Ralph never force-merges — it always aborts cleanly and lets the user decide.
|
package/docs/CHAT-CLIENTS.md
CHANGED
|
@@ -79,6 +79,7 @@ The bot will respond to commands in the allowed chats.
|
|
|
79
79
|
| `/stop` | Stop running ralph process |
|
|
80
80
|
| `/action build` | Execute a daemon action |
|
|
81
81
|
| `/claude Fix the CSS` | Run Claude Code with a prompt |
|
|
82
|
+
| `/branch list` | List branches and their status |
|
|
82
83
|
| `/help` | Show available commands |
|
|
83
84
|
|
|
84
85
|
---
|
|
@@ -132,20 +133,14 @@ Socket Mode allows the bot to receive events without a public URL.
|
|
|
132
133
|
- `message.im` - Direct messages
|
|
133
134
|
4. Click **Save Changes**
|
|
134
135
|
|
|
135
|
-
### Step 6: Create Slash
|
|
136
|
+
### Step 6: Create Slash Command (Optional)
|
|
136
137
|
|
|
137
138
|
1. Go to **Slash Commands**
|
|
138
|
-
2. Click **Create New Command
|
|
139
|
+
2. Click **Create New Command**:
|
|
139
140
|
|
|
140
141
|
| Command | Request URL | Description |
|
|
141
142
|
|---------|-------------|-------------|
|
|
142
|
-
| `/
|
|
143
|
-
| `/status` | (leave empty for Socket Mode) | Show PRD progress |
|
|
144
|
-
| `/add` | (leave empty for Socket Mode) | Add new task |
|
|
145
|
-
| `/exec` | (leave empty for Socket Mode) | Execute shell command |
|
|
146
|
-
| `/stop` | (leave empty for Socket Mode) | Stop ralph process |
|
|
147
|
-
| `/action` | (leave empty for Socket Mode) | Execute daemon action |
|
|
148
|
-
| `/claude` | (leave empty for Socket Mode) | Run Claude Code |
|
|
143
|
+
| `/ralph` | (leave empty for Socket Mode) | Ralph unified command (use subcommands like `/ralph run`, `/ralph status`) |
|
|
149
144
|
|
|
150
145
|
### Step 7: Get Channel IDs
|
|
151
146
|
|
|
@@ -186,17 +181,18 @@ ralph chat start
|
|
|
186
181
|
|
|
187
182
|
### Slack Commands
|
|
188
183
|
|
|
189
|
-
Use
|
|
184
|
+
Use the `/ralph` slash command with subcommands, or message the bot directly:
|
|
190
185
|
|
|
191
186
|
| Command | Description |
|
|
192
187
|
|---------|-------------|
|
|
193
|
-
| `/run` or `/run feature` | Start automation |
|
|
194
|
-
| `/status` | Show PRD progress |
|
|
195
|
-
| `/add Fix the bug` | Add a task |
|
|
196
|
-
| `/exec npm test` | Execute command |
|
|
197
|
-
| `/stop` | Stop ralph |
|
|
198
|
-
| `/action build` | Execute action |
|
|
199
|
-
| `/
|
|
188
|
+
| `/ralph run` or `/ralph run feature` | Start automation |
|
|
189
|
+
| `/ralph status` | Show PRD progress |
|
|
190
|
+
| `/ralph add Fix the bug` | Add a task |
|
|
191
|
+
| `/ralph exec npm test` | Execute command |
|
|
192
|
+
| `/ralph stop` | Stop ralph |
|
|
193
|
+
| `/ralph action build` | Execute action |
|
|
194
|
+
| `/ralph branch list` | Manage branches |
|
|
195
|
+
| `/ralph Fix CSS` | Run Claude Code (any unrecognized subcommand) |
|
|
200
196
|
|
|
201
197
|
---
|
|
202
198
|
|
package/docs/CHAT-RESPONDERS.md
CHANGED
|
@@ -240,10 +240,10 @@ LLM responders automatically detect file paths mentioned in messages and include
|
|
|
240
240
|
The responder will automatically read the file, extract ~20 lines around line 50, and include it in the LLM context.
|
|
241
241
|
|
|
242
242
|
**Limits:**
|
|
243
|
-
- Max
|
|
244
|
-
- Max
|
|
243
|
+
- Max 15KB total file content per message
|
|
244
|
+
- Max 8KB per individual file
|
|
245
245
|
- Files larger than 100KB are skipped
|
|
246
|
-
-
|
|
246
|
+
- 42 file extensions supported (ts, js, py, go, rs, java, etc.)
|
|
247
247
|
|
|
248
248
|
#### Git Diff Keywords
|
|
249
249
|
|
package/docs/DEVELOPMENT.md
CHANGED
|
@@ -47,23 +47,61 @@ ralph-cli-sandboxed/
|
|
|
47
47
|
├── src/
|
|
48
48
|
│ ├── index.ts # CLI entry point
|
|
49
49
|
│ ├── commands/ # Command implementations
|
|
50
|
+
│ │ ├── action.ts # ralph action
|
|
51
|
+
│ │ ├── branch.ts # ralph branch (list, merge, delete, pr)
|
|
52
|
+
│ │ ├── chat.ts # ralph chat
|
|
53
|
+
│ │ ├── config.tsx # ralph config (TUI launcher)
|
|
54
|
+
│ │ ├── daemon.ts # ralph daemon
|
|
55
|
+
│ │ ├── docker.ts # ralph docker
|
|
56
|
+
│ │ ├── fix-config.ts # ralph fix-config
|
|
57
|
+
│ │ ├── fix-prd.ts # ralph fix-prd
|
|
58
|
+
│ │ ├── help.ts # ralph help
|
|
50
59
|
│ │ ├── init.ts # ralph init
|
|
51
|
-
│ │ ├──
|
|
60
|
+
│ │ ├── listen.ts # ralph listen
|
|
61
|
+
│ │ ├── logo.ts # ralph logo
|
|
62
|
+
│ │ ├── notify.ts # ralph notify
|
|
52
63
|
│ │ ├── once.ts # ralph once
|
|
53
64
|
│ │ ├── prd.ts # PRD management commands
|
|
54
|
-
│ │ ├──
|
|
65
|
+
│ │ ├── prd-convert.ts # PRD YAML-to-JSON conversion
|
|
66
|
+
│ │ ├── progress.ts # ralph progress
|
|
55
67
|
│ │ ├── prompt.ts # ralph prompt
|
|
56
|
-
│ │ ├──
|
|
57
|
-
│ │ └──
|
|
68
|
+
│ │ ├── run.ts # ralph run
|
|
69
|
+
│ │ └── slack.ts # ralph slack
|
|
70
|
+
│ ├── providers/ # Chat platform providers
|
|
71
|
+
│ │ ├── discord.ts # Discord bot provider
|
|
72
|
+
│ │ ├── slack.ts # Slack bot provider
|
|
73
|
+
│ │ └── telegram.ts # Telegram bot provider
|
|
74
|
+
│ ├── responders/ # Chat responder implementations
|
|
75
|
+
│ │ ├── claude-code-responder.ts
|
|
76
|
+
│ │ ├── cli-responder.ts
|
|
77
|
+
│ │ └── llm-responder.ts
|
|
78
|
+
│ ├── tui/ # Terminal UI (config editor)
|
|
79
|
+
│ │ ├── ConfigEditor.tsx # Main config editor component
|
|
80
|
+
│ │ ├── components/ # UI components
|
|
81
|
+
│ │ ├── hooks/ # React hooks
|
|
82
|
+
│ │ └── utils/ # TUI utilities
|
|
58
83
|
│ ├── utils/
|
|
84
|
+
│ │ ├── chat-client.ts # Chat client interface
|
|
59
85
|
│ │ ├── config.ts # Configuration loading
|
|
86
|
+
│ │ ├── daemon-actions.ts # Daemon action handling
|
|
87
|
+
│ │ ├── daemon-client.ts # Daemon client interface
|
|
88
|
+
│ │ ├── llm-client.ts # LLM API client
|
|
89
|
+
│ │ ├── message-queue.ts # Message queue management
|
|
90
|
+
│ │ ├── notification.ts # Notification utilities
|
|
60
91
|
│ │ ├── prd-validator.ts # PRD validation and recovery
|
|
61
|
-
│ │
|
|
92
|
+
│ │ ├── prompt.ts # Interactive prompts
|
|
93
|
+
│ │ ├── responder-logger.ts # Responder logging
|
|
94
|
+
│ │ ├── responder-presets.ts # Responder preset loading
|
|
95
|
+
│ │ ├── responder.ts # Base responder logic
|
|
96
|
+
│ │ └── stream-json.ts # JSON streaming utilities
|
|
62
97
|
│ ├── templates/
|
|
98
|
+
│ │ ├── macos-scripts.ts # macOS/Swift script templates
|
|
63
99
|
│ │ └── prompts.ts # Prompt template generation
|
|
64
100
|
│ └── config/
|
|
65
|
-
│ ├──
|
|
66
|
-
│
|
|
101
|
+
│ ├── cli-providers.json # CLI provider configurations
|
|
102
|
+
│ ├── languages.json # Language configurations
|
|
103
|
+
│ ├── responder-presets.json # Chat responder presets
|
|
104
|
+
│ └── skills.json # Skill definitions
|
|
67
105
|
├── docs/ # Documentation
|
|
68
106
|
├── dist/ # Compiled output (generated)
|
|
69
107
|
└── package.json
|
package/docs/DOCKER.md
CHANGED
|
@@ -18,8 +18,8 @@ ralph docker run
|
|
|
18
18
|
| `ralph docker init` | Generate/regenerate Docker configuration files |
|
|
19
19
|
| `ralph docker build` | Build the Docker image |
|
|
20
20
|
| `ralph docker run` | Run ralph inside the container (auto-builds if needed) |
|
|
21
|
-
| `ralph docker
|
|
22
|
-
| `ralph docker
|
|
21
|
+
| `ralph docker clean` | Remove Docker image and associated resources |
|
|
22
|
+
| `ralph docker help` | Show help message |
|
|
23
23
|
|
|
24
24
|
## Generated Files
|
|
25
25
|
|
|
@@ -29,7 +29,8 @@ After running `ralph init` or `ralph docker init`, you'll find:
|
|
|
29
29
|
.ralph/docker/
|
|
30
30
|
├── Dockerfile # Container image definition
|
|
31
31
|
├── docker-compose.yml # Container orchestration
|
|
32
|
-
|
|
32
|
+
├── init-firewall.sh # Network sandbox rules
|
|
33
|
+
└── .dockerignore # Build exclusions
|
|
33
34
|
```
|
|
34
35
|
|
|
35
36
|
## Features
|
|
@@ -206,7 +207,7 @@ sudo chown -R $(id -u):$(id -g) .ralph/
|
|
|
206
207
|
|
|
207
208
|
The firewall script restricts outbound connections. If you need additional access:
|
|
208
209
|
|
|
209
|
-
1. Edit `.ralph/docker/firewall.sh`
|
|
210
|
+
1. Edit `.ralph/docker/init-firewall.sh`
|
|
210
211
|
2. Add your required domains/IPs
|
|
211
212
|
3. Rebuild: `ralph docker build`
|
|
212
213
|
|
package/docs/FAQ.md
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# FAQ
|
|
2
|
+
|
|
3
|
+
## Getting Started
|
|
4
|
+
|
|
5
|
+
### How do I initialize Ralph in my project?
|
|
6
|
+
|
|
7
|
+
Run `ralph init` in your project root. The interactive wizard walks you through selecting a language, CLI provider (Claude Code, Aider, Codex, etc.), and optional skills. It creates the `.ralph/` directory with config files and generates Docker files automatically. Use `ralph init -y` to accept defaults (Claude Code + Node.js).
|
|
8
|
+
|
|
9
|
+
### Which AI CLI tools does Ralph support?
|
|
10
|
+
|
|
11
|
+
Ralph supports **Claude Code**, **Aider**, **Codex**, **Gemini CLI**, **OpenCode**, **AMP**, **Goose**, and **Ollama** out of the box. You can also use the `custom` provider to configure any CLI tool. Select your provider during `ralph init` or change it later in `.ralph/config.json` under `cliProvider`.
|
|
12
|
+
|
|
13
|
+
### Which programming languages are supported?
|
|
14
|
+
|
|
15
|
+
18 languages: TypeScript/Node, Python, Go, Rust, Java, Kotlin, C#/.NET, Ruby, PHP, Swift, Elixir, Scala, Zig, Haskell, Clojure, Deno, Bun, and Custom. Each comes with pre-configured `checkCommand` and `testCommand`.
|
|
16
|
+
|
|
17
|
+
## Running Ralph
|
|
18
|
+
|
|
19
|
+
### What's the difference between `ralph once` and `ralph run`?
|
|
20
|
+
|
|
21
|
+
`ralph once` runs a single iteration inside the container. `ralph run` supports multiple modes:
|
|
22
|
+
- `ralph run 5` — run 5 iterations
|
|
23
|
+
- `ralph run --all` — run until all PRD items pass
|
|
24
|
+
- `ralph run --loop` — run indefinitely, polling for new items every 30 seconds
|
|
25
|
+
|
|
26
|
+
### When does Ralph stop running?
|
|
27
|
+
|
|
28
|
+
Ralph stops when:
|
|
29
|
+
- All PRD items are marked `passes: true`
|
|
30
|
+
- The requested number of iterations is reached
|
|
31
|
+
- 3 consecutive failures with the same exit code occur (likely a config error)
|
|
32
|
+
- 3 iterations pass without progress (no tasks completed and no new tasks added)
|
|
33
|
+
|
|
34
|
+
### Can I run Ralph without `ralph run`?
|
|
35
|
+
|
|
36
|
+
Sometimes the execution (e.g. OpenCode) doesn't work or get stuck or isn't possible with free AMP. The following prompt lets Ralph loop, but keep in mind that no event is triggered when a task is finished:
|
|
37
|
+
|
|
38
|
+
> Call in a loop `ralph prompt` and use this prompt — then check if @.ralph/prd.yaml has a task which isn't passes=true and start over with a fresh session and read the prompt and execute it.
|
|
39
|
+
|
|
40
|
+
### How do I use a specific model?
|
|
41
|
+
|
|
42
|
+
Pass `--model <name>` to `ralph run`, e.g. `ralph run --model claude-sonnet-4-5-20250929`. You can also set the model via environment variable (provider-specific: `CLAUDE_MODEL`, `AIDER_MODEL`, `CODEX_MODEL`, etc.).
|
|
43
|
+
|
|
44
|
+
## PRD Management
|
|
45
|
+
|
|
46
|
+
### What's the PRD format?
|
|
47
|
+
|
|
48
|
+
PRD files (`.ralph/prd.yaml` or `.ralph/prd.json`) contain an array of items with:
|
|
49
|
+
- `category` — one of: ui, feature, bugfix, setup, development, testing, docs
|
|
50
|
+
- `description` — single sentence, imperative verb (e.g. "Add login page")
|
|
51
|
+
- `steps` — concrete actions including verification steps
|
|
52
|
+
- `passes` — boolean, set to `true` when the item is complete
|
|
53
|
+
- `branch` — (optional) groups items onto a git branch
|
|
54
|
+
|
|
55
|
+
### How do I write good PRD items?
|
|
56
|
+
|
|
57
|
+
Keep items small and focused. Each item should be completable in one iteration. Write clear, concrete steps — include verification steps so the AI agent can confirm its work. Use `@{filepath}` syntax in steps to reference file contents.
|
|
58
|
+
|
|
59
|
+
### My PRD got corrupted — what do I do?
|
|
60
|
+
|
|
61
|
+
Run `ralph fix-prd`. It auto-diagnoses and repairs corruption (common when an LLM modifies the file incorrectly). Ralph also creates automatic backups in `.ralph/backups/` before each run. Use `ralph fix-prd --verify` to check without modifying, or restore from a specific backup file.
|
|
62
|
+
|
|
63
|
+
## Docker & Containers
|
|
64
|
+
|
|
65
|
+
### Why does Ralph need Docker?
|
|
66
|
+
|
|
67
|
+
Docker provides a sandboxed environment where the AI agent runs with autonomous permissions (`--dangerously-skip-permissions` for Claude Code). This keeps your host system safe. The container also enforces network restrictions — only essential domains (GitHub, npm, your API provider) are allowed by default.
|
|
68
|
+
|
|
69
|
+
### How do I add domains to the firewall whitelist?
|
|
70
|
+
|
|
71
|
+
Add domains to `docker.firewall.allowedDomains` in `.ralph/config.json`, then rebuild the image with `ralph docker build`. You can also edit `.ralph/docker/init-firewall.sh` directly.
|
|
72
|
+
|
|
73
|
+
### How do I add custom packages to the Docker image?
|
|
74
|
+
|
|
75
|
+
Use `docker.packages` in config.json for system packages (installed via apt-get), or use `docker.buildCommands.root` / `docker.buildCommands.node` for custom build steps.
|
|
76
|
+
|
|
77
|
+
### Can I customize ports, volumes, and environment variables?
|
|
78
|
+
|
|
79
|
+
Yes — configure `docker.ports`, `docker.volumes`, and `docker.environment` in `.ralph/config.json`. Run `ralph docker init` to regenerate the docker-compose.yml after changes.
|
|
80
|
+
|
|
81
|
+
## Branching
|
|
82
|
+
|
|
83
|
+
### How does branching work in Ralph?
|
|
84
|
+
|
|
85
|
+
Add a `branch` field to PRD items to group them onto a git branch. Ralph uses **git worktrees** (not `git checkout`) to isolate branch work — this avoids changing the host's mounted volume. Configure `docker.worktreesPath` in config.json to set where worktrees are stored on the host.
|
|
86
|
+
|
|
87
|
+
### What branch commands are available?
|
|
88
|
+
|
|
89
|
+
- `ralph branch list` — show all branches with item counts and status
|
|
90
|
+
- `ralph branch merge <name>` — merge a completed branch back to base
|
|
91
|
+
- `ralph branch pr <name>` — create a GitHub PR from the branch
|
|
92
|
+
- `ralph branch delete <name>` — remove a worktree and delete the branch
|
|
93
|
+
|
|
94
|
+
## Notifications & Monitoring
|
|
95
|
+
|
|
96
|
+
### How do I set up notifications?
|
|
97
|
+
|
|
98
|
+
Ralph supports **ntfy** (recommended — no install needed, just HTTP) and **command-based** notifications. Configure in `.ralph/config.json` under `notifications`. Events include `task_complete`, `prd_complete`, `ralph_complete`, `iteration_complete`, `run_stopped`, and `error`.
|
|
99
|
+
|
|
100
|
+
### How do I monitor Ralph's progress?
|
|
101
|
+
|
|
102
|
+
- `ralph status` — shows completion count, remaining items, and branch info
|
|
103
|
+
- `ralph status --head` — compact status without item headlines
|
|
104
|
+
- `.ralph/progress.txt` — detailed log of each iteration's work
|
|
105
|
+
- `ralph progress summarize` — creates a timestamped backup and compresses the progress file
|
|
106
|
+
|
|
107
|
+
## Troubleshooting
|
|
108
|
+
|
|
109
|
+
### Ralph keeps failing after a few iterations
|
|
110
|
+
|
|
111
|
+
If you see "CLI failed N times with exit code X", it's likely a configuration issue. Check:
|
|
112
|
+
1. Your API key is set correctly (environment variable or mounted credentials)
|
|
113
|
+
2. The CLI provider is installed and working outside Ralph
|
|
114
|
+
3. Network connectivity — the firewall may be blocking required domains
|
|
115
|
+
|
|
116
|
+
### Ralph seems stuck with "no progress"
|
|
117
|
+
|
|
118
|
+
"No progress" means no PRD items were completed **and** no new items were added across 3 consecutive iterations. This usually means:
|
|
119
|
+
- PRD steps are too vague for the AI to verify completion
|
|
120
|
+
- The task is too large for a single iteration — break it into smaller items
|
|
121
|
+
- The AI is hitting an error it can't resolve — check `.ralph/progress.txt` for details
|
|
122
|
+
|
|
123
|
+
### The Docker image won't build
|
|
124
|
+
|
|
125
|
+
Check that Docker is running, you have enough disk space, and platform-specific dependencies are available. If a provider installation fails, try `ralph docker build` again — transient network issues are common. For persistent failures, check the Dockerfile in `.ralph/docker/`.
|
|
@@ -22,16 +22,13 @@ Use consistent categories to organize your PRD:
|
|
|
22
22
|
|
|
23
23
|
| Category | Use for |
|
|
24
24
|
|----------|---------|
|
|
25
|
-
| `
|
|
25
|
+
| `ui` | User interface changes |
|
|
26
26
|
| `feature` | New functionality |
|
|
27
27
|
| `bugfix` | Fixing broken behavior |
|
|
28
|
-
| `
|
|
28
|
+
| `setup` | Initial project configuration, build verification |
|
|
29
|
+
| `development` | Code improvements, refactoring, configuration |
|
|
30
|
+
| `testing` | Adding or updating tests |
|
|
29
31
|
| `docs` | Documentation updates |
|
|
30
|
-
| `test` | Adding or updating tests |
|
|
31
|
-
| `release` | Version bumps, changelog updates |
|
|
32
|
-
| `config` | Configuration file changes |
|
|
33
|
-
| `ui` | User interface changes |
|
|
34
|
-
| `integration` | Connecting components, wiring, orchestration |
|
|
35
32
|
|
|
36
33
|
## Writing Good Descriptions
|
|
37
34
|
|
|
@@ -186,7 +183,7 @@ Break large features into smaller, independently completable items. Each item sh
|
|
|
186
183
|
## Quick Reference
|
|
187
184
|
|
|
188
185
|
```yaml
|
|
189
|
-
- category:
|
|
186
|
+
- category: ui|feature|bugfix|setup|development|testing|docs
|
|
190
187
|
description: Imperative verb + specific what + where (context)
|
|
191
188
|
steps:
|
|
192
189
|
- Concrete action with `commands` and file paths
|
|
@@ -392,9 +392,9 @@ ralph action gen_xcode
|
|
|
392
392
|
With Ralph's Telegram integration, you can trigger actions remotely:
|
|
393
393
|
|
|
394
394
|
```
|
|
395
|
-
/
|
|
396
|
-
/
|
|
397
|
-
/
|
|
395
|
+
/action gen_xcode # Generate Xcode project
|
|
396
|
+
/action build # Build the project
|
|
397
|
+
/action fastlane_beta # Deploy to TestFlight
|
|
398
398
|
```
|
|
399
399
|
|
|
400
400
|
See the [Chat documentation](../README.md#chat-client-configuration) for setup.
|
package/docs/PRD-GENERATOR.md
CHANGED
|
@@ -39,7 +39,7 @@ tasks: # <-- This wrapper causes issues
|
|
|
39
39
|
description: ...
|
|
40
40
|
```
|
|
41
41
|
|
|
42
|
-
> **Note:** Ralph will attempt to auto-unwrap common wrapper structures like `{tasks: [...]}`, `{items: [...]}`, or `{
|
|
42
|
+
> **Note:** Ralph will attempt to auto-unwrap common wrapper structures like `{tasks: [...]}`, `{items: [...]}`, `{features: [...]}`, `{entries: [...]}`, `{prd: [...]}`, `{requirements: [...]}`, `{todo: [...]}`, or `{checklist: [...]}`, but it's best to use the correct format from the start.
|
|
43
43
|
|
|
44
44
|
### Required Fields
|
|
45
45
|
|
|
@@ -47,7 +47,7 @@ Each PRD item must have these fields:
|
|
|
47
47
|
|
|
48
48
|
| Field | Type | Description |
|
|
49
49
|
|-------|------|-------------|
|
|
50
|
-
| `category` | string | One of:
|
|
50
|
+
| `category` | string | One of: ui, feature, bugfix, setup, development, testing, docs |
|
|
51
51
|
| `description` | string | What to implement (imperative verb + specific action) |
|
|
52
52
|
| `steps` | string[] | Concrete actions to complete the task |
|
|
53
53
|
| `passes` | boolean | **Must be `false` for new items** - Ralph sets to `true` when completed |
|
|
@@ -144,16 +144,13 @@ If a task takes 2 minutes without thinking, combine with related work.
|
|
|
144
144
|
|
|
145
145
|
| Category | When to Use |
|
|
146
146
|
|----------|-------------|
|
|
147
|
-
| `
|
|
147
|
+
| `ui` | User interface changes, frontend components |
|
|
148
148
|
| `feature` | New functionality for users |
|
|
149
149
|
| `bugfix` | Fixing broken behavior |
|
|
150
|
-
| `
|
|
150
|
+
| `setup` | Project initialization, tooling, dependencies |
|
|
151
|
+
| `development` | Code improvements, refactoring, configuration |
|
|
152
|
+
| `testing` | Test coverage (unit, integration, e2e) |
|
|
151
153
|
| `docs` | Documentation (README, guides, comments) |
|
|
152
|
-
| `test` | Test coverage (unit, integration, e2e) |
|
|
153
|
-
| `release` | Version bumps, changelogs, packaging |
|
|
154
|
-
| `config` | Configuration files, settings |
|
|
155
|
-
| `ui` | User interface changes, frontend components |
|
|
156
|
-
| `integration` | Connecting components, wiring, orchestration |
|
|
157
154
|
|
|
158
155
|
## Branch Field (Optional)
|
|
159
156
|
|
|
@@ -197,7 +194,7 @@ PRD items can include an optional `branch` field to group related work into git
|
|
|
197
194
|
ralph branch list # Show all branches and their status
|
|
198
195
|
ralph branch merge <name> # Merge a completed branch into main
|
|
199
196
|
ralph branch delete <name> # Delete a branch and its worktree
|
|
200
|
-
ralph branch pr <name> # Create a
|
|
197
|
+
ralph branch pr <name> # Create a GitHub PR from the branch
|
|
201
198
|
```
|
|
202
199
|
|
|
203
200
|
### When to Use Branches
|
|
@@ -406,7 +403,7 @@ Convert the following document into a Ralph prd.yaml file.
|
|
|
406
403
|
|
|
407
404
|
Rules:
|
|
408
405
|
1. Each sub-task or atomic feature = one PRD item
|
|
409
|
-
2. Use categories:
|
|
406
|
+
2. Use categories: ui, feature, bugfix, setup, development, testing, docs
|
|
410
407
|
3. Descriptions: imperative verb + specific what + context
|
|
411
408
|
4. Steps: 2-4 concrete actions + verification step
|
|
412
409
|
5. Reference source document sections instead of copying code
|
|
@@ -444,7 +441,7 @@ Convert the following document into a Ralph prd.json file.
|
|
|
444
441
|
|
|
445
442
|
Rules:
|
|
446
443
|
1. Each sub-task or atomic feature = one PRD item
|
|
447
|
-
2. Use categories:
|
|
444
|
+
2. Use categories: ui, feature, bugfix, setup, development, testing, docs
|
|
448
445
|
3. Descriptions: imperative verb + specific what + context
|
|
449
446
|
4. Steps: 2-4 concrete actions + verification step
|
|
450
447
|
5. Reference source document sections instead of copying code
|
|
@@ -89,29 +89,30 @@ Set up a Ralph CLI project based on the configuration above.
|
|
|
89
89
|
|
|
90
90
|
| Stack | language | checkCommand | testCommand |
|
|
91
91
|
|-------|----------|--------------|-------------|
|
|
92
|
-
| Node/TS (
|
|
93
|
-
| Node/TS (
|
|
94
|
-
|
|
|
95
|
-
|
|
|
96
|
-
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
| Python | `pypi.org`, `files.pythonhosted.org
|
|
107
|
-
| Go | `proxy.golang.org`, `sum.golang.org
|
|
108
|
-
| Rust | `crates.io`, `static.crates.io
|
|
92
|
+
| Node/TS (npm) | `node` | `npm run typecheck` | `npm test` |
|
|
93
|
+
| Node/TS (bun) | `bun` | `bun check` | `bun test` |
|
|
94
|
+
| Python | `python` | `mypy .` | `pytest` |
|
|
95
|
+
| Go | `go` | `go build ./...` | `go test ./...` |
|
|
96
|
+
| Rust | `rust` | `cargo check` | `cargo test` |
|
|
97
|
+
|
|
98
|
+
### Firewall Domains
|
|
99
|
+
|
|
100
|
+
The Docker firewall allows these domains by default: `github.com`, `api.github.com`, `raw.githubusercontent.com`, `registry.npmjs.org`, `api.anthropic.com`.
|
|
101
|
+
|
|
102
|
+
Add additional domains to `docker.firewall.allowedDomains` in `.ralph/config.json` based on your stack:
|
|
103
|
+
|
|
104
|
+
| Stack | Recommended Additions |
|
|
105
|
+
|-------|----------------------|
|
|
106
|
+
| Python | `pypi.org`, `files.pythonhosted.org` |
|
|
107
|
+
| Go | `proxy.golang.org`, `sum.golang.org` |
|
|
108
|
+
| Rust | `crates.io`, `static.crates.io` |
|
|
109
109
|
|
|
110
110
|
### API Provider Domains
|
|
111
111
|
|
|
112
|
+
Add these to `docker.firewall.allowedDomains` if using external APIs:
|
|
113
|
+
|
|
112
114
|
| Provider | Domains |
|
|
113
115
|
|----------|---------|
|
|
114
|
-
| Anthropic Claude | `api.anthropic.com` |
|
|
115
116
|
| OpenAI | `api.openai.com` |
|
|
116
117
|
| Google AI | `generativelanguage.googleapis.com` |
|
|
117
118
|
| AWS | `*.amazonaws.com` |
|
|
@@ -124,6 +125,8 @@ Set up a Ralph CLI project based on the configuration above.
|
|
|
124
125
|
|
|
125
126
|
### Notifications Config
|
|
126
127
|
|
|
128
|
+
Supported providers: `ntfy`, `pushover`, `gotify`, `command`.
|
|
129
|
+
|
|
127
130
|
Using ntfy (recommended - no install needed):
|
|
128
131
|
```json
|
|
129
132
|
{
|
|
@@ -137,6 +140,32 @@ Using ntfy (recommended - no install needed):
|
|
|
137
140
|
}
|
|
138
141
|
```
|
|
139
142
|
|
|
143
|
+
Using pushover:
|
|
144
|
+
```json
|
|
145
|
+
{
|
|
146
|
+
"notifications": {
|
|
147
|
+
"provider": "pushover",
|
|
148
|
+
"pushover": {
|
|
149
|
+
"user": "your-user-key",
|
|
150
|
+
"token": "your-app-token"
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Using gotify:
|
|
157
|
+
```json
|
|
158
|
+
{
|
|
159
|
+
"notifications": {
|
|
160
|
+
"provider": "gotify",
|
|
161
|
+
"gotify": {
|
|
162
|
+
"server": "https://gotify.example.com",
|
|
163
|
+
"token": "your-app-token"
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
140
169
|
Using custom command:
|
|
141
170
|
```json
|
|
142
171
|
{
|
|
@@ -205,10 +234,14 @@ Log task completions and ralph finished to file:
|
|
|
205
234
|
```
|
|
206
235
|
|
|
207
236
|
Chat commands (send in Telegram):
|
|
208
|
-
- `/run` - Start ralph automation
|
|
237
|
+
- `/run [category]` - Start ralph automation
|
|
209
238
|
- `/status` - Show PRD progress
|
|
239
|
+
- `/stop` - Stop a running ralph process
|
|
210
240
|
- `/add [desc]` - Add new task
|
|
211
241
|
- `/exec [cmd]` - Execute shell command
|
|
242
|
+
- `/action [name]` - Execute a daemon action
|
|
243
|
+
- `/claude [prompt]` - Run Claude Code with a prompt
|
|
244
|
+
- `/branch [subcommand]` - Manage git branches
|
|
212
245
|
- `/help` - Show help
|
|
213
246
|
|
|
214
247
|
### PRD Task Categories
|
|
@@ -216,12 +249,11 @@ Chat commands (send in Telegram):
|
|
|
216
249
|
| Category | Use For |
|
|
217
250
|
|----------|---------|
|
|
218
251
|
| `setup` | Project initialization, dependency installation |
|
|
219
|
-
| `config` | Environment variables, configuration files |
|
|
220
252
|
| `feature` | New functionality implementation |
|
|
221
|
-
| `integration` | External API clients, third-party services |
|
|
222
|
-
| `test` | Unit tests, integration tests |
|
|
223
|
-
| `refactor` | Code restructuring without behavior change |
|
|
224
253
|
| `bugfix` | Bug fixes |
|
|
254
|
+
| `ui` | User interface changes |
|
|
255
|
+
| `development` | Development tooling, build configuration |
|
|
256
|
+
| `testing` | Unit tests, integration tests |
|
|
225
257
|
| `docs` | Documentation |
|
|
226
258
|
|
|
227
259
|
### PRD Guidelines
|
|
@@ -231,7 +263,7 @@ Chat commands (send in Telegram):
|
|
|
231
263
|
- Include 2-4 concrete steps per task
|
|
232
264
|
- End with a verification step (build, typecheck, test)
|
|
233
265
|
- All tasks start with `"passes": false`
|
|
234
|
-
- Order by dependency: setup ->
|
|
266
|
+
- Order by dependency: setup -> development -> feature -> testing -> docs
|
|
235
267
|
|
|
236
268
|
### Sandbox Safety
|
|
237
269
|
|
package/docs/SECURITY.md
CHANGED
|
@@ -20,7 +20,9 @@ When running inside a container, ralph automatically passes the appropriate auto
|
|
|
20
20
|
| AMP | `--dangerously-allow-all` | ✅ Supported |
|
|
21
21
|
| Aider | `--yes-always` | ✅ Supported |
|
|
22
22
|
| Goose | (none needed) | ✅ Supported |
|
|
23
|
-
| OpenCode |
|
|
23
|
+
| OpenCode | (none) | ❌ Not yet implemented |
|
|
24
|
+
| Ollama | (none needed) | ✅ Supported |
|
|
25
|
+
| Custom | (none) | ⚙️ User-configured |
|
|
24
26
|
|
|
25
27
|
For providers without autonomous mode support, you may need to manually approve actions during execution.
|
|
26
28
|
|
|
@@ -64,7 +66,7 @@ For Claude Code users with Pro/Max subscriptions, the `~/.claude` directory is m
|
|
|
64
66
|
|
|
65
67
|
```yaml
|
|
66
68
|
volumes:
|
|
67
|
-
- ~/.claude:/home/node/.claude
|
|
69
|
+
- ~/.claude:/home/node/.claude
|
|
68
70
|
```
|
|
69
71
|
|
|
70
72
|
This allows the AI agent to use your existing OAuth credentials without exposing API keys.
|
package/docs/SKILLS.md
CHANGED
|
@@ -174,11 +174,11 @@ Target project-specific requirements:
|
|
|
174
174
|
|
|
175
175
|
## How Skills Are Applied
|
|
176
176
|
|
|
177
|
-
|
|
177
|
+
During `ralph docker init`:
|
|
178
178
|
|
|
179
179
|
1. Skills from `claude.skills` are loaded from config
|
|
180
|
-
2.
|
|
181
|
-
3. Claude
|
|
180
|
+
2. Each skill is written as a `.claude/commands/<name>.md` file with YAML frontmatter (`description`, `user-invocable`)
|
|
181
|
+
3. Claude Code natively reads these command files and applies the skill instructions
|
|
182
182
|
|
|
183
183
|
This ensures Claude consistently follows your defined rules across all iterations.
|
|
184
184
|
|
|
@@ -47,7 +47,8 @@ The Ralph CLI chat system enables external control of Ralph projects via chat pl
|
|
|
47
47
|
│ │ └─────────┘ │ ▼ │
|
|
48
48
|
│ └─────────────┘ ┌───────────────────────────────────────┐ │
|
|
49
49
|
│ │ Command Handler │ │
|
|
50
|
-
│ │ run, stop, status, exec, add, claude
|
|
50
|
+
│ │ run, stop, status, exec, add, claude, │ │
|
|
51
|
+
│ │ help, start, action, branch │ │
|
|
51
52
|
│ └───────────────────┬───────────────────┘ │
|
|
52
53
|
│ │ │
|
|
53
54
|
│ ▼ │
|
|
@@ -96,7 +97,7 @@ The Ralph CLI chat system enables external control of Ralph projects via chat pl
|
|
|
96
97
|
┌─────────────────────────────────────────────────────────────────┐
|
|
97
98
|
│ ResponderMatcher │
|
|
98
99
|
│ │
|
|
99
|
-
│ 1. Check @mention triggers: @qa, @review, @explain, @code
|
|
100
|
+
│ 1. Check @mention triggers: @qa, @review, @arch, @explain, @code│
|
|
100
101
|
│ 2. Check keyword triggers: !lint, help │
|
|
101
102
|
│ 3. Fall back to default responder │
|
|
102
103
|
└─────────────────────────────┬───────────────────────────────────┘
|
|
@@ -111,11 +112,11 @@ The Ralph CLI chat system enables external control of Ralph projects via chat pl
|
|
|
111
112
|
┌─────────────────────────────────────────────────────────────────┐
|
|
112
113
|
│ LLM Responder │
|
|
113
114
|
│ │
|
|
114
|
-
│ 1. Detect git keyword: "last" → git show HEAD
|
|
115
|
+
│ 1. Detect git keyword: "last" → git show HEAD --stat --patch │
|
|
115
116
|
│ 2. Fetch git diff content │
|
|
116
117
|
│ 3. Build message with diff │
|
|
117
118
|
│ 4. Load conversation history (if thread) │
|
|
118
|
-
│ 5. Send to LLM (Anthropic/OpenAI)
|
|
119
|
+
│ 5. Send to LLM (Anthropic/OpenAI/Ollama) │
|
|
119
120
|
│ 6. Log to .ralph/logs/responder-YYYY-MM-DD.log │
|
|
120
121
|
│ 7. Return response │
|
|
121
122
|
└─────────────────────────────┬───────────────────────────────────┘
|
|
@@ -168,48 +169,54 @@ Reply in thread history (max 20 messages)
|
|
|
168
169
|
|
|
169
170
|
## Message Queue Format
|
|
170
171
|
|
|
172
|
+
The messages file stores a direct JSON array (no wrapper object):
|
|
173
|
+
|
|
171
174
|
```json
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
"
|
|
190
|
-
|
|
191
|
-
"output": "Ralph run started (category: feature)"
|
|
192
|
-
}
|
|
175
|
+
[
|
|
176
|
+
{
|
|
177
|
+
"id": "uuid-1234",
|
|
178
|
+
"from": "host",
|
|
179
|
+
"action": "run",
|
|
180
|
+
"args": ["feature"],
|
|
181
|
+
"timestamp": 1706789012345,
|
|
182
|
+
"status": "pending"
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
"id": "uuid-1234",
|
|
186
|
+
"from": "host",
|
|
187
|
+
"action": "run",
|
|
188
|
+
"args": ["feature"],
|
|
189
|
+
"timestamp": 1706789012345,
|
|
190
|
+
"status": "done",
|
|
191
|
+
"response": {
|
|
192
|
+
"success": true,
|
|
193
|
+
"output": "Ralph run started (category: feature)"
|
|
193
194
|
}
|
|
194
|
-
|
|
195
|
-
|
|
195
|
+
}
|
|
196
|
+
]
|
|
196
197
|
```
|
|
197
198
|
|
|
199
|
+
Fields:
|
|
200
|
+
- `from`: `"sandbox"` or `"host"`
|
|
201
|
+
- `args`: optional string array
|
|
202
|
+
- `status`: `"pending"` or `"done"`
|
|
203
|
+
- `response`: optional, contains `success` (boolean), `output` (optional string), and `error` (optional string)
|
|
204
|
+
|
|
198
205
|
## Git Diff Keywords
|
|
199
206
|
|
|
200
207
|
| Keyword | Git Command | Description |
|
|
201
208
|
|---------|-------------|-------------|
|
|
202
209
|
| `diff` / `changes` | `git diff` | Unstaged changes |
|
|
203
210
|
| `staged` | `git diff --cached` | Staged changes |
|
|
204
|
-
| `last` / `last commit` | `git show HEAD` | Last commit |
|
|
211
|
+
| `last` / `last commit` | `git show HEAD --stat --patch` | Last commit |
|
|
205
212
|
| `all` | `git diff HEAD` | All uncommitted |
|
|
206
|
-
| `HEAD~N` | `git show HEAD~N` | N commits ago |
|
|
213
|
+
| `HEAD~N` | `git show HEAD~N --stat --patch` | N commits ago |
|
|
207
214
|
|
|
208
215
|
## Responder Types
|
|
209
216
|
|
|
210
217
|
| Type | Description | Example Trigger |
|
|
211
218
|
|------|-------------|-----------------|
|
|
212
|
-
| `llm` | Send to LLM (Anthropic/OpenAI) | `@qa`, `@review` |
|
|
219
|
+
| `llm` | Send to LLM (Anthropic/OpenAI/Ollama) | `@qa`, `@review` |
|
|
213
220
|
| `claude-code` | Spawn Claude Code CLI | `@code` |
|
|
214
221
|
| `cli` | Run shell command | `!lint` |
|
|
215
222
|
|
|
@@ -27,13 +27,21 @@ flowchart TD
|
|
|
27
27
|
subgraph Analysis ["4. Result Analysis"]
|
|
28
28
|
ExitCheck{Exit Code == 0?}
|
|
29
29
|
|
|
30
|
-
ExitCheck -- "No" --> FailurePath[
|
|
31
|
-
FailurePath -->
|
|
30
|
+
ExitCheck -- "No" --> FailurePath[Track Failure]
|
|
31
|
+
FailurePath --> SameCode{Same Exit Code\nas Last Failure?}
|
|
32
|
+
SameCode -- "Yes" --> IncrementFailures[Increment Consecutive\nFailure Counter]
|
|
33
|
+
SameCode -- "No" --> ResetToOne[Reset Counter to 1]
|
|
34
|
+
IncrementFailures --> CriticalCheck{Consecutive\nFailures >= 3?}
|
|
35
|
+
ResetToOne --> CriticalCheck
|
|
32
36
|
CriticalCheck -- "Yes" --> Abort([Abort: Too Many Errors])
|
|
33
|
-
CriticalCheck -- "No" -->
|
|
37
|
+
CriticalCheck -- "No" --> ProgressCheck
|
|
34
38
|
|
|
35
39
|
ExitCheck -- "Yes" --> SuccessPath[Reset Failure Counter]
|
|
36
|
-
SuccessPath -->
|
|
40
|
+
SuccessPath --> ProgressCheck
|
|
41
|
+
|
|
42
|
+
ProgressCheck{All Mode:\nProgress Made?}
|
|
43
|
+
ProgressCheck -- "Yes / Not All Mode" --> SignalCheck
|
|
44
|
+
ProgressCheck -- "No progress\n3 iterations" --> StallAbort([Abort: No Progress])
|
|
37
45
|
|
|
38
46
|
SignalCheck{COMPLETE Signal?}
|
|
39
47
|
SignalCheck -- "Yes" --> CompleteModeCheck
|
|
@@ -73,5 +81,6 @@ flowchart TD
|
|
|
73
81
|
style Analysis fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px
|
|
74
82
|
style Completion fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px
|
|
75
83
|
style Abort fill:#ffebee,stroke:#c62828,color:#c62828
|
|
84
|
+
style StallAbort fill:#ffebee,stroke:#c62828,color:#c62828
|
|
76
85
|
style End fill:#e8f5e9,stroke:#2e7d32,color:#2e7d32
|
|
77
86
|
```
|