termscope
A headless terminal emulator for the age of agents
Steve Yegge, in his Gas Town launch post, describes the current crop of AI coding agents as “an embarrassing little kid's soccer team chasing the 2025 CLI form factor of Claude Code, rather than building what's next.” I find this description hilarious, in that Yegge way. I don’t fully agree with him, but he’s right in that these agent harnesses have converged on a general form factor.
These agents inhabit the terminal — the command line — giving many their first exposure to the old ways of computing. Claude Code, Codex, Gemini CLI, OpenCode, Amp all run inside a terminal emulator and they all interact with the outside world through text formats. Increasingly, these programs are using more and more sophisticated Text-based User Interfaces: a TUI. Programs enter alternate screen buffers, redraw content, reposition the cursor, render color panels and interactive widgets. LLM Agents have gotten quite good at reading and writing text. They are less good at dealing with streams of escape sequences that allow TUI applications to spring to life. An agent will just see bytes, not the screen. Which makes TUI development itself quite challenging, because automated processes find it difficult to “see” what they’re doing.
I built a tool that lets agents “see” the screen.
It’s called termscope, and it’s a headless terminal emulator CLI. Given a command, it spawns that command in a virtual terminal, letting you interact with it programmatically, and reports back what’s being displayed on the screen. It’s like Playwright, but for the terminal1.
The VT Problem
Understanding why this is harder than it sounds takes us on a detour through fifty years of terminal history.

DEC introduced the VT100 in 1978 as one of the first terminals to implement the ANSI X3.64 standard for command codes, cementing it as the de facto protocol for screen control. Nearly every terminal emulator written since still speaks some dialect of its escape sequence language, augmented with extensions that accumulated like sediment: 256 colors then 16 million colors, mouse tracking, the Kitty keyboard protocol, inline images, synchronized output.
curses — Ken Arnold’s library for BSD, a pun on “cursor optimization” (and what developers who implemented it frequently muttered) — gave programmers a high-level way to draw to any terminal without hardcoding escape sequences. In the way that open source flows, this gave way to pcurses and eventually ncurses by 1993. If you are doing terminal UI work in the C programming language, chances are you’re still linking against ncurses, bless your heart.
This lineage solved the output problem: how to draw to a terminal portably. But created no infrastructure for observation — for reading back what’s on screen from the outside. When you wrote a TUI, you didn’t need to inspect its output, because you, a human, were its intended audience
I remember when I was early in my career doing web development, the revelation that was Firebug. A tool that finally gave web developers true insight into how our applications were rendering. Now every browser ships with its descendants in its developer tools. The terminal never got its Firebug. For fifty years, the assumption held: the only one who needs to know what’s on screen is the person sitting in front of it.
Now agents need to look at the screen. termscope is my attempt at a Firebug for the terminal.
The TUI renaissance
Terminal user interfaces are having a moment precisely when something other than humans needs to read them.
Ratatui, has become a sprawling ecosystem in Rust. Charm’s Bubble Tea brought reactive components to Go. OpenTUI from Anomaly powers OpenCode with a Zig core and JavaScript reconcilers. Terminal.shop sold coffee through a TUI and made six figures in its first year. Anthropic acquired the Bun runtime to “further accelerate Claude Code.” Thousands of people are meeting the command line for the first time because an AI agent lives there.
All this investment in building terminal interfaces. Almost none in observing them. The tools that do exist run xterm.js — a JavaScript terminal emulator designed for browsers — on Node.js, on a machine that already has terminals. It works, but feels a bit like driving to your mailbox.
Ghostty
This is where Mitchell Hashimoto’s Ghostty enters the picture2. Ghostty is a terminal emulator, and a very good one. But perhaps more intriguing Hashimoto’s ambition to build libghostty — a family of libraries for making terminal emulators. The first piece is libghostty-vt: a zero-dependency C library extracted from Ghostty’s core that handles VT sequence parsing and terminal state management.
When I saw Ghosting — the minimal terminal emulator demo built on libghostty-vt in a single C file — the shape of the thing I wanted to build came into focus. I didn’t want a testing framework for one particular TUI library. I didn’t want to wade into a swamp of runtime dependencies. I wanted a standalone CLI, powered by the same terminal engine I use daily, that gives agents and CI pipelines structured access to terminal state.
What termscope does
termscope spawns a command in a headless virtual terminal powered by libghostty-vt, lets you interact with it programmatically, and captures the terminal state.
Three modes let an agent or an automated process pilot a command and observe its output:
Snapshot captures the screen after a command runs. termscope snapshot -- htop gives you the rendered output as numbered text lines. JSON, HTML, and SVG formats are also available.
Exec runs a command with a scripted interaction sequence — type text, press keys using Emacs-style notation, wait for specific text to appear, then snapshot or assert. termscope exec --expect "Connection refused" -- my-app exits 0 if the text is found, 1 if not. CI-ready.
Session mode speaks a JSON-lines protocol over stdin/stdout. An agent can open a session with vim, see the screen, type text, press escape, query cursor position, check alternate screen status — all through structured requests and responses. The agent drives; termscope observes.
It’s written in Zig. It ships as a single static binary and comes along with an agent skill.
The terminal’s Firebug moment
Yegge is right that the industry is chasing a form factor. But the form factor itself — the terminal — is a fifty-year-old instrument that we keep building increasingly sophisticated things on top of while leaving its internals opaque to the agents that now live inside it. Web developer's got Firebug in 2006 and never went back to guessing what their pages looked like. Terminal developers — and the agents working alongside them — deserve something similar.
termscope is a start. It gives us a glimpse inside, thanks to libghostty-vt.
Give termscope on GitHub a star ⭐️
I’m not the first person to reach for this analogy. Microsoft’s tui-test uses xterm.js headlessly for end-to-end TUI testing. Charm’s VHS does declarative terminal recording with golden-file output for CI. There are MCP servers, Go libraries, .NET frameworks; the space is waking up. What’s different about termscope is the engine underneath and the form factor on top, which … keep reading!
Yes, that Mitchell Hashimoto.

