Fixes: - Tidewave CLI now downloads from correct repo (tidewave_app) with proper musl binary naming convention Features: - Python runtime managed by mise instead of system apt - Python added as selectable component in interactive menu Documentation: - WINDOWS_PLAN.md explains Hyper-V vs WSL2 security tradeoffs - Documents CVEs affecting WSL2 (2024-20681, 2025-9074, 2025-53788) - Describes full implementation architecture and workflow Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
6.6 KiB
6.6 KiB
CLAUDE.md
Project Memory
This project uses three documentation files as persistent memory. You must keep these files up to date when making changes:
| File | Purpose | Update When |
|---|---|---|
CLAUDE.md |
Technical context for Claude Code sessions | Adding new patterns, conventions, or implementation details |
CHANGELOG.md |
Version history following Keep a Changelog format | Every commit (add entry, bump version) |
README.md |
User-facing documentation | Changing user-visible behavior, adding features, or modifying usage |
Versioning Rules
- Use semantic versioning (MAJOR.MINOR.PATCH)
- Increment PATCH for bug fixes and minor updates
- Increment MINOR for new features and enhancements
- Increment MAJOR for breaking changes
- Tag every commit with its version:
git tag -a vX.Y.Z -m "Description"
Project Overview
This repository provides scripts for creating isolated development sandboxes for Claude Code on macOS (OrbStack) and Windows (Hyper-V). Both platforms offer full VM isolation for safely running AI coding assistants with elevated permissions.
Supported platforms:
- macOS: OrbStack VMs (ARM64 Apple Silicon)
- Windows: Hyper-V VMs (maximum security, stronger than WSL2)
Repository Structure
setup_env.sh - macOS script (OrbStack host mode + Linux VM provisioning)
setup_env_windows.ps1 - Windows script (Hyper-V with cloud-init)
WINDOWS_PLAN.md - Windows implementation plan and security rationale
config.env.example - Example credentials file
config.env - User credentials (gitignored, created on first run)
.gitignore - Ignores config.env
README.md - User-facing documentation
CHANGELOG.md - Version history (Keep a Changelog format)
CLAUDE.md - This file (context for Claude Code sessions)
How the Script Works
The script has two modes, detected via uname -s:
- Darwin (macOS): Orchestrator mode. Checks for OrbStack, reads/creates
config.env, creates a VM, copies itself in, runs itself inside the VM with--non-interactive. - Linux (VM): Provisioning mode. Installs all tools, configures PostgreSQL, sets up VNC, installs Claude Code plugins.
This means ./setup_env.sh my-vm on macOS does everything end-to-end.
Key Technical Details
- Target environment: OrbStack Ubuntu VM on macOS Apple Silicon (ARM64)
- Version manager: mise (manages Node.js, Erlang, Elixir)
- Versions: All tools use latest by default. Erlang/Elixir versions can be configured at the top of
setup_env.sh(ERLANG_VERSION,ELIXIR_VERSION) - set to "latest" or pin to specific versions - PostgreSQL auth: Peer for local socket, scram-sha-256 for all TCP connections (localhost and network)
- Browser: Chromium (no Chrome ARM64 Linux builds exist), symlinked to
google-chrome - VNC: TigerVNC + XFCE on display :1 (port 5901), controlled via
vnc-start/vnc-stophelpers in~/bin - Shared credentials:
config.envstores git name/email only; VNC password is prompted each time (never stored)
Working on This Project
Editing setup_env.sh
- The macOS host-mode block is at the top (inside the
if [[ "$(uname -s)" == "Darwin" ]]block) - The Linux VM-mode block is everything after that conditional
- Version numbers are defined as variables at the top (
ERLANG_VERSION,ELIXIR_VERSION) - All installation steps must be idempotent (safe to run multiple times)
- Use
log_info,log_warn,log_errorhelpers for output - New apt packages go in the base dependencies section
- New Claude plugins go in the appropriate array (
ANTHROPIC_PLUGINSorSUPERPOWERS_PLUGINS) - Redirect verbose output to
$LOG_FILE, show only meaningful progress to the user - The
LOG_FILEvariable is only set in VM mode (not available in macOS host mode) - Each optional component is wrapped in
prompt_install "Name" "Description"— this handles both interactive prompts and--yes/--non-interactiveauto-accept - Track dependency flags (
INSTALLED_NODE,INSTALLED_CHROMIUM) to skip dependent components gracefully
Script Conventions
set -euo pipefailis enforced - handle potential failures with|| trueor explicit checks- Use
command_existsto check for already-installed tools - Use
apt-get(notapt) for scripting reliability - Quote all variable expansions
- Use
findfor PostgreSQL config paths (version-agnostic) - The
--non-interactiveflag is for VM mode (implies--yes); macOS mode always uses config.env --yes/-yaccepts all components without prompting but still allows interactive credential entryMISE_GLOBAL_CONFIG_FILEandMISE_CONFIG_DIRare set to prevent OrbStack host-mount config pollution
Security Patterns
- Input validation: Use
validate_vm_name(),validate_vnc_password(),validate_safe_input()for all user inputs - Safe config loading: Use
load_config_safely()which parses key=value pairs without shell execution (neversource) - Credential passing: Base64-encode values before passing to VM via
orb runto prevent shell injection - Download helper: Use
download_verified_binary()for binary downloads (supports optional checksum verification) - Temp files: Always use
mktempwith restrictive permissions (chmod 600/700) - Symlinks: Check with
[ ! -e path ](not[ ! -L path ]) to avoid overwriting existing files - Architecture detection: Use
detect_architecture()for portable binary downloads
Testing
There are no automated tests. To test changes:
- Remove an existing test VM:
orb delete test-sandbox - Run:
./setup_env.sh test-sandbox - Verify provisioning completes
- Run again to verify idempotency:
ssh test-sandbox@orb -- bash /tmp/setup_env.sh --non-interactive(will need env vars) - Test VNC:
ssh test-sandbox@orb -- vnc-start, thenopen vnc://test-sandbox.orb.local:5901 - Clean up:
orb delete test-sandbox
Security Considerations
config.envis chmod 600 and gitignored (stores git name/email only, never VNC password)- PostgreSQL uses scram-sha-256 for all TCP connections (peer auth for local socket)
- The script refuses to run as root inside the VM
- VNC password is required (min 6 chars), validated to block shell metacharacters, never stored
- VNC binds to all interfaces (
-localhost no) to allow connections from the macOS host — this is intentional for the OrbStack use case and documented in the vnc-start script - All user inputs are validated before use to prevent command injection
- External scripts (mise, ollama) are downloaded to temp files and validated before execution
- Host filesystem access is disabled inside the VM for isolation