# Commands (/docs/commands)

The command surface for managing cells.

The command surface is intentionally small:

```text
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 update                 replace the binary with the latest release
```

## `up` is the only command that changes state [#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](/docs/concepts#changing-a-cell).

| Flag       | Meaning                                   |
| ---------- | ----------------------------------------- |
| `--detach` | Start the cell without attaching a shell. |

`up` takes a cell that is already defined. `init` scaffolds one; [`clone`](/docs/sharing) takes one from a repository.

## `update` keeps the binary current [#update-keeps-the-binary-current]

`solitary update` downloads the newest release, checks it against the published checksum and 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](/docs/installation#staying-current) for turning that off.

## Lifecycle [#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.

## Taking someone else's cell [#taking-someone-elses-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.

```sh
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](/docs/sharing) for what is copied, what is refused, and how updating one works.

## Direct execution [#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.

```sh
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's
```

The 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 [#moving-files]

```sh
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
```

See [moving work in and out](/docs/artifacts) for the rules that make this safe.

## Your terminal comes with you [#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.
