Files
lobbs/docs/lobbs-machine.md
T

3.4 KiB

LoBBS Machine API

https://discord.gg/DMrGcGQfMN

For rich clients and agents over DM. Command names and player behavior are in the daily user guide. Field numbers and hook behavior are in LoBBS internals.

Why a machine mode

The plain-text reply is written for a person on a phone. A mail row reads [2]*@ben: see you at the trailhead (3h ago). The index, the * unread mark, the truncated preview, the relative time, and the {p n/t} footer exist for eyes, and plugins can rewrite them through display_human. A client that scrapes that line breaks whenever the wording changes.

A machine reply is the same result set before rendering. That mail row arrives as separate fields: the row id, the read flag, the created time in Unix seconds, and the preview, next to the title line a person would see. A client reads the fields it knows and ignores the rest.

The request id exists because the mesh is not a socket. DMs arrive seconds or minutes late, some never arrive, and they can arrive out of order. A client with several requests in flight matches each reply to its request by the echoed id. A person typing by hand does not need that, so the id is optional, and its presence is what selects machine mode.

There is no second API. Every command a person can type, a client can send with an id, and the same handler answers both. A new command works from a client the day it ships.

Paging uses the same cached reply for both. Each page is its own request with its own id, so a client that loses page 2 asks for page 2 again instead of re-running the command. [n:max] tells it how many DMs to collect before it parses.

Requests

Put a number and a space after / on a command to get a machine reply. The number only works when a space follows it (/42 login, not /42login). Without a leading id, replies use plain text and {p i/n} footers on the same cached result set.

Run the command first, then request further pages without re-running it.

/42 mail list
<42>ok [1:2]
…payload…

/43 p2
<43>ok [2:2]
…payload…

Reply shape

Each DM is 200 bytes or less, header included.

Case Header Body
Success, one page <id>ok newline LoScalar record lines
Success, multiple pages <id>ok [n:max] newline Slice of the document
Error <id> One sentence, no ok

The [n:max] marker is separate from the request id. Use a fresh id on each page request (/43 p2, /44 p3). The reply echoes the id from that page request. Stop when n == max.

Success bodies are the cached result set encoded as LoScalar lines (number:value|number:value), one record per line. Concatenate page bodies in order, then split on newlines. Pages may cut through the middle of a line. Reassemble the full document before parsing records.

Paging

Human paging: /p2 after /mail list.

Machine paging: /43 p2 with a new id each page.

The node caches your last successful reply for about five minutes (reset on each page read). A new successful command replaces the cache. Errors do not change it. Payloads larger than 8 KiB are not cached. Page 1 is sent and /p2 replies No cached reply.. Past the end: No such page.