This doc covers Windows VM setup on an x86 Windows host for isolated development.
For other platforms, see:
- macOS Setup — for macOS VM on Mac host
- Linux x86 Setup — for Linux VM on x86 Linux host
When using AI-assisted tools like Claude Code, it's important to limit the "blast radius" of what the AI can access or modify. A VM provides hard boundaries:
- Containment: The AI can only see/modify files inside the VM — not your host machine, personal files, or other projects
- Scoped credentials: GitHub PATs and API keys are isolated to the VM and scoped to specific repos
- Easy reset: If something goes wrong, you can restore from a checkpoint or rebuild the VM from scratch
- Reproducible environment: Every developer starts from the same clean slate
- Peace of mind: You can let the AI operate more freely without worrying about unintended side effects
This isn't about distrust — it's defense in depth. The same reason you don't run untested code as admin.
See Linux x86 Setup for hardware recommendations.
Standard Windows 11 Pro install on the mini PC. Pro edition is required for Hyper-V.
- Open PowerShell as Administrator
- Run:
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All- Restart when prompted
# Run as Administrator
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
Start-Service sshd
Set-Service -Name sshd -StartupType Automatic
# Allow SSH through Windows Firewall
New-NetFirewallRule -Name sshd -DisplayName 'OpenSSH Server' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22
# Get IP address
ipconfigBy default, Hyper-V's "Default Switch" gives VMs a NAT IP only reachable from the host. To access the VM from other machines on your network (e.g., your Mac), create an External Switch:
- Open Hyper-V Manager
- Right panel → Virtual Switch Manager
- Select External → Create Virtual Switch
- Name:
External Switch - Under "External network", select your physical network adapter
- Apply/OK (this will briefly drop the host's network connection)
Download Windows 11 ISO from Microsoft: https://www.microsoft.com/software-download/windows11
- Open Hyper-V Manager
- Action → New → Virtual Machine
- Configure:
- Name:
vibium-dev - Generation: Generation 2
- Memory: 4GB minimum (8GB recommended), enable Dynamic Memory
- Network: External Switch (created above)
- Virtual Hard Disk: 64GB minimum
- Name:
- Install Options: select Windows ISO
- Finish and start installation
Right-click VM → Settings:
- Security: Enable Trusted Platform Module (required for Windows 11)
- Security: Disable Secure Boot (or set to "Microsoft UEFI Certificate Authority")
- Processor: 4 virtual processors
- Checkpoints: Enable (for snapshots)
- Start the VM and immediately click inside the console window
- Spam the spacebar — you need to hit a key while the "Press any key to boot from CD or DVD..." prompt is visible (it disappears quickly)
- Standard Windows 11 install. Use a local account for simplicity.
All commands below are run inside the VM.
# Run in PowerShell as Administrator
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
Start-Service sshd
Set-Service -Name sshd -StartupType Automatic
# Allow SSH through Windows Firewall
New-NetFirewallRule -Name sshd -DisplayName 'OpenSSH Server' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22
# Set PowerShell as default SSH shell
New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Value "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -PropertyType String -ForceGet VM IP:
ipconfigPowerShell blocks .ps1 scripts by default, which breaks tools like npm. Run this once to allow scripts you install:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUserWindows 11 includes winget by default. Open a regular PowerShell (not Administrator):
winget install Git.Git
winget install GitHub.cli
winget install GnuWin32.Make
winget install BurntSushi.ripgrep.MSVC
winget install jqlang.jqRestart terminal after installing Git, then add GnuWin32 Make and Git's Unix tools to your PATH:
[Environment]::SetEnvironmentVariable("Path", $env:Path + ";C:\Program Files (x86)\GnuWin32\bin;C:\Program Files\Git\usr\bin", "User")This adds make plus Unix tools (cp, rm, mkdir, cat, bash, etc.) that the Makefile requires. GnuWin32 Make 3.81 doesn't use the Makefile's SHELL variable, so these tools must be directly on PATH.
Restart your terminal after updating PATH. Verify:
make --version
bash --versionwinget install GoLang.GoRestart terminal, then verify:
go versionwinget install OpenJS.NodeJS.LTSRestart terminal, then verify:
node --version
npm --versionmake build builds the Java client with Gradle, which needs a JDK (11 or newer — the build targets Java 11).
winget install Microsoft.OpenJDK.21Restart terminal, then verify:
java -version
echo $env:JAVA_HOMEThe Microsoft OpenJDK package sets JAVA_HOME automatically. If ./gradlew still reports JAVA_HOME is not set and no 'java' command could be found, set it manually (point it at your JDK install — typically under C:\Program Files\Microsoft\) and restart the terminal:
[Environment]::SetEnvironmentVariable("JAVA_HOME", "C:\Program Files\Microsoft\jdk-21.0.x.x-hotspot", "User")make test runs the Python client test suite, which needs Python 3.
winget install Python.Python.3.12Restart terminal, then verify:
python --version
pip --versionwinget install Anthropic.ClaudeCodegit config --global user.name "Your Name"
git config --global user.email "you@example.com"
git config --global core.autocrlf inputmkdir C:\Projects
cd C:\Projects
git clone https://github.com/VibiumDev/vibium.git
cd vibiumNow that you know which repo you're working with, create a PAT scoped to it.
In a browser (on host or VM — wherever you're logged into GitHub):
- GitHub → Settings → Developer settings
- Personal access tokens → Fine-grained tokens
- Generate new token
Token settings:
- Token name:
windows-vm(or whatever identifies this VM) - Expiration: 7 days (or 30 if you hate rotating)
- Resource owner: your username
- Repository access: Only select repositories
- Team members: select
VibiumDev/vibium - External contributors: select
yourusername/vibium(your fork)
- Team members: select
Permissions:
- Contents: Read and write
- Issues: Read and write
- Metadata: Read-only (required, auto-selected)
- Pull requests: Read and write
- Everything else: No access
Click "Generate token" and copy it (you won't see it again).
Browser auth gives full account access. A fine-grained PAT limits blast radius:
- Scoped to specific repos
- Expires automatically
- Contained inside the VM
gh auth loginFollow the prompts:
- Account: GitHub.com
- Protocol: HTTPS
- Authenticate: Paste an authentication token
Paste your PAT when prompted. Credentials are stored automatically.
Verify it worked:
gh auth statusWith the External Switch, the VM has a LAN IP accessible from any machine on your network.
ssh yourusername@<vm-ip>- Install Zed: https://zed.dev
- Open Zed
Ctrl+Shift+P→ "remote projects: Open Remote Project"- Enter:
yourusername@<vm-ip> - Navigate to
C:\Projects\vibium
cd C:\Projects\vibium
make build
make testTo verify manually:
.\clicker\bin\vibium.exe --version
.\clicker\bin\vibium.exe pathsTake VM checkpoints before risky operations:
- Open Hyper-V Manager
- Right-click VM → Checkpoint
- Name it (e.g., "Fresh dev setup")
To restore:
- Right-click checkpoint → Apply
- Or right-click → Revert to restore to most recent
Windows has a 260-character path limit by default. Enable long paths:
# Run as Administrator
New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem" -Name "LongPathsEnabled" -Value 1 -PropertyType DWORD -ForceIf you're coming from Mac/Linux, PowerShell's default keybindings will feel wrong. This gives you familiar shortcuts (Ctrl+A, Ctrl+E, Ctrl+K, etc.):
Set-PSReadLineOption -EditMode EmacsTo make it permanent, add it to your PowerShell profile:
Add-Content $PROFILE "Set-PSReadLineOption -EditMode Emacs"Defender can slow down builds. Add exclusions:
- Windows Security → Virus & threat protection → Manage settings
- Exclusions → Add or remove exclusions
- Add folder:
C:\Projects - Add folder:
C:\Users\<you>\go