v0.8.0
What's New
Port Forwarding
Expose guest VM ports to the host for health checks, API testing, or service validation:
result = await scheduler.run(
code="import http.server; http.server.test(port=8080)",
language=Language.PYTHON,
expose_ports=[PortMapping(internal=8080, external=3000)],
)
print(result.exposed_ports[0].url) # http://127.0.0.1:3000CLI: sbx run --expose 8080:3000 'code'. Works independently of internet access — when allow_network=False, guests cannot initiate outbound but host-to-guest forwarding still works.
Automatic Boot Retry
VMs automatically retry on transient failures (CPU contention, resource pressure) with exponential backoff and jitter. timing.boot_retries reports retry count.
Two-Stage Ctrl+C Handling
- First Ctrl+C: cancels execution, allows cleanup (
__aexit__) to run - Second Ctrl+C: force kills all tracked VM process groups immediately
QEMU Stream Reconnect
Version-appropriate reconnect for transient gvproxy disconnections: reconnect-ms=250 (QEMU 9.2+), reconnect=1 (8.0-9.1).
Performance
- Initramfs zstd — Switch from LZ4 to zstd compression, strip debug symbols, uncompressed module extraction (~34% smaller)
Architecture
- VM Manager split — Monolithic
vm_manager.py(2400+ lines) refactored intoqemu_cmd.py,qemu_vm.py,system_probes.py,gvproxy.py, plusprocess_registry.pyandvalidation.py - Exception hierarchy — New
TransientError/PermanentErrorclassification for intelligent retry (e.g.VmBootTimeoutErroris transient,VmConfigErroris permanent) - System probes —
_async_cached_probedecorator for stampede-safe capability caching, QEMU version detection for feature gating
Bug Fixes
- Frozen VM detection via process state instead of socket timeouts
- Guest agent verifies gvproxy gateway reachability before package install
- Handle QEMU exit code 0 during snapshot creation
- Verify guest-agent architecture matches target before qcow2 embedding
- Prevent orphaned asyncio tasks and event loop cleanup warnings (Python 3.14 compatible)
- VM concurrency semaphore now lifecycle-bound (released on destroy, not on boot failure)
- Close parent socket after gvproxy readiness confirmation
Full Changelog: v0.7.0...v0.8.0