Skip to content

glyphrunStop eyeballing your terminal app.

Specs for CLIs and TUIs. Real PTY, deterministic screen, artifacts an agent can read.

glyph run output showing 2 of 2 outcomes passed

A spec is the contract

Testing a TUI usually means expect scripts, a framework harness, or a human at the keyboard. A Glyphrun spec replaces all three: intent and outcomes are the contract, steps are repairable hints.

hello_quits.yml
yaml
name: hello_quits
intent: a user can open the app and quit with q.
target: { cmd: ["./bin/app"] }
steps:
  - wait: { screen: { contains: "hello" } }
  - press: "q"
outcomes:
  - id: clean_exit
    description: q exits the application cleanly
    verify: { process: { exitCode: 0 } }
bash
glyph run specs/hello.yml --format md

One command launches the app in a real PTY, checks every outcome against the emulated screen, and writes a run directory: JSON/YAML/Markdown reports, the final screen as text and SVG, per-outcome evidence, and agent_context.md. Exit 0 means every outcome passed. Exit codes 1-7 each mean one distinct kind of failure.

Drive the PTY. Assert the screen.

  1. Stamp the contract. Write intent and outcomes. glyph spec verify --stamp seals them with a contract hash. Silent edits abort the run.

  2. Run it in a real PTY. Glyphrun launches your app, plays the steps, and evaluates each outcome against a deterministic virtual terminal: cells, regions, cursor, colors, OSC 8 hyperlinks. See the step and verifier vocabulary.

  3. Read the evidence. Pass or fail, you get a self-contained artifact pack. On failure, glyph context latest shows what happened, and glyph repair proposes step fixes without touching what pass means.

Agents see what you see

Agents cannot see a TUI. Glyphrun can, on the same CLI humans use. No per-agent code paths: glyph mcp starts a stdio MCP server that mirrors the commands. After a failure, agent_context.md hands the agent recent events and inspection commands.

The contract hash refuses silent edits to intent or outcomes, so an agent can repair drifted steps without redefining success:

bash
glyph run specs/app.yml --format json   # banner changed
glyph context latest --format md
glyph repair specs/app.yml --write      # steps only
glyph run specs/app.yml --format json   # green

The full loop is in the agent guide.

Stories are isolated TUI states

glyph stories catalogs specs that mount one TUI state at a time. --html inspects cells (grid, rulers, hover). --tui is the feel catalog in the host terminal. Same black-box runner, no framework bindings.

The Stories guide covers glyph stories init, the inspect overlays, and the example harness.

FAQ

Is this like Playwright, but for terminal apps?
Conceptually yes. Glyphrun drives a real process in a PTY the way Playwright drives a real browser, and asserts against a deterministic virtual terminal the way Playwright asserts against the DOM.
Does it work with any language?
Yes. Glyphrun is black-box: if your app runs in a PTY, Glyphrun can drive and assert against it, regardless of implementation language.
Does it support Windows?
Yes, via ConPTY (Windows 10 1809+), behind the same platform-neutral backend used for macOS and Linux PTYs.
How is this different from expect or tmux scripts?
Specs are declarative YAML/JSON with a stamped contract hash, not imperative scripts. Outcomes are separated from repairable interaction steps, and every run produces a structured artifact pack instead of raw terminal output. glyph import bats converts an existing BATS file; glyph export bats goes the other way.

Install

bash
brew install abdul-hamid-achik/tap/glyph
# or
go install github.com/abdul-hamid-achik/glyphrun/cmd/glyph@latest

MIT licensed. glyph init writes a passing smoke spec. The Quickstart walks through it.

Released under the MIT License.