Skip to content
// rust library · cli · json-rpc

Drive any
interactive
terminal,
from code.

ptywright is a Rust crate and CLI for spawning, observing, and driving PTY-backed terminal applications. Use it as a library in your tests, a binary in your scripts, or a JSON-RPC server for agents and UAT pipelines — one vocabulary across all three.

macOSLinuxWindowsearly dev
session-01 · claude-codesession-02 · zsh+
80×24 · stable
pty>session.spawn("claude").attach()
spawned pid 48211 · 80×24 · alt-screen
pty>wait(screen_stable(250ms))
stable after 412ms · seq 14
pty>send.text("summarize SPEC.md")
wrote 18 bytes · cursor 02:18
pty>wait(matches(r"Approve\? \(y/n\)"))
matched · row 19 · turn complete
pty>send.key("y") · transcript.snapshot()
1.2 KiB · redacted 2 patterns
pty>_
┌── observer ──┬── matcher ──┬── transcript ──┐
│ 80×24 cells  │ regex+temp. │ 64 KiB ring    │
│ vt100 engine │ on-stable   │ raw stream opt │
└──────────────┴─────────────┴────────────────┘
01 / target
Spawn anything
Program, args, env, cwd, terminal size. PTY-first, no shimming.
02 / observe
Cell-level snapshots
Style, mode, scrollback, alt-screen. Bounded transcript.
03 / wait
Deterministic matchers
Regex, temporal, lifecycle. No sleeps, no flake.
04 / automate
JSON-RPC + Lua
NDJSON, LSP framing, sockets. Trusted plugins for adapters.
// fig.01 · the runtime, end to end

Nine layers.
Every one reusable on its own.

OBSERVATION FLOWS DOWN.
↳ CONTROL LOOPS BACK UP.
↳ EACH BOX MAPS TO A FILE IN SRC/.
CALLERagent · cli · library · rpc clientJSON-RPCstdio · ndjson · lsp · socketRPC.RSSESSIONtarget · pty · reader · writerSESSION.RSSCREENvt100 · cell · style · cursorSCREEN.RSTRANSCRIPTbounded · redacted · streamedTRANS.RSMATCHERregex · stable · exited · timeoutMATCH.RSACTIONkeys · write · paste · resize · intACTION.RSTURN · EXTENSIONclassify · plan · wait · captureEXT.RSADAPTER (lua)claude-code · your tui└ optional · framed protocols└ portable-pty · target spawns process└ vt100 seam · swappable engine└ event-driven · no sleeps└ orchestration · classify+plan+wait└ trusted lua · permissioned pluginsobservation ┐predicates ┐dispatch ↑writeback ↑N 00N 09FIG·01
// caller
Drop into Rust with cargo add, shell out to the CLI, or speak JSON-RPC from any language.
// observe
Screen and transcript update on every reader tick. Snapshots are cheap, structured, and serializable.
// wait
Matcher fires on regex, stable screen, or process exit. Action commits the next step. Sleeps are forbidden by design.
// adapt
Wrap an app's prompt grammar in a trusted Lua adapter. Claude Code ships in-tree; bring your own TUI next.