I'm part of a small infrastructure team, and most days I have a handful of Claude Code sessions running on a few machines. sessionhub keeps track of them: one registry, one inbox, every machine.
Sooner or later someone asks: "can I look at that session with you?"
Until last week my honest answer was "sort of".
What I could offer before
A screen share. They watch, I type. Fine for five minutes.
An SSH account. This is the real answer most teams give, and it is the wrong size. An account on my machine shows every pane I have open, every other session, my shell history, and my files. They wanted one conversation. I would be handing over the building to show them one room.
The dashboard. sessionhub already had a web dashboard, so the first step was a guest link:
sessionhub login --name alice --session 3f2a9c10
That prints a one-time link. The browser that opens it sees that one session and nothing else. It can read it, reply to it, and answer its permission prompts and questions. It gets no other session, no tasks, no resume command, no Remote Control link. Every other route answers 403, and I take it back with sessionhub login rm alice.
That covered reading and answering. It was OK for a couple of days, then it wasn't. It did not cover the thing people ask for when they say "let me drive for a minute": the terminal.
sessionhub attach
So the same link now works in a terminal:
sessionhub attach https://hub.example.com/login/<code>
The guest's machine doesn't join anything. The command signs in with the link, shows that one session's terminal, and sends keystrokes to it. Ctrl-] detaches, and the session keeps running.
There is no SSH and no inbound port. The shape is the one the rest of sessionhub already uses: machines poll the server, and the server never connects out to them.
guest terminal ──HTTP──> sessionhub server <──HTTP── machine watcher ──> the pane
Each side holds one streaming GET for bytes coming toward it and makes small POSTs for bytes going away. The server relays between them in memory. I skipped WebSockets: Go's standard library has no WebSocket server, and sessionhub has four direct dependencies that I'd like to keep at four. Two chunked HTTP streams do the job with net/http alone.
The trade-off I took
The mirror is a snapshot, not a real terminal stream. The watcher reads the pane's screen every 250 ms and sends a fresh frame when it changed. That means:
- The guest sees the host pane's size, not their own.
- No scrollback on the guest's side.
- A fast-scrolling build log looks choppy.
For a Claude Code session that is fine. The screen changes in bursts, and what the guest needs is the current state and a keyboard. A proper stream is a later change behind the same command.
One thing to be straight about: attaching gives the guest Claude's keyboard, and that includes ! shell commands. The link is scoped to one session, but that session runs as me. Hand it only to someone you would give a shell. The link is one-time, the sign-in expires, and an attach ends after 30 minutes without traffic.
A second terminal: Rex
Everything above first worked through herdr, the terminal multiplexer I run sessions in. This week I added Rex as a second backend, using only its rex CLI:
-
sessionhub start <machine>opens a new Rex session running Claude with Remote Control on. -
sessionhub resume <id>focuses the block that runs a session. -
sessionhub move <id> <machine>carries a session between machines, herdr or Rex on either side. - A watcher runs as a systemd unit on a machine with no herdr at all.
Status, plainly: start, resume, and Remote Control are tested live on Linux. Moves into Rex pass against a fake so far, and macOS is untested.
What I took from it
- Scope the access to the question. "Can I see that session?" deserves one session, not a machine.
- Reuse the direction of trust you already have. Machines polling the server made a relay possible with no new open port.
- Ship the snapshot. The 250 ms mirror took a fraction of the work of a real stream, and it answers the request.
sessionhub is open source (MIT), a single Go binary with SQLite: github.com/abdallah/session-hub.
Top comments (0)