@beamhop/cli
v0.1.0
Published
lbx — single-binary CLI for @beamhop/lightbox: build microsandbox snapshots and launch sandboxes from them.
Maintainers
Readme
@beamhop/cli
lbx — command-line interface for the @beamhop/lightbox library.
Ships as a single self-contained binary. The napi-rs addon, the msb
host runtime, and libkrunfw are all embedded — users download one file,
chmod +x, run.
Wraps the same API: build microsandbox snapshots from a declarative config, launch sandboxes from them, list/remove them.
Install
Pre-built binary (recommended)
Grab the binary for your platform from packages/cli/dist/ (or release page):
| Platform | Binary |
|----------|--------|
| macOS (Apple Silicon) | lbx-darwin-arm64 (~113 MB) |
| Linux x86_64 (glibc) | lbx-linux-x64 (~161 MB) |
| Linux ARM64 (glibc) | lbx-linux-arm64 (~154 MB) |
curl -L -o /usr/local/bin/lbx https://.../lbx-$(uname -s | tr A-Z a-z)-$(uname -m)
chmod +x /usr/local/bin/lbx
lbx --versionFirst call extracts msb + libkrunfw into ~/.microsandbox/ automatically.
From source
From the repo root:
bun install
bun run --cwd packages/cli src/lbx.ts <command>Building binaries
The CLI is cross-compiled with bun build --compile. From the CLI package:
bun run build:bin # all three platforms → dist/
bun run build:darwin # macOS arm64 only
bun run build:linux-x64
bun run build:linux-arm64Each binary embeds:
- the napi-rs
.nodeaddon for that platform - the matching
msbhost binary - the matching
libkrunfw
so the user needs nothing on their machine besides the binary itself.
Quick start
Drop a lightbox.config.ts next to where you'll run lbx:
// lightbox.config.ts
import { codingAgentsPreset } from "@beamhop/lightbox/presets";
import { defineSnapshot } from "@beamhop/lightbox";
export default [
// The default preset — installs copilot/gemini/codex/pi on oven/bun.
codingAgentsPreset({ name: "lightbox" }),
// ...add as many custom snapshots as you like.
defineSnapshot({
name: "py-data",
image: "python:3.12",
setup: [{ kind: "shell", script: "pip install -q numpy pandas" }],
}),
];Then:
lbx build lightbox # build the "lightbox" snapshot
lbx launch lightbox a1 # boot a sandbox named "a1" from it
lbx ls # see what's there
lbx rm a1 # tear it downCommands
lbx build [name] [flags]
Build a snapshot. With a config file, [name] selects which snapshot. Flags
always override the config; pass --image to build something ad-hoc without
a config file (or to build a name not declared in the config).
| Flag | Notes |
|------|-------|
| -c, --config <path> | Config file path (default: auto-detect) |
| -i, --image <ref> | Base image — required for ad-hoc builds |
| --cpus <n> | Builder VM cpus |
| -m, --memory <size> | "1G", "512M", or raw MiB |
| --workdir <path> | Default cwd for setup steps |
| --label k=v | Snapshot label, repeatable |
| --step <script> | Extra shell setup step, repeatable, appended after config steps |
| --env k=v | Builder env var, repeatable |
| -f, --force | Overwrite existing snapshot |
| --keep-builder | Leave the builder VM around for debugging |
| -q, --quiet | Suppress streaming output |
Examples:
lbx build # only snapshot in config — implicit
lbx build py-data # named snapshot from config
lbx build py-data -f # overwrite
lbx build adhoc --image alpine \
--step "apk add curl" -f # no config neededlbx launch <snapshot> <name> [flags]
Boot a sandbox from a snapshot. Detached by default — survives the CLI's
exit. Use --attached to tie its lifetime to the CLI process.
| Flag | Notes |
|------|-------|
| --cpus <n> | vCPUs |
| -m, --memory <size> | Memory |
| --workdir <path> | Working dir (must exist in snapshot) |
| --env k=v | Repeatable |
| -p, --port host:guest | Repeatable |
| --replace | Replace existing sandbox of same name |
| --attached | Stop when CLI exits (default: detached) |
lbx ls [flags]
Two-section table of snapshots + sandboxes.
| Flag | Notes |
|------|-------|
| --snapshots | Only snapshots |
| --sandboxes | Only sandboxes |
| --json | JSON output |
lbx rm <name> [flags]
Auto-detects whether <name> is a snapshot or sandbox.
| Flag | Notes |
|------|-------|
| --snapshot | Force snapshot interpretation |
| --sandbox | Force sandbox interpretation |
| -f, --force | Default: true. Pass --no-force for soft removal. |
Config file resolution
The CLI looks for, in order:
--config <path>if supplied./lightbox.config.ts./lightbox.config.js./lightbox.config.mjs
The module may export a SnapshotConfig, an array of them, or
{ snapshots: ... }. Use defineSnapshot() for type-safe authoring.
Exit codes
| Code | Meaning | |------|---------| | 0 | success | | 1 | command failed (error message printed to stderr) | | 2 | unknown command |
