Ownership Boundaries

tastty separates terminal concerns by what the caller wants to own.

tastty-core owns terminal protocol state. It parses bytes into a virtual screen, tracks modes and events, encodes input, and represents host replies. The caller still owns the transport, the event loop, and all reads and writes.

tastty owns PTY session lifecycle. It starts a child process, reads from the PTY on a background thread, writes input to the child, resizes the PTY and screen together, and exposes snapshots of the parsed screen.

tastty-driver owns active control. It turns a live session into a higher-level surface for spawning, sending input, waiting for conditions, capturing snapshots, inspecting terminal metadata, and controlling the process.

Dependency direction

The dependency direction is intentionally one-way:

tastty-driver -> tastty -> tastty-core

This keeps protocol code usable without session management, and keeps session management usable without the driver layer. It also gives callers a clear choice between parser-only, managed session, and active control APIs.

Parser, Terminal, Driver

The same terminal state appears at different levels:

Move up a layer when you want that layer to own more lifecycle. Move down a layer when you need a smaller dependency or a custom transport.

Site docs and rustdoc

The site docs explain the shape of the libraries and the common workflows. They do not duplicate rustdoc.

Use these pages for:

Use rustdoc for:

Terminal sizes and positions

The public API uses named coordinate and size types. TerminalSize carries rows and cols; Position carries row and col. This makes resize, cursor, wait, and snapshot code read consistently across the three layers.

Use TerminalSize::new for dimensions from untrusted input. Runtime resizes reject zero rows or columns. Struct-literal construction is still available when the caller already knows the values are valid.

Input paths

There are three input paths, depending on how much abstraction you want:

Typed input is preferable when the child program may change keyboard modes. Raw bytes are appropriate when you intentionally want protocol-level control. Driver input segments are useful when a workflow mixes literal text with named keys in a single ordered sequence.

Waits and snapshots

The driver wait API polls snapshots until a condition matches, the timeout expires, or the child exits before a non-exit condition can match. Conditions cover text, regex, row regex, cell text, cursor position, process exit, stable screens, and any_of composition.

A driver Snapshot is richer than tastty::TerminalSnapshot: it includes visible text, cells, style runs, cursor state, title metadata, and alternate screen state. Use tastty::TerminalSnapshot when you only need a compact view from a managed PTY session. Use tastty-driver snapshots when waits, inspection, styles, scrollback, or process control are part of the workflow.

Feature flags

tastty-core keeps optional integrations behind features:

tastty enables widget and crossterm by default and forwards those features to tastty-core.

tastty-driver has no default features. Its async feature adds Session::wait_async, a runtime-agnostic future wrapper around the same wait logic used by Session::wait.