Track Terminal Sessions Across Machines by Name: shell.online v0.16 Adds --name and shell ls
Two announcements this month move coding agents further from the keyboard you sit at. Coder now runs Claude Code inside its Agent Relay workspaces, and OpenAI's Agents API puts the Codex harness behind a managed service with hosted, self-hosted, and partner sandboxes. Both mean more sessions on more machines you never log into directly. shell.online v0.16.0, tagged this week, adds the two pieces that make terminal sessions across machines manageable from one place: a name you give a session when it starts, and a single command that lists every session your account owns on every linked machine.
Why sessions are spreading across machines this month
Coder's September 15 announcement describes Claude Code running in Coder workspaces on the customer's cloud, VPC, or on-premises environment, with workspaces that are "sandboxed, ephemeral, and scoped to a single Claude Code session" and an audit record for every run. The Agent Relay launch post from earlier in the month spells out the split: the agent's reasoning loop still runs at the vendor, execution happens in a workspace the enterprise controls, and the workspace is destroyed the moment the session ends.
OpenAI's Agents API public beta, announced September 10, does the same thing from the other direction. OpenAI runs orchestration, long-running sessions, and context management. You pick where the code executes: an OpenAI-hosted sandbox, your own, or one of nine named partners including Cloudflare Dev, Daytona, E2B, Modal, and Vercel.
The common thread is that the process doing the work has a terminal on a box somewhere else. With five of those, the question stops being "can I see it" and becomes "which one is this."
Give the session a name before it starts
The v0.16.0 changelog in the shell.online repository adds a start option that labels a session as it is created. It takes one line of up to 120 characters and shows up on the start card, in the local session list, and in the web app:
shell --name "issue-4821 claude" claude
shell --name "web app" npm run dev
shell --name "nightly eval" --read-only python train.py
Everything else about the share is unchanged. The command keeps running on your machine, the CLI owns the PTY, and it prints a URL plus a generated ten-character password that together open the same terminal from a phone or desktop browser.
Three details from the help text and changelog matter in practice. A persistent session that restarts without a name keeps the one it had, including a name someone gave it in the web app. A session can be renamed from its own page in the app by the owner, an assignee, or a team admin, and a blank name falls back to the command. And the name is one of the few things published to an account at all, alongside the share URL, command, host name, and timing; the CLI reference lists every start option and what each one changes.
List terminal sessions across machines with shell ls
Until this release, the CLI could only tell you about processes on the machine you were typing on. The existing local command still does that:
shell list
The new one asks your account instead:
shell ls
shell ls --all
shell ls --json
It lists the sessions you started on any machine linked to your account, newest first, with each one's name, status, uptime, machine, and command. Sessions that have ended are hidden and counted rather than shown; the footer reads something like "1 ended session hidden · shell ls --all", and the flag includes them. The JSON form prints the complete records, including the share URL and the raw relay status, for scripts that decide which session to open.
One thing it never does is print a password. The help text says so directly: passwords stay on the machine that started the session and, if you opted into the personal vault, in your vault. The listing gives you the URL and the name; the password still has to come from the owner. A list that included passwords would be a list of bearer credentials sitting in scrollback.
The command requires a linked machine. Linking is optional and uses the OAuth 2.0 authorization code flow with PKCE and a loopback redirect, so the CLI ends up with a scoped token that can only publish sessions and is revocable per machine. On an unlinked machine it tells you to sign in or use the local list. For teams with their own identity provider, v0.16.0 also adds optional OpenID Connect sign-in for the accounts app, using authorization code with PKCE and provider discovery.
What the account sees, and what it cannot
What the account layer can read has not changed in this release. Terminal frames are encrypted by the CLI before they reach the relay and decrypted in the browser; the end-to-end encryption page describes the key derivation from the password and what the relay still observes, which is connection metadata, encrypted frame sizes, timing, labels, and lifecycle events. The account layer gets the share URL, the command name, the host name, timing, and now the name you chose. It does not get terminal contents and it does not get the password.
The URL and the password together are a bearer credential. Anyone holding both can open the session and, unless it was started with --read-only, type with the permissions of the wrapped process. A named session is easier to find in a list, so treat the name as public within your organization and the password as the thing you actually guard.
For agent sessions, a read-only share is usually the right default. Watching a run from a phone does not require typing into it, and a read-only link cannot be upgraded to an interactive one after creation.
When the machine behind a session goes away
A related change merged to main on September 16 fixes what a viewer sees when the session exists but its machine does not. The pull request describes the bug plainly: a machine rebooted, the relay reported the session as existing but disconnected, and the browser showed a grey "Offline" dot above a blank white rectangle with no explanation. With workspaces that are destroyed when a session ends, this state will be common.
The fix does two things. Both the standalone share page and the app now say whether they are waiting for a machine that has never connected or looking at one that is temporarily offline, with the time it was last seen. And the relay keeps the last full screen the host sent and replays it, dimmed so it cannot be mistaken for live output, to a viewer who arrives while the machine is away. For an encrypted session those stored bytes are ciphertext the relay cannot read; the frame is stored and replayed untouched. The relay asks the host for a fresh screen every five minutes so the kept copy is never older than that, and it is deleted with the session.
The retention consequence is worth stating. The relay now holds one encrypted screen per session for as long as that session exists, which the reliability page puts at 12 hours after a host disconnects for an ordinary share and 30 days for a persistent identity. If you started the session with --no-e2ee, that kept screen is plaintext, which is the same tradeoff the flag already makes for frames in flight. The notice clears itself when the machine comes back, and a restarted persistent session goes live again on the same URL.
Handing one of them to a colleague
Once sessions have names and one list, handoff is a filter and a click. In the web app, sessions from every linked machine appear in one searchable list or board, reconciled with the relay's current online, starting, offline, finished, or unavailable state. Each session has an owner and can have several assignees, and the owner can transfer it without changing the public bearer link. The app documentation is explicit that offline and unavailable never imply the process is reachable, and that finished records a known task exit; the web app guide covers the states and the cleanup rules.
The earlier post on this blog about a live browser link for any terminal covered the single-session case: one command, one URL, one password. This release is for the moment that stops being enough. If your agents run in a Coder workspace, an OpenAI-hosted sandbox, and a laptop under your desk, a session called "issue-4821 claude" on a machine called "build-3" is easier to find than a bare session ID, and the command that finds it is the same everywhere. The install is one line from shell.online on macOS, Linux, BSD, and Windows, and everything described here is in the MIT-licensed source.
Name it, list it, hand it over
Start a session with a name, see every session your account owns with one command, and give a teammate the link without ever sending the terminal contents through the service.
Try shell.online