terminal-proxy
v0.1.1
Published
Local PowerShell shared with a browser via devtunnel
Readme
Terminal Proxy
Windows-only npm package for sharing one local PowerShell session between:
- a local Windows Terminal viewer
- a browser connected through
devtunnel
Run a Node.js server in PowerShell that:
- Spawns a real PowerShell child shell (via
node-pty/ ConPTY). - Pops up a separate Windows Terminal window attached to that shell so you can watch and type into it locally.
- Exposes the same shell over HTTPS via
devtunnel, so you can attach a browser from anywhere. - Both viewers share one shell session: type in either, both see the output.
Prerequisites
- Windows 10 / 11 with Windows Terminal (
wt.exe) installed. - Node.js 20.10+ on PATH.
- PowerShell 7+ (
pwsh.exe) on PATH (falls back topowershell.exe). - devtunnel CLI on PATH — install: https://aka.ms/devtunnels/download.
- One-time login:
devtunnel user login(Microsoft / GitHub account).
Install
Global install
npm install -g terminal-proxy
terminal-proxyOne-shot with npx
npx terminal-proxyLocal development
cd C:\Code\Terminal-proxy
npm install
npm run build
npm startThe server prints something like:
Terminal Proxy ready
Local: http://127.0.0.1:7890
Public: https://abc-1234.usw2.devtunnels.ms
Token: k9bH...random...A new Windows Terminal window opens automatically, attached as the local viewer. Open the Public URL in a browser — sign in to Microsoft when prompted (devtunnel access control), then paste the Token when the page asks for it.
Type in either the local Windows Terminal window or the browser; both views update.
CLI commands
terminal-proxy— starts the server and opens the local viewer window.terminal-proxy-viewer --url <ws://host/ws> --token <token>— connects a terminal viewer to an existing server.
Detaching the local viewer
Inside the local Windows Terminal viewer, press Ctrl+] to detach without killing the server. Closing the window also detaches.
Stopping the server
Ctrl+C in the host PowerShell window where you ran npm start. This kills the child PowerShell, the local viewer, and the devtunnel.
Security model
- Two-layer auth: Microsoft sign-in on the devtunnel plus a random bearer token printed at startup. The token is required on the WebSocket upgrade.
- No anonymous access: the server does not pass
--allow-anonymousto devtunnel. - Origin check: WebSocket upgrades only accept the local 127.0.0.1 origin and the live devtunnel hostname.
- No persistence: input/output is not written to disk.
There is one shell shared by all clients. Anyone who passes both auth layers gets full keyboard access to the same shell. Treat the bearer token like a password.
Configuration
Environment variables:
TP_PORT— local HTTP port (default7890).TP_SHELL— shell binary (defaultpwsh.exe).
These can be used with the packaged CLI too:
$env:TP_PORT='7895'
$env:TP_SHELL='pwsh.exe'
terminal-proxyProject layout
src/
config.ts # token + port + shell
pty.ts # node-pty + server-side xterm snapshot model, broadcast hub
ws.ts # WebSocket auth + JSON envelope protocol
devtunnel.ts # spawn `devtunnel host`, parse public URL
viewer.ts # local CLI client (runs in the separate WT window)
server.ts # entrypoint
public/
index.html # token prompt + xterm container
client.ts # xterm.js wiring (built to client.js)Reconnect model
- The server keeps a canonical, size-aware terminal state with
@xterm/headless. - A reconnecting client must send its terminal size first (
hello) before the server snapshots anything. - The snapshot is taken only after that size is applied, so wrapped lines and cursor position match the reconnecting viewport.
- Browser reconnects also ignore stale WebSocket events from older socket generations.
This is the main guard against old screen content, mixed wrapping, and misplaced cursors after refresh or reconnect.
Troubleshooting
devtunnel: command not found— install the CLI from the link above and reopen your shell.devtunnel exited before producing a URL— rundevtunnel user loginonce.node-ptybuild fails onnpm install— install Visual Studio Build Tools (C++ workload) and Python 3, or use a Node version with prebuilds (20.x / 22.x).- No Windows Terminal window opens — make sure
wt.exeis on PATH; otherwise the server falls back to a plain PowerShell window viacmd /c start.
Publishing notes
The npm package publishes only the runtime files:
dist/server.jsdist/viewer.jspublic/index.htmlpublic/client.jsbin/
npm pack and npm publish automatically run npm run build through the package prepack hook.
