Test any terminal app
Glyphrun is black-box — if it runs in a PTY, you can spec it. Go, Rust, Python, Bash, anything. Specs describe user-visible behavior in YAML, not your framework's internals.
Glyphrun runs your CLI or TUI in a real PTY and checks the rendered screen against a deterministic terminal emulator. Any language, no framework bindings — if it runs in a terminal, you can test it.
Testing terminal applications usually means expect scripts, framework-specific harnesses, or a human keyboard-mashing before every release. A Glyphrun spec replaces all three:
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 } }glyph run specs/hello.yml --format mdOne command launches the app in a real PTY, evaluates every outcome against the emulated screen, and writes a run directory containing the report in JSON, YAML, and Markdown, 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.
intent and outcomes — the durable definition of correct behavior. glyph spec verify --stamp seals them with a contract hash.glyph context latest surfaces exactly what went wrong, and glyph repair proposes step fixes.Agents can't see a TUI — Glyphrun can. It was designed so agents use the same surface humans do, with no per-agent code paths: glyph mcp starts a stdio MCP server that mirrors the CLI — run specs, verify contracts, read failure context, diff runs. After a failure, agent_context.md hands the agent recent events and suggested inspection commands.
And because the contract hash refuses silent edits to intent or outcomes, an agent can repair drifted steps all day without ever redefining success behind your back:
glyph run specs/app.yml --format json # fails: the banner text changed
glyph context latest --format md # read what actually happened
glyph repair specs/app.yml --write # fix the steps, never the contract
glyph run specs/app.yml --format json # green — contract untouchedThe full loop is documented in the agent guide.
Most terminal testing either binds to your app's internals or lives in fragile expect scripts. Glyphrun keeps the app black-box and the assertion deterministic — and it meets you where you are: glyph import bats converts an existing BATS file into a spec, and glyph export bats goes the other way. Local-first by design: no cloud, no telemetry, one static Go binary on macOS, Linux, and Windows (ConPTY).
Is this like Playwright, but for terminal apps? Conceptually yes — Glyphrun drives a real process (PTY) the same 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 the repairable interaction steps, and every run produces a structured artifact pack instead of raw terminal output.
brew install abdul-hamid-achik/tap/glyph
# or
go install github.com/abdul-hamid-achik/glyphrun/cmd/glyph@latestMIT licensed. Run glyph init in your project and you'll have a passing smoke spec in five minutes — the Quickstart walks you through it.