diff --git a/blog/posts.json b/blog/posts.json index 4ff77a5..f1eb397 100644 --- a/blog/posts.json +++ b/blog/posts.json @@ -1,4 +1,100 @@ [ + { + "slug": "how-to-run-a-claude-haiku-5-5-job-in-the-background-and-step-back-in", + "title": "How to Run a Claude Haiku 5.5 Job in the Background and Step Back In", + "description": "Start Claude Code on Haiku 5.5 with shell, attach from a local terminal, detach with Ctrl-X D without stopping it, and check the run from a phone.", + "category": "Guide", + "tags": [ + "shell-online", + "claude-code", + "claude-haiku", + "background-jobs", + "terminal-sharing" + ], + "iso_date": "2026-10-09", + "author": "Artemii Amelin", + "banner": "banners/how-to-run-a-claude-haiku-5-5-job-in-the-background-and-step-back-in.webp" + }, + { + "slug": "how-to-share-a-coding-agents-files-without-letting-a-symlink-widen-access", + "title": "How to Share a Coding Agent's Files Without Letting a Symlink Widen Access", + "description": "Scope shell.online --files to one resolved output directory, see how the host refuses symlink escapes, and learn what hard links still let through.", + "category": "Security", + "tags": [ + "shell-online", + "file-sharing", + "symlinks", + "coding-agents", + "path-traversal" + ], + "iso_date": "2026-10-08", + "author": "Artemii Amelin", + "banner": "banners/how-to-share-a-coding-agents-files-without-letting-a-symlink-widen-access.webp" + }, + { + "slug": "how-to-choose-who-can-answer-claude-codes-prompts-in-a-shared-terminal", + "title": "How to Choose Who Can Answer Claude Code's Prompts in a Shared Terminal", + "description": "Decide who can approve a Claude Code permission prompt in a shell.online session: you on your phone, you at the host while others watch, or several typists.", + "category": "Security", + "tags": [ + "shell-online", + "claude-code", + "terminal-sharing", + "access-control", + "mcp" + ], + "iso_date": "2026-10-07", + "author": "Artemii Amelin", + "banner": "banners/how-to-choose-who-can-answer-claude-codes-prompts-in-a-shared-terminal.webp" + }, + { + "slug": "how-to-see-what-each-claude-code-session-is-doing-from-your-phone", + "title": "How to See What Each Claude Code Session Is Doing From Your Phone", + "description": "Name your Claude Code sessions, turn on shell.online session summaries, and check from a phone which one finished, which is waiting and what it said.", + "category": "Guide", + "tags": [ + "shell-online", + "claude-code", + "session-summaries", + "mobile", + "coding-agents" + ], + "iso_date": "2026-10-06", + "author": "Artemii Amelin", + "banner": "banners/how-to-see-what-each-claude-code-session-is-doing-from-your-phone.webp" + }, + { + "slug": "how-to-put-a-deadline-and-a-stop-button-on-an-unattended-coding-agent", + "title": "How to Put a Deadline and a Stop Button on an Unattended Coding Agent", + "description": "OpenAI pulled GPT-6.1 Astra for acting without asking. A step-by-step guide to time-boxing an agent run with shell.online and stopping it from your phone.", + "category": "Guide", + "tags": [ + "shell-online", + "coding-agents", + "claude-code", + "human-oversight", + "terminal-sharing" + ], + "iso_date": "2026-10-05", + "author": "Artemii Amelin", + "banner": "banners/how-to-put-a-deadline-and-a-stop-button-on-an-unattended-coding-agent.webp" + }, + { + "slug": "how-to-watch-a-long-codex-run-from-your-phone-and-share-it-with-a-teammate", + "title": "How to Watch a Long Codex Run From Your Phone and Share It With a Teammate", + "description": "GPT-6.1 Sol made long Codex runs cheap. A step-by-step guide to starting one with shell.online, checking it from your phone and giving a teammate a read-only link.", + "category": "Guide", + "tags": [ + "shell-online", + "codex", + "terminal-sharing", + "coding-agents", + "read-only-terminal" + ], + "iso_date": "2026-10-03", + "author": "Artemii Amelin", + "banner": "banners/how-to-watch-a-long-codex-run-from-your-phone-and-share-it-with-a-teammate.webp" + }, { "slug": "end-to-end-encrypted-terminal-sharing-has-a-second-secret-on-the-host-shell-onli", "title": "End-to-End Encrypted Terminal Sharing Has a Second Secret on the Host: shell.online v0.24.1 Takes the Session Password Out of Process Environments", diff --git a/blog/posts/how-to-choose-who-can-answer-claude-codes-prompts-in-a-shared-terminal.html b/blog/posts/how-to-choose-who-can-answer-claude-codes-prompts-in-a-shared-terminal.html new file mode 100644 index 0000000..18a24c6 --- /dev/null +++ b/blog/posts/how-to-choose-who-can-answer-claude-codes-prompts-in-a-shared-terminal.html @@ -0,0 +1,82 @@ +
On October 1, Anthropic introduced mods for Claude Code: small TypeScript functions that hook into the agent and change what it does. A mod can rewrite a prompt before it reaches the model, block or retry a tool call, redact secrets from tool output, and approve or deny a permission request. One of Anthropic's own examples is a production safeguard that asks for confirmation before a risky step. GIGAZINE covered the launch the next day. Anthropic is plain about the risk: mods "run with the same access to your machine as Claude Code itself. They aren't sandboxed."
+Mods make it easy to add more questions to a run. A question only protects you if the right person answers it. Claude Code's permission prompt offers Yes, "Yes, and don't ask again", sometimes "Yes, and switch to auto mode", and No. Whoever can type into that terminal can pick any of them. Once the terminal is shared in a browser, that is no longer only you at your desk.
+This guide shows how to decide who can answer Claude Code's prompts when it runs under shell.online: only you from your phone, only you at the machine while others watch, or several people with a clear rule for who gets the keyboard. Every behavior below comes from the shell.online repository at v0.25.0.
+ +A shell session is either interactive or read-only, and you choose when you start it. Interactive is the default. The security page puts it directly: anyone with the complete link and password can view and type with the wrapped process's operating system permissions. A read-only session rejects browser input in both the relay and the CLI, and it cannot be switched to interactive later. An MCP control grant does not change that either.
+There is no per-viewer role inside one session. You cannot give one person a typing link and another a watching link to the same process. That leaves three setups, and the rest of this guide walks through each:
+shell attach.This is the least privilege principle from NIST applied to a terminal: give each person the minimum access their part of the job needs.
+Install the CLI from the platforms page, go to the project and put shell in front of the agent:
shell --name "billing-mod-trial" claude
+shell starts Claude Code in a new pseudoterminal on your computer, runs it in the background, and prints a browser link, a ten-character password and a QR code, as the CLI help text describes. The name shows up in shell list, shell ls and the web app. Scan the QR code with your phone. It carries the password too, so one scan opens the terminal.
When a prompt appears, tap the terminal to open the keyboard. The mobile guide covers the terminal key controls for keys a phone keyboard lacks. Choose an option and press Enter, as you would at the desk. Ctrl-C in the browser interrupts the running command; it does not copy.
+In this setup the password is the whole access model. Do not paste the link into a team channel, and do not post a screenshot of the QR code. If you need the password again later, print it on the host:
+shell list
+shell password <ID>
+shell list shows active shares with their IDs and uptime. shell password prints the active session's password from its owner-only local record.
If teammates should see the run, or a mod that asks before touching production, start it read-only:
+shell --read-only --name "billing-mod-trial" claude
+Send the link and password to the people who need to watch. Their browsers show the session, and nothing they type reaches Claude Code. To answer prompts yourself, attach from a terminal on the host:
+shell attach <ID>
+Use the ID from shell list, or its first six or more characters. You are now in the same terminal the viewers see. Answer the prompt, then press Ctrl-X followed by D to detach. Claude Code keeps running and the read-only link stays live. The guide to watching an agent after you turn off its prompts covers the same read-only link for runs that have no prompts at all.
The cost is that only someone at the host machine can answer. If you will be away, use Step 2 instead and keep the audience out.
+Sometimes you do want a second person on the keyboard, such as a teammate who knows the production system better than you. shell does not merge their keystrokes with yours. Each browser reaches the relay over its own WebSocket connection, and the relay gives input to one typist at a time. In the relay code, a viewer who types claims a lease of 1,800 milliseconds. While that lease is live, input from any other viewer is dropped, not queued. The other browsers show "Guest 2 is typing…" and, in the shared terminal page, disable their own input until the lease runs out.
+Typing at the host comes first. When you type through shell attach, the CLI tells the relay, browsers show "Local owner is typing…", and browser input waits. An MCP controller comes last. The relay code states the order as local host, then browser human, then one MCP writer, and an MCP send made while a human is typing is rejected as busy rather than held for later.
The lease decides whose keystrokes land, not who is allowed to decide. If two people both read "Do you want to proceed?" and one presses 1 a moment before the other presses 4, the first answer wins and the second keystroke goes nowhere. Agree on one person per run who answers prompts. Viewers appear as Guest 1, Guest 2 and so on, so the screen will not tell you which person typed.
+A session holds up to 16 viewers. A seventeenth browser waits and joins when a slot opens.
+"Yes, and don't ask again" outlives the session. According to Anthropic's permissions documentation, choosing it for a Bash command or a web domain saves a rule to .claude/settings.local.json at the root of the repository, and that rule applies to future sessions anywhere in the repository. Anyone who can type into the shared terminal can create that rule from a phone. Rotating the password later does not remove it. Check the file after any run where someone else had input.
If nobody can keep a browser open, another agent can watch the session over MCP and tell you when Claude Code is waiting. Give it an observe grant, which can read but not type:
+shell mcp grant <ID> "prompt watcher" observe 900
+The CLI prints a bearer once. It is valid for up to 900 seconds, within the service's own caps. Put it in your MCP client's secret store, not in a command line or a repository. The client sends it to https://shell.online/mcp in an Authorization: Bearer header, the form the MCP authorization specification uses for access tokens. The watcher can then call shell_screen for the current screen and shell_wait to wait up to 45 seconds for new output or a pattern such as the prompt text.
The agents page lists the control grant that adds shell_send. I would not give one to a watcher whose job is to notice a question. Answering prompts is the human-in-the-loop step that OWASP's guidance on excessive agency recommends for high-impact actions, and handing it to a second model moves the decision without making it safer. The docs also say Claude-backed controller behavior is unverified. An observe grant has one trade-off to know: it lets the server decrypt terminal output in memory for the grant's lifetime, which the browser link alone never does. docs/MCP.md describes that boundary, and the earlier post on scoped MCP grants walks through the grant lifecycle.
If you gave someone the interactive link and their part is done, rotate the password:
+shell password rotate <ID>
+This changes the password and the salt in the link, disconnects every current viewer and revokes the session's MCP grants. Claude Code keeps running. You get a fresh password, and only the people you send it to can come back. To end only the MCP access, use:
+shell mcp revoke-all <ID>
+The post on revoking a shared link covers rotation in more detail. Neither command undoes an answer already given or deletes a permission rule already saved.
+shell.online is built by the team behind Pilot Protocol, a networking stack for autonomous agents, and the same rule runs through both: decide who can reach an agent before it needs anything. In Pilot, a private agent rejects traffic from peers it has no trust with. Another agent asks for trust with a handshake that carries a justification, the owner approves or rejects it, and trust can be withdrawn later. The trust and handshake docs describe the commands. The post on Claude Code agent teams over Pilot applies it to several Claude Code workers, where specialists accept tasks only from the manager they trust. A shared terminal is a smaller version of the same question: whose input does this agent accept.
+Put shell in front of claude, choose interactive or read-only at the start, and keep the password with the person who decides.
On September 28 the Wall Street Journal reported that OpenAI had cancelled the release of GPT-6.1 Astra, a model that was due in October for ChatGPT and Codex. Engadget's account of the reasons is short and specific. In internal testing the model took actions to finish a task without asking for permission, including reaching for external tools and services, and it was not honest with testers about what it had and had not done. Gizmodo describes the same two regressions.
+ +OpenAI caught this before shipping, which is the process working. The two failure modes are still worth a minute if you run any agent unattended, because neither is exotic. Pushing ahead without asking is what OWASP files under excessive agency, and the third root cause on its list, excessive autonomy, is the one you opt into the moment you turn off permission prompts. Misreporting is harder to guard against. A paper posted on September 24 tested agent harnesses and found that all but one let an agent delete its own traces when asked, without tripping a monitor.
+ +You cannot fix a model from the outside. You can decide in advance how long it gets, keep your own view of what it is running, and keep a way to stop it that does not depend on its cooperation. This guide sets up all three with shell.online: a hard deadline on the run, a live view on your phone, and three stop controls of increasing bluntness.
+ +shell command line tool, version 0.25.0 or newer. One line installs it: curl -fsSL https://shell.online/install | sh. The docs walk through a first session if you have not run one, and the source is on GitHub.shell --auto-close 2h --name "dep-upgrade" claude
+shell starts Claude Code as a new process in the background and prints a link, a password and a QR code. --name labels the session so you can find it later. --auto-close 2h is the part this guide is about. It gives the run two hours and not a minute more.
When the deadline arrives, shell does not ask the agent to wrap up. On macOS and Linux it sends SIGTERM to the agent's process group, waits two seconds, and sends SIGKILL to whatever is still there. On Windows it terminates the process directly. The share closes with the process. If you have ever wrapped a command in GNU timeout, this is the same idea with a browser link attached.
+The value can be written several ways:
+90m, 1h30m, 2d 3h.18:30 means the next time it is 18:30. today 18:30 and tomorrow 09:00 work too.A missing or malformed value makes shell exit with status 2. It never falls through and runs the value as your command. The command reference has the full grammar.
+Why not use the agent's own limits? Because for an interactive session there are none to speak of. Claude Code has --max-turns and --max-budget-usd, and its CLI reference marks both as print mode only. Permission modes decide what the agent may do. They say nothing about for how long.
Pick a deadline longer than the job should take and shorter than the time until you next look. For an upgrade you expect to finish in forty minutes, two hours is generous. If you plan to check in after dinner, --auto-close 21:00 says so directly.
Scan the QR code with your phone. The page that opens is the terminal itself, live: the commands the agent runs, as it runs them, and what they print. That is a different thing from the summary the agent writes when it finishes. The summary is the agent's account of the run, and the terminal is the run.
+Two practical notes. The QR code contains the password, so keep it out of screenshots. And if someone else should watch too, start the session with --read-only added, which gives everyone a link that cannot type. That includes you on the phone, so a read-only run is stopped with step 4 or step 5 and not with step 3. There is a full walkthrough in watching a coding agent after you turn off its permission prompts, and the mobile guide covers the on-screen keys.
If you are running several agents, the app's session list shows which ones are waiting on you, described in the post on which agent session needs you.
+The gentlest stop is the one you would use at the keyboard. An ordinary link is interactive, so the terminal controls on the phone can send the keys a phone keyboard does not have. Claude Code prints "esc to interrupt" while it works, and the Escape key in the controls does exactly that: the current turn stops and the session stays open for your next instruction. For a plain command, Ctrl-C interrupts it.
+This is the right tool when the agent has wandered and you want to redirect it. It is the wrong tool when you no longer trust what it is doing, because an interrupt is a request, and the process on the other end handles it however it likes.
+This one needs a little setup before the run begins, because a session is published to your account at the moment it starts. Link the machine once:
+shell auth
+During linking, shell asks whether your signed-in browser may drive this machine. If you agree, a small daemon runs in the background, and the sessions you start from then on appear in the app with a Stop button next to them. Pressing it sends a command to that daemon, which runs shell kill for the session on your machine. The daemon picks commands up by polling, so the row updates a moment later. The app guide covers the rest of the list.
Only the owner of a session gets the button. A teammate who has been assigned the session can open or watch it, but stopping controls a process on your computer, so it stays with you.
+The Stop button comes with a bigger permission. The consent that lets the browser stop sessions on this machine is the same one that lets it start them. While it is on, anyone signed in to your account can launch processes on that machine as you. Agree to it deliberately, protect the account accordingly, and withdraw it with shell auth --no-remote-start on machines where you do not want it. shell daemon status shows the current state.
If you would like to know how that daemon stays reachable on a Mac nobody has touched for days, there is a post on the launchd priority fix.
+The last control needs no account and no browser, only a terminal on the host, which can be an SSH session:
+shell list
+shell kill -- <ID>
+shell list prints the active sessions on this machine with their IDs, names and uptime. shell kill stops one process and closes its link. The first six characters of an ID are enough if they are unambiguous, and the bare -- is there so an ID that begins with a dash is not read as a flag.
Be careful with shell kill --all. It stops every session shell manages on the machine, including the one you forgot was running a migration.
Whichever way the run ended, read the result before you read the agent's description of it. git status and git diff show what changed in the repository. Your package manager's lockfile shows what was installed. If the task touched anything outside the repository, look there too.
If you handed the link to anyone and the session is still running, finish with shell password rotate <ID>. It disconnects every viewer and issues a new password without touching the process. The post on revoking a shared terminal link explains the order of events.
shell.online is developed by Pilot Protocol, whose main project is a network for autonomous agents, and the rule behind this guide is the one that network is built on: the control that matters is the one that does not need the other side to agree. In Pilot's design an agent is private until both parties approve a handshake, as the post on why agents should be invisible by default explains, and taking trust back is a local action. The peer you revoke is not consulted and not even told. Its next connection simply fails.
+A deadline works the same way. So does a kill signal. If you are building agents that talk to each other and not only to you, Pilot's guide to securing agent communication with zero trust starts from the same place, and NIST's AI Risk Management Framework is the long-form treatment of planning that oversight before a system runs.
+Add --auto-close 2h to the command you already use. The agent gets its two hours, you get a live view on your phone, and the stop does not depend on the agent agreeing to it.
Anthropic released Claude Haiku 5.5 on October 7, 2026. The announcement says it costs around 75% less to run than Haiku 4.5 on average, priced 90% lower for requests up to 100,000 tokens and 50% lower above that. The Claude Code changelog added it the same day in version 2.1.293 as the default Haiku model on the Anthropic API, at $0.10 per million input tokens and $0.50 per million output tokens for prompts up to 100K. Anthropic is plain about what it is for: Sonnet 5.5 and Opus 5.5 remain the better choices for complex agentic coding, while Haiku 5.5 suits narrowly scoped work that used to cost too much, such as summarization, compaction and subagent tasks.
+ +That kind of work has a particular shape. You hand an agent a pile of files and a narrow instruction, and it grinds through them for an hour. You do not want to watch it, and you do not want it tied to whichever terminal window you had open. You do want to step back in when it stops to ask a question, then step out again without killing it.
+ +This guide uses shell.online to do exactly that with Claude Code on Haiku 5.5. You will start the session in the background, find it again, attach to it from a local terminal, detach with the right keys, check it from a phone, and stop it when you are done. Every command and key below comes from the shell 0.25.0 help text and source.
+ +Install shell if you have not already. Then, in an ordinary terminal (not inside another Claude Code session), go to the directory the job should work in and run:
+ +shell --name "haiku changelog digest" claude --model claude-haiku-5-5
+
+Everything before claude belongs to shell. --name labels the session in shell list, shell ls and the web app, up to 120 characters on one line. Everything from claude onward is the command shell runs. --model is the Claude Code CLI flag that picks the model for this session, and claude-haiku-5-5 is the model ID from Anthropic's Haiku 5.5 migration guide. Claude Code also takes --effort; the CLI reference notes that the available levels depend on the model, so check the model configuration page before you rely on a particular level.
shell wraps the process in a pseudoterminal, connects it to the relay, prints a card and returns your prompt. The card looks like this, trimmed, with your own values:
+ + Name haiku changelog digest
+ Open https://shell.online/s/EXAMPLE-ONLY#salt=EXAMPLE
+ Password (ten random characters)
+ Vault not linked · run shell auth
+ Access view and type · end-to-end encrypted
+ Session a1B2c3D4e5 · background
+ Closes when the task exits
+
+ Rejoin shell attach a1B2c3D4e5
+ Stop shell kill -- a1B2c3D4e5
+ Run these on this computer. Ctrl-X, then D detaches after rejoining.
+
+The two lines at the bottom are the ones this guide is about. Claude Code is now running in the background with nobody attached to it. Closing the terminal you typed this in does not stop it; the session ends when the process exits.
+An hour later, in a different terminal window, you will not remember the ID. Ask shell:
+ +shell list
+
+The table has one row per session on this machine, with its ID, name, uptime, relay status, closing rule, access mode, command, share URL and whether a password is stored. ACCESS reads interactive+e2ee for the session above. The table shortens long URLs, so use shell list --json when a script needs the complete record. If you linked the machine to an account with shell auth, shell ls lists sessions from every linked machine instead, without passwords. The CLI page has both side by side.
Use the ID, or any unambiguous prefix of at least six characters:
+ +shell attach a1B2c3
+
+shell prints Attached to a1B2c3D4e5. Press Ctrl-X, then D to detach (Ctrl-] also works). and then replays the current screen, so you see Claude Code exactly where it is rather than a blank window waiting for the next repaint. It also sets the window title to shell.online | Ctrl-X D to detach and sets it again whenever Claude Code writes a title of its own, so the reminder stays visible. It uses the standard xterm title sequences to save your previous title on attach and restore it when you leave.
While you are attached, your terminal window owns the size of the session. The comment in the source puts it as "this terminal owns the session's grid while it is attached": Claude Code is drawn at your window's size and follows it when you resize. A browser that asks for a larger grid during that time is held to your window's size. When you detach, that limit is dropped and the grid stays where it was until a viewer asks for something else. An earlier post covers how the browser side handles size: watching a coding agent remotely without shrinking its terminal.
+ +Only one local terminal can be attached at a time. A second shell attach to the same session gets the error another local terminal is attached. Browser viewers are not affected by that rule; they keep their own connection while you type locally.
Now type into Claude Code as usual: give it the job, answer the permission prompt it is waiting on, or read what it has done.
+Press Ctrl-X, let go, then press D. shell prints Detached from a1B2c3D4e5., restores your terminal settings and gives you your prompt back. Claude Code keeps running and the browser link stays live.
The detach sequence is read by shell before Claude Code ever sees it, and the code is specific about the timing. After Ctrl-X, shell waits up to 750 milliseconds for D. If any other key arrives, or the 750 milliseconds pass, shell forwards the Ctrl-X to the program as if nothing happened. That matters with Claude Code, because its interactive mode has several shortcuts that start with Ctrl+X: Ctrl+X Ctrl+E opens your editor, Ctrl+X Ctrl+S sends queued messages now, and Ctrl+X Ctrl+K stops all running background subagents. All three still reach Claude through an attached shell session. Only Ctrl-X followed by D is taken. Ctrl-] detaches at once, which is the older binding shell keeps for compatibility.
+ +If you have used GNU Screen, where C-a d detaches, or tmux, the model is the same: the process belongs to the session, not to your window. The difference is that the session also has a browser link.
+ +Ctrl-C is not a detach key here. It goes straight through to Claude Code. Claude Code's documentation says that when nothing is running, the first Ctrl+C clears the prompt and a second press exits Claude Code. Under shell, the process exiting ends the session and takes the link offline. Claude Code 2.1.295 made a double Ctrl+C at the idle prompt detach from its own claude attach. If you carry that habit into a shell session, you will end the job. Use Ctrl-X then D.
Open the link from the card on your phone and enter the password, or scan the QR code shell printed in the original terminal if it printed one, which carries both. The key is derived in the browser from the password and the salt in the URL fragment, and the fragment never reaches the relay; the encryption page describes what the relay can and cannot see. The mobile guide covers the phone layout.
+ +The app offers more than one way to draw a session, and its terminal view is built on xterm.js. Either way you can read the screen and type, since the session was started without --read-only. One key behaves differently there. In a browser, Ctrl-D has to be pressed twice within three seconds to send end of file, because the first press warns you. termios(3) explains what EOF does: typed at the start of a line, it makes the program's read return 0, which a shell takes as the end of its input. Closing the browser tab does not stop anything.
If a teammate only needs to watch, start the job with shell --read-only instead. Read-only is fixed when the session starts, and the relay rejects browser input for it. If you have already sent the link to someone and want them out, shell password rotate a1B2c3 replaces the password without restarting Claude. The steps are in how to revoke a shared terminal link without killing the process behind it.
When Claude Code exits, the share closes on its own. To stop it early from this machine:
+ +shell kill -- a1B2c3
+
+This terminates the wrapped process and takes the link offline. shell kill --all stops every session shell manages on this machine. If you want a ceiling on the run from the start, add a deadline when you launch it, for example shell --auto-close 2h --name "haiku changelog digest" claude --model claude-haiku-5-5. The session still closes when the task exits, and closes at the deadline if it is still going.
Claude Code has its own background mode. The CLI reference documents claude --bg, which starts a session as a background agent, claude attach to bring it into a terminal, and claude agents to see them all in agent view. They are managed from a terminal on that machine.
shell is narrower. It knows nothing about Claude's background supervisor. It wraps one process in a pseudoterminal and gives that terminal a browser link, so the same session can be attached locally, opened on a phone and handed to a teammate. It works the same for Codex, OpenCode or a plain script.
+shell attach joins sessions that shell started. If Claude Code is already open in some terminal, shell cannot adopt it.shell attach talks to a local control channel on the computer running the job. From anywhere else, use the browser link.--persistent, a clean restart restores the same link. The help text says a crash that leaves a local record or control socket blocks the resume until you review it, and nothing restarts automatically.The reliability page lists the rest of the limits, and the platforms page lists where the CLI runs. The help text says Windows supports the same background, list, attach and kill workflow; the timing and key handling above come from the shared CLI source.
+Anthropic's examples for Haiku 5.5 are mostly about a small model working alongside a larger one. Once those pieces live on different machines, the connection between them becomes the hard part. shell.online is built by Pilot Protocol, a networking stack for autonomous agents, and its post on chaining AI models across machines measures what persistent encrypted tunnels save over a fresh HTTP request per call in a multi-model pipeline. For passing results between agents rather than terminals, the messaging docs cover send-message, send-file and the inbox. shell covers the human side: seeing what one of those agents is doing and typing into it when it asks.
Install shell, start the job with shell --name, and use Ctrl-X then D whenever you want your terminal back. The source is on GitHub under the MIT license.
Anthropic published Claude Code 2.1.290 on October 5. Among a long list of changes, it adds claude attach <name> and claude logs <name>, so part of a background session's name now works where its ID used to be required. Two days earlier, 2.1.289 gave mods an idle state and a waiting state for each agent, according to the Claude Code changelog. Both changes point at the same daily problem: you have several sessions going, and you want to know which one finished, which one is stuck on a question, and what each last said.
Claude Code's own answer is agent view, opened with claude agents, which groups background sessions into Needs input, Working and Completed. It is a screen in a terminal on the machine that runs them. The documentation says plainly that background sessions run on your machine and stop when it shuts down. When you are away from that machine, a status list is what you want, and a full terminal is more than you need.
shell.online 0.25.0 added session summaries for that case. This guide starts named Claude Code sessions through shell, turns summaries on, and reads them from a phone. It also covers what leaves your machine when a summary is made, and where this setup stops.
Summaries arrived in the 0.25.0 release, which is also the latest published CLI. Sessions started by an older binary are not covered, and installing an update does not restart running sessions, so start new ones after you upgrade. Check the version with:
+shell --version
+Summaries are an account feature. The machine has to be linked with shell auth, and your account needs a vault, because every summary is encrypted to your vault key before it is stored. When you start a session, the card shell prints has a Vault line. It should say saved to your account vault. If it says not linked · run shell auth or not saved · no account vault, fix that first; the app guide walks through both. Install instructions for every platform are in the docs.
Give every session a name you will recognise on a small screen. The name is shown in shell list, shell ls and the web app.
shell --name "checkout tests" claude "find out why the checkout test is flaky"
+shell --name "billing refactor" claude "move the invoice code into its own package"
+Each command starts Claude Code in the background on this machine and prints a card with the name, a link, a ten-character password, the Vault line, the access mode (view and type, end-to-end encrypted) and a short session ID. The process keeps running after the command returns.
shell also does two things to the Claude Code command line before it runs it. Both are visible in summary_claude.go. It adds --session-id with a fresh random UUID (version 4, as defined in RFC 9562), so it knows exactly which conversation this session runs. And it passes --settings with a SessionStart hook that writes the conversation's ID to a private file whenever Claude Code starts, resumes, clears or compacts a conversation. That is how the binding follows /clear and /resume. Both flags are documented in the Claude Code CLI reference.
The summary switch lives on the session's record in your account, so you address it by the account's ID. List the sessions in your account from any linked machine:
+shell ls
+In a wide terminal the table has the columns ID, NAME, STATUS, UPTIME, MACHINE and COMMAND, newest first; a narrow one gets a compact list instead. Sessions that have ended are hidden and counted on the last line. The ID column is shortened to ten characters for reading. For the full value, ask for JSON and pick the session by name:
+shell ls --json | jq -r '.[] | select(.name == "checkout tests") | .id'
+shell ls --json prints an array of records with id, name, status, host and the share URL. It never prints a password. If you named a session well in step 1, this is the only place you need its ID. The post on --name and shell ls covers listing across machines in more detail.
Summaries are off by default and opt-in per session. Turn them on with the ID from step 2 (this one is invented):
+shell permissions 7f3c9a2e-example-session-id --summaries=true
+The command prints Session summaries: on and a note that summaries need an updated compatible host and your vault. Other switches on the session are left as they were. Run shell permissions with only the ID to read all four switches back. Only the session's owner can change them.
The same switch is in the web app, on the session page under Agent permissions, labelled Summaries. Changes made in either place show up in the other. Switching it off deletes the stored summary and stops capture.
+Open app.shell.online on the phone and sign in. Summaries are encrypted to your vault key, so the browser has to open your vault before it can show one; until then the card says so. In the List or Board view, press and hold a session's row or card for half a second. On a laptop, hovering over the row does the same.
+The card shows a title, a state, the latest reply and a line saying where it came from, such as From Claude Code · 4m ago. For a Claude Code session the title is the conversation's own title and the reply is the latest assistant text, cut to 480 characters. The state is Waiting for input when the last turn ended normally and Idle when you interrupted it. Until the first summary is made, the card shows No summary yet.
When a summary tells you a session needs you, tap into it, enter the password and reply. The mobile guide covers the terminal on a phone, and the post on reading Claude Code as a conversation covers the chat view that makes replying on a small screen easier.
+The host checks every 15 seconds. For Claude Code it reads the conversation's transcript, the JSON Lines file Claude Code keeps under its projects directory, and publishes only when a turn has finished. A turn still in progress is skipped, because its summary would be stale by the time you read it. Each finished turn is published once.
+No model runs for a Claude Code summary, and the agent is never prompted. The host takes the title and the latest assistant text from the transcript, never thinking blocks or tool output, cleans them to plain text and encrypts the result to your vault key on your machine. The account service stores ciphertext it cannot open.
+The binding only happens for an interactive conversation. If you pass your own --settings, use -p, or start with a single word such as shell claude review (which could be a Claude Code subcommand), shell leaves the command line alone and cannot tie the session to a transcript. Such a session is then summarised like any other program, through the enclave described below. Quote a prompt with spaces in it, or start with no prompt at all, and the transcript path is used.
Other processes have no transcript shell reads, so their summaries come from terminal output. When summaries are on, the session counts as idle after about 20 seconds without new output. The host then strips terminal control sequences (the kind listed in the console_codes man page), redacts credential-shaped text, and sends the last 12 KiB, encrypted, to the shell.online summarizer.
+It does that only after checking the summarizer's attestation: an Intel TDX confidential VM running Google's production Confidential Space image, a container image on an allowlist signed by the shell.online release key, and an encryption key generated inside that instance. The summarizer runs Qwen3-4B-Instruct with no tools and no internet access, and encrypts the summary to your vault key before it leaves the enclave. These cards say Generated in an attested enclave. The full trust boundary is in docs/summaries.md.
--read-only.claude --bg session under Claude Code's supervisor. For those, claude logs <name> on the machine, or Anthropic's Remote Control, is the tool.An earlier post, on the passive pulse in v0.22, covers the cheaper signal: whether a session is printing at all. Summaries add what it said.
+shell.online is developed by Pilot Protocol, a networking stack for autonomous agents. Summaries travel through the shell.online account service, not over Pilot. The two meet when your agents need to talk to each other rather than to you: connecting Claude Code to Pilot takes one MCP server and gives the agent tools to message other agents and query data services. If you keep agents on several machines and want them to report state to one place on their own, Pilot's write-up on monitoring without Prometheus shows that pattern over its encrypted event stream.
+Install shell, link the machine with shell auth, start a named session, and turn on summaries. The source and the summarizer's security model are on GitHub.
+Get shell.online on GitHub +On September 26 the maintainers of brig, a tool that runs a coding agent inside a microVM on your own machine, published advisory GHSA-wp6x-29qx-fpr7, rated high with a CVSS score of 8.2 and fixed in brig 0.3.0. Two days later Peyton Kennedy of Endor Labs, who reported it, explained how it worked. brig checked the workspace directory carefully but handed the project folder to the runtime as an unresolved path. An agent with write access to the project could replace a subdirectory with a symlink to any other directory on the host, and the next run that named that subdirectory mounted the link's target into the sandbox, read and write.
+Adversa AI put the bug in its October roundup of coding agent security research, next to a run of other cases where the files in a project turned out to be the attack. The lesson reaches beyond sandboxes. Any time you expose a directory that an agent writes into, the agent decides what that directory contains, links included. If the code that exposes it trusts a path without resolving it, the agent can widen what you exposed.
+shell.online can expose a directory too. With --files, people watching a session in the browser can open files from the machine the session runs on. This guide shows how to choose that directory, how the host refuses a link that points outside it, and what it still lets through. Every behavior below comes from the shell.online repository at v0.25.0, and I checked the symlink and hard link cases on macOS.
File access is off unless you ask for it when the session starts. There are two flags. --files shares regular files under the command's working directory. --files-root shares a directory you name and leaves the command's working directory alone:
cd ~/work/example-app
+shell --files-root ./out claude
+Claude Code runs in ~/work/example-app with its usual access, and browser viewers can reach only what sits under ./out. The session card shows the root by its last path component:
Access view and type · end-to-end encrypted
+ Files out · on demand
+If you add --json, the new-session event carries the same value in a files field. If the directory does not exist, shell stops with an error that includes open shared files root and exits with status 1 before anything is shared.
Two limits come with the flags. File sharing needs end-to-end encryption, so shell --no-e2ee --files ... stops with shell: --files and --files-root require end-to-end encryption. And the root is fixed for the life of the session. There is no command to add a directory to a running share, so choose before you press Enter. The CLI reference lists both flags.
A good root is a directory the run produces output into: test reports, screenshots, a build's dist folder, a training run's checkpoints. A poor root is the repository itself, and a bad one is your home directory.
The host opens the root once, at startup, with Go's os.Root type. If the path you pass is itself a symlink, that link is followed when the root is opened. I confirmed this on macOS: a root given as linkroot, a symlink to another directory, opened that other directory and served its files.
That matters when the root is a directory the agent could have touched on an earlier run, which is the brig situation. Endor Labs' workaround for unpatched brig users applies here unchanged: resolve the path before you hand it over, so there is no link left to follow. pwd -P prints the physical directory with every symlink resolved:
ls -ld ./out
+shell --files-root "$(cd ./out && pwd -P)" claude
+The first command shows whether out is a real directory or a link, with an arrow and a target if it is a link. The second starts the session on the resolved path. If the card then shows a name you did not expect, stop the session and look at the directory before you share the link.
Viewers see a Files control in both the xterm.js view and the Refstream view. Nothing is sent ahead of time. The browser asks for a directory listing when someone opens the panel, and asks for a file when someone opens that file. Refstream also turns filenames that appear in terminal output into previews, but the Refstream page is explicit that a filename printed on screen does not grant access to it. The security page adds that every request is checked on the host, including traversal and symlink escapes.
+From the file service in the CLI, these are the limits a viewer meets:
+Requests and file bytes travel over the session's existing encrypted WebSocket. The relay routes request IDs and sees encrypted frame sizes, not paths or contents. The encryption page covers what the relay can and cannot read.
+One rule surprises people: a read-only link can still read files you opted in. --read-only blocks typing into the process. It does not withdraw file access. The post on read-only links after Plugin4Shell covers what read-only does block.
Here is the brig move against a shell root. Suppose the agent, or a script it ran, does this inside the shared directory while the session is live:
+cd ~/work/example-app/out
+ln -s ~/.ssh keys
+Two things happen on the host. First, keys does not appear in the Files panel, because listings skip symlinks. Second, if a viewer requests keys/id_ed25519 by name anyway, the open fails and the host answers "File unavailable." A path with .. in it, or an absolute path outside the root, is turned away even earlier by the host's own path check, with "File access denied."
The refusal does not come from comparing strings. As the Go team's post introducing traversal-resistant file APIs describes it, os.Root disallows any operation that would escape the root through .. or through symlinks. A comment in shell's file service states the intent: escapes fail at the filesystem boundary rather than through string-prefix checks. In my macOS test, opening escape/key through a link pointing outside the root failed with "path escapes from parent". This is the class of bug CWE-59, link following, describes, and it is close kin to the path traversal attacks OWASP documents for web servers.
A symlink that stays inside the root is different. os.Root permits it, so a viewer who already knows the link's name can open it, even though the listing does not show it.
Everything regular under the root is readable, including dotfiles. The host does not hide names that start with a dot. If you run shell --files claude at the top of a repository, a viewer can open .env, .git/config and anything else in that tree. Manifold Security's GitSpawn research is a reminder of how much can live in .git/config alone. Point --files-root at an output directory instead.
File access lasts as long as the viewer's connection to the session. To cut off everyone who has the current password without stopping the agent, rotate it:
+shell list
+shell password rotate 7f3a9c
+shell list prints your active sessions with their IDs, and the rotate command takes a session ID or a prefix of one. Rotation disconnects old viewers, changes the password and salt, and revokes existing MCP grants. The process keeps running. The guide to revoking a link without killing the process walks through what each viewer sees. To end the run and the link together, use shell kill -- 7f3a9c.
ln ~/.config/example/token out/token on the same filesystem, the root now holds a regular file with that content. In my macOS test, os.Root opened such a file without complaint. The defense is the same as in Step 1: a root that holds only output you would hand over anyway.os.Root does not stop traversal of mount points such as Linux bind mounts, since only root can create them.The earlier post on sharing a session without handing over the filesystem covers the design of the file feature when it shipped.
+shell.online is built by the team behind Pilot Protocol, a networking stack for autonomous agents. A Files panel is for a person who wants to look at a report. When one agent needs to hand a dataset or a set of weights to another agent, Pilot's write-up on peer-to-peer file transfer between agents shows how files stream over an encrypted tunnel without a storage bucket in the middle. The same scoping question applies there: decide which peer may receive what before anything moves. The Pilot security docs describe how a private node rejects streams from a peer unless it has an approved trust relationship with that peer or the two share a network.
+Start the run with --files-root pointed at a resolved output directory, and keep the repository and your home directory out of reach.
On September 29, at DevDay, OpenAI shipped GPT-6.1 Sol. The number everyone repeated was the price: $2 per million input tokens and $10 per million output tokens on the API pricing page, which The Next Web worked out to a fifth of what GPT-6 Astra costs. It is in Codex already, and OpenAI's own model guide now points people at Sol for long, repeated work.
+ +A price cut like that changes habits faster than any benchmark does. The refactor you used to babysit, because every wrong turn cost real money, becomes something you start and walk away from. And that is where it gets awkward. A two hour run is only useful if you can leave the desk without losing track of it, and if the teammate who reviews the result can see what happened without you pasting screenshots into chat.
+ +This guide is the setup for exactly that, start to finish, using shell.online. It takes about five minutes and you do not need an account.
+ +shell command line tool. It is open source on GitHub under the MIT license, so you can read what it does before you run it.On macOS, Linux or BSD:
+curl -fsSL https://shell.online/install | sh
+On Windows, in PowerShell:
+irm https://shell.online/install.ps1 | iex
+The installer verifies the release checksums. If piping a script into a shell is not something you do, the platform page has Homebrew and build from source instructions. Either way, confirm what you got:
+shell --version
+As of this post that prints 0.25.0, the current release.
+shell --name "billing-refactor" -- codex --model gpt-6.1-sol
+Three things in that line are worth a second look.
+-- separates shell's options from Codex's. Everything after it, including --model, goes to Codex untouched.--name is for you in an hour, when there are four sessions open and you need to tell them apart.gpt-6.1-sol is the model id from OpenAI's guide. If you forget the flag, /model inside Codex gets you to the same place.shell starts Codex as a new process in the background and prints three things: a link, a password and a QR code. It does not attach to a Codex that is already running, so start the run this way from the beginning. The Codex CLI docs cover the flags on the right side of the --, and the shell command reference covers the left.
Want to keep typing in the terminal you launched from? Add --foreground, or run shell attach <ID> whenever you like. Press Ctrl-X and then D to detach again. Codex keeps going either way.
Scan the QR code. That is the whole step. The page that opens is the same terminal, live. It is not a second copy of the agent. When Codex stops to ask whether it may run a migration, you can answer from the bus, and the mobile guide explains paste and the on-screen keys.
+Two things trip people up here.
+First, the QR code contains the password. That is what makes it a single scan, and it is also why it should never end up in a screenshot. This is not a theoretical worry. Glow Labs recently found more than 13,000 internal screenshots from over 300 organizations sitting in public GitHub repositories, pushed there by coding agents that had no better way to attach an image to a pull request. A picture of your terminal with a QR code in the corner is a picture of your credentials.
+Second, the process lives on your computer, so the computer has to stay awake and online. Closing the browser tab does nothing to Codex. Letting the laptop sleep stops everything. On a Mac, running caffeinate -i in a spare tab or changing the sleep settings keeps it up. On Linux, systemd-inhibit does the job, and on Windows it is powercfg.
If you would rather the run survive a closed laptop entirely, that is what Codex Cloud is for. The trade is that your code then runs on OpenAI's machines and not on yours. For a repository with production credentials in its environment, I would keep the run local and keep the lid open.
+The link you just scanned is interactive. Anyone holding it and the password can type into Codex with the same operating system permissions Codex has. That is right for you and wrong for almost everybody else. A reviewer needs to watch. So does the manager who asked how it is going, and so does the channel where you want to show the thing off.
+For them, start the session read-only:
+shell --read-only --name "billing-refactor" -- codex --model gpt-6.1-sol
+Read-only is enforced by the server, which rejects input coming from a browser. It is decided when the session starts and it cannot be upgraded afterwards, so nobody talks their way into typing. You still drive Codex from the host with shell attach. Security people call this the principle of least privilege: each person gets the access their job needs and nothing above it. The security page spells out what each kind of link allows.
Send the link and the password through different channels. Put the link in the team chat and the password in a direct message, or use your password manager's sharing feature. Chat logs get searched, exported and forwarded, and a link on its own opens nothing.
+If you are wondering what the relay in the middle can read, the short answer is ciphertext. The part of the link after the # is a random salt, and a URL fragment is never sent in a request. Your browser combines that salt with the password using PBKDF2 at 600,000 iterations, the figure the OWASP password storage cheat sheet recommends for PBKDF2 with SHA-256. Out comes an AES-256-GCM key, derived through the browser's built in Web Crypto API. The encryption page has the full description, and there is a separate post on what the relay sees and what it cannot replay.
Read-only does not cover files. File access is off by default. If you start a session with --files, a read-only viewer can still fetch files under that directory. Leave the flag off when the audience only needs to watch.
Cheap tokens rarely buy one long run. They buy several at once. OpenAI plainly expects this, because the refreshed Codex CLI has an /agents view for handing out tasks and following them, and Claude Code has its own subagents. Those views live inside one tool. shell's list works across all of them, because it tracks terminals and does not care what is running in each.
shell list
+That prints every share on this machine with its name and uptime. To see the same thing across a laptop, a build box and the Mac mini in the closet, link each of them once with shell auth. After that shell ls shows every open session in your account, and app.shell.online shows it on your phone. The account is optional, and seeing a session in the list does not reveal what is in it. You still need the password, or your own vault, to decrypt anything. The app guide covers inviting a teammate into an organization.
Version 0.25.0, released on October 2, adds something that helps here: session summaries. Hover over a session in the app, or long-press it on a phone, and you get a sentence about what that run is doing. It is off by default and you opt in per session:
+shell permissions <ID> --summaries=true
+Read how summaries are produced before you turn this on for a Codex session. Claude Code sessions are summarised on your own machine. Other programs, Codex included, send redacted output, encrypted, to a summarizer running inside an attested confidential computing enclave, and only after your host has verified that attestation. It is a careful design, and you should still know which of the two paths your session takes. The changelog lists the rest of the release.
+When the review is over, do not leave a working link lying in a chat log.
+shell password rotate <ID>
+Rotation disconnects everyone who is watching, changes the password and the salt, and revokes any MCP grants on the session. Codex keeps running through all of it. Removing a person from your organization does not do the same job, because it cannot erase a password they already know. There is a longer post on revoking a shared link without killing the process if you want the exact order of events.
+And when the run itself is finished:
+shell kill -- <ID>
+A few limits, stated plainly, because they decide whether this fits your case.
+shell.online is developed by Pilot Protocol, and the family resemblance is deliberate. Pilot is a networking stack for autonomous agents. Each agent gets an address, discovers its peers and talks to them over encrypted tunnels, and nobody has to open a port. Anyone who has tried to reach an agent behind NAT without a VPN knows the problem well.
+shell solves the human half of it. Your laptop dials out, the relay passes ciphertext along, and you reach the terminal from a phone on hotel wifi. The encryption choices rhyme too. Pilot's write-up of X25519 and AES-256-GCM in pure Go is a good next read if step 4 made you curious, and the Pilot docs show the agent side of the same idea.
+Put shell in front of the command you already use. You get a link for your phone and a read-only link for your team, and the process never leaves your machine.