A lightweight VM tool for development and testing. Create isolated environments, run commands, and experiment safely without affecting your host system.
Background
Using AI commandline tools can require allowing some scary permissions (ex: "allow model to rm -rf?"), I wanted to isolate commands using a VM that could be ephemeral (erased each time), or persistent, as needed. So instead of the AI trying to "reason out" math, it can write a little program and run it to get the answer directly. This VASTLY increases good output. This was also an experiment to use claude to create what I needed, and I'm very happy with the result.
Is this Docker or similar tool?
This is a Virtual Machine image being run through QEMU. You can prep the image with packages you need (I've been using Ubuntu), then have your tool call into the VM directly to run commands.
Features
- Ephemeral by default: Changes are discarded unless explicitly saved
- Persistent mode: Save changes when you want to build up a VM
- Fast startup: Pre-built VM images with cloud-init
- Work directory mounting: Access your local files inside the VM
- Multiple VMs: Create specialized environments for different projects
- Flexible output: Direct, minimal, or verbose output modes
- Non-interactive support: Install packages without prompts
Requirements
- Linux (Ubuntu/Debian, RHEL/CentOS/Fedora, Arch) or macOS
- QEMU/KVM (for virtualization)
- Node.js 14+ and npm
- SSH client tools
- ISO creation tools (genisoimage/mkisofs)
Installation
- Clone or download this repository
- Run the installer:
- Follow the prompts - the installer will:
- Install system dependencies (QEMU, etc.)
- Install Node.js dependencies
- Set up global CLI commands
- Create necessary directories
After installation, you can use scratchpad and scratchpad-prepare commands globally.
Quick Start
-
Prepare a VM with your desired packages:
scratchpad-prepare --name dev nodejs python3 git
-
Run commands in the VM:
scratchpad run --vm dev "node --version" -
Start an interactive shell:
scratchpad shell --vm dev
VM Preparation
Use scratchpad-prepare to create VMs with pre-installed software:
Basic Syntax
scratchpad-prepare [options] [packages...]
Options
-n, --name <name>- VM name (default: 'default')-b, --base <image>- Base image: ubuntu, alpine, debian (default: 'ubuntu')-m, --memory <size>- Memory allocation (default: '1G')-d, --disk <size>- Disk size (default: '10G')-v, --verbose- Show detailed output-h, --help- Show help
Example: Node.js Development VM
# Create a VM with Node.js and development tools scratchpad-prepare --name nodedev nodejs npm git vim # The VM will be created with all packages installed and ready to use
Usage
Use scratchpad to run commands or start shells in prepared VMs:
Basic Syntax
scratchpad run [options] <command> # Execute a command scratchpad shell [options] # Start interactive shell scratchpad [options] <command> # Execute command (shorthand)
CLI Options
| Option | Description |
|---|---|
--vm <name> |
Use specific VM (default: 'default') |
-m, --memory <size> |
Memory allocation (default: '512M') |
-d, --dir <path> |
Directory to mount (default: current) |
-k, --keep-alive |
Keep VM running after command |
-n, --non-interactive |
Run in non-interactive mode |
-p, --persistent |
Save changes to VM disk |
-v, --verbose |
Show startup/connection details |
--direct |
Show only command output |
--debug |
Show debug information |
-h, --help |
Show help |
VM Modes
Ephemeral (default): Changes are discarded when VM stops
scratchpad run "sudo apt-get install git" # Test installation, changes lost
Persistent: Changes are saved permanently
scratchpad run -p "sudo apt-get install git" # Install permanently
Output Modes
Direct (--direct): Pure command output only - perfect for scripting
scratchpad run --direct "node --version" # Output: v18.17.0
Default: Minimal VM messages + command output
scratchpad run "node --version" # Output: Starting VM... connecting... ready. # v18.17.0
Verbose (-v): Full VM details + command output
scratchpad run -v "node --version" # Output: 🚀 Starting VM 'default'... # ⏳ Connecting to VM... # ✓ Connected to VM # v18.17.0 # 🛑 Stopping VM...
Examples
Prepare and Test Node.js Environment
# 1. Create a Node.js development VM scratchpad-prepare --name nodedev nodejs npm git # 2. Check the installed version (direct output) scratchpad run --vm nodedev --direct "node --version" # Output: v18.17.0 # 3. Test npm (minimal output) scratchpad run --vm nodedev "npm --version" # Output: Starting VM... connecting... ready. # 9.6.7 # 4. Install a package temporarily (ephemeral) scratchpad run --vm nodedev "npm install -g typescript" # 5. Install a package permanently scratchpad run --vm nodedev -p "npm install -g typescript" # 6. Interactive development session scratchpad shell --vm nodedev
Python Data Science
# Create VM with Python and data tools scratchpad-prepare --name datascience python3 python3-pip # Install packages permanently scratchpad run --vm datascience -p -n "pip3 install pandas numpy jupyter" # Run analysis script with direct output scratchpad run --vm datascience --direct "python3 analysis.py" # Start Jupyter notebook (persistent session) scratchpad run --vm datascience -p -k "jupyter notebook --ip=0.0.0.0"
Testing and Development
# Quick test in default VM (ephemeral) scratchpad run "python3 -c 'print(\"Hello VM!\")'" # Test with more memory scratchpad run -m 2G "python3 memory_intensive_script.py" # Debug with verbose output scratchpad run -v "python3 problematic_script.py" # Work with local files (automatically mounted) scratchpad run "ls -la" # Shows your current directory files # Install something just for testing (changes discarded) scratchpad run "sudo apt-get install -y htop && htop" # Install something permanently scratchpad run -p -n "sudo apt-get install -y htop"
Automation and Scripting
# Get command output for scripts (direct mode) VERSION=$(scratchpad run --direct "python3 --version") echo "VM Python version: $VERSION" # Run tests quietly scratchpad run --direct "pytest tests/ -v" > test_results.txt # Batch processing with different VMs scratchpad run --vm nodedev --direct "npm test" > node_results.txt scratchpad run --vm python --direct "python3 test.py" > python_results.txt # Check if a package is available if scratchpad run --direct "which docker" > /dev/null 2>&1; then echo "Docker is available in the VM" fi
Multi-VM Workflow
# Create specialized VMs scratchpad-prepare --name frontend nodejs npm yarn scratchpad-prepare --name backend python3 postgresql-client redis-tools scratchpad-prepare --name tools git docker.io curl # Use different VMs for different tasks scratchpad run --vm frontend "npm run build" scratchpad run --vm backend "python3 manage.py test" scratchpad run --vm tools "docker ps" # Compare versions across VMs echo "Frontend Node: $(scratchpad run --vm frontend --direct 'node --version')" echo "Backend Python: $(scratchpad run --vm backend --direct 'python3 --version')"
Advanced Usage
Keep VM Running for Multiple Commands
# Start VM and keep it running scratchpad run -k "echo 'VM started'" # Run more commands on the same VM instance (faster) scratchpad run --vm default "python3 script1.py" scratchpad run --vm default "python3 script2.py"
Non-Interactive Package Installation
# Install packages without prompts scratchpad run -n -p "sudo apt-get update && sudo apt-get install -y nginx" # Configure system settings non-interactively scratchpad run -n -p "sudo dpkg-reconfigure -f noninteractive tzdata"
Working with Different Base Images
# Alpine Linux VM (smaller, faster) scratchpad-prepare --base alpine --name minimal python3 # Debian VM scratchpad-prepare --base debian --name stable nodejs # Use the different VMs scratchpad run --vm minimal "python3 --version" scratchpad run --vm stable "node --version"
Combining Options
# Install packages permanently, non-interactively, with direct output scratchpad run --vm myvm -p -n --direct "sudo apt-get install -y git vim curl" # Debug a failing command with full verbosity scratchpad run --vm problematic -v -p "failing_command_here" # Test in ephemeral mode, then install permanently scratchpad run --vm dev "npm install lodash" # Test first scratchpad run --vm dev -p "npm install lodash" # Install permanently
List Available VMs
Output:
Available VMs:
• default
Base: ubuntu, Packages: python3
• nodedev
Base: ubuntu, Packages: nodejs, npm, git
• datascience
Base: ubuntu, Packages: python3, python3-pip
Best Practices
VM Management
- Start with ephemeral mode to test things safely
- Create specialized VMs for different projects/languages
- Use persistent mode sparingly - keep VMs minimal and rebuild when needed
- Name your VMs descriptively (
--name frontend,--name datascience)
Output Control
- Use
--directfor scripting to get clean output - Use default mode for interactive work - shows progress without clutter
- Use
--verbosefor debugging when things go wrong
Performance Tips
- Use
--keep-alivewhen running multiple commands on the same VM - Allocate appropriate memory with
-mfor memory-intensive tasks - Use Alpine base for lightweight, fast-starting VMs
Package Management
- Test installations in ephemeral mode first
- Use
-nflag for automated package installation - Group related installations together in single commands
Troubleshooting
Common Issues
Permission denied on /dev/kvm
# Add yourself to kvm group and re-login sudo usermod -aG kvm $USER # Then log out and back in, or run: newgrp kvm
Command not found: scratchpad
# Check if ~/.local/bin is in your PATH echo $PATH | grep -q "$HOME/.local/bin" || echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc source ~/.bashrc
VM won't start
# Check QEMU installation qemu-system-x86_64 --version # Check if VM exists scratchpad list # Try with verbose mode scratchpad run -v "echo test"
SSH connection fails
# Try with verbose mode to see connection details scratchpad run -v --vm myvm "echo test" # Check if VM disk exists ls ~/.scratchpad/vms/myvm/disk.qcow2
Package installation prompts
# Use non-interactive mode scratchpad run -n "sudo apt-get install package" # For persistent installation scratchpad run -p -n "sudo apt-get install package"
Debug Mode
Use --debug to see detailed parsing and execution information:
scratchpad run --debug --vm myvm "python3 --version"This shows:
- Argument parsing steps
- VM startup details
- SSH connection process
- Command execution details
Need help?
scratchpad --help- CLI helpscratchpad-prepare --help- VM preparation helpscratchpad list- Show available VMs