User feedback: re-checking the registry on every launch (PullPolicy:: Always) made fast launches feel surprising — when there *was* a new image, the next innocuous `agent-vm shell` blew up into a multi-minute pull. Move pulls onto an explicit `agent-vm pull` verb and just notify on launch when the registry has something newer. - pull.rs: new `agent-vm pull` subcommand. Image::remove(force=true) the cached entry first (PullPolicy::Always empirically re-fetches layer blobs but does NOT update the cached manifest digest record, so subsequent Image::get returns the stale digest forever) then boot a throwaway sandbox to trigger a fresh pull, then stop+remove. - image_check.rs: cheap manifest probe. Compare microsandbox's cached per-platform manifest digest against the registry's. Critical subtlety: microsandbox stores the per-platform (linux/amd64) digest while a HEAD on a tag returns the multi-arch *index* digest. A `docker tag X Y; docker push Y` churns the index digest but reuses the per-platform manifest, so naively comparing the two would warn forever. We GET the index, find the linux/amd64 entry, take its digest, compare that. - run.rs: switch PullPolicy back to IfMissing, call notify_if_update_available before create. Failures (registry down, etc.) are silently swallowed so offline launches still work. - setup.rs: chain an explicit pull_image() call after build.sh so setup itself updates the cache. - Cargo.toml: add reqwest + serde_json. Verified end-to-end: (1) churn list digest only -> no banner. (2) Real Dockerfile change -> "A newer image is available (cached X, registry Y)" banner. (3) After `agent-vm pull` -> banner gone. |
||
|---|---|---|
| crates/agent-vm | ||
| images | ||
| vendor | ||
| .gitignore | ||
| .gitmodules | ||
| ARCHITECTURE.md | ||
| Cargo.lock | ||
| Cargo.toml | ||
| LICENSE | ||
| PLAN.md | ||
| README.md | ||
agent-vm (microsandbox rewrite)
Work-in-progress rewrite of agent-vm
on top of microsandbox. The goal
is sub-second cold-start microVMs for AI coding agents (Claude Code, Codex CLI,
OpenCode) with host-rooted credentials and no in-VM proxy.
This is a long-running rewrite. The current state lives on
rewrite-microsandbox. The original agent-vm continues to live on main
until v1 of the rewrite ships.
Where to look
PLAN.md— phased roadmap, what's in/out of v1.ARCHITECTURE.md— running record of design decisions, filled in as each phase lands.
Status
- Phase 0 (scaffolding): done.
- Phase 1 (base OCI image +
agent-vm setup): done. - Phase 2 (launcher MVP —
claude/codex/opencode/shell): done; live API smoke deferred to Phase 3. - Phase 3 (host-rooted secrets via microsandbox TLS intercept): pending.
Building
git submodule update --init vendor/microsandbox
cargo build -p agent-vm
Building the base image
./target/debug/agent-vm setup # build + verify in a throwaway sandbox
./target/debug/agent-vm setup --no-verify
Requires Docker on the host. A registry:2 container named
agent-vm-registry will be created on first run and bound to
127.0.0.1:5000.
Running an agent
cd your/project
agent-vm claude # or codex / opencode / shell
agent-vm claude -- -p "fix the lint errors" # forward args to the agent
# Smoke / scripted use:
agent-vm shell -- -c 'ls /workspace && claude --version'
The first arg after the subcommand is treated as input to the agent. Use
-- if any forwarded arg starts with - (otherwise clap will try to claim
it). Project state lives in ~/.local/state/agent-vm/<hash>/ and survives
between launches. Phase 2 supports auth via the ANTHROPIC_API_KEY /
OPENAI_API_KEY env vars only; the OAuth-refresh path lands in Phase 3.
Actually running a sandbox requires the microsandbox runtime prerequisites
(Linux with KVM, or macOS Apple Silicon). See microsandbox's
README.