Sessions and persistence

A session is Sox’s unit of work: one host, its SSH connection, its shells, and the windows bound to them. Understanding where each piece lives explains what survives a quit and what does not.

Where things live

PieceLivesSurvives quitting Sox
Shell processesOn the remote hostYes
Scrollback and screen stateOn the remote hostYes
SSH connection and tunnelYour MacNo — re-established on start
Window layout and bindingsYour MacYes — replayed on next launch

Because the shells are remote, closing a window detaches rather than kills. A build, a test run, or an agent keeps working while the app is closed and your laptop is asleep.

The Sessions menu

Start sessions with sox up my-host (or sox up my-host /project). The Sessions menu lists the sessions Sox knows about and offers recovery and teardown actions:

Refresh Sessions : Re-walk the hosts and rebuild the list from what the remote daemons actually report. Use it when the menu disagrees with reality.

Reopen (under a session) : Reattach the kept shells using the daemon’s current arrangement. It does not start a new session or replace shells that are still running.

Stop Session : Tear down the active GUI session. CLI host disconnect uses sox down my-host and preserves its shells.

When a pane fails to reconnect, choose that session’s Reopen, or use sox up to reconnect from the CLI.

Restore after a restart

When Sox reopens, it replays the windows you had and reconnects each pane to the shell it was bound to. Panes show a connecting state while their host is being re-established, which can legitimately take a few seconds on a slow link.

That wait is bounded. If a pane is still waiting after ninety seconds, it stops waiting and says so rather than spinning forever:

Session start failed
Restore timed out. This pane was waiting to be reconnected to
<host>, and that never happened. Its shell may still be running —
use sox up to reconnect, or Reopen for this session in Sox.

The wording is precise about what is and is not known: the pane’s own reconnect did not happen, and the shell behind it is usually still alive on the host. Close that window and choose Reopen under that session in Sessions, or run sox up for the target; you are reconnecting to a running shell, not starting over. To confirm the shell is there first, sox ls lists what the control plane can still address.

Terminal capabilities for a new shell

New shells request xterm-ghostty by default. A host’s TERM setting or the mobile Settings choice can select another value. Saved choices stay selected; the new default does not rewrite Settings, a running shell, or a creation already reserved.

On a prepared updated host, the new child uses Ghostty’s terminfo capabilities. When its entry cannot be loaded or checked, the new operation uses xterm-256color and shows the reason and repair advice. A fallback notice does not change the saved preference. If both selected and baseline entries are confirmed missing, creation explains the readiness failure before starting an unusable child. Restoring an entry after a reservation allows retrying that same creation.

Foreground activation and pairing offer bounded account preparation after the daemon is ready. Missing tools and timeouts remain advisory. Adopted starts and reconnects preserve existing work and do not repair a deleted entry; a later foreground preparation or manual installation repairs it. An older compatible host keeps its fixed 256 cold wrapper, and default qualified CLI births also keep 256 there, with a limitation notice. Upgrading supplies the new birth behavior without recreating existing shells.

Managed shells keep TERM_PROGRAM=sox. Application identity and terminal capabilities are separate settings.

Project configuration

Sox starts terminal sessions and RPC connections. Existing sox.toml files are ignored and remain on disk. Browser launching, Mutagen sync, SOCKS proxies, service actions, extension loading, and declared forwards have been removed.

After upgrading, older Chrome, Mutagen, and SOCKS processes remain running. Disconnecting or running sox down leaves those processes alone; terminate them by PID if needed. Live shells continue normally.

Stopping without losing shells

sox down my-host disconnects the host’s SSH transport and RPC tunnel. It preserves every shell, host config entry and saved arrangement. The next sox up my-host reconnects.

To destroy shells, use sox kill host/handle, or sox kill --all my-host. Kill-all prints the resolved home and the live daemon’s exact backing ids, then asks for assent. Automation uses --yes --home <resolved-home>. An unavailable daemon refuses the bulk kill.

Inspecting state

QuestionCommand
What hosts are configured?sox host ls
What shells exist right now?sox ls
Why is this host misbehaving?sox doctor host:path
Why won’t this shell reattach?sox doctor --shell s1.g12 / sox doctor host:path --shell s1.g12

sox ls asks each configured host’s daemon, because the daemon that owns a shell is the only thing that knows whether it is still there. A host that does not answer inside the deadline gets one unreachable line naming why, and none of its shells are listed — an inventory that quietly showed you yesterday’s rows would be worse than one that says it came up short. Use --deadline-ms to wait less; naming a single host makes its silence the command’s own exit status.

status, prune and workspace are retired CLI verbs. Use ls and doctor for inspection, explicit kill for destruction, and host rm to remove a configured host. Removing a host config entry kills nothing.