feat: shareable terminals#6484
Draft
gustavosbarreto wants to merge 4 commits into
Draft
Conversation
Adds a tmate/upterm-style shareable terminal: a public, read-only (or collaborative) web link that mirrors a live terminal session to guests without requiring them to sign in. The ssh service gains an in-memory share registry and a fan-out hub (one producer, N consumers, with a scrollback ring buffer), exposed via: - POST /ssh/shares create a share (device-authenticated) - GET /ssh/shares list a namespace's active shares - DELETE /ssh/shares/:token revoke a share - GET /ssh/shares/:token/stream agent producer stream - GET /ws/share/:token public guest viewer The console web terminal can also share its own live session in-process (CreateLocal), teeing PTY output to the hub and, in collaborative mode, feeding guest input back into the session. CE-compatible — it does not depend on the Enterprise session recorder.
`shellhub-agent share [-- command]` hosts a command in a PTY and exposes it as a public shareable terminal. Flags: --name, --write (collaborative), --duration (time limit) and --user. The command runs on the host using the same path as SSH sessions (command.NewCmd, i.e. nsenter+setpriv in Docker mode) as the resolved user. Adds a host wrapper (scripts/shellhub-agent) to install at /usr/local/bin: it auto-detects the agent container and binary and forwards the invoking host user via SHELLHUB_SHARE_USER, so the shared command runs on the host as that user with no configuration.
Adds a "Share" action to the console terminal that creates a public link to the live session (name, time limit, collaborative toggle); a public, no-login viewer page at /share/:token (xterm, themed, mirrors host geometry, read-only or collaborative, with clear ended/expired states); and a "Shared Terminals" page listing a namespace's active shares with live viewer counts, duration, mode and a revoke action.
A guest opening a share link mid-session saw a blank terminal until new output arrived, because the shared console session only captured output from the moment the share was created. Capture the console session's output from the start and seed the share hub with it when the share begins, so a late joiner is replayed the screen that was already there. The hub's replay buffer is also reset whenever the screen is cleared (erase screen / scrollback, alternate-screen enter/leave, full reset), so the replay starts from a clean screen and stays bounded at 128KB per share. Viewers reconstruct the current screen at full fidelity from the raw replayed output — no server-side terminal emulator needed.
|
Claude finished @gustavosbarreto's task in 2m 7s —— View job Code Review
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Adds shareable terminals to ShellHub: a live, public link to a running terminal session that anyone can open in a browser and watch, without signing in. Read-only by default, with an optional collaborative mode where guests can also type. Think tmate or upterm, built into ShellHub.
There are two ways to start a share.
From the web terminal
While connected to a device in the console, click the share icon in the terminal toolbar, pick a name, a time limit and whether guests can type, and you get a link to send.
Anyone with the link gets a read-only (or collaborative) view of the live session. A guest joining mid-session sees the current screen right away, not a blank terminal.
From the device, with the agent CLI
Run
shellhub-agent shareon a device to share a local terminal directly, the same way you would reach for tmate. You keep using the terminal normally while guests watch.Flags:
--nameto label it,--writefor collaborative input,--duration 30mfor a time limit,--userto choose the host account. A small host wrapper script (agent/scripts/shellhub-agent) forwards the invocation into the agent container and runs the command as the invoking host user, so the same command works in development and production.Managing shares
Active shares show up under a new Shared Terminals page, with the device, mode, live viewer count and time left, plus controls to copy the link, open it, or end the share.
How it works
The share lifecycle lives entirely in the ssh service, in a new
sharehub (ssh/web/share). There are no new database tables: an active share is in-memory state keyed by an opaque, unguessable token.New endpoints, proxied through the gateway:
POST /ssh/sharescreate a share (agent-authenticated)GET /ssh/shareslist active shares for the namespace (user-authenticated)DELETE /ssh/shares/:tokenrevoke a share (namespace owner)GET /ssh/shares/:token/streamproducer stream pushed by the hostGET /ws/share/:tokenpublic guest viewer (no auth)The producer (a web terminal session or the agent) pushes raw PTY output to the hub, which fans it out to every connected guest. A small per-share ring buffer keeps the most recent output so a late joiner can be replayed the current screen. It resets on screen-clear sequences, so full-screen apps replay just the current screen and memory stays bounded. A guest that cannot keep up is dropped rather than back-pressuring the producer. In collaborative mode, guest keystrokes are forwarded back into the PTY.
Safety defaults: read-only unless explicitly made collaborative, an opaque token, a configurable default lifetime (
SHARE_TTL, 4h), and the share always ends when the underlying session closes.Notes
The screenshots above are from the web flow. The agent CLI path produces the same shares (they appear in the Shared Terminals list and open in the same viewer); it is just harder to capture in a screenshot since it runs in your own terminal.