Skip to content

0.0.18 cohort: intuiTUIve grows up

Published on 2026-10-11, with rs-rich 0.0.6 on PyPI. See Publication.

0.0.18 is the third release of intuiTUIve, the TUI framework, and it is the one where an app stops being only a terminal program:

  • Keys as they were pressed. The kitty keyboard protocol in rs-rich-interact: Ctrl+I is not Tab, Shift+Enter is not Enter, and a key release can be read, on terminals that have the protocol. Terminals without it behave exactly as before.
  • More backends. termion and termwiz beside crossterm, chosen with a feature, with the same keys, mouse, paste, suspend and restore.
  • Synchronized output. Each frame is one synchronized update (DEC mode 2026) on a terminal that answers the query for it, so a large redraw never shows half drawn; RICH_SYNC_OUTPUT forces it on or off.
  • Stylesheets. A CSS subset for an app's look and layout: selectors by node kind, name and class, :focus, :hover, :selected and :disabled, colours, borders, padding, sizes and docking, read from a file and reloaded as it changes. Code wins over the sheet where both set something.
  • The widget gaps. Horizontal scrolling, sortable and resizable table columns with a cell cursor, a virtual lazy tree, tooltips, drag and drop, and hover styles.
  • Accessibility. Every node has a role, an accessible name and states (checked, expanded, selected, busy, disabled); an app can announce, mark nodes hidden from assistive technology, and run in an accessible mode that parks the cursor on the focus for a screen reader, or a linear mode that writes the accessibility tree as lines of text in reading order.
  • In a browser. rs-rich-web (new) serves an app to a browser tab over a WebSocket, drawn by xterm.js or by a DOM renderer that carries the accessibility tree as ARIA; it also serves any terminal program on a PTY. rich serve -- htop does that from the CLI, behind its off-by-default serve feature. Localhost, a token in the URL, an Origin check and a session cap by default.
  • Embedding. rs-rich-embed (new) puts a terminal pane (a shell or any program on a PTY) and a web view (Chrome over DevTools, Browsh, or a text browser) inside an app, each over a backend trait that can be swapped.

A default build of rs-rich is unchanged, still 0.0.9, and still renders exactly like upstream rich 15.0.0.

Independent package versions

Package Version Release role
rs-rich-record 0.0.6 Mouse and more keys in tapes; the PTY and emulator shared with web and embed
rs-rich-interact 0.0.6 The kitty keyboard protocol, the termion and termwiz backends, synchronized output
rs-rich-ratatui 0.0.3 Manifest only: requires interact 0.0.6
rs-rich-intuituive 0.0.3 Stylesheets, the widget gaps, accessibility, linear mode
rs-rich-embed 0.0.1 (new) The terminal pane and the web view
rs-rich-web 0.0.1 (new) Serving apps and programs to a browser
rs-rich-data 0.0.2 From the 0.0.17 cohort, published just before this one (see Publication)
rs-rich-cli 0.0.18 rich serve; requires the versions above

rs-rich 0.0.9, rs-rich-macros 0.0.3, rs-rich-plugin-api 0.0.3, rs-rich-art 0.0.12, rs-rich-diagram 0.0.2, rs-rich-mermaid 0.0.5, rs-rich-lumis 0.0.3, rs-rich-ext 0.0.15 and rs-rich-micro 0.0.4 do not change.

The Python package, rs-rich 0.0.6 on PyPI, carries rs_rich.tui (intuiTUIve from Python). It was held back while the cohort was prepared, then published with it.

Migration

The 0.0.x crates take breaking changes. In rs-rich-interact:

  • Key has a private field, so it is built with Key::new, Key::with, Key::ctrl, Key::char or Key::parse, not a struct literal.
  • Event has a new variant: a match on it needs a _ arm.
  • SessionOptions has new fields: build it with ..SessionOptions::default().

Release test

  • Each workstream PR's CI passed: fmt, clippy, tests on Linux, macOS and Windows, the feature matrix (with each interact backend and the CLI's serve), MSRV, golden parity, the tapes, the docs site, and the intuiTUIve-against-ratatui benchmark gate (#683–#697).
  • Three independent audits of everything since the 0.0.17 cohort found 22 defects, each reproduced, and four suspected ones; all are fixed, each with a regression test that fails without its fix where one is practical (see the CHANGELOG, "0.0.18 release test"):
  • rs-rich-web and rs-rich-embed (security): a paste flood grew a served program's memory without bound; a slow request could hold the server's connections; a program ignoring SIGHUP outlived its session and the server; Chrome's sandbox switch had other spellings that got through, and its profile was readable by other users; a web-view address starting with - became a browser option; a served program could write the browser's clipboard; Browsh listened on every interface.
  • intuiTUIve: linear mode wrote terminal controls from names, toasts and announcements raw, left out what did not fit the terminal's rows, and left the cursor hidden after a suspend; a lazy tree whose data repeats an ancestor's key overflowed the stack; large stylesheet padding overflowed; comments and quoted values with a brace or ; broke a sheet; the wheel over a table's header did nothing.
  • rs-rich-interact and rs-rich-record: rich record hung on a program that asks and never reads; the emulator's control-sequence and answer buffers had no bound; termwiz typed out a sequence split across reads; an inline termion or termwiz session stalled 2 s when a key came before the cursor report; termion's paste scan was quadratic; termwiz left modifyOtherKeys on.
  • scripts/validate_release.py --tag rs-rich-cli-v0.0.18 passed on the release head (fmt, clippy with and without features, 3,788 tests, the release tooling's tests, the version and CLI reference checks, staged packages, the release plan).
  • Every tape (32, 104 checkpoints) matches its recording, and the golden fixtures recapture byte-identically from rich 15.0.0.

Not yet done, and by whom

  • A real-terminal pass (kitty, WezTerm, iTerm2, Windows Terminal, xterm) of the kitty protocol, the three backends and synchronized output, and a screen-reader pass (Orca or NVDA) of accessible and linear mode, following the checklist: the maintainer's, before tagging. CI and the PTY tests cover the bytes, not what a person sees and hears.
  • Both browser pages (xterm.js and the DOM renderer) have been tested at the protocol level only; open each once in a real browser.

Known limits

  • The DevTools port of the Chrome web view can be reached by other local users while the view is open; moving it to a pipe is planned.
  • Sessions served by rs-rich-web are threads in one process; one process per session is a 0.0.19 item.

Publication

All published on 2026-10-11:

  1. The 0.0.17 cohort's two leftovers, from their tags on the 0.0.17 commit e9003a2: rs-rich-data 0.0.2, once its Trusted Publishing entry was added (see Registry authentication), and rs-rich-cli 0.0.17.
  2. From main at 3cd1bce, the crates, tagged in order by python3 scripts/release_cohort.py tag --registry crates.io: rs-rich-record-v0.0.6, rs-rich-interact-v0.0.6, rs-rich-ratatui-v0.0.3, rs-rich-intuituive-v0.0.3, rs-rich-embed-v0.0.1, rs-rich-web-v0.0.1 and rs-rich-cli-v0.0.18. rs-rich-embed and rs-rich-web are new crates, so their first versions uploaded with the crates-io environment's CARGO_REGISTRY_TOKEN.
  3. The Python package, python-v0.0.6 on 3cd1bce, through pypi-release.yml.