Wire: sockets and framing
How TermSurf bytes move: local Unix domain sockets, length-prefixed protobuf frames, and the TERMSURF_* env clients use to find the host.
What this is
TermSurf IPC is Unix domain socket traffic on your machine—not a public TCP server and not free-form JSON per tool. The payload of each frame is a protobuf TermSurfMessage. Field tables live on Messages; this page is only transport and discovery.
Roles on the wire
client (ahweb / TermSurf app)
│ connect(TERMSURF_SOCKET)
│ framed TermSurfMessage
▼
host (ahterm)
│ --ipc-socket / --listen-socket (spawned helper)
▼
engine helper (ah-chromiumd)- Client — connects to the host socket; does not embed Chromium. Examples:
ahweb,ahcalc. - Host — owns panes and the client-facing socket path; routes work to engine helpers and composites surfaces.
- Engine helper — product path is Chromium (
ah-chromiumd). Connects to the host with--ipc-socket=; may also--listen-socket=for additional local IPC clients. Same framed protobuf language.
Connect
Inside Astrohacker TermSurf, the host injects environment for pane clients:
- Read
TERMSURF_SOCKET— a filesystem path to a Unix domain socket. If it is unset, a client such asahwebcannot open IPC (it is not running inside TermSurf). UnixStream::connect(or language equivalent) to that path.- Read
TERMSURF_PANE_IDso Hello, overlays, and queries name the correct pane.
The host listens; the client connects. There is no public listen port for this protocol. Historical default path shapes under the host’s temp/XDG layout may appear in implementation comments (for example a gui.sock under a termsurf directory)—always prefer the live TERMSURF_SOCKET value the host set for your process.
Frame format
4-byte little-endian unsigned length (u32 LE) of the following payload, then a protobuf-encoded TermSurfMessage.
Write path (conceptual):
- Build a
TermSurfMessageand serialize it (e.g. prostencode_to_vec). - Let
Nbe the payload length in bytes. WriteNas a little-endian u32 (4 bytes). - Write the
Npayload bytes.
Read path (conceptual):
- Accumulate bytes until at least 4 are available.
- Parse the first 4 bytes as little-endian
N. - Wait until
4 + Nbytes are buffered; decode bytes[4, 4+N)asTermSurfMessage; drain that frame and continue.
The same framing is used on client↔host and host↔engine links in the shipped Rust helpers. Do not send bare protobuf without the length prefix.
Protocol environment
Process environment used for protocol discovery and optional traces. Packaging and release knobs (ASTROHACKER_TERMINAL_*) are not the TermSurf wire surface—see monorepo docs/environment.md for the full product taxonomy.
Primary (required for clients)
| Variable | Role |
|---|---|
| TERMSURF_SOCKET | Filesystem path of the host Unix domain socket. Clients connect here (e.g. ahweb). Unset outside TermSurf → client cannot open IPC. |
| TERMSURF_PANE_ID | Pane id for this client process. Identifies which host region the client is bound to (Hello, overlays, queries). |
Secondary (optional debug / harness)
Not required to open a socket or complete Hello.
| Variable | Role |
|---|---|
| TERMSURF_ENGINE_STARTUP_TRACE | Enable engine warmup/startup trace logging. |
| TERMSURF_ENGINE_STARTUP_TRACE_FILE | Optional file path for engine startup traces. |
| TERMSURF_BROWSER_STARTUP_TRACE | Host browser-startup trace. |
| TERMSURF_GEOMETRY_TRACE | Geometry harness / layout traces. |
| TERMSURF_GEOMETRY_SCENARIO | Named geometry scenario for harnesses. |
| TERMSURF_DEVTOOLS_RESERVATION_TIMEOUT_MS | DevTools reservation timeout (milliseconds). |
| TERMSURF_PDF_INPUT_TRACE | PDF input trace toggle. |
| TERMSURF_PDF_INPUT_TRACE_FILE | Optional file for PDF input traces. |
| TERMSURF_WEBTUI_STATE_TRACE_FILE | WebTUI debug state dump path. |
Generated protobuf symbol names such as TERMSURF__TERM_SURF_MESSAGE__MSG_* are API constants, not user environment variables.
Lifecycle notes
- Clients fail closed when
TERMSURF_SOCKETis missing. - Engine helpers that lose the host GUI connection may exit (EOF on the GUI socket is treated as fatal for the helper in the shipped Chromium path).
- Stale socket files from a crashed process are removed by listeners before bind when the helper owns a listen path.
Minimal sequence
- Host starts a pane client with
TERMSURF_SOCKETandTERMSURF_PANE_IDset. - Client connects to the socket.
- Client writes a framed
HelloRequest(see Messages for fields). - Host replies with a framed
HelloReply. Later,BrowserReadymay signal a browser connection for the pane.
Payload catalog
Every frame payload is a TermSurfMessage variant. Full field reference: TermSurf messages. Concepts: protocol overview.
Source
rust/ahweb/src/ipc.rs— client framing andTERMSURF_SOCKETrust/ah-chromiumd/src/ipc.rs— engine length-prefix write/read loopsrust/proto/test-socket/— small language probes for the same wire shape- Monorepo
docs/environment.md— full env taxonomy (protocol vs packaging)
