CI/CD Runners

The core scenario: replace bare-metal runners with cloned VMs. Get 2x capacity on the same hardware, with ephemeral runners that reset after each job.

github-actions-setup.sh
# Create a base image once, clone it for every runner
$ spook create base --from-ipsw latest --cpu 4 --memory 8
$ spook clone base runner-01
$ spook clone base runner-02
 
# Ephemeral runners reset when the job completes
$ spook start runner-01 --headless --ephemeral \
--provision ssh --template github-runner \
--var repo=org/app --var token=$GH_TOKEN
✓ runner-01 registered with GitHub Actions
Shipped

GitHub Actions Runner Template

Built-in template generates a complete runner registration script. Pass repo and token as variables. Supports labels and ephemeral mode.

View source →
Shipped

Clone in 48ms

FileManager.copyItem triggers APFS clonefile(2). Zero-byte delta clones in ~48ms. No disk copy, no image registry required.

View source →
Shipped

Ephemeral Runners

The --ephemeral flag on start automatically destroys the VM when it stops. Perfect for single-use CI runners that guarantee a clean environment.

View source →
Shipped

SSH Provisioning

Wait-for-SSH with configurable timeout, then execute scripts with streaming output. Works with any user-data script format.

View source →
Shipped

Disk-Inject Provisioning

Zero-network provisioning. Injects a LaunchDaemon and script directly into the VM disk image before boot. No SSH, no network required.

View source →
Shipped

MachineIdentifier Regeneration

Each clone gets a unique hardware identifier. Avoids conflicts when multiple clones run on the same host or register with the same CI service.

View source →
Shipped

Disk Snapshots

Save, restore, list, and delete snapshots per VM. Snapshot before installing Xcode, restore if something breaks. Instant rollback.

View source →
Planned

BuildKite / CircleCI Templates

Runner registration templates for BuildKite and CircleCI. On the roadmap, not yet shipped.

View Roadmap →

Remote Desktop

Give every developer a personal macOS desktop in a VM. Built-in template enables Screen Sharing, and the auto-resize display tracks your window size.

Shipped

Remote Desktop Template

Built-in template generates a script that enables Screen Sharing (VNC) on the guest. One command to create a remote desktop VM.

View source →
Shipped

Metal GPU Acceleration

1-2 Metal GPU-accelerated displays per VM at 1920x1200 resolution. Hardware-accelerated rendering for a responsive desktop experience.

View source →
Shipped

Auto-Resize Display

Display resolution automatically adjusts when you resize the VM window. Requires macOS 14+ on the host.

View source →
Shipped

Audio Output + Microphone

Full audio passthrough including microphone input. Video calls and audio playback work inside the VM.

View source →
Shipped

VirtIO Shared Folders

Mount host directories inside the VM. Share project files, build artifacts, datasets between host and guest without network.

View source →
Shipped

Full Accessibility

VoiceOver labels, hints, and identifiers on every control. Accessibility announcements for state changes. Reduce motion support.

View source →

ML Workloads

Run ML training and inference workloads in isolated VMs with Metal GPU performance, shared folders for datasets, and network isolation.

Shipped

Metal GPU Acceleration

Up to 2 Metal GPU-accelerated displays per VM at 1920x1200. GPU compute is available to guest workloads through the virtualization layer.

View source →
Shipped

Shared Folders for Datasets

Mount host directories in the VM via VirtIO. Load training data from the host filesystem without copying into the VM image.

View source →
Shipped

Isolated Networking

Air-gapped VMs with zero network access. Run untrusted models or experiments in complete network isolation.

View source →
Shipped

OpenClaw AI Template

Built-in template for OpenClaw AI workloads. Generates a provisioning script tailored for ML environments.

View source →

DevOps Automation

Full VM lifecycle management. LaunchDaemon services, PID tracking, capacity enforcement, and machine state save/restore.

automation.sh
# Register as a LaunchDaemon service (survives reboots)
$ spook service install runner-01
✓ LaunchDaemon installed: com.spooktacular.runner-01
 
# Save machine state (macOS 14+)
$ spook stop runner-01 --save-state
✓ Machine state saved, VM paused
 
# Resolve VM IP for SSH access
$ spook ip runner-01
192.168.64.3
Shipped

Full VM Lifecycle

Start, stop, pause, and resume VMs programmatically. Save and restore machine state on macOS 14+ for instant resume.

View source →
Shipped

Per-VM LaunchDaemon Service

Register any VM as a macOS LaunchDaemon. Automatically starts on boot, restarts on failure. Full lifecycle management.

View source →
Shipped

PID File Tracking

Every running VM writes a PID file. Enables safe process management, prevents duplicate starts, and supports external monitoring.

View source →
Shipped

2-VM Capacity Enforcement

Apple limits 2 concurrent macOS VMs per host. Spooktacular enforces this at the API level to prevent capacity errors.

View source →
Shipped

IP Resolution

Resolve VM IP addresses via DHCP leases with ARP fallback. Enables dynamic SSH connections without hardcoded addresses.

View source →
Shipped

IPSW Restore Image Manager

Auto-download the latest compatible macOS restore image. No manual IPSW hunting. Manages a local image library.

View source →
Shipped

Unattended Setup Assistant

Keyboard driver automates macOS Setup Assistant on 15+. Create a VM, install the OS, complete setup, and provision in one command.

View source →
Shipped

VirtIO Socket Provisioning

Host-side VirtIO socket provisioner. Communicates with the guest agent over vsock for zero-network provisioning.

View source →
Shipped

Guest Agent

VirtIO socket daemon that runs inside the guest VM. Receives provisioning commands from the host over vsock.

View source →

Guest Agent

A lightweight daemon running inside the guest VM, exposing 12 HTTP endpoints over VirtIO socket. Clipboard sync, remote command execution, app control, file transfer, port discovery, and health monitoring -- all without SSH or network access.

remote-control.sh
# Execute a command inside the VM
$ spook remote exec my-vm -- "pbcopy <<< 'hello world'"
✓ Exit code: 0
 
# Check VM health
$ spook remote health runner-01
✓ Agent v1.0.0 — uptime 4h32m
 
# List running applications
$ spook remote apps runner-01
Xcode (16.3) Finder Terminal Safari
Shipped

12 HTTP Endpoints over vsock

Full REST API running inside the guest over VirtIO socket. Clipboard, exec, apps, files, ports, and health endpoints. No SSH or network required.

View source →
Shipped

Clipboard Sync

Read and write the guest clipboard from the host. Copy text into or out of the VM without screen sharing or VNC.

View source →
Shipped

Remote Exec

Execute arbitrary commands inside the guest VM and stream output back to the host. Works over vsock -- no SSH keys or network configuration needed.

View source →
Shipped

App Control

List running applications inside the guest, launch new apps, and query app state. Enables automation without a display connection.

View source →
Shipped

File Transfer

Transfer files between host and guest over the vsock channel. Upload build artifacts, download logs, or inject configuration files.

View source →
Shipped

Port Discovery & Health

Discover listening ports inside the guest and monitor agent health. Enables service discovery without network scanning.

View source →
Shipped

GuestAgentClient Actor

Swift actor in SpooktacularKit for type-safe communication with the guest agent. Async/await API for all 12 endpoints.

View source →
Shipped

spook remote CLI

Dedicated CLI command group for guest agent interaction: exec, clipboard, apps, health, and ports subcommands.

View source →

HTTP API & Kubernetes

Control everything over REST. 9 endpoints for VM lifecycle, 15+ CLI commands, native SwiftUI GUI, and a Kubernetes operator.

api-examples.sh
# Start the HTTP API server
$ spook serve --port 8080
 
# List all VMs
$ curl http://localhost:8080/vms
 
# Create a VM via the API
$ curl -X POST http://localhost:8080/vms/runner-01/start
 
# Kubernetes: kubectl apply -f vm.yaml
$ kubectl get macosvm
NAME STATE AGE
runner-01 Running 2m
Shipped

HTTP REST API

9 REST endpoints built on Network.framework with Codable request/response types. Control VM lifecycle from any language or CI system.

View source →
Shipped

15+ CLI Commands

Create, clone, start, stop, pause, resume, delete, list, get, ip, ssh, exec, snapshot, service, set, share, serve, and remote. 25+ including subcommands.

View source →
Shipped

SwiftUI GUI

Native macOS app with NavigationSplitView, inspector panel, and VM creation sheet. Liquid Glass support on macOS 26+.

View source →
Shipped

Menu Bar Extra

Persistent menu bar icon for quick VM status checks and actions without opening the full app.

View source →
Shipped

Full DocC API Reference

Complete API documentation generated from source. Browse types, methods, and articles in the hosted DocC archive.

View API Docs →
Shipped

Kubernetes Operator

kubectl apply -f vm.yaml creates macOS VMs. MacOSVM CRD with full spec/status, Helm chart, Swift controller that reconciles via the HTTP API on Mac nodes.

View source →
Planned

OCI Registry Push/Pull

Push and pull VM images to/from OCI-compliant container registries. On the roadmap, not yet shipped.

View Roadmap →

424 tests across 53 suites

Every feature is tested. Every claim is backed by code. Audit the source yourself.

Get Started View on GitHub