# Remote sessions

Connect the desktop app or the TUI on this machine to Shelbi running on another machine, over your own SSH.

A **remote session** is a Shelbi project that lives on another machine (a
devbox, a build server, a Mac mini in the closet) opened from the Shelbi on
the machine in front of you. The project, its daemon, its orchestrator and
its workspaces all keep running over there; you just look in and drive.

This is different from [remote workspaces](/docs/concepts/workspaces), where
*your* hub dispatches agents to slots on other machines. A remote session
connects to a whole other Shelbi: its own hub, its own projects.

## Connecting

Open **Connect to Remote Session** from any of these:

- the launch screen's **Connect to remote** button,
- the **Shelbi** menu, **Connect to Remote Session…** (desktop),
- the command palette (**Connect to Remote Session…**),
- a terminal: [`shelbi remote connect <host> [project]`](/docs/cli/remote).

It is the same two-step dialog wherever you start:

1. **SSH host.** Type an SSH alias from your `~/.ssh/config` (`devbox`) or
   `user@hostname`, then **Find Sessions**.
2. **Choose session.** Shelbi signs in, shows the user it is **Connected as**,
   and lists that machine's projects with their folders. Pick one and
   **Connect**. **Change host** goes back to step 1.

Every project you connect to lands in **Recent remote sessions** on the launch
screen, newest first, so next time it is one click. The list keeps the eight
most recent, one entry per host, user and project.

## What a remote session looks like

How a remote session opens depends on the Shelbi on the other machine.

**The same version as yours: the full window.** The desktop app opens its
whole window for the project, as it does for a project on this Mac: the
sidebar, the Orchestrator, the Issues board and task pane, Workspaces,
Activity, Machines and Settings. The title bar and the sidebar name the user
and host (`jlong@devbox`), and the project switcher lists that machine's
projects. Everything you do runs on the other machine: moving a card, starting
a review, toggling Zen Mode, saving a workflow or a workspace in Settings,
checking a machine. **Edit** opens the file in that machine's `$EDITOR`, in a
terminal there, and a file you drop on one of its terminals is copied there and
its path pasted.

**Any other version: the terminal view.** The desktop app opens the other
machine's own Shelbi in its terminal interface, running over SSH
(`ssh -t <host> shelbi --project <project>`), in a window of its own with the
host and project in the title bar. A line under the title bar says why:

> Shelbi on devbox is 0.12.1 and this Mac has 0.13.0, so it opens in its
> terminal view. Update both to get the full window.

The full window needs **exactly** the same version on both machines. Another
patch release (0.13.0 and 0.13.1) or a Shelbi from before the full window
opens the terminal view. Update both machines to the same release to get the
full window.

From a full window you can still use the terminal view: choose
**View ▸ Open in Terminal View**, or **Open in Terminal View** in the command
palette. It opens in a window beside the full one, on the same project.

In the **TUI**, a remote session always opens the other machine's Shelbi in the
terminal: it takes over until you quit it, and then you're back.

A full window leaves a few things to the other machine itself. **Add Project**,
**New Window**, **Quit Shelbi** and **Detach Other Clients** are grayed out
with the reason; run them there.

A workspace the other machine's project runs on yet another of its machines
streams into the full window too. The other machine reaches it the way it
always does, over its own connection to that machine, and passes the terminal
through, so your Mac needs no route to that machine and no credentials for it.

## When the connection drops

Sessions on the other machine never depend on your connection: agents keep
working when your Wi-Fi blinks or your laptop sleeps. If SSH drops, Shelbi
shows "Reconnecting to *host*… (attempt N)" and tries again, quickly at
first and then backing off, until the machine answers. You land back where you
were. A workspace on yet another machine reconnects the same way when either
connection drops, yours to the other machine or the other machine's to it.

In the TUI (and with `shelbi remote connect`), press Esc to stop reconnecting.
A reconnect never starts the other machine's Shelbi: if it has stopped, the
retries end with "Shelbi isn't running on *host*." and you're offered
**Start Shelbi** instead.

A full window also checks the other machine's version each time it
reconnects, since Shelbi there may have been updated while you were away. If
the versions no longer match, the window closes its terminals, stops sending
anything to that machine, and shows **Reopen**. Reopen opens the project again
in whichever window now fits: the full window if the versions match again,
otherwise the terminal view.

## SSH and credentials

Shelbi uses your existing SSH setup:

- It runs your own `ssh`, so your keys, `ssh-agent`, `~/.ssh/config` aliases,
  jump hosts and Tailscale all apply.
- When SSH needs something from you, Shelbi asks in a macOS dialog. A host
  that wants a password, a key whose passphrase isn't loaded in your agent,
  or a one-time code shows SSH's own prompt ("*user*@*host*'s password:",
  "Enter passphrase for key …") with a hidden field. **OK** carries on
  connecting; **Cancel** stops with "Couldn't sign in to *host*". A wrong
  password is asked again, as many times as SSH allows.
- Every dialog starts with "SSH sign-in to *host*" and "*host* asks:" above
  the prompt. A one-time-code prompt is text the other machine sends, so
  treat it as that machine's question: Shelbi never asks for your Mac's own
  password.
- A machine you haven't connected to before shows SSH's host-key question,
  with the key's fingerprint, in the same kind of dialog, with **Yes** and
  **No**. **No** is the default, so pressing Return refuses; accepting the key
  takes a click on **Yes**. Shelbi never answers it for you.
- You're asked once. The steps of a connection, the session's terminal and a
  full window's link share one SSH connection, which stays open for ten minutes
  after you leave.
- If a full window loses its connection, it asks once to reconnect. If you click
  **Cancel**, it stops asking and shows **Sign In** until you're ready.
- Shelbi never stores, logs or sees your password: the dialog hands it straight
  to `ssh`.
- Where no dialog can be shown (on Linux, or when Shelbi itself runs over SSH
  rather than in your Mac's desktop session), SSH runs in batch mode and never
  prompts. A host that wants a password then fails with "Couldn't sign in to
  *host*" and a hint to add a key (`ssh-copy-id <host>`) or load yours with
  `ssh-add`. Set
  `SHELBI_ASKPASS=never` to get that behavior on a Mac too.

## The other machine's daemon

Shelbi does not start or stop the other machine's daemon on its own. If Shelbi
is installed there but not running, the dialog says so and offers
**Start Shelbi**, which starts it the same way a client on that machine
would. Stopping it is up to you, on that machine.

## Requirements and errors

The other machine needs Shelbi installed and at least one project. The dialog
explains each thing that can go wrong:

| Message | What to do |
| --- | --- |
| Couldn't connect to *host* | Check the name, your network, or VPN. `ssh <host>` in a terminal shows the same failure. |
| Couldn't sign in to *host* | The password was wrong, or you clicked **Cancel**: connect again. Without a dialog (see above), load your key (`ssh-add`) or add it to the host (`ssh-copy-id <host>`). |
| *host*'s host key isn't trusted | You answered **No** to the host-key question, or the key changed. Run `ssh <host>` once to check it. |
| Shelbi isn't installed on *host* | Install Shelbi there. Shelbi looks on your login shell's `PATH`, then in `~/.shelbi/bin`. |
| Shelbi on *host* is *X*, and this machine has *Y* | Update one so both share the same major and minor version (patch releases mix fine). |
| Shelbi isn't running on *host* | Click **Start Shelbi**, or start it there yourself. |

To see what a remote client will find on a machine, run
[`shelbi remote list`](/docs/cli/remote) on it.

## See also

- [`shelbi remote`](/docs/cli/remote): what a machine reports to remote clients.
- [Workspaces](/docs/concepts/workspaces): dispatching agents to other machines
  from your own hub.
