Solitary

The dashboard

Every cell and its state in one live view.

solitary dashboard is the same operations as the CLI in one live view: every cell, its state as it changes, and the actions that apply to the selected one.

 solitary
 ╭─────────────────────╮╭──────────────────────────────────╮
 │ cells               ││ claude                           │
 │ › ● claude  running ││ image   build:./Containerfile    │
 │   ○ demo    stopped ││ machine 4 cpus · 4GiB · 40GiB    │
 ╰─────────────────────╯│ ports   all reach host localhost │
                        │ network 2 allowed                │
                        │         github.com               │
                        │         api.anthropic.com        │
                        │ secrets 2 of 2 set               │
                        ╰──────────────────────────────────╯
 ↑↓ move · ⏎ shell · u up · s stop · e secrets · n network · t traffic · d rm · q quit

It does nothing the commands cannot, and the slow ones it runs as those commands: pressing u runs solitary up --detach, so a build prints what a build prints and a cell missing a secret asks for it the way it always does. The dashboard steps out of the way and comes back rather than owning a second, worse version of each.

Keys

KeyAction
/ k jMove between cells
Shell into the selected cell
uBring it up (solitary up --detach)
sStop it
dDestroy its machine, after a confirmation
eManage its secrets
nShow the whole allow list
tFollow its network traffic
rRefresh
qQuit

The provision row

A cell whose vm.provision changed since its machine was provisioned says so in its detail view. It is the one setting stopping and starting the cell does not apply: the old script has already run, and only d then u — destroying the machine and its disk — gets one built by the current script alone. Every other change to vm, ports or network is applied by a restart, so the dashboard leaves those to up.

The VPN row

A cell with network.vpn set reports the tunnel in its detail view, refreshed as the view is open:

ShownMeans
vpn noneNo tunnel configured.
vpn configuredThe cell is not running, so there is nothing to ask.
vpn down — this cell reaches nothingThe tunnel is not up, and the kill switch is therefore dropping everything.
vpn up, no recent handshakeUp but silent. From inside the cell this is indistinguishable from a broken network, which is why it is said here.
vpn up · handshake 12s agoWorking, with the peer it is actually talking to and the bytes moved in each direction.

The peer address is read live rather than taken from the configuration: a provider that balances one hostname across servers moves it between handshakes.

The traffic view

t follows what the selected cell's network is doing, as it happens: every name it asks about, what it resolved to, and every connection the firewall refused.

 ╭─────────────────────╮╭─────────────────────────────────────────────────╮
 │ cells               ││ traffic · claude                                │
 │ › ● claude  running ││ 12:07:53 query    api.github.com ×2             │
 ╰─────────────────────╯│ 12:07:53 resolved api.github.com → 140.82.121.6 │
                        │ 12:07:53 refused  example.com                   │
                        │ 12:07:53 denied   1.1.1.1:443                   │
                        ╰─────────────────────────────────────────────────╯
 ↑↓ scroll · G live · / filter · b refused only · c clear · esc back
KeyAction
/ k jScroll
pgup pgdown / ctrl+b ctrl+f / spacePage
g / GOldest / back to live
/Filter as you type; keeps it, esc clears it
bRefused connections only
cClear what is shown
escBack to the cell list

It reads the machine's log, where both halves of the allow list record what they did — so a cell cannot see, let alone edit, what is recorded about it. Repeats fold into a count, since one lookup answers with every address a name has.

This is the fastest way to find what an allow list is missing: a refused line names it.

Secrets

e manages the selected cell's secrets: which names are set, which are not, and a masked field to set or rotate one (↑↓ to move, to set a value, esc to go back).

Values are never displayed. The dashboard reads only whether each declared name has one.

On this page