Commands
The command surface for managing cells.
The command surface is intentionally small:
solitary init <name> scaffold a cell definition
solitary clone <source> install a cell definition from a repository
solitary up <name> start the cell and attach
solitary shell <name> shell into a running cell
solitary exec <name> <cmd...> run one command in a running cell
solitary down <name> stop the cell, keep the disk
solitary rm <name> destroy the VM; definition and secrets stay
solitary ls list cells and their state
solitary fetch <name> [files] collect what a cell published
solitary send <name> <file...> put files into a cell's inbox
solitary secrets <name> set the values a cell is allowed to see
solitary dashboard manage cells in a live view
solitary doctor check that this host can run cells
solitary update replace the binary with the latest releaseThe dashboard's cell details show gpu: false as disabled. For a running cell with gpu: true, it lists every Venus device reported by vulkaninfo --summary inside the container, including software devices such as llvmpipe. A stopped cell says GPU is enabled and lists the devices after it starts; the image needs vulkaninfo installed for the live list.
up is the only command that changes state
It is idempotent: it creates the cell's machine if absent, boots it if stopped, and attaches if it is already running. It also replaces the container when the image or the secrets changed, so editing cell.yaml and running up again is what a change takes.
vm, ports and network are read when the machine boots. up applies them to a stopped machine itself, and warns rather than pretending when the cell is already running — down then up applies them without touching the disk. The one change no restart applies is vm.provision: the old script has already run, and only rm then up gets a machine built by the current one. up says so when it happens. See changing a cell.
| Flag | Meaning |
|---|---|
--detach | Start the cell without attaching a shell. |
--rebuild | Build the image again without a cache, or pull it again, and replace the container with it. |
--rebuild is how the tools in a cell are updated, since nothing about the cell has changed to make up replace the container on its own. The home is kept. See updating the tools in a cell.
up takes a cell that is already defined. init scaffolds one; clone takes one from a repository.
doctor checks the host
solitary doctor asks the questions a cell would otherwise answer for you halfway through an up, or not at all:
limactl— onPATH, and new enough. Solitary is written against Lima 2.0.hypervisor— whether this machine can run a guest at all. On Linux that is whether/dev/kvmexists and this user can open it; the group that owns it is the usual reason a create fails minutes in. On macOS it iskern.hv_support.memory— what/dev/shmholds against what the defined cells ask for.upalready refuses a single machine larger than the filesystem behind it, but it only ever sees one cell; whether they all fit at once is a question only doctor asks, and it is a warning rather than an error. See a machine has to fit the host.disk— free space where Lima keeps machines. A disk is allocated sparsely, so what cells declare cannot be summed and the space left to grow into is the only number worth watching.machines— where the machines on this host and the cells defined for them have drifted apart. Two ways they do: a machine whose disk is larger than its cell'svm.disk, which cannot start until one of them changes, and a machine no cell names any more — the shape a cell renamed by renaming its directory leaves behind, still holding the disk it was given.config— thatconfig.yamlparses, and that the state directory can be written. Nothing fails outright without the latter, but drift goes undetected, so a change tovm,portsornetworkis never reported as needing a restart.proxy— a host proxy the cells will not inherit, which they deliberately do not: a proxy configuration names internal hosts and carries credentials. It is worth saying because of how it fails — a cell behind an unset proxy reaches nothing, which looks exactly like an incomplete allow list.
It changes nothing, and every check that is not ok names what to do about it. It exits non-zero when one failed outright, so it can stand at the top of a script; warnings alone exit zero.
update keeps the binary current
solitary update downloads the newest release, verifies the release workflow's Sigstore signature and archive checksum, then replaces the running binary. --check reports whether a newer release exists and installs nothing. An install a package manager owns is left to it: update says which command to use instead of overwriting the file behind Homebrew's back.
Every other command mentions a newer release at most once a day, and only to a terminal. See staying current for turning that off.
Lifecycle
down keeps the disk. rm removes the VM and its disk but leaves the definition and host-held secrets, so the cell can be recreated already authenticated. That makes a clean rebuild a normal operation rather than incident response.
rm --force skips the confirmation prompt. init --force overwrites an existing definition.
Machines that outlived their cell
A cell is named by its directory, so deleting that directory — or renaming it — leaves the VM behind, still holding the disk it was given. ls lists such a machine as orphaned rather than hiding it, since nothing else on the host says it is there. down and rm take its name like any other cell's, and rm --orphans destroys every one of them at once. solitary init <name> gives the machine a definition again instead.
rm --orphans says of each machine whether it carries solitary's own mark — the cell name written into the VM's definition, which is also what puts /etc/solitary/cell in the guest. A machine created before that mark existed, and a VM someone named solitary-… themselves, both come up unmarked and look alike, so the prompt reports it and leaves the decision to you.
Taking someone else's cell
clone installs one cell definition out of a git repository — a repository that is a single cell, or one directory out of a catalogue of them.
solitary clone owner/repo # a repository that is one cell
solitary clone owner/repo/claude # one cell out of a catalogue
solitary clone owner/repo # a catalogue, unnamed: lists it
solitary clone ../my-cells#claude # any git URL or local path, #cell inside it| Flag | Meaning |
|---|---|
--as <name> | Install under a different name. |
--force | Replace an existing definition, keeping its .env. |
--yes | Install without asking. |
--list | Show what the definition asks for without installing it. |
See sharing cells for what is copied, what is refused, and how updating one works.
Direct execution
exec is shell for one command: it exits with the command's status and leaves its streams alone, so a cell can be scripted from the host without a terminal in the middle.
solitary exec claude git status
solitary exec claude bash -lc 'npm test | tail -20'
solitary exec claude cat notes.md > notes.md # redirection is the host'sThe command is run directly rather than through a shell, so flags after it are its own and quoting survives. Ask for a shell explicitly when you want one.
Moving files
solitary fetch <name> # everything published, into the current directory
solitary fetch <name> --list # see what is there without copying it
solitary fetch <name> --into <dir> # land them somewhere else
solitary fetch <name> --force # replace files already there
solitary send <name> <file...> # into the cell's inbox
solitary send <name> --clipboard # the host clipboard's image, as a PNGSee moving work in and out for the rules that make this safe.
Your terminal comes with you
A session you are watching carries your terminal into the cell: its name, whether it does true colour, and its description, compiled into the cell the first time you attach. Terminals that ship their own terminfo — ghostty, kitty, wezterm — work without the cell having heard of them, and a theme arrives in the colours it was written in.