| name | lima-devbox |
| description | Guide users through setting up a Lima VM for isolated development on macOS. Use when users want to create a sandboxed development environment, set up a VM for AI coding tools, or isolate code execution from their host machine. Walks through VM configuration (name, RAM, shared directories, languages) via wizard, then executes setup systematically. |
Lima Devbox Setup Skill
This skill guides users through creating a Lima VM configured for development work on macOS.
Prerequisites
- macOS with Homebrew installed
- Lima (
brew install lima)
Workflow
Phase 1: Configuration Wizard
Use AskUserQuestion to gather configuration. Ask these in sequence:
Question 1: VM Name
- Header: "VM Name"
- Options: "devbox" (default), "sandbox", "test"
- Description: Name for your Lima VM (used in commands like
limactl shell <name>)
Question 2: Resources
- Header: "Resources"
- Options:
- "Standard (6 CPU, 8GB RAM, 100GB disk)" - Good for most development
- "Light (4 CPU, 4GB RAM, 50GB disk)" - Lower resource usage
- "Heavy (8 CPU, 16GB RAM, 200GB disk)" - For large projects or multiple services
- multiSelect: false
Question 3: Shared Directories
- Header: "Mounts"
- Options:
- "Single directory" - Recommended, simple setup
- "Multiple directories" - I'll ask for a comma-separated list
- Description: Only these directories will be accessible from the VM (read/write). The VM has no access to any other host files.
Question 3b: Ask for the directory path(s)
- If single directory selected: Ask "What directory should the VM have access to?" with options like "
/github", "/projects", or let them type a custom path
- If multiple directories selected: Ask for comma-separated paths
Question 4: Git Configuration
Ask for git user.name and user.email (can use AskUserQuestion with text input)
Question 5: Languages
- Header: "Languages"
- Options: "Node.js", "Go", "Rust", "Python"
- multiSelect: true
- Description: Languages to install via mise (version manager)
Question 6: Tools
- Header: "Tools"
- Options: "GitHub CLI (gh)", "Docker (nerdctl already included)"
- multiSelect: true
- Description: Optional tools. Note: nerdctl (docker-compatible CLI) is already installed by default - try it before installing Docker.
Question 6b: AI Coding Agents
- Header: "AI Agents"
- Options: "Claude Code (Anthropic)", "Gemini CLI (Google)", "Codex CLI (OpenAI)", "OpenCode", "None"
- multiSelect: true
- Description: AI coding assistants to install. All support autonomous/YOLO modes for hands-off operation in this sandboxed environment.
Question 7: SSH Password (Optional)
- Header: "SSH Password"
- Options: "No password (key-only)" (default), "Set a password"
- Description: Lima uses SSH keys by default. You can optionally set a password for convenience.
Question 7b (if password selected): Ask user to enter their desired password
Question 8: Port Forwarding
- Header: "Ports"
- Options: "8080", "3000", "5000", "5432 (PostgreSQL)", "6379 (Redis)", "None"
- multiSelect: true
- Description: Forward these ports from VM to host. Access VM services at localhost: on your Mac.
Question 9: SSH Agent Forwarding
- Header: "SSH Agent"
- Options: "Yes - forward SSH agent (Recommended)", "No"
- multiSelect: false
- Description: Allows the VM to use your Mac's SSH keys for git operations, etc.
Question 10: VM Type
- Header: "VM Type"
- First, detect macOS version. If macOS 13+, recommend "vz":
- Options: "vz (Virtualization.framework) - Recommended, faster" (default on macOS 13+), "qemu - More compatible, slower"
- multiSelect: false
- Description: "vz" uses Apple's native virtualization (faster, requires macOS 13+). "qemu" works on older macOS.
Question 11: Rosetta (Apple Silicon only)
- Skip this question on Intel Macs
- Header: "Rosetta"
- Options: "Yes - enable Rosetta (Recommended)", "No"
- multiSelect: false
- Description: Run x86_64 Linux binaries in the VM. Useful for compatibility with older tools. Requires vz VM type.
Phase 2: Setup Execution
After gathering configuration, create a todo list and execute each step:
Step 1: Install Lima (if needed)
limactl --version
If not installed, install it:
brew install lima
Step 2: Create VM
limactl start --name=<vm_name> --cpus=<cpus> --memory=<memory> --disk=<disk> -y
Wait for VM to be running:
limactl list --json | jq -r '.[] | select(.name=="<vm_name>") | .status'
Step 3: Configure VM Settings
Edit ~/.lima/<vm_name>/lima.yaml to apply user's configuration choices:
VM Type (if user selected vz):
vmType: "vz"
Rosetta (if enabled, requires vmType: vz):
rosetta:
enabled: true
SSH Agent Forwarding (if enabled):
ssh:
forwardAgent: true
Port Forwarding (for each selected port):
portForwards:
- guestPort: 8080
hostPort: 8080
- guestPort: 3000
hostPort: 3000
Mounts - configure ONLY the shared directories (no home directory access):
Find the mounts: section and replace it with:
mounts:
- location: "<writable_path>"
writable: true
For multiple directories:
mounts:
- location: "~/github"
writable: true
- location: "~/projects"
writable: true
IMPORTANT: Do NOT include a location: "~" mount. Only the specified directories should be accessible.
Step 4: Full Stop/Start VM (required after mount changes)
IMPORTANT: Mount configuration changes (especially writable: true) require a full stop/start cycle to take effect. A simple limactl restart is NOT sufficient - you must explicitly stop and then start the VM.
limactl stop <vm_name>
limactl start <vm_name>
After restarting, verify the mount is writable by checking the mount flags:
limactl shell <vm_name> -- mount | grep <mount_path>
The output should show rw (read-write), not ro (read-only):
mount0 on /path/to/mount type virtiofs (rw,relatime)
If it still shows ro, stop and start again.
Step 5: Setup SSH Config Symlink
mkdir -p ~/.ssh/config.d
ln -sf ~/.lima/<vm_name>/ssh.config ~/.ssh/config.d/<vm_name>
Ensure ~/.ssh/config includes:
Include config.d/*
After this, user can SSH with: ssh <vm_name>
SSH Authentication Note: Lima uses key-based authentication by default:
- Creates a private key at
~/.lima/_config/user
- Sets up the VM user with your macOS username
- Configures all SSH settings in the symlinked config file
- Password authentication is optional (configured in Step 7 if requested)
Step 6: Run Base Setup Script
Copy and execute scripts/setup-vm.sh in the VM:
limactl shell <vm_name> -- bash -c "$(cat <skill_path>/scripts/setup-vm.sh)" -- "<git_name>" "<git_email>" "<working_dir>"
Where <working_dir> is the first (or primary) mounted directory path. This will be the default directory when the user shells into the VM.
This installs system packages, configures git, sets up .bash_profile for SSH sessions, and configures the shell to start in the shared directory.
Step 7: Set SSH Password (if requested)
If user chose to set a password:
limactl shell <vm_name> -- bash -c "echo '<username>:<password>' | sudo chpasswd"
Where <username> is the user's macOS username (same as VM user).
Step 8: Install Languages (if selected)
limactl shell <vm_name> -- bash -c "$(cat <skill_path>/scripts/install-mise.sh)" -- <languages>
Where <languages> is a space-separated list like nodejs go rust python.
Step 9: Install Optional Tools
For GitHub CLI:
limactl shell <vm_name> -- bash -c "$(cat <skill_path>/scripts/install-gh.sh)"
For Docker (if user specifically wants Docker instead of nerdctl):
limactl shell <vm_name> -- bash -c "curl -fsSL https://get.docker.com | sh && sudo usermod -aG docker \$USER"
Note: nerdctl is already available (nerdctl run, nerdctl build, etc.) and is docker-compatible. Most users won't need Docker.
Step 10: Install AI Coding Agents (if selected)
For Claude Code:
limactl shell <vm_name> -- bash -c "$(cat <skill_path>/scripts/install-ai-agent.sh)" -- claude
For Gemini CLI:
limactl shell <vm_name> -- bash -c "$(cat <skill_path>/scripts/install-ai-agent.sh)" -- gemini
For Codex CLI:
limactl shell <vm_name> -- bash -c "$(cat <skill_path>/scripts/install-ai-agent.sh)" -- codex
For OpenCode:
limactl shell <vm_name> -- bash -c "$(cat <skill_path>/scripts/install-ai-agent.sh)" -- opencode
All agents are configured with aliases for autonomous/YOLO mode operation.
Step 11: Verify Setup
limactl shell <vm_name> -- bash -c "echo 'VM is ready!' && git --version && mise --version"
Step 12: Final Restart (ensures mount permissions are correct)
Stop and restart the VM to ensure shared directory permissions are properly applied:
limactl stop <vm_name>
limactl start <vm_name>
Wait for the VM to be running before presenting the summary to the user.
Phase 3: Post-Setup Summary
After successful setup, provide the user with:
-
Access commands:
limactl shell <vm_name> - Interactive shell (starts in shared directory)
ssh <vm_name> - SSH access (if config symlink created)
exit or Ctrl+D - Exit the VM shell and return to Mac terminal
-
Common Lima commands:
limactl stop <vm_name> - Stop the VM
limactl start <vm_name> - Start the VM
limactl restart <vm_name> - Restart the VM
limactl delete <vm_name> -f - Delete the VM
-
Working with files:
- Only files in configured directories (e.g.,
~/github) are accessible from the VM
- Files are available at the same path in the VM
- Changes sync bidirectionally between host and VM
-
Container tools:
nerdctl is pre-installed (docker-compatible commands)
- Example:
nerdctl run -it ubuntu bash
-
Port forwarding (if configured):
- Forwarded ports are accessible at
localhost:<port> on your Mac
- Example: A server running on port 8080 in the VM is available at
localhost:8080
-
SSH agent (if enabled):
- Your Mac's SSH keys are available inside the VM
- Git operations using SSH will work without additional configuration
-
Reference: Point to references/lima-commands.md for full command reference
Script Locations
Scripts are located in scripts/ relative to this skill:
setup-vm.sh - Base system setup (packages, git config, bash_profile, default working directory)
install-mise.sh - Mise installation and language setup
install-gh.sh - GitHub CLI installation
install-ai-agent.sh - AI coding agent installation (Claude Code, Gemini CLI, Codex CLI, OpenCode)
Error Handling
- If Lima not installed: Guide user to
brew install lima
- If VM creation fails: Check Lima logs with
limactl logs <vm_name>
- If script fails: Can re-run individual scripts after SSH into VM
- If mounts are read-only: This is a common issue. Mount changes require a full
limactl stop followed by limactl start (not just restart). Verify with mount | grep <path> - look for rw not ro
- If mounts don't work: Verify lima.yaml syntax, then do a full stop/start cycle
Notes
- Default Lima template uses Ubuntu 24.04 LTS
- Only explicitly configured directories are mounted (VM has no access to other host files)
- nerdctl (containerd CLI) is included by default for container operations