Skip to main content

ADR-166: WebSocket Protocol for Browser IDE - Sidecar Communication

Status: Proposed Date: 2026-02-09 Author: Claude (Opus 4.6) Deciders: Hal Casteel, Engineering Team Tags: protocol, websocket, browser-ide, sidecar

Context

The CODITECT Browser IDE requires a real-time bidirectional communication channel between the WASM client in the browser and the native sidecar process. This channel must support:

  1. Agent streaming - Token-by-token LLM responses (high throughput, low latency)
  2. Terminal I/O - Raw byte streams for PTY (latency-critical)
  3. File operations - Large file content transfers (throughput-critical)
  4. Tool use events - Structured agent tool calls and results (reliability-critical)
  5. Diagnostics - LSP-like diagnostics pushed from sidecar (periodic)

We must choose a protocol and wire format for this communication.

Decision

Use WebSocket with MessagePack binary framing over two dedicated connections:

Connection 1: IDE Channel (ws://localhost:42424/ws)

  • Agent messages, file operations, completions, search, diagnostics
  • MessagePack binary frames for efficiency
  • Request-response correlation via UUID id field
  • Server-initiated push for diagnostics and agent streaming

Connection 2: Terminal Channel (ws://localhost:42424/ws/terminal)

  • Raw binary frames for PTY I/O
  • Text frames for control messages (resize, close)
  • One WebSocket per terminal session

Wire Format

MessagePack envelope:
{
"id": "uuid-v4", // Request correlation
"type": "AgentChat", // Message type enum
"ts": 1707436800000, // Unix millis
"payload": { ... } // Type-specific data
}

Reconnection Strategy

  1. Heartbeat: client sends Ping every 15s, expects Pong within 5s
  2. On disconnect: exponential backoff (1s, 2s, 4s, 8s, max 30s)
  3. On reconnect: send Reconnect{session_id} to resume agent state
  4. Session state persisted in SQLite, survives sidecar restart

Alternatives Considered

Alternative 1: HTTP/2 + SSE

Use HTTP/2 for requests, Server-Sent Events for streaming responses.

Rejected because:

  • SSE is unidirectional (server-to-client only)
  • Terminal I/O requires bidirectional binary streaming
  • Two separate transports (HTTP + SSE) add complexity
  • No standard reconnection protocol for SSE

Alternative 2: gRPC-Web

Use gRPC-Web with Protocol Buffers.

Rejected because:

  • Requires Envoy proxy or grpc-web-proxy for browser compatibility
  • Complex tooling overhead for a localhost connection
  • Protobuf code generation adds build complexity
  • MessagePack is more flexible for evolving schemas

Alternative 3: JSON over WebSocket

Use JSON text frames instead of MessagePack binary frames.

Rejected as default because:

  • 2-3x larger payload size than MessagePack
  • Slower serialization/deserialization
  • Retained as fallback for debugging (?format=json query parameter)

Alternative 4: WebTransport (HTTP/3)

Use WebTransport for multiplexed streams.

Rejected because:

  • Not universally supported in browsers (2026 coverage ~85%)
  • Requires HTTPS/TLS for localhost (self-signed cert management)
  • Overkill for localhost communication
  • Could revisit for cloud deployment

Consequences

Positive

  • Single WebSocket connection for IDE operations (simple lifecycle)
  • MessagePack is 30-50% smaller than JSON, faster to parse
  • Separate terminal WebSocket isolates high-frequency PTY I/O
  • UUID correlation enables concurrent requests without head-of-line blocking
  • Reconnection with session resume prevents data loss

Negative

  • MessagePack requires library in both Rust (rmp-serde) and TypeScript (msgpack-lite)
  • Binary frames harder to debug than JSON (mitigated by JSON fallback mode)
  • Two WebSocket connections per browser tab

Protocol Evolution

  • Version byte in frame header allows future format changes
  • New message types can be added without breaking existing clients
  • Payload schema is flexible JSON/MessagePack (no rigid protobuf schema)

Message Type Catalog

Client -> Server (22 types)

CategoryTypes
SessionAuthenticate, Ping, Reconnect
AgentAgentChat, AgentCancel, AgentUndo
FileFileOpen, FileEdit, FileSave, FileList, FileCreate, FileDelete
TerminalTerminalCreate, TerminalInput, TerminalResize, TerminalClose
CompletionInlineComplete
SearchSearchFiles, SearchSymbols, SearchRepoMap
ConfigGetConfig, SetConfig

Server -> Client (18 types)

CategoryTypes
SessionAuthenticated, Pong, Error, SessionResumed
AgentAgentThinking, AgentToolUse, AgentToolResult, AgentStreamChunk, AgentComplete
FileFileContent, FileTree, DiagnosticUpdate
TerminalTerminalCreated, TerminalOutput, TerminalExited
CompletionInlineCompletionResult
SearchSearchResults
  • ADR-165: WASM Split Architecture
  • ADR-169: Browser Terminal Emulation
  • SDD: docs/architecture/browser-ide/SDD-CODITECT-BROWSER-IDE.md