waos-dev-protocol 0.2.0

What cargo waos and a running WaOS say to each other: the messages of one run, their frames, and the Unix socket that carries them.
Documentation

waos-dev-protocol

What cargo waos and a running WaOS say to each other: the messages of one run, how they are framed on a stream, and the Unix socket on this machine that carries them. The connection is the run (the design's decision 29): cargo waos run connects, sends the program's id and its component, and reads what it writes until it ends; closing the connection, by Ctrl-C or the terminal closing, stops the program, and a later run of the same id replaces it. A run is the program its id names (decision 11 of docs/proposals/2026-10-23-permissions.md), which WaOS runs with that program's settings and folders, installed or not. There is no stop message. waos open <file> --program <id> connects the same way and sends one Open, files to open with the program the id names, which WaOS answers Opened or Refused (decision 3 of docs/proposals/2026-10-29-opening.md, until programs register what opens them). cargo waos screenshot connects the same way and sends one Screenshot of the program an id names, which WaOS answers Screenshots, a WindowPicture for each of its windows, numbered from 1 in the order they opened, with the title the program gave it, its size in physical pixels, whether it is in sight, and its last picture as a PNG, none before it showed one; cargo waos tap, type, key and scroll send one Input to a window of the program, by its number, a Tap or a Scroll at a point in the window's physical pixels from its top-left, Text to commit into what it edits, or a Key or a chord by name (cmd+s), which WaOS answers InputDone once the window shows its next picture, saying whether a new one came. Both are answered Unreached and why while no run of cargo waos run runs the program, for a program the library opened among them, which no tool reads or drives (the design's decision 60), and for a window the program does not have, a point outside the window, text with nothing in the window edited, and a chord naming no key. The socket is in the user's own folder, so the system's file permissions decide who may connect (decision 30); the network transport for phones carries the same messages.

  • Takes: a program's id, its waos-package ProgramId, and its component, from cargo waos; a program's id and files to open with it, from waos open; a program's id with a screenshot or an input to one of its windows, from cargo waos; what the program writes and how it ends, its windows' pictures and what came of an input, from the WaOS app; a tokio runtime, on both sides.
  • Provides: ToWaOS and FromWaOS, the messages, with Input, WindowPicture and Unreached; Connection, which agrees on the protocol's number with the other side first (PROTOCOL, agree_on_protocol), then sends and receives them as frames over a stream, split into a half that sends and one that receives when one task writes a program's output while another watches for the close; socket_path, where a WaOS listens on this machine; Listener, the WaOS side's end, which makes the socket's folder, replaces a socket file a WaOS that died left, refuses to start while another WaOS answers, and removes its file when dropped.
  • Used by: waos-cli, for cargo waos run, screenshot, tap, type, key and scroll, and the WaOS app, which serves them and is waos open.

The socket's path: ~/Library/Application Support/WaOS/dev.sock on Apple's systems; $XDG_RUNTIME_DIR/waos/dev.sock elsewhere, or ~/.local/share/waos/dev.sock without one. The folder is made for the user alone (0700), and the socket file too (0600). macOS allows a socket path 103 bytes long, so a user's name may be 50 bytes.

A frame: a four-byte little-endian count of the message's bytes, then the message as postcard encodes it, a component, a program's output and a window's PNG as strings of bytes (serde_bytes), which postcard writes as it writes a Vec<u8>, so the encoding is the one of a sequence of bytes, read in one copy. Either side refuses a frame over 256 MiB, the receiver on the count alone, before it allocates anything: a component is megabytes, a debug build tens of them, and a count beyond that is a stream that is not ours. After a frame cut short or refused, the connection is done. A variant's place and a field's place is its encoding, so a change to a message adds at the end, and anything else raises the protocol's number; the screenshot and the input, added at the end, raised it to 3 all the same, so a WaOS of an earlier build refuses a cargo waos that may send them by number rather than at a message it cannot read. A message's Debug leaves out the text typed into a program, which may be a password, and writes a component's and a PNG's sizes rather than their bytes.

The first frame each way is that number, PROTOCOL, outside the messages' encoding: a count of four, then the number little-endian, the one shape every build reads. Each side sends its own and reads the other's before anything else; when they differ, each ends the connection with an error naming both numbers, which cargo waos prints, so a cargo waos and a WaOS of different builds find out rather than misread each other.

On Windows the crate carries the messages and Connection, but no transport: its named pipe is step 11.