Skip to content

Using barista-cloud

barista-cloud gives you pausable compute sessions: a process running in a sandbox that you can exec into, pause (freezing its memory), and resume (continuing exactly where it froze) — multi-tenant, behind an API key. This is the Barista model: session-centric compute, not web hosting (see architecture.md for why).

Live control plane: https://beta.barista.sh (gateway API + console), co-located with a real hypeman/KVM node.

The CLI

From this repo (until it's published to a package index):

uv run barista --help          # or: python -m barista_cloud.cli --help

Point it at the control plane and log in with an API key:

export BARISTA_URL=https://beta.barista.sh
barista login bk_xxxxxxxx.xxxxxxxxxxxxxxxxxxxx     # saved to ~/.config/barista/key
# or, per-shell: export BARISTA_KEY=bk_xxxxxxxx.xxxxxxxxxxxxxxxxxxxx

Get a key from the console (/app/keys) once you can log in, or ask an operator to mint one (demos/seed.py).

A session, end to end

# one command: `attach` (or `exec`) against a new name CREATES the session —
# from --template <name>, or the platform default — and waits until it's ready
barista attach mybox                     # a shell in a fresh microVM

# walk away: it parks itself when idle (memory kept, zero compute).
# come back: any exec/attach wakes it — same process, same state.
barista exec mybox -- cat /tmp/count     # wakes it if parked, prints the count

barista ls                               # your sessions + state
barista status mybox                     # one session's detail

barista rm mybox                         # delete (frees the name)

Sessions report one of four states — starting, running (awake and ready), parked (memory kept, costs storage only), failed. Explicit plumbing still exists when you want each step by hand:

barista create web1 --image busybox:latest -- \
  sh -c 'i=0; while true; do i=$((i+1)); echo $i >/tmp/count; sleep 1; done'
barista pause web1                       # park now (memory held on KVM)
barista resume web1                      # continue from where it froze

On the real hypeman/KVM node, pause/resume preserve the process's memory, so the counter continues. On the local fake/Docker dev node it cold-boots (memory isn't snapshotted) — same commands, different substrate.

Commands

Command What it does
login [--url URL] Browser login via GitHub OAuth — remembers the gateway URL (or login <key> to save a key directly, for CI)
create <name> --image <img>\|--template <tpl> [--digest …] [--env K=V…] [--meta K=V…] [--size small|medium|large] -- <cmd…> Create a session from an image (the digest is pinned server-side; --digest for private images) or a registered template; --env sets the workload's env, --meta attaches key/value metadata. A name you already hold is refused (409) — exec/attach reuse it, rm it to recreate
ls [--meta K=V…] List your sessions + state; --meta filters to sessions carrying every given pair
template build <name> --repo REG/REPO [--image IMG] [--platform P] Build (or tag), push, resolve the platform manifest digest (never the multi-arch index), and register a reusable template
template ls / template rm <name> List / delete your templates (sessions already created keep their pinned digest)
status <name> One session's detail (one state word; raw node view under node)
exec <name> [--template T] [--no-ensure] [--env K[=V]…] [--workdir DIR] -- <cmd…> Run a command inside the session — created if missing (from --template or the platform default), woken if parked; --no-ensure fails on a missing name instead
attach <name> [--template T] [--no-ensure] [--env K[=V]…] [--workdir DIR] [-- <cmd…>] Interactive PTY into the session (default /bin/sh) — same create-if-missing, wake-if-parked behavior
acp <name> [--workdir DIR] [--env …] [--client-fs] [-- <agent-argv…>] Bridge an ACP client (Zed) to the session's agent; edits stay in the session
sync <name> [dir] Pull the session's /work down to a local dir (one-way, git-aware; like amp sync)
events <name> Tail the node's events for this session (state changes, wake, …)
pause <name> / resume <name> Freeze (keep memory) / continue
rm <name> Delete the session

Where --env lands. On create it sets the workload's env (process.env) — the long-lived process. On exec/attach it is applied to that command (a fresh process the node's guest agent spawns with the given env/workdir), so an interactive tool you attach gets the key even though the workload can't pass it on. Bare --env KEY forwards your local value (like docker -e KEY); --env KEY=value passes a literal. For real secrets, prefer the control-plane secrets store over the command line.

Templates, metadata, size — in one breath.

barista template build cc --repo ghcr.io/you/tpls   # build+push+register once (tutorial 7)
barista create w1 --template cc --size medium \
  --meta team=ml --meta task=eval -- sleep 3600     # 2 vCPU/2 GiB, tagged, digest-pinned by name
barista ls --meta team=ml                           # find sessions by their tags
Sizes: small (1 vCPU/512 MiB, the default), medium (2/2048), large (4/8192).

Agents in the session. barista acp <name> drives the session's agent from Zed (or any ACP client), and keeps the agent's file edits in the session (/work) so editing and running commands agree — Zed is the chat/diff UI. Pull the result down with barista sync <name> [dir] (one-way, session→local; git history preserved when /work is a repo), like amp sync. barista acp --client-fs opts out (route edits to the client).

Auth, status, progress

  • Auth: API key as Authorization: Bearer <key_id>.<secret>. login stores it; the console uses GitHub OAuth for humans.
  • Status: barista ls / status, or the console at https://beta.barista.sh.
  • Interactivity: exec is one-shot; attach gives you an interactive PTY you type into — a shell, or a claude-code/codex session (barista attach web1 -- claude) — over a WebSocket, the streaming variant of the same Contract A Exec. pause/resume while attached freeze and thaw it.

Notes

  • Images are pinned by digest — the node requires it. The CLI resolves the digest from your local Docker (the platform RepoDigest, not the multi-arch index digest). Pre-docker pull an image or pass --digest if you're offline.
  • The workload runs the OCI image, so it must be a real, pullable image; the command after -- is its entrypoint/argv.
  • Sessions are tenant-scoped: your key only sees your own.