Current Interface Surface
Local (no HTTP daemon): voidbox run --file … executes a spec in-process on the host. Validation, inspection, snapshot file management, and config also run locally.
Daemon: voidbox serve starts the HTTP API (default bind 127.0.0.1:43100). Remote-only commands status, logs, and tui talk to that server. Set VOIDBOX_DAEMON_URL or use --daemon to override the default http://127.0.0.1:43100.
The TUI is an interactive client over the same HTTP API as those remote commands.
CLI — local commands
These do not require voidbox serve.
| Command | Description |
|---|---|
voidbox run --file <spec> | Run a spec (agent, pipeline, or workflow) in-process. Optional --input. Output respects global --output (human or JSON). |
voidbox validate --file <spec> | Validate a spec without executing it. |
voidbox inspect --file <spec> | Validate and print resolved sandbox-related configuration. |
voidbox skills --file <spec> | List skills declared in the spec. |
voidbox snapshot create --kernel <path> | Create a base snapshot after a cold boot (optional --initramfs, --memory, --vcpus; --diff for a delta on top of an existing base). Configuration hash is derived from kernel/initramfs/memory/vcpus — there is no --config-hash flag. |
voidbox snapshot list | List stored snapshots (hash prefixes and metadata). |
voidbox snapshot delete <hash-prefix> | Delete a snapshot by hash prefix. |
voidbox config init | Write a template config to ~/.config/voidbox/config.yaml (XDG paths apply). |
voidbox config validate | Validate and print the merged CLI configuration. |
voidbox version | Print version information. |
voidbox exec … | Legacy sandbox exec (deprecated); prefer voidbox run --file …. |
CLI — interactive shell
voidbox shell boots a micro-VM and attaches an interactive PTY session — like SSH into a sandboxed environment. It auto-detects LLM credentials, stages them into the guest, and opens a raw terminal session over vsock.
| Command | Description |
|---|---|
voidbox shell | Boot a VM with defaults and attach an interactive PTY. Auto-detects claude-personal (OAuth) or claude (API key). |
voidbox shell --file <spec> | Use a YAML spec for shell-oriented settings the shell path actually consumes: kernel/initramfs, memory, vCPUs, network, mounts, env, and snapshot. It does not currently resolve sandbox.image or sandbox.guest_image. |
voidbox shell --program <name> | Program to run in the PTY (default: claude). Must be in the guest allowlist. |
voidbox shell --mount HOST:GUEST[:ro|rw] | Mount a host directory into the guest. Repeatable. |
voidbox shell --memory-mb <N> | Guest memory in MB (default: 1024). |
voidbox shell --vcpus <N> | Number of vCPUs (default: 2). |
voidbox shell --network | Enable guest networking (SLIRP on Linux/KVM, NAT on macOS/VZ; default: true). |
voidbox shell --snapshot <hash|path> | Restore from a snapshot instead of cold boot. |
voidbox shell --provider <name> | Override Claude shell auth mode. Supported values today: claude, claude-personal. |
voidbox shell --env KEY=VALUE | Set guest environment variable. Repeatable. |
voidbox attach --run-id <id> | Attach PTY to a running VM via the daemon. (Not yet implemented.) |
Examples:
# Interactive shell (bare sh)
voidbox shell --program sh --memory-mb 512
# Claude Code with mounted workspace
voidbox shell \
--mount $(pwd):/workspace:rw \
--program claude \
--memory-mb 3024 \
--vcpus 4 \
--network
Security: Interactive PTY sessions preserve the VM boundary, session secret auth, command allowlist, privilege drop to uid:1000, and backend-specific guest networking controls. The only relaxation: RLIMIT_FSIZE is not enforced for interactive sessions, since tools like Claude Code write large conversation logs.
PTY sessions: Up to 4 concurrent PTY sessions per VM. Each session is a separate forkpty child process.
CLI — daemon and remote-only commands
Start the server with voidbox serve (optional --listen, default 127.0.0.1:43100). Then:
| Command | Description |
|---|---|
voidbox status --run-id <id> | Fetch JSON status for one run. Optional --daemon <url>. |
voidbox logs --run-id <id> | Fetch the run’s events payload as JSON (single HTTP GET). Optional --daemon. For live updates, poll the API or use a client that reads /v1/runs/:id/events repeatedly. |
voidbox tui | Interactive TUI; optional --file to start a run via the daemon, --session, --daemon, --logo-ascii. |
Global options and configuration
On any subcommand: --output human|json, --no-banner, --log-level (or env VOIDBOX_LOG_LEVEL). Log level and paths also merge from ~/.config/voidbox/config.yaml, /etc/voidbox/config.yaml, and VOIDBOX_CONFIG; see voidbox config validate.
Daemon API Endpoints
The daemon exposes JSON over HTTP. Default base URL http://127.0.0.1:43100. Selected routes:
| Method | Path | Description |
|---|---|---|
GET | /v1/health | Health check and persistence backend name. |
POST | /v1/runs | Create a run. JSON body includes file, optional input, snapshot, etc. Returns run_id. |
GET | /v1/runs | List runs. Optional query ?state=active or terminal. |
GET | /v1/runs/:id | Get run status and metadata. |
GET | /v1/runs/:id/events | Get run events as a JSON array (optional query from_event_id). |
POST | /v1/runs/:id/cancel | Cancel a run. |
POST | /v1/sessions/:id/messages | Append a session message. |
GET | /v1/sessions/:id/messages | Get session message history. |
Additional routes include run stages, telemetry, and stage output files under /v1/runs/… — see the daemon implementation in the repository.
TUI Commands
The TUI provides an interactive command prompt connected to the daemon. Available commands:
| Command | Description |
|---|---|
/run <file> | Start a new run from a spec file path. |
/input <text> | Stage input text for the next /run. It does not send input into a live session. |
/status | Show JSON status for the current run, if one has been started in this TUI session. |
/logs | Fetch the current run’s event payload as JSON. |
/cancel | Cancel the current run. |
/history | Show persisted message history for the current TUI session. |
Known UX Gap
Minimal but Functional
The current TUI is functional but minimal: polling-oriented and plain text. A richer panel-based, live-streaming UX is planned and can be layered on top of the existing /v1/runs/:id/events JSON APIs without changes to the daemon.