TUI over the wire (TUIOW) — gRPC + protobuf pages rendered by a terminal client.
| Document | Purpose |
|---|---|
| CHANGES.md | What changed in protocol v2 and the 2026 surface work |
| ../DEVELOPERS.md | Server developer guide (primitives, helpers, examples) |
| ../STREAMING.md | Live surfaces: streaming, latency, Event input |
| ../CHANGELOG-v2.md | Short implementation checklist (proto + client + helpers) |
| ../uggly.proto | Source of truth for all messages and services |
| ../README.md | Project overview and ecosystem links |
Client repository: uggly-client.
| Service | RPC | Required | Notes |
|---|---|---|---|
Page |
GetPage |
Yes | One-shot document pages |
Page |
GetPageStream |
Optional | Live surface frames (stream PageResponse) |
Feed |
GetFeed |
Recommended | Index for client “Browse Feed” (F4) |
Meta |
Hello |
Optional | Capability handshake (ClientHello → ServerHello) |
PageRequest: name, clientWidth / clientHeight, formData, sendCookies,
stream, plus v2 query (map) and event.
PageResponse: divBoxes, elements (text, forms, tables, lists, prompts),
keyStrokes, setCookies, optional theme, root layout tree, error,
streamDelayMs.
| Mechanism | Wire | Use |
|---|---|---|
| Link | KeyStroke.link |
Navigate to a page (optional query / event) |
| Event | KeyStroke.event |
Structured action without page-name dialects |
| Form | KeyStroke.formActivation + Form / Prompt |
Text entry; Form.autofocus |
| DivScroll | KeyStroke.divScroll |
Client-side scroll of a named box |
| Stream link | Link.stream = true |
Start GetPageStream |
Document mode = classic GetPage. Surface mode = long-lived GetPageStream +
session cookie + unary Event inject (client sends query[_input]=1).
See STREAMING.md for latency rules (stream_delay_ms = 0,
server-paced ticks, no double sleep, input-only RPCs).
Core layout: DivBox (+ borderCharStr / fillCharStr / scrollable), DivBoxes,
TextBlob, Style (+ Attr enum), Theme.
Widgets: Table, ItemList, Prompt, Form, TextBox, Node + Layout.
Navigation: KeyStroke, Link, Event, DivScroll, FormActivation.
Cookies / errors / meta: Cookie, PageError, ClientHello, ServerHello,
PageListing, FeedRequest / FeedResponse.
Full field definitions live in uggly.proto. Older
protoc-gen-doc extracts below this folder may lag; trust the .proto file.
python/
uggly.py # betterproto messages
uggly_pb2_grpc.py # gRPC servicers / stubs
helpers.py # declarative page builders
import helpers as ug
page = ug.simple_page("home", "hello", width=w, height=h, title="Hi")
page.key_strokes.append(ug.key_event("n", "next", hint="(n) Next"))
page.key_strokes.append(ug.key_link("s", "play", stream=True, hint="(s) Stream"))Modern ugglyc expands tables/lists/prompts itself; call expand_widgets only
for legacy clients.
- Samples:
samples/python,samples/go - Ecosystem (separate repos): uggly-server, puggly-server, uggly-chat-server
- Advanced surface demos (not in this repo): platformer / docstream servers