crush-sandbox 0.5.2

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.
@@ -0,0 +1,113 @@
1
+ # Contributing to Crush Sandbox
2
+
3
+ Thank you for your interest in contributing! We welcome contributions from everyone.
4
+
5
+ ## How to Contribute
6
+
7
+ ### Reporting Issues
8
+
9
+ If you find a bug or have a feature request:
10
+
11
+ 1. Check existing [issues](https://github.com/wireless25/crush-sandbox/issues) to avoid duplicates
12
+ 2. Use the [issue template](https://github.com/wireless25/crush-sandbox/issues/new) if available
13
+ 3. Include:
14
+ - Steps to reproduce
15
+ - Expected behavior
16
+ - Actual behavior
17
+ - Environment information (macOS version, Docker version)
18
+
19
+ ### Submitting Pull Requests
20
+
21
+ 1. Fork the repository
22
+ 2. Create a branch for your changes:
23
+ ```bash
24
+ git checkout -b feature/your-feature-name
25
+ ```
26
+ 3. Make your changes
27
+ 4. Test thoroughly:
28
+ - Run `bash -n docker-sandbox-crush` to check syntax
29
+ - Test all commands: `./docker-sandbox-crush run`, `clean`, `install`
30
+ - Test with flags: `--version`, `--shell`, `--force`
31
+ 5. Commit your changes with clear messages
32
+ 6. Push to your fork:
33
+ ```bash
34
+ git push origin feature/your-feature-name
35
+ ```
36
+ 7. Open a pull request
37
+
38
+ ### Development Setup
39
+
40
+ 1. Clone the repository:
41
+ ```bash
42
+ git clone https://github.com/wireless25/crush-sandbox.git
43
+ cd crush-sandbox
44
+ ```
45
+
46
+ 2. Make the script executable:
47
+ ```bash
48
+ chmod +x docker-sandbox-crush
49
+ ```
50
+
51
+ 3. Test your changes:
52
+ ```bash
53
+ # Test help
54
+ ./docker-sandbox-crush
55
+
56
+ # Test version
57
+ ./docker-sandbox-crush --version
58
+
59
+ # Test syntax
60
+ bash -n docker-sandbox-crush
61
+ ```
62
+
63
+ ### Code Style
64
+
65
+ - Follow existing bash conventions in the script
66
+ - Use 4 spaces for indentation
67
+ - Add comments for complex logic
68
+ - Keep functions small and focused
69
+ - Use descriptive variable names
70
+
71
+ ### Testing
72
+
73
+ Since there are no automated tests, manual testing is essential:
74
+
75
+ - Test on macOS (primary target)
76
+ - Verify Docker Desktop is running
77
+ - Test with multiple workspace directories
78
+ - Test container reuse
79
+ - Test cache persistence
80
+ - Test with `--shell` flag for debugging
81
+
82
+ ### Documentation
83
+
84
+ - Update README.md if you change user-facing behavior
85
+ - Update AGENTS.md if you change internal architecture
86
+ - Keep changelog for version changes
87
+
88
+ ## Guidelines
89
+
90
+ ### Do
91
+
92
+ - Write clear, concise commit messages
93
+ - Test your changes thoroughly
94
+ - Update documentation
95
+ - Be respectful and constructive
96
+
97
+ ### Don't
98
+
99
+ - Make breaking changes without discussion
100
+ - Add dependencies without justification
101
+ - Change the project scope significantly without agreement
102
+ - Commit sensitive information
103
+
104
+ ## Getting Help
105
+
106
+ If you need help:
107
+ 1. Check the [README](README.md)
108
+ 2. Review existing issues and pull requests
109
+ 3. Ask questions in a new issue with the "question" label
110
+
111
+ ## License
112
+
113
+ By contributing, you agree that your contributions will be licensed under the MIT License.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,515 @@
1
+ # Crush Sandbox
2
+
3
+ A lightweight bash wrapper that runs the [Crush CLI](https://github.com/charmbracelet/crush) in a Docker sandbox with persistent package manager caches. Perfect for isolating your development environment while keeping tools and dependencies cached per workspace.
4
+
5
+ ## 🚀 Quick Start
6
+
7
+ ### Prerequisites
8
+
9
+ - **macOS** (primary target)
10
+ - **Docker Desktop** installed and running
11
+
12
+ ### Installation
13
+
14
+ #### One-command installation (recommended)
15
+
16
+ ```bash
17
+ curl -fsSL https://raw.githubusercontent.com/wireless25/crush-sandbox/main/docker-sandbox-crush | sudo tee /usr/local/bin/crush-sandbox > /dev/null
18
+ sudo chmod +x /usr/local/bin/crush-sandbox
19
+ ln -s /usr/local/bin/crush-sandbox /usr/local/bin/crushbox
20
+ ```
21
+
22
+ #### Manual installation
23
+
24
+ 1. Download the script:
25
+ ```bash
26
+ curl -fsSL https://raw.githubusercontent.com/wireless25/crush-sandbox/main/docker-sandbox-crush -o docker-sandbox-crush
27
+ ```
28
+
29
+ 2. Make it executable:
30
+ ```bash
31
+ chmod +x docker-sandbox-crush
32
+ ```
33
+
34
+ 3. Move it to your PATH:
35
+ ```bash
36
+ sudo mv docker-sandbox-crush /usr/local/bin/crush-sandbox
37
+ ```
38
+
39
+ #### Install using the script itself
40
+
41
+ If you've cloned the repository, you can use the built-in install command:
42
+
43
+ ```bash
44
+ ./docker-sandbox-crush install
45
+ ```
46
+
47
+ This will:
48
+ - Validate Docker is available
49
+ - Install the script to `/usr/local/bin/crush-sandbox`
50
+ - Create a `crushbox` alias symlink
51
+ - Display version information for installed tools
52
+
53
+ **Note:** gitleaks Docker image will be pulled automatically on first use for credential scanning. No additional installation is required.
54
+
55
+ ## ✨ Features
56
+
57
+ - **Workspace isolation**: Each workspace directory gets its own sandbox container
58
+ - **Persistent caches**: npm and pnpm caches persist per workspace for faster subsequent runs
59
+ - **Automatic Crush CLI installation**: Crush CLI is installed automatically on first use
60
+ - **Git config injection**: Your Git user.name and user.email are passed into the container
61
+ - **Container reuse**: Containers are stopped but not removed, enabling fast restarts
62
+ - **Debugging support**: Use `--shell` flag to get an interactive shell instead of Crush CLI
63
+ - **Configuration support**: Automatically mounts and merges Crush configuration from host
64
+
65
+ ## ⚙️ Configuration
66
+
67
+ The Docker sandbox automatically provides Crush CLI configuration:
68
+
69
+ ### Configuration Sources
70
+
71
+ **Host configuration** (global defaults):
72
+ - `~/.config/crush/`
73
+
74
+ **Workspace configuration** (workspace-specific):
75
+ - `.crush.json` or `crush.json` (relative to workspace root)
76
+
77
+ If you maintain global Crush config with commands, skills, or settings, this will be mounted into the container. Any workspace-specific config will override these settings.
78
+ Config files in the workspace are mounted into the container with the rest of the code and take precedence over host config by default in Crush. Make sure to configure your skills
79
+ and commands accordingly. If you want to use global configured skills, add the `/tmp/crush-config/merged/skills` path to the skills option in the config (global on host or in workspace) to make Crush pick them up.
80
+
81
+ **Example to include skills from global host in the config**:
82
+ ```json
83
+ {
84
+ "$schema": "https://charm.land/crush.json",
85
+ "options": {
86
+ "skills_paths": [
87
+ "~/.config/crush/skills",
88
+ "/tmp/crush-config/merged/skills"
89
+ ]
90
+ }
91
+ }
92
+ ```
93
+
94
+ With this configuration, you can still use `crush` on your host machine with the same setup.
95
+
96
+ ### Configuration Merge Behavior
97
+
98
+ 1. Host configuration is copied to the container
99
+ 2. Workspace configuration is mounted with the workspace, **overwriting** host config (Crush default behavior)
100
+ 3. Host configuration is available at `/tmp/crush-config/merged` inside the container
101
+ 4. `CRUSH_GLOBAL_CONFIG` environment variable is set to this location
102
+
103
+ This means workspace-specific settings always override global defaults.
104
+
105
+ ### Security
106
+
107
+ - All configuration mounts are **read-only** (`:ro` flag)
108
+ - The container cannot modify your host configuration files
109
+
110
+ ### Configuration Control Flags
111
+
112
+ You can control configuration behavior with these flags:
113
+
114
+ | Flag | Description |
115
+ |------|-------------|
116
+ | `--no-host-config` | Skip mounting host Crush config directory |
117
+
118
+ **Examples**:
119
+
120
+ ```bash
121
+ # Skip host configuration
122
+ crush-sandbox run --no-host-config
123
+ # Or use alias:
124
+ crushbox run --no-host-config
125
+ ```
126
+
127
+ ### Configuration Directory Structure Example
128
+
129
+ ```
130
+ ~/.config/crush/ # Host configuration (global)
131
+ ├── crush.json # Main Crush config
132
+ └── skills # Skills directory
133
+ └── commands # Commands directory
134
+ ```
135
+
136
+ If you have a `crush.json` or `.crush.json` already in the workspace root, this will take precedence over the `.config/crush/` directory by Crush CLI's own behavior.
137
+
138
+ ## 📖 Usage
139
+
140
+ ### Start Crush CLI in a sandbox
141
+
142
+ Navigate to your workspace directory and run:
143
+
144
+ ```bash
145
+ crush-sandbox run
146
+ ```
147
+
148
+ Or use the alias:
149
+
150
+ ```bash
151
+ crushbox run
152
+ ```
153
+
154
+ This will:
155
+ 1. Create (or reuse) a sandbox container for your workspace
156
+ 2. Mount your workspace at the same absolute path
157
+ 3. Install Crush CLI if not already installed
158
+ 4. Install pnpm for package management
159
+ 5. Start the Crush CLI
160
+
161
+ ### Start a debug shell
162
+
163
+ If you need to debug or run manual commands:
164
+
165
+ ```bash
166
+ crush-sandbox run --shell
167
+ ```
168
+
169
+ Or with the alias:
170
+
171
+ ```bash
172
+ crushbox run --shell
173
+ ```
174
+
175
+ This gives you an interactive shell in the sandbox container instead of running Crush CLI.
176
+
177
+ ### Clean up the sandbox
178
+
179
+ To remove the container and cache volume for the current workspace:
180
+
181
+ ```bash
182
+ crush-sandbox clean
183
+ ```
184
+
185
+ Or with the alias:
186
+
187
+ ```bash
188
+ crushbox clean
189
+ ```
190
+
191
+ Add `--force` to skip confirmation:
192
+
193
+ ```bash
194
+ crush-sandbox clean --force
195
+ ```
196
+
197
+ ### Show version
198
+
199
+ ```bash
200
+ crush-sandbox --version
201
+ ```
202
+
203
+ ### Update to latest version
204
+
205
+ ```bash
206
+ crush-sandbox update
207
+ ```
208
+
209
+ This will:
210
+ - Check for the latest version on GitHub
211
+ - Compare with your current version
212
+ - Prompt for confirmation if a newer version is available
213
+ - Download and replace the script automatically
214
+ - Validate the downloaded script before installing
215
+
216
+ ### Get help
217
+
218
+ ```bash
219
+ crush-sandbox --help
220
+ ```
221
+
222
+ ## 🔒 Security
223
+
224
+ ### Security Overview
225
+
226
+ The docker-sandbox-crush tool implements several security controls to make AI-assisted development safe(er). However, the tool requires you to follow certain security practices to ensure safe operation.
227
+ Crush asks for your permission before performing any operation, but if you use `--yolo` mode or use it programmatically with `crush run` in a ralph loop, you must be aware of the security implications.
228
+
229
+ ### Read-Write Workspace Access
230
+
231
+ The Crush agent inside the container has **full read-write access** to your workspace files. This is intentional and necessary for the agent to:
232
+
233
+ - Read and modify source code files
234
+ - Run build commands and tests
235
+ - Create new files and directories
236
+ - Install packages and dependencies
237
+ - Execute git operations
238
+
239
+ **Security Implications:**
240
+
241
+ 1. **Trust the AI agent**: The agent can modify any file in your workspace
242
+ 2. **Credential exposure risk**: Never store secrets (API keys, passwords, tokens) in your workspace files
243
+ 3. **Review all changes**: Always review agent-generated changes
244
+ 4. **Use version control**: Git provides a safety net - you can revert any unwanted changes
245
+
246
+ **Best Practices:**
247
+
248
+ - Store credentials in:
249
+ - Environment variables
250
+ - Secret management tools
251
+ - CI/CD pipeline secrets (GitHub Actions Secrets, GitLab CI Variables)
252
+ - `.env` files that are gitignored
253
+ - Never commit credentials to git
254
+ - Use `.gitignore` to exclude files with secrets
255
+ - Rotate credentials if they were ever committed accidentally
256
+
257
+ ### Git Branch Protection for Production
258
+
259
+ When planning to use `--yolo` mode or use it programmatically with `crush run`, you should configure git branch protection to prevent direct pushes to production branches. This ensures:
260
+
261
+ - All agent-generated code goes through a pull request process
262
+ - Code review is required before merging
263
+ - CI/CD checks must pass before merging
264
+ - Unauthorized direct commits are blocked
265
+
266
+ ### What the Agent Can and Cannot Do
267
+
268
+ #### Capabilities
269
+
270
+ The Crush agent inside the sandbox container can:
271
+
272
+ ✅ **Read and write workspace files**
273
+ - Full access to all files in the mounted workspace
274
+ - Can create, modify, delete any file
275
+ - Can execute any command within the workspace
276
+
277
+ ✅ **Run commands and scripts**
278
+ - Execute build commands (npm build, cargo build, etc.)
279
+ - Run tests (npm test, pytest, etc.)
280
+ - Install packages (npm install, pip install, etc.)
281
+
282
+ ✅ **Make git operations**
283
+ - Create commits
284
+ - Create branches
285
+ - Stage files
286
+ - Push to remote repositories
287
+
288
+ ✅ **Access network resources**
289
+ - Download dependencies from npm, PyPI, etc.
290
+ - Make HTTP requests (if in code)
291
+ - Clone other git repositories
292
+
293
+ #### Limitations
294
+
295
+ The Crush agent cannot:
296
+
297
+ ❌ **Access files outside the workspace**
298
+ - Container is limited to mounted workspace directory
299
+ - Cannot access your home directory (except workspace subdirectories)
300
+ - Cannot access system files or other projects
301
+
302
+ ❌ **Run with elevated privileges**
303
+ - Container runs as non-root user
304
+ - Cannot install system packages globally
305
+ - Cannot modify Docker host
306
+
307
+ ❌ **Escalate privileges**
308
+ - Docker capabilities are dropped (except CHOWN and DAC_OVERRIDE)
309
+ - Cannot gain root access
310
+ - Cannot modify container configuration
311
+
312
+ ❌ **Access host resources directly**
313
+ - No direct access to host network
314
+ - No access to host filesystem beyond workspace
315
+ - Cannot interact with other containers
316
+
317
+ #### Security Controls in Place
318
+
319
+ The tool implements these security controls:
320
+
321
+ 1. **Resource limits** - Prevents resource exhaustion attacks:
322
+ - Memory limited to 4GB
323
+ - CPU limited to 2 cores
324
+ - Process count limited to 100 PIDs
325
+
326
+ 2. **Non-root user** - Limits attack surface:
327
+ - Container runs as your UID/GID
328
+ - Cannot perform privileged operations
329
+
330
+ 3. **Capability dropping** - Reduces Linux capabilities:
331
+ - All capabilities dropped by default
332
+ - CHOWN and DAC_OVERRIDE added back (required for cache and workspace access)
333
+
334
+ 4. **Credential scanning** - Warns about exposed secrets:
335
+ - Scans workspace with gitleaks before starting
336
+ - gitleaks is automatically installed when you run `crush-sandbox run --cred-scan`
337
+ - Prompts you to continue or abort if credentials detected
338
+ - Can be bypassed with `--no-cred-scan` flag (use with caution)
339
+
340
+ 5. **Workspace isolation** - Prevents cross-project contamination:
341
+ - Each workspace has its own container
342
+ - Caches are per-workspace
343
+ - No shared state between workspaces
344
+
345
+ ## 🔧 How It Works
346
+
347
+ ### Workspace Isolation
348
+
349
+ Each workspace directory (your current working directory) gets its own:
350
+ - **Container**: Named `crush-sandbox-<hash>` where `<hash>` is derived from your workspace path
351
+ - **Cache volume**: Named `crush-cache-<hash>` for persistent package manager caches
352
+
353
+ This means different projects have completely isolated sandbox environments.
354
+
355
+ ### Container Lifecycle
356
+
357
+ 1. **Create**: Container is created from `node:18-alpine` base image
358
+ 2. **Configure**: Workspace and cache volumes are mounted, environment variables are set
359
+ 3. **Start**: Container is started
360
+ 4. **Use**: Crush CLI or shell runs inside the container
361
+ 5. **Stop**: Container is stopped when you exit (kept for reuse)
362
+
363
+ Containers are **not removed** automatically, so subsequent starts are instant.
364
+
365
+ ### Cache Persistence
366
+
367
+ The cache volume stores:
368
+ - **npm cache**: `/workspace-cache/npm`
369
+ - **pnpm store**: `/workspace-cache/pnpm/store`
370
+ - **pnpm cache**: `/workspace-cache/pnpm/cache`
371
+
372
+ This means:
373
+ - Packages downloaded once stay cached
374
+ - Switching workspaces switches cache volumes
375
+ - Faster installs after the first run
376
+
377
+ ### Automatic Tool Installation
378
+
379
+ On container startup:
380
+ 1. **Crush CLI**: Installed via `npm install -g @charmland/crush` (cached after first install)
381
+ 2. **pnpm**: Installed via `npm install -g pnpm` (uses npm cache)
382
+
383
+ Installation happens automatically and silently on every container start, with fast-path checks to skip re-installation.
384
+
385
+ ## 📋 Examples
386
+
387
+ ### Typical workflow
388
+
389
+ ```bash
390
+ # Navigate to your project
391
+ cd ~/projects/my-app
392
+
393
+ # Start Crush CLI in sandbox
394
+ crush-sandbox run
395
+ # Or use alias:
396
+ # crushbox run
397
+
398
+ # ... work with Crush CLI ...
399
+
400
+ # When done, Crush CLI exits and container stops
401
+ # Next time, container is reused (instant start)
402
+ ```
403
+
404
+ ### Using with different workspaces
405
+
406
+ ```bash
407
+ cd ~/projects/project-a
408
+ crush-sandbox run # Uses crush-sandbox-<hash-a>
409
+
410
+ cd ~/projects/project-b
411
+ crush-sandbox run # Uses crush-sandbox-<hash-b>
412
+ ```
413
+
414
+ Each workspace has its own isolated environment.
415
+
416
+ ### Debugging setup issues
417
+
418
+ ```bash
419
+ # Get a shell to check installation
420
+ crush-sandbox run --shell
421
+ # Or:
422
+ crushbox run --shell
423
+
424
+ # Inside the container:
425
+ which crush # Check if Crush CLI is installed
426
+ pnpm --version # Check pnpm version
427
+ npm --version # Check npm version
428
+ ```
429
+
430
+ ## 🐛 Troubleshooting
431
+
432
+ ### "docker daemon is not running or not accessible"
433
+
434
+ **Problem**: Docker Desktop is not running.
435
+
436
+ **Solution**: Start Docker Desktop and wait for it to be ready. Verify with:
437
+ ```bash
438
+ docker info
439
+ ```
440
+
441
+ ### "Git user.name and user.email not configured"
442
+
443
+ **Problem**: Git user configuration is missing.
444
+
445
+ **Solution**: This is a warning, not an error. Add to `~/.gitconfig` if Crush CLI needs git operations:
446
+ ```bash
447
+ git config --global user.name "Your Name"
448
+ git config --global user.email "your.email@example.com"
449
+ ```
450
+
451
+ ### Crush CLI not working in container
452
+
453
+ **Problem**: Crush CLI installation failed.
454
+
455
+ **Solution**: Run with `--shell` flag to debug:
456
+ ```bash
457
+ crush-sandbox run --shell
458
+ # Then manually install:
459
+ npm install -g @charmland/crush
460
+ ```
461
+
462
+ ### Cache not persisting
463
+
464
+ **Problem**: Packages are re-downloaded every time.
465
+
466
+ **Solution**: Verify cache volume exists:
467
+ ```bash
468
+ docker volume ls | grep crush-cache
469
+ ```
470
+
471
+ Check if volume is mounted:
472
+ ```bash
473
+ docker inspect <container-name> | grep Mounts
474
+ ```
475
+
476
+ ### "Cannot write to /usr/local/bin" during install
477
+
478
+ **Problem**: No write permissions to `/usr/local/bin`.
479
+
480
+ **Solution**: Run with sudo:
481
+ ```bash
482
+ sudo ./docker-sandbox-crush install
483
+ ```
484
+
485
+ Or choose a different installation directory in your PATH.
486
+
487
+ ### Container name changes unexpectedly
488
+
489
+ **Problem**: Different containers for the same project.
490
+
491
+ **Solution**: Ensure you're in the same workspace directory. Container names are based on the current working directory (`pwd`).
492
+
493
+ ## 📝 License
494
+
495
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
496
+
497
+ ## 🤝 Contributing
498
+
499
+ Contributions are welcome! Please feel free to submit a Pull Request.
500
+
501
+ ## 🙋 Support
502
+
503
+ If you encounter issues or have questions:
504
+ 1. Check the [Troubleshooting](#-troubleshooting) section above
505
+ 2. Search existing [GitHub Issues](https://github.com/wireless25/crush-sandbox/issues)
506
+ 3. [Open a new issue](https://github.com/wireless25/crush-sandbox/issues/new) with details
507
+
508
+ ## 🔗 Related
509
+
510
+ - [Crush CLI](https://github.com/charmbracelet/crush) - The AI-powered CLI assistant
511
+ - [Docker Desktop for Mac](https://www.docker.com/products/docker-desktop) - Container runtime
512
+
513
+ ---
514
+
515
+ Made with ❤️ for developers who love isolated environments