Agent-generated UI in the terminal: the closest neighbours
Agent-generated UI in the terminal splits into two groups. The first is about how an agent puts something in front of a person and gets an answer back. Projects take five paths. Prebuilt canvases: claude-canvas had about 1,500 stars within a week, then was abandoned as an unsupported proof of concept. A format plus a terminal renderer shipped as a library: json-render's Ink renderer, the Rust a2ui crate on ratatui, a2ui-ink and a2tea, so A2UI now renders in a terminal in three languages. UI drawn inline in the agent's own chat: a2tea's Crush fork and json-render's ink-chat example. A workspace the agent drives: Laura, which tiles panes of files, diffs and logs by pane id over a socket and returns the person's inline review to the chat. Code-first frameworks with an agent surface: Raxol derives MCP tools from its component tree, and Melker makes apps permissioned, readable documents. The second group is about how an agent uses a screen it didn't write. There has been a flood of near-identical PTY drivers in 2026 (tui-use, pilotty, two unrelated agent-tuis, agent-tty and others), alongside older MCP servers (tmux-mcp, iterm-mcp, terminalcp, ht), Microsoft's tui-test rewritten in Rust with Playwright-style locators, and VHS for recording. The best drivers try to recover structure: ConductorOne's agent-tui adds roles and refs through per-program adapters ("A terminal program is already a state machine. The problem is that the state is presented as a screen.").
The entries
a2ui (Rust crate, ratatui)
A Rust implementation of A2UI v1.0 with a framework-agnostic core and a ratatui terminal backend covering all 18 basic components (plus six desktop backends).
For fictty A2UI on ratatui already exists, so an A2UI adapter is table stakes. fictty might borrow a2ui-base types or validation for its adapter, but should write the adapter as a translation onto its own value. Copy parse_and_fix (repair smart quotes and trailing commas, then report what changed) and test against the official spec examples.
terminal · renderer · libraryjson-render Ink renderer (@json-render/ink)
Vercel's catalogue-constrained JSON UI spec, rendered as an interactive terminal UI through Ink, streamed as RFC 6902 patches.
For fictty JSON UI in the terminal is not fictty's moat; json-render has it with real adoption. Accept json-render Ink-catalogue specs as input alongside A2UI and use RFC 6902 patches. Generate the agent skill from the catalogue as catalog.prompt() does, and borrow ink-chat's terminal design rules. Don't copy the expression language. Main risk: json-render ships an attachable terminal host.
terminal · harness · projectTerminal MCP servers and headless terminals (tmux-mcp, iterm-mcp, terminalcp, ht)
The first generation of 'let the model use a terminal': MCP tools over tmux panes or iTerm tabs, PTY process control with screen or stream reads, and ht's JSON-over-stdio headless terminal.
For fictty Keep fictty's MCP adapter thin with a short tool list; CLI plus skill comes first, as Zechner's benchmark suggests. Make headless screens attachable from any terminal, as terminalcp does. Consider a stdin/stdout JSON mode like ht's for hosts that can't open sockets.
terminal · harness · projectagent-tty (Coder)
A terminal an agent drives, with every session recorded and exportable as text snapshots, PNG screenshots, asciicasts or WebM, so a human can verify what it did.
For fictty Make fictty history exports double as PR proof: a .cast, a text transcript of frames and a picture, all exact because they are built from states. Add a doctor command that says what will degrade on this terminal.
tui-test (Microsoft)
Playwright for terminals, rewritten in Rust with CLI, Python, JS and Go bindings: locators, auto-retrying expects, cell and style reads, mouse and keys, recordings, and an agent skill.
For fictty Adopt it for emulator-level conformance tests: run fictty run in a real PTY and check that screen matches the emulator cell for cell, which render can't prove. Ship a fictty agent-context JSON command schema. Consider text locators (click --text) alongside ids.
tui-use (and the PTY-driver crowd: pilotty, pproenca/agent-tui, PTY-Agent, agentic-tui)
'Like BrowserUse, but for the terminal': run any program in a PTY behind a headless xterm, snapshot the screen as text, send keys, and wait for the screen to settle or a pattern to appear.
For fictty Generic screen-driving is a commodity; many clones appeared in 2026. fictty's value must be what only a state-owning runtime can do. Add wait-for-text or stable predicates to watch for agents that only know screen-driving, and mark selection explicitly in screen.
VHS (.tape)
Charm's terminal recorder: a small .tape script language replayed in a headless terminal to produce GIFs, videos, screenshots or text golden files.
For fictty Use it for the site's and README's demo captures. Model fictty's history export as a readable, editable, tape-like text (one line per input: key j, push ui.json, patch header). Replay of messages into state stays fictty's own, and exact.
terminal · runtime · projectLaura (laura-tui)
A TUI workspace that runs your agent CLI and gives it a socket API to tile panes of files, plans, diffs and logs, highlight and comment, with the person's inline review returned to the chat.
For fictty This is the closest loop to fictty in the terminal, but it shows documents, not components. Copy its agent ergonomics: post-push overflow and clipping reports, dry runs, holding writes while the person types, never-reused ids, and feedback pushed into the chat for agents that can't long-poll. It also names learning ('shows and explains concepts live') as a use case.
terminal · framework · libraryRaxol
An Elixir Elm-architecture runtime that renders one module to the terminal, LiveView, SSH and MCP tools derived automatically from the component tree.
For fictty Same architecture and read-back goal as fictty, but a developer writes the UI in code, so an agent can't conjure a screen. fictty's MCP adapter should derive semantic tools from the current UI value with a focus lens to keep the list short. Its headless test verbs should match the agent's verbs.
terminal · framework · libraryMelker
A Deno TUI framework where apps are readable .melker documents with a declared permission policy, run sandboxed and even from a URL.
For fictty Make a pushed UI's permissions visible data: list every command its sources and keys can run in get --state. Let the person approve once by hash, which makes the planned allow/ask/deny policy readable. Its serialised-tree-for-an-assistant also points at fictty's planned linear accessibility rendering.
terminal · harness · projectagent-tui (ConductorOne)
A PTY driver that exposes any terminal screen as an outline of regions with roles and stable refs (a 'DOM for terminal apps'), with waits on ref state.
For fictty The clearest outside statement of fictty's thesis; a screen that is data needs no adapter. Offer screen --outline in roles/refs vocabulary and write an agent-tui adapter that reads get --state, so driver users see fictty screens exactly. Support wait-on-ref-value predicates in watch, and quote the essay in the blog post.
claude-canvas
A Claude Code plugin that opens prebuilt Ink canvases (calendar, document, flight) in a tmux split and returns the person's selection over a Unix socket.
For fictty It proves the demand: an agent opens a screen beside itself and gets the answer back as JSON. fictty should ship an 'answer by pointing' example (meeting picker, seat map) as a UI value. Its watch should return selected/cancelled results, and it should offer a one-command 'open beside me' for tmux, herdr and TUIOS.
terminal · renderer · librarya2tea
A Go bridge that finds A2UI messages in a model's reply and renders them as embeddable Bubble Tea models inline in a chat host (a Crush fork).
For fictty Inline UI in the chat is the natural home for one-shot forms and pickers. If Crush or another major agent ships it, fictty's room narrows to screens that outlive a message (live dashboards, queues, walkthroughs). Keep render good for inline static snapshots, and default embedded chrome to monochrome so the host theme wins.
a2ui-ink
A community Ink renderer for A2UI v0.9/v0.9.1 on the official web_core message processor, covering all 18 basic components.
For fictty Use the official A2UI v0.9.1 examples as conformance fixtures for fictty's adapter. Once the adapter works, get fictty listed on a2ui.org's renderer page, which is where A2UI users look.
The overview
Agent-generated UI in the terminal: the closest neighbours
Research as of 10 October 2026. This extends the “Terminal: let the model drive a screen” section
of the landscape post. One dossier per entry, in this
directory, named terminal-gen--<slug>.md.
What’s really being solved
Every project here is answering one of two questions:
- How does an agent put something in front of a person, in the terminal, and get an answer back? (claude-canvas, Laura, json-render’s Ink renderer, the A2UI renderers, Raxol, fictty)
- How does an agent use a terminal screen it didn’t write? (tui-use, agent-tui, tui-test, agent-tty, tmux and terminal MCP servers, ht, VHS)
Underneath both is the same gap that ConductorOne’s Paul Querna put in one line: “A terminal program is already a state machine. The problem is that the state is presented as a screen.” The first group tries to give the agent a screen it understands because it described it. The second tries to recover understanding from screens that were never meant to be read by machines.
The paths people are going down
1. Prebuilt canvases. claude-canvas: a few hand-designed screens (calendar, document, flight) the agent fills with JSON and opens in a tmux split; the person’s click comes back over a socket. Proved the demand in a week (about 1,500 stars), then stopped. Lesson: people want the agent to open a screen beside itself and get an answer back; a fixed set of screens doesn’t scale.
2. A format plus a terminal renderer, as a library. json-render’s Ink renderer (Vercel Labs), the Rust a2ui crate on ratatui, a2ui-ink, a2tea for Bubble Tea. The agent (or the host app’s model) writes a declarative spec; a renderer embedded in someone’s app draws it. A2UI now renders in a terminal in three languages, and json-render has the adoption. None of them is a process an outside agent attaches to: no socket, no patch by id from outside, no read-back of the frame, no data sources besides the agent itself. They answer “what should a UI value look like”, not “where does it live while the agent works”.
3. Inline in the agent’s own chat. a2tea’s target (a fork of Charm’s Crush) and json-render’s
ink-chat example render generated UI inside the transcript. This is the most natural home for a
one-shot form or picker, and if a major agent ships it, that use case leaves every standalone tool.
4. An agent-driven workspace. Laura (laura-tui): the agent tiles panes of files, diffs, plans and logs over an NDJSON socket by pane id, highlights lines and comments; the person answers with an inline review that arrives in the chat. The loop is the same as fictty’s; the content is documents rather than components. Very new and unknown (0 stars), but the most fictty-like thing in the terminal.
5. Code-first frameworks with an agent surface. Raxol (Elixir) derives MCP tools from its component tree, so an agent operates an app structurally; Melker (Deno) makes apps readable, permissioned documents. Both are for apps a developer writes; an agent can’t conjure a screen in them without writing code.
6. Drive any screen. A flood of near-identical PTY drivers in 2026 (tui-use, pilotty, two unrelated agent-tuis, agent-tty, PTY-Agent, agentic-tui), the older MCP servers (tmux-mcp, iterm-mcp, terminalcp) and ht, Microsoft’s tui-test rewritten in Rust with a Playwright-style locator API, and VHS for recording. They work with every program and know nothing about any. The best of them try to recover structure: ConductorOne’s agent-tui adds roles and refs through per-program adapters; tui-test reads cells and styles; tui-use reads inverse-video highlights as “selection”. The number of clones says the plumbing is a commodity.
The open debate
- Where does generated UI live: in the chat, beside it, or in a browser? a2tea and ink-chat say inline; claude-canvas and Laura say a split beside the agent; the HTML camp (other cluster) says a browser tab. fictty bets on beside, for screens that outlive one message.
- Format or runtime? The format question is close to settled (A2UI and json-render, both with terminal renderers). The runtime question (a long-lived, attachable screen with exact read-back and data that skips the model) has almost no takers: Laura for documents, Raxol for code-first apps, fictty for data-first screens.
- Retrofit or publish structure? Drivers retrofit a DOM onto programs with adapters. A screen that is data publishes its own. Both will coexist; fictty should make itself the easiest screen for drivers to read, not compete with them.
- Code or data in the value? json-render allows expressions (
$cond,$computed); Melker allows handlers; fictty and A2UI keep logic out. The trade is expressiveness against safety and read-back.
Where this leaves fictty
Nothing here does all of fictty’s loop: a process the agent pushes to, patches by id, drives with keys and mouse, reads back exactly as text and state, with live data bound to commands and streams. The closest are Laura (same loop, documents only) and the format renderers (same values, no loop). That position is real but narrow, and the risks are concrete:
- If json-render or A2UI ships an attachable terminal host with a socket, the format renderers close most of the gap quickly, with far more adoption.
- If the big agents render generated UI inline in their own TUIs, short-lived forms and pickers stop needing a separate screen.
- The driver crowd can read any screen “well enough” for many tasks.
What to take, in priority order (each is argued in its dossier):
- Overflow and visibility read-back after every push (Laura).
watchwithselected/cancelledresults and screen predicates (claude-canvas, tui-use, agent-tui).- Accept json-render (Ink catalogue) specs as input alongside A2UI, use RFC 6902 patches, and test against the official A2UI v0.9.1 examples (json-render, a2ui-ink, a2ui crate).
- An outline view in roles and refs, and an agent-tui adapter, so drivers see fictty screens exactly (agent-tui).
- Emulator-level conformance tests with tui-test, and
fictty agent-contextas a JSON command schema (tui-test). - Visible, approvable command policy for pushed UIs (Melker), and tree-derived MCP tools with a focus lens (Raxol).
- History exports that double as proof (agent-tty) in a readable, tape-like text form (VHS).
Entities checked
Covered with dossiers: claude-canvas, json-render’s Ink renderer, the Rust a2ui crate, a2tea, a2ui-ink, Laura, Raxol, Melker, tui-use (with pilotty, pproenca/agent-tui, PTY-Agent, agentic-tui), ConductorOne agent-tui, Microsoft tui-test, Coder agent-tty, terminal MCP servers and ht, VHS.
Added beyond the brief: Laura, a2tea, a2ui-ink, Melker, ConductorOne agent-tui, Microsoft tui-test’s Rust rewrite.
Looked at and left out: GitHub’s TUIKit (an LLM compiles component specs into framework code; see
framework--tuikit.md), chicago-desktop/tui-desktop (a terminal compositor on the Wippy runtime
with an agent command channel; 0 stars, two weeks of commits), agent session managers such as
agent-deck and agent-manager (frame layer, not content), Toad (an agent front end, not generated
UI). We found no project named “tui-use” other than onesuper’s, and no evidence that “terminalcp”
is maintained beyond August 2025.
Couldn’t verify: how much of @json-render/ink’s 591,000 monthly npm downloads is real terminal
use; whether Charm officially backs a2tea; Raxol’s performance and agent claims (README only).