Share a Windows Terminal Session in the Browser: Codex on ConPTY, Without OpenSSH or WSL

Share a Windows Terminal Session in the Browser: Codex on ConPTY, Without OpenSSH or WSL

OpenAI published Codex CLI 0.160.1 on October 5, and its one listed fix is for Windows: SYSTEMROOT, TEMP and TMP are now preserved when Codex launches a remote stdio MCP server with explicitly configured remote environment variables. Version 0.160.0, four days earlier, fixed Windows sandbox PowerShell fallbacks and long-path permission repairs. Before that, 0.159.2 on September 29 stopped console windows flashing when Codex starts background processes and sandboxed commands. OpenAI's Windows documentation for Codex describes running natively in PowerShell with a Windows sandbox instead of requiring WSL or a virtual machine. With the agent running on the Windows desktop itself, the practical question is how to share a Windows terminal session in the browser when that desktop is at the office and you are somewhere else.

Codex and shell.online need the same Windows component

The same OpenAI page says that on Windows 10, Codex depends on modern console support, including ConPTY, and that in practice version 1809 or newer is required. Microsoft's reference for the CreatePseudoConsole function lists the same floor: Windows 10 October 2018 Update (version 1809). shell.online has the same requirement for the same reason. Running shell help windows prints this line in its platform table:

Windows:     386, amd64, arm64 (Windows 10 1809+; native ConPTY)

A pseudoconsole lets one program host a console application without a console window. The host creates the input and output channels, starts the child process attached to them, and reads back UTF-8 text interleaved with virtual terminal sequences. Microsoft's guide to creating a pseudoconsole session points out that the host may relay those channels over a network so that another machine does the presenting.

That is the design of shell.online, a browser link to any terminal process, on Windows. In cmd/shell/process_windows.go the CLI opens a pseudoconsole, sizes it to the session grid, and starts your command inside it. Terminal payloads are encrypted on the PC before a relay forwards them, and a browser holding the link and the password decrypts and draws them. Codex is started the way any terminal would start it.

How to share a Windows terminal session in the browser

Two commands in PowerShell:

irm https://shell.online/install.ps1 | iex
shell codex

The installer reads the processor architecture, downloads shell-windows-amd64.exe (or the 386 or arm64 build) together with the SHA256SUMS manifest, and stops if the SHA-256 of the binary does not match. It copies shell.exe to %LOCALAPPDATA%\Programs\shell.online. If that directory is not on PATH, it prints the commands that would add it and leaves PATH alone. It also sends one request reporting how the install went and which binary it was; setting SHELL_ONLINE_INSTALL_REPORT=0 skips that.

The second command starts Codex in a detached background process and prints a link, a ten-character password and a QR code. Open the link on a phone, enter the password, and you are looking at the same Codex session and can type into it. The rest of the command reference applies unchanged: shell list shows the sessions on the PC, shell attach <ID> joins one from a local console (Ctrl-X, then D detaches), and shell kill -- <ID> stops one. Running shell with no command starts pwsh.exe if it is on PATH, then powershell.exe, then whatever COMSPEC names. The link, password and QR flow itself is described in our first post about the tool, written when encryption was still an opt-in flag. It is on by default now.

Compare the usual route. Microsoft's OpenSSH Server guide for Windows asks for an account in the built-in Administrators group, the OpenSSH Server optional feature on Windows 10 and 11, a started sshd service, and an inbound firewall rule named OpenSSH-Server-In-TCP on port 22. After all of that, the PC still has to be reachable through whatever NAT it sits behind. The shell CLI needs outbound HTTPS and WebSockets, so there is no Windows service to enable and no inbound rule to add. Machines that can dial out but cannot be dialed are the same problem Pilot Protocol handles for agent-to-agent traffic with STUN, hole-punching and an encrypted relay fallback. Here the other end is a browser, so a relay carries everything.

What the Windows build does differently

The Windows-specific code is a handful of files ending in _windows.go in the MIT-licensed repository. Three differences are worth knowing before you rely on it.

  • Local control is a named pipe. shell attach and shell kill reach a session over \\.\pipe\shell-online-<ID>, which local_transport_windows.go creates with a protected DACL granting access to SYSTEM, the built-in Administrators group and your own user SID. A --persistent state file gets the same DACL, because Unix permission bits mean nothing on Windows. Read that list literally: another administrator on the same PC can open the pipe.
  • Stopping a session stops the process tree. The command is assigned to a job object with JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE, so closing the job terminates everything Codex spawned along with Codex. The source notes one gap: a very short command can exit before Windows allows the assignment.
  • Windows has no SIGWINCH, so the size of a local console is polled every 250 ms instead of arriving as a signal.

What does not work on Windows yet

There is no service installer. On macOS and Linux, agreeing to browser-started sessions during shell auth also installs the machine daemon as a background service, so an idle machine stays reachable after a restart. On Windows, the installer function returns an error whose text is "installing a background service is not supported on this platform yet". The daemon still starts whenever you run a shell command on a linked machine that has remote start allowed, and its control channel is a named pipe with your user SID in the name, so two people signed in to one PC each get their own. It does not come back by itself after a reboot. The comment in service_other.go explains the choice: we would rather say so than ship a scheduled task nobody has run.

Commands typed into the web app are handled differently too. A line with no shell metacharacters runs directly as an argument list. Anything else is handed to powershell.exe -NoLogo -NoProfile -Command. The backslash is on the metacharacter list, so on Windows any command containing a path such as C:\work\build.ps1 takes the PowerShell route, and -NoProfile means the aliases and functions in your profile are not loaded.

Two smaller limits. The SessionStart hook that keeps a Claude Code session summary bound across /clear and /resume relies on a POSIX shell, so it is unavailable on Windows and sessions there bind only through --session-id. And test coverage is uneven: the CI workflow runs the Go test suite on a windows-latest runner, including a test that starts cmd.exe in a real pseudoconsole and one for list, attach and stop, and then exercises the installer's checksum verification. The platforms page states the result plainly: native runtime checks on amd64, with the 386 and arm64 builds build-verified only.

The process and its pseudoconsole stay on the PC, so a PC that goes to sleep takes the session offline. The CLI and the browser retry temporary connection failures automatically, and an ordinary disconnected share can recover its link for 12 hours. Set the power plan accordingly before leaving an agent running overnight.

Who can type into the PC

The link and the password together are a bearer credential. Anyone holding both can view the session and, unless it is read-only, type into it with the operating-system permissions of the wrapped process. The QR code contains the password as well, so keep it out of screenshots.

This matters more with an agent behind the link. Codex's Windows documentation says agent mode uses the sandbox to block filesystem writes outside the working folder and to prevent network access without your explicit approval. shell.online adds no sandbox of its own, and a viewer who can type can answer an approval prompt. If the person on the other end only needs to watch, start the session read-only:

shell --read-only codex

Per the security page, input is then rejected by both the relay and the CLI, and a modified browser cannot turn the session interactive. If a password has travelled further than intended, shell password rotate <ID> disconnects existing viewers and changes the password and salt while Codex keeps running.

Terminal traffic is end-to-end encrypted by default. The key is derived from the password in the CLI and in the browser, and the URL carries only a random salt. The relay still sees metadata, including connection IPs, timing, encrypted sizes and the terminal grid dimensions. Starting a session with --no-e2ee gives up the content protection and leaves only HTTPS and WSS on each hop, which exposes terminal contents to the relay.

Put a browser link on a Windows terminal

Run the PowerShell installer, then shell codex, or shell alone for a plain PowerShell session. It needs Windows 10 version 1809 or newer and outbound HTTPS.

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