Negotiate downstream delivery credit and schedule response streams fairly before encryption. Bound queued output, preserve deltas and WebSocket close ordering, and retain legacy peer compatibility.
Validated with 81 relay tests, workspace type-check and lint, web build and mobile assets, and slow-link tests through the production relay. Confirmed on LTE by the maintainer.
- A saved host now keeps every transport its pairing link carried: direct URL
plus the relay descriptor, with one token for both (the mobile connection
model). Switching tries the direct leg and falls back to the E2EE tunnel;
list probes report Connected · Relay when only the tunnel reaches the host;
relaunch restore picks direct first
- Host switching trusts the dropdown's fresh probe instead of re-probing on
click (no doubled latency, no transient Unreachable flashes); statuses are
written once with the final outcome, survive the dropdown closing via a
last-known cache, and an unprobed host reads Checking — never Unknown
- Open-in-new-window works for relay hosts: a new IPC command boots the local
UI with the host id injected and the renderer picks the transport; the app
render holds on the relay restore so the splash shows instead of a transient
auth screen (10s safety valve)
- Relay host control socket gained protocol-level keepalive: a missed pong
window terminates and reconnects, so the relay can no longer hold a ghost
registration that leaves every client tunnel hanging; the desktop relay
probe also hard-times-out at 8s instead of hanging status flows
- Services dropdown restyled with mobile-style cards: per-provider usage
cards, per-host instance cards with a selected highlight and a toned
status line, MCP servers grouped in a card
Reworks how devices connect to an OpenChamber server, end to end.
Pairing v2:
- One-time pairing links/QR codes (openchamber://connect?v=2) carrying a set of transport candidates (LAN/tunnel/relay) and a single-use secret redeemed server-side; no tokens embedded in links
- Add-a-device dialog written for first-time users: intent-based transport choice (Anywhere / Home network only / This computer only) with plain-language descriptions, transparent fallback checkboxes, server-authoritative LAN detection, high-res QR dialog
- Private relay folded into pairing as a transport candidate with a demand-driven lifecycle (enables when a relay device is paired, disables when none remain)
Multi-transport devices:
- A saved device holds all its transports and one token; mobile re-probes on connect, resume, and network change and hot-switches LAN<->relay seamlessly (no re-pairing, no remount, session preserved)
- Desktop can import relay pairing links, switch to relay hosts through the E2EE tunnel, and restore a relay default host after relaunch
Device management:
- Device list (web + desktop) shows live per-device connectivity with the active transport (Connected - Local network / Relay) and platform badges (iOS/Android/macOS/Windows/Linux)
- One physical device = one record: stable per-install dedupe keys across pairing and password re-login; typed pairing label names the device, paired devices name the connection by the issuing server hostname
- Trusted desktop-local client manages all devices (list, revoke, clear revoked); relay host reaps dead client sockets after 3 missed keepalives
Android:
- LAN transport unblocked (cleartext + mixed content, mirroring iOS ATS exceptions); resume re-probe retries through network flux and silently auto-reconnects from a disconnected state
Adds OpenChamber Relay — an opt-in way to reach an instance from a phone,
browser, or another desktop from anywhere, with no open inbound ports, no
tunnel, and no shared LAN. The instance dials outbound to a relay; all app
traffic (HTTP, the event stream, terminal, dictation) is multiplexed and
encrypted through a single connection per client, so the relay only ever
forwards opaque ciphertext.
Transport
- End-to-end-encrypted channel over WebCrypto (ECDH P-256 -> HKDF ->
AES-256-GCM) with a capability-negotiated handshake and a small
HTTP/SSE/WebSocket multiplexing protocol. A byte-compatible JS host mirror
is cross-checked by tests.
- Host: outbound connection manager, per-client tunnel dispatcher to the local
server over loopback, reuse of the existing instance identity key, and
management routes. Disabled by default; explicit opt-in.
- Client: plugs into the existing runtime layer (runtime-fetch/-url/-switch/
-auth, event pipeline, terminal, dictation) so features work over the relay
unchanged; direct-URL and Electron realtime-proxy paths are untouched.
Pairing & UX
- Relay section in Settings -> Remote Instances (live status, QR/link pairing,
revocation via the existing client-token list) and the mobile connect flow.
- Frame batching and idle-gated keepalive keep tunnel message volume low
without affecting streaming smoothness.
Security
- The tunnel is transport only; the server authenticates every tunneled
request exactly as for a direct remote client.
fragments only. The relay stores no keys, tokens, or payloads.
Operability
- The endpoint can be pinned to a self-hosted rel
paired clients inherit it from the offer automatically.
- Relay module DOCUMENTATION.md and a relay-trans
invariants that future WebSocket/streaming changes must follow.
The relay transport is complete and tested; the UI for enabling and pairing
is gated behind openchamber_relay_gate and stays