
VM Lab
FreeAutomate GUI testing in macOS VMs with precision.
Free · Opens the source repo
What VM Lab does
VM Lab is a specialized tool designed for developers and testers who need to perform GUI automation and validation within macOS virtual machines (VMs). By leveraging Parallels, this skill allows users to run applications in a clean VM environment while simultaneously verifying actions and outputs from the host system. This two-way validation approach ensures that tests are not only executed but also accurately verified, making it essential for tasks involving TCC prompts, screenshot captures, and performance assessments.
The core functionality of VM Lab revolves around executing commands within the VM and capturing screenshots or other outputs from the host. Users can list available VMs, check their status, and run guest commands seamlessly. The skill emphasizes a disposable approach to VM snapshots, ensuring that the host system remains unaffected by the testing process. It also provides guidelines for safely handling sensitive data and maintaining a clean testing environment.
With VM Lab, developers can automate the testing of applications like Peekaboo, ensuring that GUI interactions are validated through both internal and external signals. This includes capturing screenshots for comparison, checking application states, and validating outputs. The skill is particularly useful for those who require a reliable method to test macOS applications without risking the integrity of the host environment.
In summary, VM Lab is an essential tool for anyone involved in macOS application development or testing, providing a robust framework for GUI automation and validation that prioritizes safety and accuracy.
When to use it
Use VM Lab when you need to automate GUI testing in a macOS VM and require reliable verification of the results from the host.
When not to use it
Avoid using VM Lab for non-macOS environments or when GUI automation is not a primary requirement, as it is specifically tailored for macOS VMs.
What you can build with it
Automating GUI Tests for Peekaboo
Use VM Lab to run automated tests for the Peekaboo application, capturing screenshots and validating outputs.
Testing TCC Prompts
Leverage VM Lab to validate TCC prompts by executing commands in a VM and verifying permissions from the host.
Performance Benchmarking
Utilize VM Lab to benchmark application performance by running tests in a VM and capturing metrics for analysis.
How to install VM Lab
View source1. Install with the skills CLI
npx skills add steipete/agent-scripts/vm-lab --agent claude-code2. Or install it manually
Download the skill folder and drop it into ~/.claude/skills/ for all projects, or .claude/skills/ to scope it to one repo. Restart Claude Code so it picks up the new skill.
Anthropic's agentic coding CLI, and the reference implementation of Agent Skills. Drop a skill folder into ~/.claude/skills and Claude Code loads it automatically whenever a task matches the skill's description. Claude Code docs
Inside SKILL.md
Written by steipeteVM Lab
Use this when the task needs a clean macOS VM to test GUI automation, TCC prompts, screenshot capture, clicking, typing, performance, or "two-way validation" of Peekaboo-like tools.
Core idea: run the tool under test inside the guest, but verify it from outside the guest with Parallels screenshots and host-side observations. Do not close apps you do not own.
Safety Rules
- Treat the VM snapshot as disposable, not the host.
- Never print secrets. If
opis needed, follow the 1Password skill and run it only insidetmux. - Prefer fresh app windows you create yourself: TextEdit, a local HTML test page, or a small test app.
- Avoid modifying host state except temporary screenshots under
/tmp. - For git repos inside the VM, use HTTPS remotes and normal branch discipline.
VM Discovery
List VMs:
prlctl list --all
Get VM status/IP:
prlctl list --info "macOS Tahoe"
Run guest commands as Peter:
prlctl exec "macOS Tahoe" \
'sudo -u steipete -H /bin/zsh -lc '\''source ~/.zprofile 2>/dev/null || true; uname -a'\'''
Capture an independent host-side screenshot:
prlctl capture "macOS Tahoe" --file /tmp/vm-reference.png
sips -g pixelWidth -g pixelHeight /tmp/vm-reference.png
TCC / GUI Attribution
For macOS Screen Recording and Accessibility, the responsible process matters.
prlctl execis headless and can fail to produce useful Screen Recording attribution.- Launch the test command from a visible terminal app in the guest when Screen Recording is involved.
- Ghostty works as a GUI terminal if installed.
- After a first failed capture, check
System Settings > Privacy & Security > Screen & System Audio Recording. permissions statusrun throughprlctl execmay still report Screen Recording false after Ghostty is allowed; validate Screen Recording by rerunning the capture from Ghostty.
Open the Screen Recording pane:
prlctl exec "macOS Tahoe" \
'sudo -u steipete -H open "x-apple.systempreferences:com.apple.preference.security?Privacy_ScreenCapture"'
Open Ghostty:
prlctl exec "macOS Tahoe" 'sudo -u steipete -H open -a Ghostty'
Running Commands Through Ghostty
Best path: create a guest script with prlctl exec, open/focus Ghostty, then type only a short launcher path into the visible terminal.
Guest script pattern:
prlctl exec "macOS Tahoe" 'sudo -u steipete -H /bin/zsh -lc '\''cat > /tmp/run-vm-lab.zsh <<EOF
#!/bin/zsh
source ~/.zprofile 2>/dev/null || true
cd ~/Projects/Peekaboo || exit 1
Apps/CLI/.build/debug/peekaboo image --path /tmp/peekaboo-vm.png --json
rc=$?
echo "EXIT:$rc"
[ -f /tmp/peekaboo-vm.png ] && sips -g pixelWidth -g pixelHeight /tmp/peekaboo-vm.png
echo "Press return to close..."
read _
exit $rc
EOF
chmod +x /tmp/run-vm-lab.zsh
ln -sf /tmp/run-vm-lab.zsh /tmp/r
open -a Ghostty'\'''
Then link the launcher into Ghostty's home directory and type ./r with scripts/parallels_type.py. This avoids unreliable path characters in Parallels key injection.
prlctl exec "macOS Tahoe" \
"sudo -u steipete -H /bin/zsh -lc 'ln -sf /tmp/run-vm-lab.zsh ~/r'"
python3 skills/vm-lab/scripts/parallels_type.py "macOS Tahoe" $'./r\n'
Avoid long command typing. Parallels key injection uses its own key-code table and can be layout-sensitive.
Known Pitfalls
- macOS clipboard APIs may fail from
prlctl exec;pbcopy, AppleScript clipboard, and Peekaboo paste can all fail in headless guest context. open -na Ghostty.app --args -e ...may only focus an existing Ghostty window on macOS; do not assume it runs the command.prlctl execmay re-join argv through a guest shell; for complex payloads, pass one fully shell-quoted command string or create the file with a tiny Python writer.- Parallels
send-key-event --keyuses Parallels key values, not macOS virtual key codes. - For normal typing, send
prlctl send-key-event <vm> --key <key>with no--event; explicitpress/releasecan repeat or stick. Return is an exception: use press then release. - Prefer one
prlctl send-key-event --jsonbatch over many separatesend-key-eventprocesses; separate calls can drift under focus/latency. - Use
PRL_KEY_ENTER = 36,PRL_KEY_SLASH = 61,PRL_KEY_R = 27,PRL_KEY_T = 28,PRL_KEY_M = 58,PRL_KEY_P = 33. - If keystrokes produce garbage, send Return to clear the line, create a shorter launcher, then retry.
- If Peekaboo permission probes hang with Screen Recording missing and emit
SWIFT TASK CONTINUATION MISUSE, record it as a product bug; do not confuse it with the VM harness.
Two-Way Validation
For each GUI action, verify through two independent signals:
- Tool-under-test output: JSON, screenshot file, AX result, or app state.
- External verifier:
prlctl capture, host-side image inspection, file content in guest, or process/window state.
Examples:
- Screenshot: compare Peekaboo image dimensions/content against
prlctl capture. - Click: use Peekaboo to click a test button, then verify both guest app state and host screenshot.
- Type: use Peekaboo to type into a controlled text field, then verify AX value and host screenshot.
- Performance: wrap commands with
/usr/bin/time -p; repeat cold/warm runs; keep outputs in/tmp.
Peekaboo VM Baseline
Inside guest:
cd ~/Projects/Peekaboo
git pull --recurse-submodules
swift build --package-path Apps/CLI
Apps/CLI/.build/debug/peekaboo --version
Apps/CLI/.build/debug/peekaboo permissions status --json
Host-side reference capture:
prlctl capture "macOS Tahoe" --file /tmp/vm-prlctl-reference.png
Guest-side Peekaboo capture through Ghostty:
/tmp/r
Compare:
prlctl exec "macOS Tahoe" \
'sudo -u steipete -H /bin/zsh -lc '\''sips -g pixelWidth -g pixelHeight /tmp/peekaboo-vm.png'\'''
sips -g pixelWidth -g pixelHeight /tmp/vm-prlctl-reference.png
Reporting
When handing off, include only:
- VM name and OS build.
- repo commit tested.
- permission state.
- commands that passed/failed.
- independent verifier result.
- product bugs discovered.
Frequently asked questions about VM Lab
Similar skills
Spring Boot Testing
Master testing techniques for Spring Boot 4 applications.
GitHub Issues
Manage GitHub issues efficiently with MCP tools.
Geofeed Tuner
Optimize your IP geolocation feeds in CSV format.
Batch Files
Master Windows batch scripting for automation and task management.
Adobe Illustrator Scripting
Automate your Illustrator workflows with ExtendScript.
Plugin Structure
Create and organize Claude Code plugins effectively.
