Protocol Overview
The TermSurf protocol is the most important artifact in the project. It defines how terminals, browser engines, and TUIs communicate over Unix sockets using length-prefixed protobuf messages.
Wire Format
Every message on the wire is a serialized TermSurfMessage
protobuf, prefixed with a 4-byte little-endian length:
[4 bytes: length (LE u32)] [N bytes: serialized protobuf] TermSurfMessage is a wrapper with a oneof msg
field. Each message on the wire is exactly one variant.
Connections
The GUI (Wezboard) listens on a PID-scoped Unix socket. Two types of clients connect:
- TUIs — discover the socket via the
TERMSURF_SOCKETenvironment variable. Send overlay and navigation messages. - Browser engines — receive the socket path via
--ipc-socket=command-line argument. Send registration and state updates.
The GUI identifies the connection type from the first message:
ServerRegister means browser engine, anything else means TUI.
Message Categories
| Category | Direction | Messages |
|---|---|---|
| Tab lifecycle | GUI → Engine | CreateTab, CreateDevtoolsTab, Resize, CloseTab |
| Navigation | TUI → GUI, GUI → Engine | Navigate |
| Input | GUI → Engine | MouseEvent, MouseMove, ScrollEvent, KeyEvent |
| State | GUI → Engine | FocusChanged, SetColorScheme |
| Engine events | Engine → GUI | ServerRegister, TabReady, CaContext, UrlChanged, LoadingState, TitleChanged, CursorChanged, TargetUrlChanged |
| Overlay | TUI → GUI | SetOverlay, SetDevtoolsOverlay, OpenSplit |
| Mode sync | TUI ↔ GUI | ModeChanged |
| Direct connection | GUI → TUI | BrowserReady |
| Request/reply | TUI ↔ GUI | Hello, QueryLast, QueryDevtools, QueryTabs |
Message Flow
A typical session when a user types web example.com:
- TUI connects to GUI socket
- TUI sends
HelloRequest→ GUI repliesHelloReply - TUI sends
SetOverlaywith URL, profile, pane dimensions - GUI spawns browser engine (if not already running for this profile)
- Engine connects, sends
ServerRegister - GUI sends
CreateTabto engine - Engine creates WebContents, sends
TabReady - GUI sends
BrowserReadyto TUI (with engine's listen socket) - TUI connects directly to engine for navigation
- Engine renders, sends
CaContext(GPU layer ID) - GUI creates
CALayerHostoverlay — browser appears in pane
Direct Browser Connection
After initialization, the TUI can send Navigate and
SetColorScheme directly to the browser engine, bypassing the
GUI. The engine also listens on its own socket (passed via
--listen-socket=). The GUI provides this path to the TUI in
the BrowserReady message.
Serialization
- Rust (GUI, TUI, engines) — prost
- C++ (Chromium) — protobuf
The protocol is defined in proto/termsurf.proto. See
Messages for the full reference.