Skip to main content
Glama
README.md
# ptywright

[中文文档](./README_ZH.md)

ptywright is a terminal/TUI automation driver. It launches CLI/TUI programs in a
PTY, feeds ANSI/VT output into `@xterm/headless`, rebuilds the terminal screen,
and exposes that state through MCP tools, script runners, replayable cassettes,
and browser-terminal regression workflows.

The core idea is simple: prefer deterministic terminal snapshots over screenshots
when testing terminal behavior.

## What It Solves

- Drive a live terminal from an MCP client or agent.
- Test CLI/TUI flows with JSON/TypeScript scripts, goldens, and HTML reports.
- Record raw PTY byte streams once and replay them without rerunning the command.
- Test browser-hosted terminal renderers with terminal/DOM snapshots.
- Keep generated artifacts portable with manifests, hashes, and reusable argv
  commands.

Non-goals remain intentional: ptywright does not try to reverse-engineer a full
component tree from terminal cells, and pixel-level screenshot diff is not the
main regression path.

## Install

```bash
# One-off usage
bunx ptywright@latest --help
npx -y ptywright@latest --help

# Or install globally
bun add -g ptywright
npm install -g ptywright
```

Inside this repository, use the local CLI:

```bash
bun run src/cli.ts help
```

## Pick A Workflow

| Need | Use | Start here |
| --- | --- | --- |
| Let an agent inspect and control a live CLI/TUI | MCP server | [MCP tools](./docs/mcp.md) |
| Write deterministic CLI/TUI regression tests | Script runner | [Script runner](./docs/script-runner.md) |
| Capture terminal bytes once and replay them later | Raw PTY cassette | [Raw PTY cassettes](./docs/pty-cassette.md) |
| Test a browser page that renders a terminal | Browser agent regression | [Browser agent regression](./docs/agent-regression.md) |
| Feed raw PTY replay into a downstream browser terminal renderer | Browser harness | [Browser terminal harness](./docs/browser-terminal-harness.md) |
| Debug CI failures, moved artifacts, or snapshot drift | Artifact commands | [Artifacts and CI](./docs/artifacts-and-ci.md) |

## Quick Start

### MCP Server

```bash
ptywright mcp
ptywright mcp --caps core
ptywright mcp --caps core,script,recording
ptywright mcp-http --port 3000
```

MCP client config:

```json
{
  "mcpServers": {
    "ptywright": {
      "command": "bunx",
      "args": ["ptywright@latest", "mcp", "--caps", "core,script,recording"]
    }
  }
}
```

Typical MCP flow: `launch_session`, `wait_for_text`, `send_text` or
`press_key`, `wait_for_stable_screen`, `snapshot_text` or `snapshot_view`, then
`close_session`.

### Script Runner

Create a JSON script:

```json
{
  "$schema": "./schemas/ptywright-script.schema.json",
  "name": "tui_smoke",
  "launch": {
    "command": "bun",
    "args": ["run", "tests/fixtures/tui_demo.ts"],
    "cols": 80,
    "rows": 24
  },
  "steps": [
    { "type": "waitForText", "text": "PTYWRIGHT TUI DEMO" },
    { "type": "snapshot", "kind": "text", "saveAs": "ready" },
    { "type": "expect", "from": "ready", "contains": ["status: ok"] }
  ]
}
```

Run it:

```bash
ptywright run scripts/tui_smoke.json
ptywright run-all --dir scripts
ptywright script inspect .tmp/run-all
```

Run output is written under `.tmp/runs/<name>/` for single scripts and
`.tmp/run-all/` for suites by default.

### Raw PTY Cassette

```bash
ptywright pty record --out tests/cassettes/session.pty.json -- codex
ptywright pty replay tests/cassettes/session.pty.json --speed 0
ptywright pty validate tests/cassettes/session.pty.json
ptywright pty inspect tests/cassettes/session.pty.json
```

For projects that already own a `node-pty` or `bun-pty` style process, use the
programmatic wrapper:

```ts
import { wrapPtyLike } from "ptywright/pty-cassette";

const recorded = wrapPtyLike(pty, {
  path: "tests/cassettes/session.pty.json",
  terminal: { cols: 120, rows: 40, term: "xterm-256color" },
  command: { file: "codex", args: [] },
});

recorded.write("hello\r");
```

### Browser Agent Regression

Use this when a browser page renders a terminal and exposes
`[data-terminal-root]`.

```bash
ptywright agent run examples/agent_deterministic.json --update-snapshots
ptywright agent run examples/agent_deterministic.json
ptywright agent replay .tmp/agent/agent_deterministic/agent_deterministic.cassette.json
ptywright agent check
```

The preferred integration is `launch.mode="command"`: start a wrapper command,
read the first printed URL, open it with Playwright, and snapshot terminal/DOM
state across configured viewports.

## Command Map

```bash
ptywright mcp                         # MCP over stdio
ptywright mcp-http --port 3000        # MCP over Streamable HTTP
ptywright run <file.json|file.ts>     # Run one script
ptywright run-all --dir scripts       # Run a script suite
ptywright script inspect <dir>        # Inspect script artifacts
ptywright pty record --out <file> -- <command> [args...]
ptywright pty replay <file>
ptywright agent run <flow.json>
ptywright agent replay <run-or-cassette>
ptywright agent promote <run-or-cassette>
ptywright agent replay-all [dir]
ptywright agent check [dir]
ptywright agent inspect <artifact-or-dir>
ptywright agent exec <artifact-or-dir> --command rerun
```

Run `ptywright help` for the full CLI surface.

## Documentation

- [MCP tools](./docs/mcp.md)
- [Script runner](./docs/script-runner.md)
- [Raw PTY cassettes](./docs/pty-cassette.md)
- [Browser agent regression](./docs/agent-regression.md)
- [Browser terminal harness](./docs/browser-terminal-harness.md)
- [Artifacts and CI](./docs/artifacts-and-ci.md)
- [Documentation maintenance](./docs/documentation-maintenance.md)
- [Roadmap](./plan.md)
- [Historical research notes](./DEEPRESEARCH.md)

JSON schemas live in [`schemas/`](./schemas/), and examples live in
[`examples/`](./examples/) and [`scripts/`](./scripts/).

## Project Layout

```text
src/cli/           CLI argument parsing and command dispatch
src/mcp/           MCP server and tool registrations
src/session/       TerminalSession lifecycle, waits, snapshots, frames
src/pty/           PTY adapter abstraction and Bun backends
src/terminal/      xterm/headless snapshot, ANSI, style, mouse helpers
src/script/        JSON/TS script runner, suites, reports, manifests
src/agent/         Browser terminal agent flows, replay, promote, check
src/pty-cassette/  Raw PTY record/replay and wrapper APIs
src/trace/         Cast and HTML report generation
schemas/           Published JSON schemas
tests/             Deterministic fixtures, goldens, cassettes, snapshots
```

## Development

```bash
bun install

# Local CLI and MCP
bun run src/cli.ts help
bun run src/cli.ts mcp

# Main gates
bun run test
bun run agent:check
bun run check

# Formatting and linting
bun run format:check
bun run lint

# Useful focused runs
bun run src/cli.ts run examples/report_demo_pass.json
bun run src/cli.ts run-all --dir scripts
bun run src/cli.ts agent run examples/agent_deterministic.json --update-snapshots
```

CI installs Chromium, runs `bun run check`, and uploads `.tmp/agent-check`.

## Environment

- `TUI_TEST_PTY_BACKEND=auto|bun-terminal|bun-pty`
  - Default `auto`: macOS/Linux prefer `bun-terminal`; Windows uses `bun-pty`.
- `PTYWRIGHT_CAPS=all|core|debug|script|recording`
  - Equivalent to `ptywright mcp --caps ...`.

## License

Apache-2.0