monoverse — Design Spec
An app halfway between a terminal emulator and a graphical server.
monoverse is a rich terminal: a local server runs a child app that paints a screen of styled text and true-pixel graphics over a single PTY-style byte stream and reads input events back. Clean-slate — no ANSI compatibility; apps target the monoverse protocol directly. The plain byte stream means it works over SSH, pipes, and multiplexers with zero special support.
Decisions
| Dial | Choice | Consequence |
|---|---|---|
| Concept | Rich terminal — text + inline graphics | Not a window server; not a plain TTY |
| Backward compat | None — clean-slate protocol | No ANSI; new apps only |
| Interop | No fallback; binary always | Apps refuse to run without a server; flattening is mono-cat's job, so there's always one server-side speaker |
| Topology | Local, like a terminal emulator | Server local, app is a child process |
| Channel | Single plain byte stream | Survives SSH / pipes / multiplexers |
| Framing | Length-prefixed binary packets with a type tag | Compact, fast to parse |
| Primitive | Rich cells — grid cell holds styled text or part of a graphic region | Familiar grid mental model, graphics-capable |
| Pixels↔cells | Pixels within cells | Graphic reserves a cell rectangle, renders at true pixel res inside it |
| State model | Immediate mode | App paints each frame; server owns no widget tree |
| Redraw | Dirty regions only; server retains last framebuffer | App resends only changed cells/rects |
| Region identity | None — re-declare the rect each frame | State is the framebuffer; coords are the address. RGBA patches a sub-rect, JPEG re-sends the whole rect |
| Pixel format | RGBA or JPEG, chosen per blit, no negotiation | Server supports both, decodes to one uniform RGBA framebuffer |
| Input | Structured event stream up the byte stream | Key/mouse/click/resize read like stdin; no server-side widgets in v1 |
| Surfaces | Single live surface, no server scrollback | One screen's framebuffer only; history is the app's job. Multiplexing is tmux's job |
| Mux seam | Reserve a surface-id field, hardwired to 0 in v1 | Forward-compat for multi-surface later, no v1 complexity |
| Geometry | Live negotiation; app refuses to run without a server | Server reports grid (cols×rows), cell px (w×h), HiDPI scale on init / change / request |
| Resize | Server emits a resize event; app redraws | Consistent with immediate mode |
| Language | Zig | Emulator + server + reference client |
| First app | An interactive shell | Dogfoods the entire stack |
Protocol
A bidirectional byte stream of length-prefixed, type-tagged binary frames;
every frame carries the v1 surface-id (0). PTY in raw mode so bytes pass
unmangled.
App → server (paint). text-run (styled run at row,col); blit (pixels —
RGBA or JPEG — into a cell-rect, addressing pixels within it); clear (rect);
present (commit frame). The app emits paint ops only for cells/rects that
changed; the server's retained framebuffer holds the rest. A blit's rect is
its identity — re-blit a smaller rect to patch (RGBA), or the whole rect for JPEG.
Server → app (events). handshake, geometry (grid cols×rows, cell px w×h,
HiDPI scale — sent on init, on change, and on request), key, mouse
(move/button/click at a coordinate), scroll, focus. Events are low-level: a
clicked button is just a click coordinate the app resolves against what it
painted — no server-side widgets in v1.
The handshake is mandatory; with no server-side speaker (real GUI server or the
headless mono-cat flattener), the app errors out. There is no serverless mode.
Reference shell
The first app and de-facto conformance test: reads command lines, renders styled
output, blits an image inline when a command produces one, handles resize/mouse,
and owns its own scrollback (the server has none — it repaints the viewport
from its history buffer on scroll).
Rough milestones
- Protocol crate — frame types, encoder/decoder, handshake (Zig).
- Server v0 — open a window, run a child over a PTY, paint text frames, emit key/resize events.
- Graphics — graphic regions, pixel blit, dirty-region retention.
- Mouse — click/move events end-to-end.
- Reference shell — text + one inline-image command; owns its scrollback.
mono-cat— headless pseudo-server: handshake + flatten frames to text.- Conformance demo — a tiny app exercising every frame type.