Skip to content

Formats

Cx::run and Cx::run_from follow the --progress json lines the PITO MD command-line tools print, version 1: one JSON object a line.

{"v":1,"op":"check","app":"demo","ref":null,"stage":"resolve","state":"start","fraction":null,"msg":"resolve starting","at":1792004625071}
{"v":1,"op":"check","app":"demo","ref":null,"stage":"resolve","state":"progress","fraction":0.062,"msg":"resolve 1 of 4","at":1792004625272}
{"v":1,"op":"check","app":"demo","ref":null,"state":"end","ok":true,"msg":"every check passed","at":1792004628472}

The fields pito-tui reads; any other field is ignored:

Field Type Meaning
v number the version; a line with a v other than 1 is not a progress line
state string, required start, progress, done, fail or end
stage string the step the command is on
fraction number how far along, 0 to 1
msg string a short status for the band
ok boolean on the end line, whether the command succeeded

A line that isn’t JSON, or has no state, is not a progress line; it still goes into the activity’s detail and reaches Screen::heard as text. command::read(line) parses one line into a command::Progress. The activity ends on the end line, or with the command’s exit status.

dump::keys("tab / foo enter ctrl+c") reads keys separated by spaces:

  • the names enter, esc, up, down, left, right, pgup, pgdn, home, end, backspace, delete, space, tab and backtab, in any case;
  • ctrl+ or alt+ followed by one character, such as ctrl+k;
  • any other word types its characters one by one, so foo is f, o, o.

A ctrl+ or alt+ word with more than one character after it is an error, returned as that word.

dump::size("120x34") reads WIDTHxHEIGHT (an X works too), both above zero.

  • dump::text(&buffer) prints each row’s symbols, a wide character once, with the trailing spaces of each row trimmed, rows joined by newlines.
  • dump::ansi(&buffer) hides the cursor, clears the screen, then writes each row at its position with the SGR codes for its colours and modifiers, resetting at the end of each row.

capture::capture and capture::Recorder write one folder per scenario, and one file per size in it:

tmp/before/
00-home/
40x12
80x24
120x34
200x60
01-what-to-do-next/
drill-in/
quit-guard/

A screen’s folder is its index among the app’s screens, two digits, then its name; a script’s is its name. Names are lowercased, with each run of other characters turned into one -.

Each file is one frame, as text:

pito-tui frame 1
80 24
<row 0 symbols, tab-separated>
<row 0 styles>
<row 1 symbols, tab-separated>
<row 1 styles>
...
  • The first line names the format and its version; the second is the width and the height.
  • Then two lines a row. The first holds every cell’s symbol, separated by tabs, with \\, \t, \n and \r escaped.
  • The second holds the row’s styles as runs, separated by tabs: a count of cells, the foreground, the background and the modifier bits, such as 1 #5B8CFF Reset 1 (one cell, the accent, on the terminal’s background, bold) or 78 Reset Reset 2 (78 dim cells). Colours are ratatui’s names (Reset, Red, …), #RRGGBB or an index.

capture::compare and Recorder::finish return capture::Differences, which print one a line:

00-home 80x24 0,0: "X" Reset Reset NONE → " " Reset Reset NONE
about 40x12: +
gone 80x24: -
  • A cell: the scenario, the size, x,y, then the cell before and after (its symbol, foreground, background and modifiers).
  • +: a frame only the new walk draws (Added).
  • -: a frame only the capture holds (Removed).

The demo’s --compare exits 1 when any frame differs.