ralph-cli-sandboxed 0.2.5 → 0.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/docs/DOCKER.md ADDED
@@ -0,0 +1,225 @@
1
+ # Docker Sandbox
2
+
3
+ Ralph runs AI agents in isolated Docker containers for security. This document covers Docker setup and usage.
4
+
5
+ ## Quick Start
6
+
7
+ ```bash
8
+ # Run container (auto-builds image on first run)
9
+ ralph docker run
10
+ ```
11
+
12
+ > **Note:** `ralph init` automatically creates Docker files in `.ralph/docker/`. Use `ralph docker init` to regenerate them if needed.
13
+
14
+ ## Docker Commands
15
+
16
+ | Command | Description |
17
+ |---------|-------------|
18
+ | `ralph docker init` | Generate/regenerate Docker configuration files |
19
+ | `ralph docker build` | Build the Docker image |
20
+ | `ralph docker run` | Run ralph inside the container (auto-builds if needed) |
21
+ | `ralph docker shell` | Open an interactive shell in the container |
22
+ | `ralph docker status` | Show container and image status |
23
+
24
+ ## Generated Files
25
+
26
+ After running `ralph init` or `ralph docker init`, you'll find:
27
+
28
+ ```
29
+ .ralph/docker/
30
+ ├── Dockerfile # Container image definition
31
+ ├── docker-compose.yml # Container orchestration
32
+ └── firewall.sh # Network sandbox rules
33
+ ```
34
+
35
+ ## Features
36
+
37
+ The Docker setup is based on [Claude Code devcontainer](https://github.com/anthropics/claude-code/tree/main/.devcontainer) and includes:
38
+
39
+ - **Network sandboxing** - Firewall allows only GitHub, npm, and Anthropic API
40
+ - **Credential mounting** - Your `~/.claude` OAuth credentials are mounted automatically
41
+ - **Language tooling** - Pre-installed based on your selected language
42
+ - **Non-root user** - Runs as `node` user for security
43
+
44
+ ## Customization
45
+
46
+ ### Adding Ports
47
+
48
+ Edit `.ralph/config.json`:
49
+
50
+ ```json
51
+ {
52
+ "docker": {
53
+ "ports": ["3000:3000", "5432:5432"]
54
+ }
55
+ }
56
+ ```
57
+
58
+ Then regenerate: `ralph docker init`
59
+
60
+ ### Adding Volumes
61
+
62
+ ```json
63
+ {
64
+ "docker": {
65
+ "volumes": ["./data:/app/data"]
66
+ }
67
+ }
68
+ ```
69
+
70
+ ### Environment Variables
71
+
72
+ ```json
73
+ {
74
+ "docker": {
75
+ "environment": {
76
+ "NODE_ENV": "development",
77
+ "DEBUG": "true"
78
+ }
79
+ }
80
+ }
81
+ ```
82
+
83
+ ### Git Configuration
84
+
85
+ ```json
86
+ {
87
+ "docker": {
88
+ "git": {
89
+ "name": "Your Name",
90
+ "email": "your@email.com"
91
+ }
92
+ }
93
+ }
94
+ ```
95
+
96
+ ### Asciinema Recording
97
+
98
+ Record terminal sessions inside the container for demos, debugging, or sharing AI coding sessions. Recordings are saved as `.cast` files that can be played back with `asciinema play` or uploaded to asciinema.org.
99
+
100
+ ```json
101
+ {
102
+ "docker": {
103
+ "asciinema": {
104
+ "enabled": true,
105
+ "autoRecord": true,
106
+ "outputDir": ".recordings"
107
+ }
108
+ }
109
+ }
110
+ ```
111
+
112
+ | Setting | Description |
113
+ |---------|-------------|
114
+ | `enabled` | Install asciinema in the container |
115
+ | `autoRecord` | Automatically start recording when container starts |
116
+ | `outputDir` | Directory for recordings (default: `.recordings`) |
117
+
118
+ After enabling, regenerate Docker files: `ralph docker init`
119
+
120
+ **Where recordings are stored:**
121
+
122
+ Recordings are saved to the mounted workspace directory (e.g., `.recordings/`). They never leave the container automatically - no network access is needed.
123
+
124
+ To upload recordings:
125
+ 1. Exit the container
126
+ 2. From your host machine: `asciinema upload .recordings/session-*.cast`
127
+ 3. Or set `ASCIINEMA_SERVER_URL` environment variable before uploading to use a self-hosted server
128
+
129
+ **Manual recording** (when `autoRecord: false`):
130
+
131
+ ```bash
132
+ # Inside the container
133
+ asciinema rec .recordings/session.cast # Start recording
134
+ exit # Stop recording
135
+
136
+ # After exiting the container, from your host machine:
137
+ asciinema play .recordings/session.cast # Playback
138
+ asciinema upload .recordings/session.cast # Upload to asciinema.org
139
+ ```
140
+
141
+ **Auto-recording** (when `autoRecord: true`):
142
+
143
+ Sessions are automatically recorded to `<outputDir>/session-YYYYMMDD-HHMMSS.cast` when the container starts. Recording stops when you exit the container. Files are available on your host machine in the configured output directory.
144
+
145
+ ### Firewall Configuration
146
+
147
+ The container firewall allows only specific domains by default: GitHub, npm registry, and Anthropic API. To allow additional domains (e.g., PyPI, internal registries), configure `firewall.allowedDomains`:
148
+
149
+ ```json
150
+ {
151
+ "docker": {
152
+ "firewall": {
153
+ "allowedDomains": ["pypi.org", "files.pythonhosted.org"]
154
+ }
155
+ }
156
+ }
157
+ ```
158
+
159
+ After adding domains, regenerate Docker files: `ralph docker init`
160
+
161
+ The firewall script resolves domains to IPs at container startup using `dig`. Common use cases:
162
+
163
+ | Use Case | Domains |
164
+ |----------|---------|
165
+ | Python/PyPI | `pypi.org`, `files.pythonhosted.org` |
166
+ | Maven Central | `repo1.maven.org`, `repo.maven.apache.org` |
167
+ | Internal registry | `registry.mycompany.com` |
168
+
169
+ ## Installing Packages
170
+
171
+ To install additional packages inside the container, run as root:
172
+
173
+ ```bash
174
+ # Update package list and install
175
+ docker compose run -u root ralph apt-get update
176
+ docker compose run -u root ralph apt-get install <package>
177
+ ```
178
+
179
+ For persistent changes, add the installation to the Dockerfile and rebuild:
180
+
181
+ ```bash
182
+ ralph docker build
183
+ ```
184
+
185
+ ## Troubleshooting
186
+
187
+ ### Image won't build
188
+
189
+ Check Docker is running and you have sufficient disk space:
190
+
191
+ ```bash
192
+ docker info
193
+ df -h
194
+ ```
195
+
196
+ ### Permission denied errors
197
+
198
+ The container runs as user `node`. If you have permission issues with mounted volumes:
199
+
200
+ ```bash
201
+ # Fix ownership on host
202
+ sudo chown -R $(id -u):$(id -g) .ralph/
203
+ ```
204
+
205
+ ### Network connectivity issues
206
+
207
+ The firewall script restricts outbound connections. If you need additional access:
208
+
209
+ 1. Edit `.ralph/docker/firewall.sh`
210
+ 2. Add your required domains/IPs
211
+ 3. Rebuild: `ralph docker build`
212
+
213
+ ### Platform-specific dependencies
214
+
215
+ If you switch between running on host and in container, reinstall node_modules:
216
+
217
+ ```bash
218
+ rm -rf node_modules && npm install
219
+ ```
220
+
221
+ Or use a separate volume for node_modules:
222
+
223
+ ```bash
224
+ docker run -v $(pwd):/workspace -v /workspace/node_modules your-image
225
+ ```
@@ -30,9 +30,11 @@ Use consistent categories to organize your PRD:
30
30
  | `bugfix` | Fixing broken behavior |
31
31
  | `refactor` | Code improvements without behavior change |
32
32
  | `docs` | Documentation updates |
33
+ | `test` | Adding or updating tests |
33
34
  | `release` | Version bumps, changelog updates |
34
35
  | `config` | Configuration file changes |
35
- | `test` | Adding or updating tests |
36
+ | `ui` | User interface changes |
37
+ | `integration` | Connecting components, wiring, orchestration |
36
38
 
37
39
  ## Writing Good Descriptions
38
40
 
@@ -200,7 +202,7 @@ Break large features into smaller, independently completable items. Each item sh
200
202
 
201
203
  ```json
202
204
  {
203
- "category": "feature|bugfix|docs|release|setup|refactor|config|test",
205
+ "category": "setup|feature|bugfix|refactor|docs|test|release|config|ui|integration",
204
206
  "description": "Imperative verb + specific what + where (context)",
205
207
  "steps": [
206
208
  "Concrete action with `commands` and file paths",
@@ -92,6 +92,7 @@ If a task takes 2 minutes without thinking, combine with related work.
92
92
  | `test` | Test coverage (unit, integration, e2e) |
93
93
  | `release` | Version bumps, changelogs, packaging |
94
94
  | `config` | Configuration files, settings |
95
+ | `ui` | User interface changes, frontend components |
95
96
  | `integration` | Connecting components, wiring, orchestration |
96
97
 
97
98
  ## Writing Descriptions
@@ -307,7 +308,7 @@ Convert the following document into a Ralph prd.json file.
307
308
 
308
309
  Rules:
309
310
  1. Each sub-task or atomic feature = one PRD item
310
- 2. Use categories: setup, feature, bugfix, refactor, docs, test, release, config, integration
311
+ 2. Use categories: setup, feature, bugfix, refactor, docs, test, release, config, ui, integration
311
312
  3. Descriptions: imperative verb + specific what + context
312
313
  4. Steps: 2-4 concrete actions + verification step
313
314
  5. Reference source document sections instead of copying code
@@ -0,0 +1,78 @@
1
+ # Security
2
+
3
+ Ralph automates AI agents that execute code and modify files autonomously. This document explains the security model and requirements.
4
+
5
+ ## Container Requirement
6
+
7
+ **It is strongly recommended to run ralph inside a Docker container for security.** The Ralph Wiggum technique involves running an AI agent autonomously, which means granting it elevated permissions to execute code and modify files without manual approval for each action.
8
+
9
+ ## The `--dangerously-skip-permissions` Flag
10
+
11
+ When running inside a container, ralph automatically passes the `--dangerously-skip-permissions` flag to Claude Code. This flag:
12
+
13
+ - Allows Claude to execute commands and modify files without prompting for permission
14
+ - Is **only** enabled when ralph detects it's running inside a container
15
+ - Is required for autonomous operation (otherwise Claude would pause for approval on every action)
16
+
17
+ **Warning:** The `--dangerously-skip-permissions` flag gives the AI agent full control over the environment. This is why container isolation is critical:
18
+
19
+ - The container provides a sandbox boundary
20
+ - Network access is restricted to essential services (GitHub, npm, Anthropic API)
21
+ - Your host system remains protected even if something goes wrong
22
+
23
+ ## Container Detection
24
+
25
+ Ralph detects container environments by checking:
26
+
27
+ 1. `DEVCONTAINER` environment variable
28
+ 2. Presence of `/.dockerenv` file
29
+ 3. Container indicators in `/proc/1/cgroup` (docker, podman, lxc, containerd)
30
+ 4. `container` environment variable (podman, docker)
31
+
32
+ If you're running outside a container and need autonomous mode, use `ralph docker` to set up a safe sandbox environment first.
33
+
34
+ ## Network Sandboxing
35
+
36
+ The Docker configuration includes firewall rules limiting network access to:
37
+
38
+ - **GitHub** - For git operations (clone, push, pull)
39
+ - **npm registry** - For dependency installation
40
+ - **Anthropic API** - For Claude API calls
41
+
42
+ All other outbound network traffic is blocked by default.
43
+
44
+ ## Credential Handling
45
+
46
+ ### OAuth Credentials (Claude Code)
47
+
48
+ For Claude Code users with Pro/Max subscriptions, the `~/.claude` directory is mounted into the container:
49
+
50
+ ```yaml
51
+ volumes:
52
+ - ~/.claude:/home/node/.claude:ro
53
+ ```
54
+
55
+ This allows the AI agent to use your existing OAuth credentials without exposing API keys.
56
+
57
+ ### API Keys
58
+
59
+ For API key-based authentication, pass environment variables to the container:
60
+
61
+ ```bash
62
+ docker compose run -e ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY ralph
63
+ ```
64
+
65
+ **Never commit API keys to version control.** Use environment variables or Docker secrets.
66
+
67
+ ## Best Practices
68
+
69
+ 1. **Always use containers** - Never run `ralph run` or `ralph once` outside a container
70
+ 2. **Review PRD items** - Check what you're asking the AI to do before running
71
+ 3. **Use separate branches** - Let the AI work on feature branches, review before merging
72
+ 4. **Monitor progress** - Check `.ralph/progress.txt` and git commits periodically
73
+ 5. **Limit scope** - Keep PRD items small and focused to reduce risk
74
+
75
+ ## Reporting Security Issues
76
+
77
+ If you discover a security vulnerability, please report it by opening an issue at:
78
+ https://github.com/choas/ralph-cli-sandboxed/issues
@@ -1,68 +1,77 @@
1
1
  # Run Command State Machine
2
2
 
3
3
  ```mermaid
4
- stateDiagram-v2
5
- [*] --> ParseFlags : run(args)
6
-
7
- ParseFlags --> DetermineMode
8
-
9
- state DetermineMode {
10
- [*] --> CheckLoopFlag
11
- CheckLoopFlag --> LoopMode : --loop
12
- CheckLoopFlag --> CheckIterationArg : no --loop
13
- CheckIterationArg --> CountMode : number provided
14
- CheckIterationArg --> AllMode : no number (default)
15
- }
16
-
17
- DetermineMode --> CheckItems
18
-
19
- state "Check Items" as CheckItems {
20
- [*] --> CreateFilteredPRD
21
- CreateFilteredPRD --> HasIncomplete
22
- HasIncomplete --> StartIteration : yes
23
- HasIncomplete --> HandleComplete : no
24
- }
25
-
26
- state HandleComplete {
27
- [*] --> CheckMode
28
- CheckMode --> WaitForNewItems : LoopMode
29
- CheckMode --> PrintComplete : AllMode/CountMode
30
- WaitForNewItems --> PollLoop
31
- PollLoop --> CheckNewItems : every 30s
32
- CheckNewItems --> StartIteration : found
33
- CheckNewItems --> PollLoop : not found
34
- PrintComplete --> [*]
35
- }
36
-
37
- state "Start Iteration" as StartIteration
38
-
39
- StartIteration --> RunCLI
40
-
41
- state "Run CLI" as RunCLI {
42
- [*] --> SpawnProcess
43
- SpawnProcess --> WaitForExit
44
- WaitForExit --> ProcessOutput
45
- }
46
-
47
- RunCLI --> CheckResult
48
-
49
- state "Check Result" as CheckResult {
50
- [*] --> CheckExitCode
51
- CheckExitCode --> TrackFailure : non-zero
52
- CheckExitCode --> ResetFailures : zero
53
- TrackFailure --> CheckConsecutive
54
- CheckConsecutive --> StopRun : >= 3 consecutive
55
- CheckConsecutive --> CheckCompletionSignal : < 3
56
- ResetFailures --> CheckCompletionSignal
57
- CheckCompletionSignal --> HandleLoopComplete : COMPLETE signal
58
- CheckCompletionSignal --> NextIteration : no signal
59
- HandleLoopComplete --> WaitForNewItems : LoopMode
60
- HandleLoopComplete --> PrintFinalStatus : AllMode/CountMode
61
- StopRun --> [*]
62
- PrintFinalStatus --> [*]
63
- }
64
-
65
- NextIteration --> CheckIterationLimit
66
- CheckIterationLimit --> CheckItems : more iterations
67
- CheckIterationLimit --> [*] : limit reached
4
+ flowchart TD
5
+ subgraph Initialization ["1. Initialization"]
6
+ Start([Start]) --> ParseArgs[Parse CLI Arguments]
7
+ ParseArgs --> ModeSelect{Determine Mode}
8
+
9
+ ModeSelect -- "--loop flag" --> LoopMode[Loop Mode]
10
+ ModeSelect -- "number N" --> CountMode[Count Mode]
11
+ ModeSelect -- "default" --> AllMode[All Mode]
12
+ end
13
+
14
+ subgraph Validation ["2. Item Validation"]
15
+ CreateFilteredPRD[Create Filtered PRD] --> HasIncomplete{Incomplete Items?}
16
+
17
+ HasIncomplete -- "Yes" --> StartIteration
18
+ HasIncomplete -- "No" --> ModeCheck
19
+ end
20
+
21
+ subgraph Execution ["3. Execution"]
22
+ StartIteration[Start Iteration] --> SpawnProcess[Spawn CLI Process]
23
+ SpawnProcess --> MonitorProcess[Monitor & Wait]
24
+ MonitorProcess --> CaptureResult[Capture Exit Code]
25
+ end
26
+
27
+ subgraph Analysis ["4. Result Analysis"]
28
+ ExitCheck{Exit Code == 0?}
29
+
30
+ ExitCheck -- "No" --> FailurePath[Increment Failure Counter]
31
+ FailurePath --> CriticalCheck{Failures >= 3?}
32
+ CriticalCheck -- "Yes" --> Abort([Abort: Too Many Errors])
33
+ CriticalCheck -- "No" --> SignalCheck
34
+
35
+ ExitCheck -- "Yes" --> SuccessPath[Reset Failure Counter]
36
+ SuccessPath --> SignalCheck
37
+
38
+ SignalCheck{COMPLETE Signal?}
39
+ SignalCheck -- "Yes" --> CompleteModeCheck
40
+ SignalCheck -- "No" --> IterationCheck
41
+ end
42
+
43
+ subgraph Completion ["5. Completion & Polling"]
44
+ ModeCheck{Mode?}
45
+ ModeCheck -- "Loop Mode" --> PollWait
46
+ ModeCheck -- "All/Count Mode" --> FinalReport
47
+
48
+ CompleteModeCheck{Mode?}
49
+ CompleteModeCheck -- "Loop Mode" --> PollWait[Wait 30 Seconds]
50
+ CompleteModeCheck -- "All/Count Mode" --> FinalReport[Final Report]
51
+
52
+ PollWait --> CheckNewItems{New Items Found?}
53
+ CheckNewItems -- "Yes" --> StartIteration
54
+ CheckNewItems -- "No" --> PollWait
55
+
56
+ FinalReport --> End([End])
57
+
58
+ IterationCheck{Limit Reached?}
59
+ IterationCheck -- "Yes" --> FinalReport
60
+ IterationCheck -- "No" --> CreateFilteredPRD
61
+ end
62
+
63
+ %% Cross-subgraph connections
64
+ LoopMode --> CreateFilteredPRD
65
+ CountMode --> CreateFilteredPRD
66
+ AllMode --> CreateFilteredPRD
67
+ CaptureResult --> ExitCheck
68
+
69
+ %% Styling
70
+ style Initialization fill:#f9f9f9,stroke:#333,stroke-width:2px
71
+ style Validation fill:#fff4dd,stroke:#d4a017,stroke-width:2px
72
+ style Execution fill:#e1f5fe,stroke:#01579b,stroke-width:2px
73
+ style Analysis fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px
74
+ style Completion fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px
75
+ style Abort fill:#ffebee,stroke:#c62828,color:#c62828
76
+ style End fill:#e8f5e9,stroke:#2e7d32,color:#2e7d32
68
77
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ralph-cli-sandboxed",
3
- "version": "0.2.5",
3
+ "version": "0.2.7",
4
4
  "description": "AI-driven development automation CLI for Claude Code",
5
5
  "type": "module",
6
6
  "bin": {