alktty 0.5.0

Terminal session protocol: wire format, TtyBackend trait, TtyAdapter, and typed consumer client. Producer/consumer protocol crate on top of alkcall channels.
Documentation
//! alktty: Terminal session protocol for the `alk/tty` ALPN.
//!
//! Producer/consumer protocol crate on top of alkcall channels. Two
//! halves (per alkcall's protocol-crate pattern):
//!
//! - **Producer half** — [`adapter::TtyAdapter`] (direct `alk/tty`
//!   ALPN via `ProtocolHandler`) + [`channels`] (registers the
//!   `channels/tty/sub` open op via `ChannelCore::register_openable`
//!   for the `alk/channels` multiplexed path).
//! - **Consumer half** — [`session::TtySession`] (typed client wrapper
//!   around the wire protocol, with `connect_direct` and
//!   `open_via_channels` constructors).
//!
//! Two-carriage wire format (ADR-052): a JSON negotiation frame, then
//! raw chunks (`[stream_type: u8][length: u32 be][payload]`).
//! Backend-agnostic via the [`backend::TtyBackend`] trait (ADR-053).
//! Depends on alkcall (ADR-057 — the negotiation framing is
//! self-contained; alkcall's `EventEnvelope` framing is not reused).
//!
//! # WASM target
//!
//! The default crate (no features) compiles to
//! `wasm32-unknown-unknown`. The `local` module is feature-gated
//! and non-wasm by design (`portable-pty` + `tokio::process` need a
//! real OS). Downstream TS/Python adapters compile the protocol
//! layer in a sandbox; the local-process backend runs on a real OS.
//!
//! # Local backend
//!
//! The local backend (`local::LocalTtyBackend`) is gated behind the
//! `local` feature. It implements [`backend::TtyBackend`] via
//! `portable_pty` (PTY mode, terminal semantics) and
//! `tokio::process::Command` (pipe mode, the runner case). The
//! blocking→async bridge for PTY mode uses three dedicated std
//! threads feeding tokio mpsc/oneshot channels (REQ-TTY-01).
//!
//! # Assembly pattern
//!
//! ```ignore
//! let mut backends = std::collections::HashMap::new();
//! backends.insert(
//!     "local".into(),
//!     std::sync::Arc::new(alktty::LocalTtyBackend::new())
//!         as std::sync::Arc<dyn alktty::TtyBackend>,
//! );
//! let tty_adapter = alktty::TtyAdapter::new(backends);
//! ```
//!
//! # Crate-root surface
//!
//! The primary types are re-exported at the crate root —
//! [`TtyAdapter`]/[`drive_session`] (producer), [`TtySession`]
//! (consumer), [`TtyBackend`]/[`TtyHandle`]/[`TtyParams`] (backend
//! authors), plus the wire codec ([`Chunk`], [`ChunkReader`],
//! [`ChunkWriter`]), the wire constants ([`STREAM_STDOUT`],
//! [`MAX_CHUNK_LEN`], ...), [`ControlMessage`], the negotiation types
//! [`NegotiateRequest`], ...), the channels registration helpers
//! ([`register_openable`]), and `local::LocalTtyBackend` under the
//! `local` feature. The module paths below remain the full public surface —
//! the root re-exports are the ergonomic short paths for the common
//! imports.

pub mod adapter;
pub mod backend;
pub mod channels;
pub mod control;
pub mod negotiation;
pub mod session;
pub mod wire;

#[cfg(feature = "local")]
pub mod local;

#[cfg(test)]
pub(crate) mod testing;

pub use adapter::{drive_session, drive_session_pre_negotiated, TtyAdapter, TTY_OPEN_SCOPE};
pub use backend::{
    BoxFuture, TerminalParams, TtyBackend, TtyControl, TtyControlHandle, TtyError, TtyHandle,
    TtyParams,
};
pub use channels::{register_openable, tty_open_spec, OP_TTY_OPEN, TTY_ALPN};
#[cfg(unix)]
pub use control::signal_from_name;
pub use control::ControlMessage;
pub use negotiation::{
    error_response_bytes, NegotiateRequest, NegotiationError, NegotiationReader, NegotiationWriter,
    TerminalParamsWire,
};
pub use session::{TtySession, TtySessionError};
pub use wire::{
    Chunk, ChunkReader, ChunkWriter, RawError, CHUNK_HEADER_LEN, MAX_CHUNK_LEN, STREAM_CTRL_IN,
    STREAM_CTRL_OUT, STREAM_STDERR, STREAM_STDIN, STREAM_STDOUT,
};

#[cfg(feature = "local")]
pub use local::LocalTtyBackend;