ralph-cli-sandboxed 0.2.8 → 0.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -196,6 +196,36 @@ Ralph can be configured to use different AI CLI tools. By default, it uses Claud
196
196
 
197
197
  The prompt content and `--dangerously-skip-permissions` (in containers) are added automatically at runtime.
198
198
 
199
+ ### Skills Configuration
200
+
201
+ Skills are reusable instruction sets that extend Claude's behavior for specific languages or project requirements. They inject additional context and rules into prompts.
202
+
203
+ Configure skills in `.ralph/config.json`:
204
+
205
+ ```json
206
+ {
207
+ "claude": {
208
+ "skills": [
209
+ {
210
+ "name": "swift-main-naming",
211
+ "description": "Prevents naming files main.swift when using @main attribute",
212
+ "instructions": "IMPORTANT: In Swift, files with @main attribute MUST NOT be named main.swift...",
213
+ "userInvocable": false
214
+ }
215
+ ]
216
+ }
217
+ }
218
+ ```
219
+
220
+ | Field | Description |
221
+ |-------|-------------|
222
+ | `name` | Unique skill identifier (kebab-case) |
223
+ | `description` | Brief description shown during selection |
224
+ | `instructions` | Full instructions injected into Claude's prompt |
225
+ | `userInvocable` | If `true`, user can invoke via `/skill-name` (default: `true`) |
226
+
227
+ During `ralph init`, you can select built-in skills for your chosen language. See [docs/SKILLS.md](docs/SKILLS.md) for detailed configuration, custom skills, and best practices.
228
+
199
229
  ### Stream-JSON Output
200
230
 
201
231
  Ralph supports stream-json output mode for real-time streaming of AI responses. This feature provides cleaner terminal output and enables recording of raw JSON logs for debugging or replay.
@@ -122,17 +122,16 @@
122
122
  "command": "goose",
123
123
  "defaultArgs": [],
124
124
  "yoloArgs": [],
125
- "promptArgs": ["run", "--text"],
125
+ "promptArgs": ["run", "--no-session", "--with-builtin", "developer", "--text"],
126
126
  "streamJsonArgs": ["--output-format", "stream-json"],
127
127
  "docker": {
128
- "install": "# Install Goose CLI (requires Python)\nRUN apt-get update && apt-get install -y python3 python3-pip python3-venv && rm -rf /var/lib/apt/lists/* \\\n && pip3 install --break-system-packages --no-cache-dir goose-ai",
128
+ "install": "# Install Goose CLI (as node user)\nRUN su - node -c 'curl -fsSL https://github.com/block/goose/releases/download/stable/download_cli.sh | CONFIGURE=false bash' \\\n && echo 'export PATH=\"$HOME/.local/bin:$PATH\"' >> /home/node/.zshrc \\\n && echo 'export GOOSE_MODE=auto' >> /home/node/.zshrc",
129
129
  "note": "Check 'goose --help' for available flags"
130
130
  },
131
131
  "envVars": ["OPENAI_API_KEY", "ANTHROPIC_API_KEY"],
132
132
  "credentialMount": null,
133
133
  "modelConfig": {
134
- "envVar": "GOOSE_PROVIDER",
135
- "note": "Set provider via GOOSE_PROVIDER env var"
134
+ "note": "Run 'goose configure' to setup the provider and model. See https://block.github.io/goose/docs/getting-started/providers/"
136
135
  },
137
136
  "modelArgs": ["--model"]
138
137
  },
@@ -1,5 +1,13 @@
1
1
  {
2
2
  "skills": {
3
+ "common": [
4
+ {
5
+ "name": "sandbox-safe",
6
+ "description": "Prevents starting dev servers in sandboxed environments",
7
+ "instructions": "IMPORTANT: You are running in a sandboxed Docker/Podman container. Do NOT start long-running development servers to verify your work.\n\nAVOID these commands for verification:\n- `npm run dev`, `npm start`, `yarn dev`\n- `uvicorn`, `gunicorn`, `flask run`, `python -m http.server`\n- `rails server`, `rails s`\n- `go run main.go` (for servers)\n- `cargo run` (for servers)\n- Any command that starts a web server and waits for connections\n\nWHY: Dev servers hang in sandboxed environments because:\n1. Network restrictions may block telemetry/update checks\n2. The server waits indefinitely for connections\n3. This prevents the iteration from completing\n\nINSTEAD, use these verification methods:\n- `npm run build` or `npx tsc --noEmit` (TypeScript/JavaScript)\n- `go build ./...` (Go)\n- `cargo build` or `cargo check` (Rust)\n- `python -m py_compile file.py` or `mypy .` (Python)\n- `bundle exec rake` or `rails runner \"puts 'OK'\"` (Ruby)\n- Run unit tests: `npm test`, `pytest`, `go test ./...`\n\nIf you need to verify a server starts correctly, use a brief timeout:\n```bash\ntimeout 5 npm run dev || true # Only if absolutely necessary\n```\n\nBut prefer build/compile checks over actually starting servers.",
8
+ "userInvocable": false
9
+ }
10
+ ],
3
11
  "swift": [
4
12
  {
5
13
  "name": "swift-main-naming",
@@ -61,7 +61,9 @@ export function getSkillsJson() {
61
61
  }
62
62
  export function getSkillsForLanguage(language) {
63
63
  const skills = getSkillsJson().skills;
64
- return skills[language] || [];
64
+ const languageSkills = skills[language] || [];
65
+ const commonSkills = skills["common"] || [];
66
+ return [...commonSkills, ...languageSkills];
65
67
  }
66
68
  export function getLanguages() {
67
69
  if (!_languagesCache) {
@@ -25,6 +25,10 @@ export function getCliConfig(config) {
25
25
  if (result.fileArgs === undefined && provider?.fileArgs !== undefined) {
26
26
  result.fileArgs = provider.fileArgs;
27
27
  }
28
+ // Use provider's yoloArgs if not already set
29
+ if (result.yoloArgs === undefined && provider?.yoloArgs !== undefined) {
30
+ result.yoloArgs = provider.yoloArgs;
31
+ }
28
32
  // Default promptArgs for backwards compatibility
29
33
  if (result.promptArgs === undefined) {
30
34
  result.promptArgs = ["-p"];
@@ -360,3 +360,63 @@ After generating prd.json, verify:
360
360
  | Missing verification | No way to confirm completion | Add test/build/check step |
361
361
  | Too many steps | Overwhelming, hard to track | Max 4-5 steps per item |
362
362
  | Wrong granularity | Items too big or too small | One iteration = one item |
363
+ | Starting dev servers | Hangs in sandbox, blocks iteration | Use build/typecheck instead |
364
+
365
+ ## Sandbox Constraints
366
+
367
+ When running in Docker/Podman sandboxes, certain operations can cause the iteration to hang or fail. Write PRD steps that avoid these issues.
368
+
369
+ ### Avoid Starting Dev Servers
370
+
371
+ **Problem:** Starting development servers (`npm run dev`, `uvicorn --reload`, `rails server`, etc.) in verification steps can hang the sandbox:
372
+ - Servers wait for network connections that may be blocked by firewall
373
+ - Long-running processes prevent the iteration from completing
374
+ - Telemetry/update checks may timeout on restricted networks
375
+
376
+ **Bad:**
377
+ ```json
378
+ "steps": [
379
+ "Create the component",
380
+ "Run `npm run dev` and verify server starts on port 3000",
381
+ "Open browser and check the page renders"
382
+ ]
383
+ ```
384
+
385
+ **Good:**
386
+ ```json
387
+ "steps": [
388
+ "Create the component",
389
+ "Run `npm run build` and verify compilation succeeds",
390
+ "Run `npm run lint` to check for errors"
391
+ ]
392
+ ```
393
+
394
+ ### Verification Alternatives
395
+
396
+ Instead of starting servers, use these verification methods:
397
+
398
+ | Instead of | Use |
399
+ |------------|-----|
400
+ | `npm run dev` | `npm run build` or `npx tsc --noEmit` |
401
+ | `uvicorn app:app` | `python -m py_compile app.py` or `mypy app.py` |
402
+ | `rails server` | `rails runner "puts 'OK'"` or `bundle exec rake` |
403
+ | `go run main.go` | `go build ./...` |
404
+ | curl to localhost | Unit tests or integration tests |
405
+
406
+ ### Network-Dependent Operations
407
+
408
+ Be aware that sandboxed environments may have restricted network access:
409
+ - Package installs work (npm, pip, etc.) if registries are allowed
410
+ - External API calls may be blocked
411
+ - Telemetry and update checks may timeout
412
+
413
+ **Tip:** Add domains your app needs to the firewall allowlist in `.ralph/config.json`:
414
+ ```json
415
+ {
416
+ "docker": {
417
+ "firewall": {
418
+ "allowedDomains": ["api.example.com", "cdn.example.com"]
419
+ }
420
+ }
421
+ }
422
+ ```
package/docs/SKILLS.md ADDED
@@ -0,0 +1,203 @@
1
+ # Skills Configuration
2
+
3
+ Skills are reusable instruction sets that extend Claude's behavior for specific languages, frameworks, or project requirements. They inject additional context and rules into the prompt sent to Claude during each iteration.
4
+
5
+ ## Overview
6
+
7
+ Skills help enforce best practices, prevent common mistakes, and provide domain-specific guidance. For example, a Swift skill might prevent naming files `main.swift` when using the `@main` attribute.
8
+
9
+ ## Configuration
10
+
11
+ Skills are configured in `.ralph/config.json` under the `claude.skills` array:
12
+
13
+ ```json
14
+ {
15
+ "claude": {
16
+ "skills": [
17
+ {
18
+ "name": "skill-name",
19
+ "description": "Brief description of what the skill does",
20
+ "instructions": "Detailed instructions injected into Claude's prompt",
21
+ "userInvocable": false
22
+ }
23
+ ]
24
+ }
25
+ }
26
+ ```
27
+
28
+ ## Skill Definition
29
+
30
+ Each skill has the following fields:
31
+
32
+ | Field | Type | Required | Description |
33
+ |-------|------|----------|-------------|
34
+ | `name` | string | Yes | Unique identifier for the skill. Use kebab-case (e.g., `swift-main-naming`). |
35
+ | `description` | string | Yes | Brief human-readable description shown during selection. |
36
+ | `instructions` | string | Yes | Full instructions injected into Claude's prompt. Can include examples, rules, and formatting. |
37
+ | `userInvocable` | boolean | No | If `true`, user can invoke the skill via `/skill-name`. Defaults to `true`. |
38
+
39
+ ### Field Details
40
+
41
+ #### name
42
+
43
+ The skill name should be:
44
+ - Unique within the project
45
+ - Descriptive of its purpose
46
+ - Use kebab-case (lowercase with hyphens)
47
+
48
+ Examples: `swift-main-naming`, `react-hooks-rules`, `go-error-handling`
49
+
50
+ #### description
51
+
52
+ A concise one-line description that:
53
+ - Explains what the skill does
54
+ - Helps users understand when to use it
55
+ - Is shown during `ralph init` skill selection
56
+
57
+ #### instructions
58
+
59
+ The detailed instructions that Claude receives. Best practices:
60
+ - Start with a clear statement of the rule or guidance
61
+ - Explain the "why" so Claude understands the reasoning
62
+ - Include concrete examples of correct and incorrect patterns
63
+ - Use code blocks for examples
64
+ - Keep instructions focused on a single concern
65
+
66
+ Example:
67
+ ```
68
+ IMPORTANT: In Swift, files containing the @main attribute MUST NOT be named main.swift.
69
+
70
+ When the @main attribute is used, Swift automatically generates an entry point.
71
+ If the file is also named main.swift, Swift treats it as having a manual entry point,
72
+ causing a conflict.
73
+
74
+ RULES:
75
+ - Never name a file main.swift if it contains @main attribute
76
+ - Use descriptive names like App.swift or the actual type name
77
+
78
+ BAD:
79
+ // main.swift
80
+ @main struct App { ... }
81
+
82
+ GOOD:
83
+ // App.swift
84
+ @main struct App { ... }
85
+ ```
86
+
87
+ #### userInvocable
88
+
89
+ Controls whether the skill can be invoked on-demand:
90
+ - `true` (default): User can trigger the skill with `/skill-name`
91
+ - `false`: Skill is always active but cannot be explicitly invoked
92
+
93
+ Set to `false` for skills that should always be active (like language-specific rules).
94
+
95
+ ## Built-in Skills
96
+
97
+ Ralph includes built-in skills for specific languages in `src/config/skills.json`. During `ralph init`, you can select which skills to enable for your project.
98
+
99
+ ### Currently Available Skills
100
+
101
+ **Common Skills** (applied to all languages):
102
+
103
+ | Skill Name | Description |
104
+ |------------|-------------|
105
+ | `sandbox-safe` | Prevents starting dev servers in sandboxed environments |
106
+
107
+ **Language-Specific Skills**:
108
+
109
+ | Language | Skill Name | Description |
110
+ |----------|------------|-------------|
111
+ | Swift | `swift-main-naming` | Prevents naming files main.swift when using @main attribute |
112
+
113
+ ## Adding Skills During Init
114
+
115
+ When running `ralph init`, you'll be prompted to select skills for your chosen language:
116
+
117
+ ```bash
118
+ ralph init
119
+
120
+ # ... language selection ...
121
+
122
+ ? Select skills for Swift (optional):
123
+ ◉ swift-main-naming - Prevents naming files main.swift when using @main attribute
124
+ ```
125
+
126
+ Selected skills are automatically added to your `.ralph/config.json`.
127
+
128
+ ## Custom Skills
129
+
130
+ You can add custom skills directly to your config file:
131
+
132
+ ```json
133
+ {
134
+ "claude": {
135
+ "skills": [
136
+ {
137
+ "name": "project-conventions",
138
+ "description": "Project-specific coding conventions",
139
+ "instructions": "Follow these project conventions:\n\n1. Use camelCase for variables\n2. Use PascalCase for types\n3. All public functions must have documentation comments\n4. Error messages must include error codes in format ERR-XXX",
140
+ "userInvocable": false
141
+ },
142
+ {
143
+ "name": "review-checklist",
144
+ "description": "Code review checklist",
145
+ "instructions": "Before committing, verify:\n- [ ] All tests pass\n- [ ] No console.log statements\n- [ ] No TODO comments without issue links\n- [ ] Public APIs are documented",
146
+ "userInvocable": true
147
+ }
148
+ ]
149
+ }
150
+ }
151
+ ```
152
+
153
+ ## Skill Scopes
154
+
155
+ Skills can be scoped for different purposes:
156
+
157
+ ### Language-Specific Skills
158
+ Target common pitfalls or best practices for a language:
159
+ - Naming conventions
160
+ - Common anti-patterns
161
+ - Language-specific idioms
162
+
163
+ ### Framework Skills
164
+ Target framework-specific patterns:
165
+ - React hooks rules
166
+ - Express middleware patterns
167
+ - Django model conventions
168
+
169
+ ### Project Skills
170
+ Target project-specific requirements:
171
+ - Code style guides
172
+ - Architecture decisions
173
+ - Team conventions
174
+
175
+ ## How Skills Are Applied
176
+
177
+ When ralph runs an iteration:
178
+
179
+ 1. Skills from `claude.skills` are loaded from config
180
+ 2. Skill instructions are injected into the prompt template
181
+ 3. Claude receives the combined prompt with all active skill instructions
182
+
183
+ This ensures Claude consistently follows your defined rules across all iterations.
184
+
185
+ ## Troubleshooting
186
+
187
+ ### Skill not appearing in selection
188
+
189
+ - Ensure the skill is defined in `src/config/skills.json` under the correct language key
190
+ - Verify the JSON syntax is valid
191
+
192
+ ### Skill instructions not being followed
193
+
194
+ - Check that the skill is listed in `.ralph/config.json` under `claude.skills`
195
+ - Ensure the instructions are clear and specific
196
+ - Add concrete examples of correct/incorrect patterns
197
+
198
+ ### Conflicting skills
199
+
200
+ If two skills have conflicting instructions:
201
+ - Review and consolidate the instructions
202
+ - Remove the less important skill
203
+ - Adjust instructions to handle edge cases explicitly
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ralph-cli-sandboxed",
3
- "version": "0.2.8",
3
+ "version": "0.2.9",
4
4
  "description": "AI-driven development automation CLI for Claude Code",
5
5
  "type": "module",
6
6
  "bin": {