Boot a Linux VM, run a command, collect structured JSON. Sessions exec in ~31ms, cold boots land in ~390ms P50 on an M3 Pro, and the sandbox is sealed by default — no host fs, no SSH, no escape hatch. Built for the agent loop. v0.7.1 hardens desktop boot — stable MAC across reboots, cancel-safe retry, pre-start crash delegate, live serial tail when the framebuffer's still dark.
curl -fsSL abdul-abdi.github.io/lumina/install.sh | sh
macOS 14+ Apple Silicon Built on the native Virtualization framework. Linux host support on the roadmap.
q to exit · ? for keys
—
# boot, run, tear down. zero state. $ lumina run "uname -a" { "stdout": "Linux lumina 6.12-virt …\n", "stderr": "", "exit_code": 0, "duration_ms": 542 }
$ SID=$(lumina session start --memory 4GB \ --forward 3000:3000 | jq -r '.sid') $ lumina cp ./project/ "$SID:/work/" $ lumina exec "$SID" --workdir /work "npm ci" $ lumina exec --pty "$SID" "claude" # many execs in parallel, ~30ms each. # terminal restores on SIGINT — handled for you.
Two clicks from cold-launch to a booting Ubuntu installer. Sealed
guest disk under ~/.lumina/desktop-vms/,
shared with the CLI. Spin up, use, dispose — same primitive, with
a screen.
lumina desktop create v0.7.1lumina images create builds, one-click Terminal v0.7.1lumina desktop create --os-variant ubuntu-24.04 --iso ./*.iso
▷ CLI ↔ App share state · open the .app or stay in the terminal
lumina runone-shotDisposable VM. Boots, runs, tears down. Per-invocation flags only — provisioning goes on session start.
session startpersistentSpawns a long-lived VM. Returns a UUID-form SID. Provisioning belongs here, not on exec.
exec <sid>~30msFresh shell per invocation. Multiple execs run in parallel on one session. No state persists.
cptransferExplicit direction. Whichever side starts with <sid>: is the VM. Use this over virtio-fs for writes.
pslistingLive sessions. Piped output is JSON. Stale sockets surface as unreachable.
desktop createv0.7.0Make a .luminaVM bundle for a full-OS guest. Stages an installer ISO; ARM64 pre-flight rejects x86.
desktop bootv0.7.0Boot a .luminaVM bundle through EFI. Headless or windowed. macOS guests via desktop install-macos + IPSW.
exec --ptyraw bytesInteractive TTY. Separate protocol from exec — raw byte stream, not envelope. For isatty() apps.
When stdout is a pipe, every run and exec emits a single JSON object.
Success and error are disjoint — dispatch on the presence of the error field first.
A non-zero exit_code is a successful exec, not an error.
{
"stdout": "hello\n",
"stderr": "",
"exit_code": 0,
"duration_ms": 31
}
{
"error": "timeout",
"duration_ms": 30012,
"partial_stdout": "starting…\n",
"partial_stderr": ""
}
timeout--timeout. partial_* present.vm_crashedpartial_* present.session stop & restart.connection_failedpartial_*.session_disconnectedexec, never run.truetrue round-trip. 1ms stdev.Claude Code, Cursor, OpenDevin — any agent running untrusted shell commands. One session, thousands of execs, full teardown when done. The session is the tab.
Per-job VM, no cross-contamination between builds, exact resource ceiling. Fast enough to replace docker run in the hot path.
Run code from users, plugins, or model output. Sealed guest — no host filesystem. --forward only binds 127.0.0.1. Audit via lumina ps.
$ curl -fsSL \ abdul-abdi.github.io/lumina/install.sh | sh
One-liner installer fetches the signed CLI binary from the latest GitHub release and drops it in ~/.local/bin. macOS 14+ on Apple Silicon.
$ lumina run \ "echo hello from a VM"
Auto-pulls the default image (~30 MB) from GitHub Releases the first time. After that, every run gets a fresh APFS COW clone — no state crosses.
$ lumina session start \
--memory 4GB
Captures the SID. Pipe to jq -r '.sid' and drive it from your agent.
— LUMINA_OUTPUT=ndjson opt-in remains for legacy consumers until v0.8.0 —