Overview
The web mirror is a Bun-served HTTP + WebSocket endpoint that streams the full τ-mux UI to anything on the LAN. Terminal text, sideband panels, metadata chips, and notifications all flow over a single WebSocket.
This is a feature overview — see Web mirror feature for the user-facing summary, and protocol v2 for wire-format details.
What it does
Section titled “What it does”- Renders the same xterm.js view as the native app.
- Mirrors workspaces, sidebar, sideband panels, notifications.
- Round-trips stdin (typing in the browser → PTY).
- Exposes port chips that open
http://<host>:<port>from the viewer’s machine. - Resumes seamlessly across disconnects via a 2 MB ring buffer per session.
Who it’s for
Section titled “Who it’s for”- Phone / iPad as a glanceable monitor while you’re away from the desk.
- Pair-programming over a LAN without screen sharing.
- Touch-screen terminals.
- Lightweight remote access without SSH (when the LAN is trusted).
How to enable
Section titled “How to enable”In the τ-mux app:
- Settings → Network → Auto-start Web Mirror to turn it on at launch.
- Settings → Network → Token to require auth (recommended for any non-loopback bind).
- Note the URL —
http://<your-laptop-ip>:3000by default.
Or by env (forces auto-start regardless of the setting):
HYPERTERM_WEB_PORT=3000 bun startPerformance notes
Section titled “Performance notes”- Stdout coalesced at 16 ms granularity.
- Metadata changes deduped server-side — only deltas go on the wire.
- Resume uses
@xterm/headless+SerializeAddonfor a single-frame catch-up snapshot.
Updates and the service worker
Section titled “Updates and the service worker”The mirror ships as an installable PWA backed by a service worker. When a new τ-mux build is deployed and a previous SW is still controlling an open page:
- The new SW stays in the
waitingstate — it does not auto-activate mid-session. - The page renders a small banner: “A new version is available.” with Reload and Later buttons.
- Reload posts
{type: "SKIP_WAITING"}to the waiting SW; the SW activates;controllerchangefires and the page reloads onto the new bundle. - Later dismisses the banner without affecting the running session — the new bundle waits until you reload manually or open a new tab.
- Old caches are deleted in the new SW’s
activatehandler — i.e. only after you accept the update — so a tab still on the old version doesn’t suddenly white-screen on a fresh asset request.
First-install path (no previous SW) is unchanged: the very first SW skips waiting automatically so the app comes up immediately.
Source files
Section titled “Source files”src/bun/web/server.ts—Bun.serve, envelopes, resume, auth.src/bun/web/connection.ts— per-session ring buffer + seq tracking.src/bun/web/state-store.ts— server-side cache.src/web-client/— client bundle.