Watch a Coding Agent Remotely Without Shrinking Its Terminal: shell.online v0.23.2 Gives the Host Its Grid and Each Viewer Its Own Layout

Watch a Coding Agent Remotely Without Shrinking Its Terminal: shell.online v0.23.2 Gives the Host Its Grid and Each Viewer Its Own Layout

Claude Code 2.1.282 shipped on September 24 with a setting called maxProseWidth. It caps how wide Claude's replies run in a wide terminal, while tables and code blocks keep the full width. The minimum is 40 columns and the default is unset, so prose wraps at the terminal edge. That line is about a problem anyone who has tried to watch a coding agent remotely already knows: a program breaks its lines wherever the terminal told it the edge was, and every other screen inherits those breaks. shell.online v0.23.2, released September 25, takes the other side of the same problem. The program keeps the grid of the terminal it actually runs in, and each browser viewer lays the session out for its own screen.

Where a terminal's width actually comes from

A terminal program never measures a window. It asks the kernel. The TIOCGWINSZ ioctl returns a struct winsize with ws_row and ws_col, and when the size changes, the kernel sends SIGWINCH to the foreground process group so the program can ask again and redraw. Whoever sets the PTY size decides where every line wraps.

When you share a terminal through a relay, someone has to pick that size, and until this release shell.online picked it centrally. A desktop-only session ran at 120 by 36. The moment a phone connected, the session dropped to 80 by 40 for everyone, including a read-only phone, and it went back when the last phone left. The pull request behind v0.23.2 lists the consequences: a 200 by 60 terminal running the CLI showed a 120 by 36 program in its corner, a phone got 80-plus columns scaled to a few pixels per character, and a phone joining reshaped the program for everyone.

Watch a coding agent remotely at the size it was started at

The fix has two halves, and the first one is about the host. As of v0.23.2, the CLI owns its grid. Running the CLI in the foreground or attaching locally opens the program at your terminal's size and follows it on SIGWINCH as you resize. A session started in the background, which is the default, opens at the size of the terminal that launched it. One controller resizes the PTY and the snapshot emulator together, and a repeated size is a no-op.

The workflow is the same command it has always been:

shell claude

The CLI prints a URL and an eight-character password. Open the link on your phone, enter the password, and you are looking at the same Claude Code process running on your machine. In v0.23.2 your phone joining changes nothing about the terminal Claude Code sees. The CLI reference covers the flags around this: the foreground flag keeps local interaction while sharing, the attach command reconnects a local terminal to a background session, and Ctrl-X followed by D detaches without ending the process.

The second half is about viewers, and it never touches the network. The new default renderer is called Adaptive. It keeps an exact hidden copy of the session grid and a visible canvas. Where the pane can draw the grid legibly, which the implementation defines as at least 11 pixels, it draws the grid whole, exactly as before. Where it cannot, which is most phones, it lays the content out again at the pane's width at 13 pixels. Terminal wraps are undone, and so are the line breaks a coding agent inserts into its own prose; the PR notes that Claude Code breaks replies at the session width using cursor moves and runs in the alternate screen, and the layout handles both.

Layout is a pure function of the screen contents and the pane width, computed in the browser. Nothing a viewer does reaches the relay or another viewer. A viewer who prefers the old behaviour can switch to the Fixed grid renderer, which is the previous one unchanged.

Fit to my screen, and who is allowed to press it

One viewer should be able to change the program's size: the person who started it. The session owner gets a Fit to my screen button. It sends a grid request for the owner's pane, capped at the size of any attached local terminal so a phone can never shrink a terminal someone is typing into locally. The button hides when the grid already matches. A session started from the browser through a linked account opens at the size of the pane that started it, and asks once.

At the protocol level, grid requests are accepted from writers only and only for hosts that advertise a dynamic grid. That means a link created with the read-only flag cannot resize anything, which is the right default when you hand someone a link to watch an agent work:

shell --read-only claude

The URL and the password together are a bearer credential. Anyone holding both can view the session, and unless the link is read-only, can type with the permissions of the wrapped process. The sizing machinery adds no new secret and no new capability for a viewer beyond asking for a grid, and that is refused for read-only links. Terminal frames stay end-to-end encrypted by default. The security model page spells out what an interactive link grants.

Why the relay had to learn a new word first

The hard part of this release is compatibility, because the CLI, the relay and the web app ship separately and an update never restarts a running host. The host advertises what it can do in a header, X-Shell-Terminal-Grid, which now lists dynamic alongside the fixed grids it already supported. A relay that understands this sends a relay_features message first, before any snapshot request. Only after that does the host send its terminal_grid message, then again on every change, and it resets on every reconnect.

The ordering matters because the previous relay closes a host over any unknown control message. So a new CLI against an old relay never sends one. The old relay's own grid choice arrives as a terminal_size message and is applied inside the local terminal, which the release notes verified end to end. In the other direction, an old CLI that does not list dynamic gets exactly the fixed-grid behaviour it had before, byte for byte. The source repository has the controller in cmd/shell/terminal_grid.go and the renderer under app/src/terminal/adaptive/, and the layout tests replay real captures of Claude Code, bash and vim at every width from 10 to 130 columns, asserting that no row is wider than the viewer and no text is lost.

Installing v0.23.2 does not restart sessions that are already running, and the host-owned grid only takes effect once both the CLI and the relay are updated. Check the installed version with shell --version and start a new session to get the new sizing.

What this looks like on a phone during a long agent run

Start the agent on your workstation in a normal 200-column terminal. Leave the desk. Open the link on your phone in portrait. Before v0.23.2, that action would have forced the agent into 80 columns and rewrapped every reply for your colleague still at the desk. Now the agent keeps its 200 columns, your phone gets 13-pixel text reflowed to its own width with the agent's own line breaks rejoined, and your colleague's screen does not move. Rotate the phone and the layout recomputes locally. On the phone, dragging with one finger scrolls history, and inside full-screen programs that take mouse input the gesture is sent as wheel input instead, as the mobile guide describes.

Network loss behaves the same as before. The process runs on your computer, a temporary browser or network failure does not stop it, and the reliability notes say an ordinary disconnected share can recover its link for 12 hours while the CLI and browser retry temporary failures on their own. Add an auto-close deadline if the agent should not stay reachable past a certain time:

shell --auto-close 2h --read-only claude

Claude Code's maxProseWidth and this release solve the same annoyance from opposite ends. The setting tells the agent to wrap prose at a chosen column in a wide terminal. The Adaptive renderer accepts whatever width the agent wrapped at and reflows it for the screen in front of you, without the agent or anyone else knowing. Set maxProseWidth to 80 on the host and the phone view still rejoins those 80-column lines to fit its own width. The earlier overview of what a live terminal browser link is still applies; what changed is who decides the shape of the terminal. shell.online is developed by Pilot Protocol and released under the MIT license, so the grid controller and the renderer are both there to read.

Watch your agent from any screen, at its own size

Start a session with one command on the machine doing the work, open the link on your phone, and let each screen lay out the terminal for itself. Read-only links cannot resize anything.

Try shell.online
About this article

Published by the Pilot Protocol team. Product claims are scoped to the availability labels and technical references linked in the article; deployment behavior can vary by version and environment.

How we publish · Suggest a correction · Technical references