# Python parity ledger
## Baseline and policy
The first Rust release targets the Python public API at commit
[`c4a980b`](https://github.com/tmux-python/libtmux/tree/c4a980b). The baseline
does not move during implementation. A later Python change enters scope only
through an explicit baseline update and ledger diff.
Public scope follows the pinned API reference and public-API policy:
- root exports from `src/libtmux/__init__.py`;
- modules documented under `docs/api/`;
- test helpers documented under `docs/api/testing/`;
- behavior of internal return types when it is observable through a public
API.
Modules under `libtmux._internal` and `libtmux._vendor` are not independently
public. The [boundary appendix](#ambiguous-public-boundaries) records places
where documentation, import mechanics, and return types disagree.
This ledger records Python behavior, cardinality, error behavior, tmux gates,
the intended Rust surface, and the delivery slice that owns it. Python test
paths are corroborating sources; their presence does not claim that every row
has a dedicated test. Rust test evidence is added only when a row advances
beyond `planned`.
The Rust hierarchy-collection policy is uniform. Each public listing has a
lenient accessor and a loud `try_*` form: `Server::sessions` beside
`Server::try_sessions`, and so on down the hierarchy. The lenient form returns
an empty `Vec` when its tmux list operation fails and records the failure
through tracing when enabled, so a caller that needs to tell "no rows" from
"tmux unreachable" reaches for the `try_*` form. `Server::hierarchy` returns
the whole tree in one pass. Expression construction, singular relationships,
mutations, decoding, and capability validation are loud `Result` APIs.
## Status vocabulary
| Status | Meaning |
| ------------- | ------------------------------------------------------------------------- |
| `planned` | Python behavior and Rust target are mapped; implementation has not begun. |
| `in progress` | The owning delivery slice is active, but the row is not complete. |
| `implemented` | The Rust symbol exists and focused behavior tests pass. |
| `verified` | Focused evidence and the relevant full delivery gate pass. |
| `excluded` | A reviewed public-boundary decision intentionally leaves the symbol out. |
Capability rows begin as `planned`. An intentional delta remains planned until
its Rust behavior and tests exist.
Delivery slices are named: `Foundation`,
`Formats, snapshots, winlinks, and queries`, `Discovery, traversal, refresh,
and environment resolution`, `Object mutations and interactions`, `Options,
hooks, and advanced command families`, and `Documentation, compatibility, and
parity closure`.
## Crate facade
Sources: `src/libtmux/__init__.py`, `src/libtmux/__about__.py`,
`docs/api/index.md`, and `docs/project/public-api.md`.
| Python API | Python baseline | Rust target or delta | Delivery slice | Status |
| ---------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- | ------------- |
| `Server` | Root re-export of the Server handle. | Root `pub use` of the concrete `Server`; covered by [`tests/server_command.rs`](../tests/server_command.rs). | Foundation | `implemented` |
| `Client`, `Pane`, `Session`, `Window` | Root re-exports of the remaining handle classes. | Root `pub use` of the corresponding concrete handles; covered by [`tests/hierarchy.rs`](../tests/hierarchy.rs) and [`tests/commands.rs`](../tests/commands.rs). | Discovery, traversal, refresh, and environment resolution | `implemented` |
| `__title__`, `__package_name__`, `__version__`, `__description__`, `__license__` | Package metadata strings; no tmux I/O or error path. | Cargo package metadata; no runtime accessors or Python dunder names. | Foundation | `excluded` |
| `__author__`, `__email__`, `__copyright__` | Package metadata re-exported at the root. | Cargo authors preserve contributor attribution; email, copyright, and runtime constants are omitted. | Foundation | `excluded` |
| `libtmux.client`, `common`, `constants`, `exc`, `hooks`, `neo`, `options`, `pane`, `server`, `session`, `window` | Modules in the pinned API reference. | Capabilities live in the Rust component modules described in [design.md](design.md). Python's module namespace is not a promise this crate makes. | Documentation, compatibility, and parity closure | `excluded` |
| `libtmux.test` | Documented downstream test helpers. | Optional `libtmux::test` support; covered by [`tests/test_server.rs`](../tests/test_server.rs). | Foundation | `implemented` |
| `libtmux.pytest_plugin` | Pytest-specific fixture injection. | No Rust equivalent; downstream tests opt into `test-support` and construct guards explicitly. | Foundation | `excluded` |
## Commands, versions, and common values
Sources: `src/libtmux/common.py`, `tests/test_common.py`, and
`tests/test_version.py`.
| Python API | Python baseline | Rust target or delta | Delivery slice | Status |
| --------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- | ------------- |
| `TMUX_MIN_VERSION` | String for the supported floor, 3.2a. | `TmuxVersion::MIN_SUPPORTED`; covered by [`tests/version.rs`](../tests/version.rs). | Foundation | `implemented` |
| `TMUX_MAX_VERSION` | String for the newest release modeled by the Python field table, 3.7. | No public maximum: private descriptor floors model each capability without claiming a truthful upper bound; covered by catalog tests in [`src/formats.rs`](../src/formats.rs). | Formats, snapshots, winlinks, and queries | `excluded` |
| `SessionDict`, `WindowDict`, `PaneDict` | Runtime aliases for object `dict[str, Any]` values. | `SessionFields`, `WindowFields`, and `PaneFields`: typed snapshots, so there is no loose public alias to keep in step with tmux. | Formats, snapshots, winlinks, and queries | `implemented` |
| `WindowOptionDict` | Runtime alias for a window-option `dict[str, Any]`. | `OptionValue`, which decodes a flag and a number by what tmux declares about the option rather than by the caller guessing. | Options, hooks, and advanced command families | `implemented` |
| `CmdProtocol.__call__` | Public structural typing surface for a callable that returns `tmux_cmd`. | `Server::cmd` backed by a private executor; no public executor or extension trait; covered by [`tests/server_command.rs`](../tests/server_command.rs). | Foundation | `implemented` |
| `CmdMixin.cmd` | Annotation-only mixin surface used by all hierarchy handles. | Inherent `cmd` on `Server`, `Session`, `Window`, and `Pane`. Nothing to import. | Discovery, traversal, refresh, and environment resolution | `implemented` |
| `tmux_cmd` input argv and diagnostic command string | Accepts unclassified variadic strings and can log an executable command line. | Consuming `Command` builders classify arguments and expose only a bounded, ASCII-only `CommandSummary`; covered by [`tests/command.rs`](../tests/command.rs) and private lowering tests in [`src/command.rs`](../src/command.rs). | Foundation | `implemented` |
| `tmux_cmd(*args, tmux_bin=None)` execution | Executes argv synchronously without a shell. Missing executable raises `TmuxCommandNotFound`; ordinary nonzero status and stderr remain data. | `Server::cmd(Command) -> Result<CommandResult, Error>`, backed by a private `CommandRequest` and supervised Tokio executor; covered by [`tests/server_command.rs`](../tests/server_command.rs) and [`src/internal/subprocess.rs`](../src/internal/subprocess.rs). | Foundation | `implemented` |
| `tmux_cmd` output storage and normalization | Text decoding uses UTF-8 with `backslashreplace`; trailing stdout blanks and empty stderr lines are removed. `has-session` copies its first stderr line into stdout when stdout is empty. | Public `CommandResult` preserves exact stdout/stderr bytes and provides borrowed strict and named lossy views; covered by [`tests/server_command.rs`](../tests/server_command.rs) and [`src/command.rs`](../src/command.rs). | Foundation | `implemented` |
| `tmux_cmd.cmd`, `process`, `returncode`, `stdout`, `stderr` | Public mutable result attributes, including the underlying process. | Public immutable `CommandResult` accessors expose request ID, summary, status, signal, and byte streams without exposing the child process or executable argv; covered by [`tests/server_command.rs`](../tests/server_command.rs). | Foundation | `implemented` |
| `raise_if_stderr` | Returns `None`; any stderr raises `LibTmuxException` with subcommand context. | Private domain-result conversion introduced with the first loud discovery operation. Raw `cmd()` remains non-escalating. | Discovery, traversal, refresh, and environment resolution | `planned` |
| `get_version_str` | Independently cached raw version string. Preserves suffixes; `master` stays raw; OpenBSD without `-V` receives a synthetic maximum-version suffix. Detection errors propagate. | `Server::capabilities()` exposes the exact cached `TmuxVersion`; no synthetic OpenBSD maximum or public function-cache attributes; covered by [`tests/server_command.rs`](../tests/server_command.rs). | Foundation | `implemented` |
| `get_version` | Independently cached `LooseVersion`; strips lowercase letters and hyphens, maps `master` above the modeled maximum, and uses the OpenBSD fallback. | `EngineCapabilities::tmux_version()` returns parsed `TmuxVersion`; suffix ordering is retained, and development identifiers are only minimum-capable; covered by [`tests/version.rs`](../tests/version.rs). | Foundation | `implemented` |
| `has_version`, `has_gt_version`, `has_gte_version`, `has_lte_version`, `has_lt_version` | Return one bool; version-detection errors propagate. | `TmuxVersion::meets()` and release-backed `PartialOrd`; covered by [`tests/version.rs`](../tests/version.rs). | Foundation | `implemented` |
| `has_minimum_version` | Returns true above 3.2a; below the floor returns false only when `raises=False`, otherwise raises `VersionTooLow`. | `TmuxVersion::ensure_supported() -> Result<()>` plus `meets()` for bool callers; covered by [`tests/version.rs`](../tests/version.rs). | Foundation | `implemented` |
| `session_check_name` | Returns `None`; rejects `None`, empty names, periods, and colons with `BadSessionName`. | `SessionName::new`, rejecting an empty name and one holding `:` or `.`. Not inherited convention: tmux accepts such a name, stores it, then splits it on the separator when asked to find it again, so `has-session -t 'a:b'` answers "can't find window: b" and the session cannot be killed by its own name. Covered by [`tests/mutations.rs`](../tests/mutations.rs). | Discovery, traversal, refresh, and environment resolution | `implemented` |
| `get_libtmux_version` | Returns the parsed Python package version. | Cargo package metadata; no runtime package-version accessor. | Foundation | `excluded` |
| `EnvironmentMixin`, `EnvironmentMixin.__init__`, `CmdMixin` | Public mixin types. Environment behavior is usable through `Server` and `Session`. | Inherent environment methods on both `Server` and `Session`, sharing the private `internal::environment` module. No trait to import. | Discovery, traversal, refresh, and environment resolution | `implemented` |
| `set_environment` | One unit mutation. Stderr becomes `ValueError`; `expand_format` and `hidden` have no wrapper version preflight. | `Session::set_environment`, a loud method taking sensitive values; covered by [`tests/mutations.rs`](../tests/mutations.rs). | Object mutations and interactions | `implemented` |
| `unset_environment`, `remove_environment` | One unit mutation each; stderr becomes `ValueError`. | `Session::unset_environment`, one loud action; `remove_environment` has no separate meaning in Rust; covered by [`tests/mutations.rs`](../tests/mutations.rs). | Object mutations and interactions | `implemented` |
| `show_environment` | One dictionary of zero or more string/bare-unset values. Stderr is ignored, so failure may look empty. | `environment() -> Result<BTreeMap<_, EnvironmentValue>>`; represent set and unset explicitly. | Discovery, traversal, refresh, and environment resolution | `implemented` |
| `getenv` | One string, bare-unset bool, or `None`. Stderr is ignored, so failure may look absent. | `environment(name) -> Result<Option<EnvironmentEntry>>`, distinguishing a value from a removal mark rather than reporting both as absent: tmux keeps "hold this" and "do not pass this on" separately, and the second is set deliberately. Covered by [`tests/mutations.rs`](../tests/mutations.rs). | Discovery, traversal, refresh, and environment resolution | `implemented` |
## Errors
Source: `src/libtmux/exc.py`. Query behavior is also exercised in
`tests/_internal/test_query_list.py`.
| Python API | Python baseline | Rust target or delta | Delivery slice | Status |
| ----------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- | ------------- |
| `LibTmuxException` | Base exception with public `subcommand`; string output prefixes the subcommand when present. | `#[non_exhaustive] Error` is the Foundation error surface with sanitized request and source context; later slices add domain variants. Covered by [`tests/version.rs`](../tests/version.rs) and [`src/internal/subprocess.rs`](../src/internal/subprocess.rs). | Foundation | `implemented` |
| `DeprecatedError` | Builds an always-failing removal message from deprecated name, replacement, and version. | Omit Python APIs whose only behavior is this exception. | Documentation, compatibility, and parity closure | `excluded` |
| `TmuxCommandNotFound` | The tmux executable could not be launched. | `Error::ExecutableNotFound` with the sanitized spawn source; covered by [`tests/server_command.rs`](../tests/server_command.rs) and private executor tests in [`src/internal/subprocess.rs`](../src/internal/subprocess.rs). | Foundation | `implemented` |
| No direct Python equivalent | Python defers most server-configuration validation until command execution. | `Error::InvalidServerConfiguration` and `ServerConfigurationErrorKind`; covered by [`tests/server_command.rs`](../tests/server_command.rs). | Foundation | `implemented` |
| No direct Python equivalent | Version detection exposes heterogeneous subprocess and parsing failures. | `Error::InvalidVersionOutput` and `Error::VersionProbeFailed`; covered by [`tests/version.rs`](../tests/version.rs) and [`tests/server_command.rs`](../tests/server_command.rs). | Foundation | `implemented` |
| No direct Python equivalent | Raw execution has no typed input, spawn, or output-read failure taxonomy. | `Error::InvalidCommandInput`, `Error::Spawn`, and `Error::ReadOutput`; covered by [`tests/server_command.rs`](../tests/server_command.rs), [`src/internal/core.rs`](../src/internal/core.rs), and [`src/internal/subprocess.rs`](../src/internal/subprocess.rs). | Foundation | `implemented` |
| No direct Python equivalent | Raw execution does not distinguish a child-wait failure after process ownership transfers. | `Error::WaitChild`; covered by the focused cleanup test in [`src/internal/subprocess.rs`](../src/internal/subprocess.rs). | Foundation | `implemented` |
| No direct Python equivalent | Raw execution has no built-in deadline, shutdown registry, duplicate-request guard, or typed supervisor failure. | `Error::Timeout`, `Error::ExecutorShutdown`, `Error::DuplicateRequest`, and `Error::SupervisorLost`; covered by [`src/internal/subprocess.rs`](../src/internal/subprocess.rs). | Foundation | `implemented` |
| `TmuxSessionExists` | Requested Session name collides with a live Session. | `Error::SessionExists`, classified from tmux's refusal rather than checked beforehand: a name can be taken between a check and a create, so tmux refusing is the only answer that cannot be stale. Reachable from a plan step too, through `StepOutcome::refusal`. Covered by [`tests/mutations.rs`](../tests/mutations.rs). | Object mutations and interactions | `implemented` |
| `NotInsideTmux` | Optional environment-variable and reason context. | `ServerConfigurationErrorKind::NotInsideTmux` for an absent `TMUX`, and `MalformedTmuxVariable` for one that is present and not tmux's triple. Split because they are different situations: the first is an ordinary state a caller branches on, the second is a rewritten environment. Covered by [`tests/server_command.rs`](../tests/server_command.rs). | Discovery, traversal, refresh, and environment resolution | `implemented` |
| `ObjectDoesNotExist`, `MultipleObjectsReturned` | Zero and multiple local matches. The first exposes `query`; the second exposes `count` and `query`. A default suppresses only the zero-match case. | Borrowed `QueryIteratorExt::exactly_one` and `one_or_none` use source-less `ExactlyOneError` and `MultipleItemsError`, retain no query, and inspect at most two items; covered by [`tests/query.rs`](../tests/query.rs). | Formats, snapshots, winlinks, and queries | `verified` |
| `TmuxObjectDoesNotExist` | A live target was absent from tmux output. | `Error::ObjectGone { kind, id }`, naming which object and which identity rather than the fact alone. Classified from tmux's own "can't find …" wording, pinned against every supported release. | Discovery, traversal, refresh, and environment resolution | `implemented` |
| `VersionTooLow` during connection | tmux is below the library floor. | `Error::UnsupportedTmuxVersion`; construction and diagnostics are covered by [`tests/version.rs`](../tests/version.rs). | Foundation | `implemented` |
| `VersionTooLow` for an optional operation | A requested operation or flag is unavailable on the detected tmux. | `Error::UnsupportedCapability`, checked before dispatch. Verified refusing on tmux 3.2a and accepting on 3.3a and 3.7b; covered by [`tests/commands.rs`](../tests/commands.rs). | Object mutations and interactions | `implemented` |
| `BadSessionName` | Invalid session-name reason and optional name. | `SessionNameError`, raised by `SessionName::new` rather than by a command: the name is wrong before tmux is asked, so the failure belongs at construction. Covered by [`tests/mutations.rs`](../tests/mutations.rs). | Discovery, traversal, refresh, and environment resolution | `implemented` |
| `OptionError`, `UnknownOption`, `InvalidOption`, `AmbiguousOption` | Option-error hierarchy selected from tmux stderr. | `Error::OptionRejected { kind, detail }` with `OptionErrorKind::{Unknown, Ambiguous, BadValue}`. Three kinds, not four: tmux resolves a name with `options_match` before the branch that says `unknown option`, so Python's `UnknownOption` cannot fire on any supported release. | Options, hooks, and advanced command families | `implemented` |
| `UnknownColorOption` | Invalid color mode is raised locally by `Server.cmd`. | Eager `ServerBuilder` color validation through `Error::InvalidServerConfiguration`; covered by [`tests/server_command.rs`](../tests/server_command.rs). | Foundation | `implemented` |
| `WaitTimeout` | Retry condition did not become true before timeout. | `test::RetryTimeout`, returned by `test::retry_until`, and distinct from a subprocess timeout so a condition that never held is not read as tmux failing to answer. | Documentation, compatibility, and parity closure | `implemented` |
| `VariableUnpackingError` | Malformed environment-variable row. | A future typed environment-row parse error owned by discovery; the current public `Error` has no environment or format-row variant. | Discovery, traversal, refresh, and environment resolution | `planned` |
| `PaneError`, `PaneNotFound`, `WindowError` | Marker bases plus a pane-not-found message. | `Error::ObjectGone { kind, id }` carries which kind, so a marker type per object is unnecessary; `ObjectKind` is the discriminant. | Discovery, traversal, refresh, and environment resolution | `implemented` |
| `MultipleActiveWindows`, `NoActiveWindow`, `NoWindowsExist` | Relationship cardinality failures. | Absence is `Option`, since a window with no active pane is a state rather than a fault; `query::ExactlyOneError::{NoItems, MultipleItems}` keeps local iterator cardinality separate from it. | Discovery, traversal, refresh, and environment resolution | `implemented` |
| `AdjustmentDirectionRequiresAdjustment`, `WindowAdjustmentDirectionRequiresAdjustment`, `PaneAdjustmentDirectionRequiresAdjustment` | Direction without an adjustment; also `ValueError`. The pane-specific class inherits through `WindowError`. | Typed request construction or `Error::InvalidArgument`; do not reproduce the inheritance anomaly. | Object mutations and interactions | `planned` |
| `RequiresDigitOrPercentage` | Resize value is neither a digit nor a percentage; also `ValueError`. | No such error: `PaneSize` is `Cells(u32)` or `Percent(u32)`, so a size that is neither cannot be constructed and there is nothing to reject at run time. | Object mutations and interactions | `excluded` |
## Constants and targets
Source: `src/libtmux/constants.py`.
| Python API | Python baseline | Rust target or delta | Delivery slice | Status |
| ------------------------------------------------------- | ----------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- | ------------- |
| `ResizeAdjustmentDirection.Up`, `Down`, `Left`, `Right` | Enum members mapping to `-U`, `-D`, `-L`, and `-R`. | `ResizeDirection`, with the flag conversion private so the mapping cannot be mutated. Covered by [`tests/mutations.rs`](../tests/mutations.rs). | Object mutations and interactions | `implemented` |
| `RESIZE_ADJUSTMENT_DIRECTION_FLAG_MAP` | Public mutable direction-to-flag dictionary. | No public map. `ResizeDirection` converts through a private exhaustive match, so the mapping cannot be mutated by a caller and a new direction is a compile error rather than a missing key. | Object mutations and interactions | `excluded` |
| `WindowDirection.Before`, `After` | Enum members mapping to `-b` and `-a`. | `WindowPlacement`. Covered by [`tests/mutations.rs`](../tests/mutations.rs). | Object mutations and interactions | `implemented` |
| `WINDOW_DIRECTION_FLAG_MAP` | Public mutable direction-to-flag dictionary. | `Session::next_window`, `previous_window`, and `last_window`: distinct methods, so there is no map to mutate and no direction that fails to resolve. | Object mutations and interactions | `implemented` |
| `PaneDirection.Above`, `Below`, `Right`, `Left` | Maps to vertical/horizontal and before flag combinations. | `SplitDirection`, named for what it does rather than for a placement: tmux's flags are a vertical/horizontal axis plus a before bit, and the enum spells the four results. Covered by [`tests/mutations.rs`](../tests/mutations.rs). | Object mutations and interactions | `implemented` |
| `PANE_DIRECTION_FLAG_MAP` | Public mutable direction-to-flag-list dictionary. | `PaneDirection` and `Window::focus_direction`, over a private exhaustive match. Returns the pane rather than an `Option`, because tmux wraps at the edge instead of reporting nothing there. | Object mutations and interactions | `implemented` |
| `OptionScope.Server`, `Session`, `Window`, `Pane` | Scope enum. | `OptionScope`. | Options, hooks, and advanced command families | `implemented` |
| `OPTION_SCOPE_FLAG_MAP`, `HOOK_SCOPE_FLAG_MAP` | Public mutable maps; Session maps to an empty flag. | `internal::options::Scope::apply`, a private exhaustive match. Nothing downstream can mutate the mapping. | Options, hooks, and advanced command families | `implemented` |
| `DEFAULT_OPTION_SCOPE` | Public instance of a private sentinel, distinguishing omitted scope from explicit `None`. | No public sentinel. A builder default says the same thing without a value callers can name. | Options, hooks, and advanced command families | `excluded` |
| Raw Python IDs and target strings | IDs are unchecked optional strings; many methods accept overlapping string and integer targets. | Validated `SessionId`, `WindowId`, `PaneId`, scope-specific targets, and `ServerIdentity`; covered by [`tests/target.rs`](../tests/target.rs) and private resolver tests in [`src/target.rs`](../src/target.rs). | Foundation | `implemented` |
| Window and winlink identity strings | Window identity and one Session/index link to it are carried in overlapping raw fields. | Separate `WindowLink` and `WindowLinkIdentity` values. | Formats, snapshots, winlinks, and queries | `planned` |
## Formats and snapshots
Sources: `src/libtmux/formats.py`, `src/libtmux/neo.py`,
`tests/test_neo.py`, `tests/test_dataclasses.py`, and the pinned upstream tmux
sources: [3.2a format callbacks](https://github.com/tmux/tmux/blob/3b929f3/format.c),
[session listings](https://github.com/tmux/tmux/blob/3b929f3/cmd-list-sessions.c),
[window listings](https://github.com/tmux/tmux/blob/3b929f3/cmd-list-windows.c),
[pane listings](https://github.com/tmux/tmux/blob/3b929f3/cmd-list-panes.c),
[client listings](https://github.com/tmux/tmux/blob/3b929f3/cmd-list-clients.c),
[point resolution](https://github.com/tmux/tmux/blob/3b929f3/cmd-find.c),
[3.3 format callbacks](https://github.com/tmux/tmux/blob/87fe00e/format.c),
[3.6 format callbacks](https://github.com/tmux/tmux/blob/0dac7fe/format.c),
and [3.7 format callbacks](https://github.com/tmux/tmux/blob/81f88f8/format.c).
Transport evidence is intentionally asymmetric. Pinned upstream tmux 3.4 and
3.5 source establishes the VIS output transform, while the release-range unit
test models 3.4 through 3.5 patch releases. The explicitly selected distro
`/usr/bin/tmux` 3.4 executable supplies the exact live VIS-output
characterization and q-only parser refusal. No pinned or distro 3.5 executable
has run that fixture, so 3.5 remains source-modeled rather than
live-characterized. Pinned 3.2a and 3.6 plus current 3.7b prove raw-q recovery.
Neither source modeling nor the live 3.4 characterization proves arbitrary
original callback-byte recovery.
The causal transport path is pinned in full. tmux
[3.4 `cmdq_print`](https://github.com/tmux/tmux/blob/9ae69c3795ab5ef6b4d760f6398cd9281151f632/cmd-queue.c#L826-L849)
and
[3.5 `cmdq_print`](https://github.com/tmux/tmux/blob/ac44566c9c7e3e94d23be6def4c7ae83472543f5/cmd-queue.c#L835-L858)
send `parse = 0` to
[3.4 `server_client_print`](https://github.com/tmux/tmux/blob/9ae69c3795ab5ef6b4d760f6398cd9281151f632/server-client.c#L3272-L3289)
and
[3.5 `server_client_print`](https://github.com/tmux/tmux/blob/ac44566c9c7e3e94d23be6def4c7ae83472543f5/server-client.c#L3328-L3345),
whose `!parse` branch applies `VIS_OCTAL | VIS_CSTYLE | VIS_NOSLASH`. tmux
[3.6 `cmdq_print`](https://github.com/tmux/tmux/blob/0dac7fe434d029a4f0b819cba8eb7963df291990/cmd-queue.c#L835-L858)
instead sends `parse = 1`, and
[3.6 `server_client_print`](https://github.com/tmux/tmux/blob/0dac7fe434d029a4f0b819cba8eb7963df291990/server-client.c#L3877-L3897)
preserves the buffer on that branch.
| Python API | Python baseline | Rust target or delta | Delivery slice | Status |
| --------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- | --------- |
| `FORMAT_SEPARATOR` | Import-time `LIBTMUX_TMUX_FORMAT_SEPARATOR` override, otherwise a record-separator glyph. | Private collision-safe `#{q:field}%` framing has no process-global setting; covered by codec tests in [`src/formats.rs`](../src/formats.rs), with version-specific transport evidence summarized above. The q-only parser does not reconstruct arbitrary callback bytes from tmux 3.4/3.5 VIS transport, so this row cannot become `verified` until the discovery transport blocker closes. | Formats, snapshots, winlinks, and queries | `implemented` |
| `SESSION_FORMATS`, `CLIENT_FORMATS`, `WINDOW_FORMATS`, `PANE_FORMATS` | Public mutable legacy reference lists. They are not the runtime source of truth and contain obsolete or unmodeled tokens. | Omit the duplicate mutable lists; the checked private `FormatDescriptor` catalog is the single modeled source, covered by [`src/formats.rs`](../src/formats.rs). | Formats, snapshots, winlinks, and queries | `excluded` |
| `OutputRaw`, `OutputsRaw` | Aliases for one raw dictionary and a list of raw dictionaries. | Actual private `ParsedRow` and `ParsedSlot` values feed typed hydrators. Public raw aliases and selectors wait for a discovery consumer. | Formats, snapshots, winlinks, and queries | `planned` |
| No direct Python equivalent: raw text value | Python format fields are decoded strings, so invalid bytes are replacement-escaped before object construction. | Public `TmuxText` provides raw, strict, and named lossy views with bytewise traits and payload-free `Debug`; covered by [`tests/tmux_text.rs`](../tests/tmux_text.rs). | Formats, snapshots, winlinks, and queries | `verified` |
| `SCOPES_BY_LIST_CMD` | Mutable map of format scopes supported by each `list-*` command. Client listings add client scope; buffer, context, and event scopes are excluded. | Private `FormatDescriptor::profiles`, `owner`, and `required_context` provide checked static metadata; covered by catalog tests in [`src/formats.rs`](../src/formats.rs). | Formats, snapshots, winlinks, and queries | `verified` |
| `FIELD_VERSION` | Mutable minimum-version overrides. Unlisted fields default to 3.2a. | Private `FormatDescriptor::minimum_release` gates each field; covered by release-selection and catalog tests in [`src/formats.rs`](../src/formats.rs). | Formats, snapshots, winlinks, and queries | `verified` |
| `Obj(server, **fields)` | Public dataclass constructor with one `Server` and 178 optional string fields. Missing, empty, unsupported, and out-of-scope values all collapse to `None`; generated equality and repr cover the whole snapshot. | Crate-private hydration into `SessionInfo`, `WindowInfo`, `PaneInfo`, and `ClientInfo`; typed fields retain explicit availability while parser slots remain transient. Public snapshots wait for listing APIs. | Formats, snapshots, winlinks, and queries | `planned` |
| Parent-row active-child fields | Session rows can contain current-window and active-pane values; Window rows can contain active-pane values; Client rows contain attached Session, current Window, and active Pane snapshots. | Document the same projection while keeping identity and live relationships separate. | Formats, snapshots, winlinks, and queries | `planned` |
| `get_output_format` private plan construction | Cached `(field_names, format_string)` pair filtered by scope and detected version. Unknown list commands fall back to universal/session/window/pane scopes. | Private `FormatPlan::for_profile`, `for_descriptors`, and `template` bind descriptor order and version selection. Closed `ListProfile::{Sessions, Windows, Panes, Clients}` inputs make unknown command strings unrepresentable; covered by [`src/formats.rs`](../src/formats.rs). | Formats, snapshots, winlinks, and queries | `verified` |
| `get_output_format` public selector | The Python helper is callable directly and accepts list-command strings. | A public format-token or profile selector remains deferred until discovery has a consumer. | Discovery, traversal, refresh, and environment resolution | `planned` |
| `parse_output` private parsing and hydration | One raw dictionary. Strict field/value count can raise `ValueError`; empty values are dropped. | Private `FormatPlan::parse_rows`, `ParsedRow`, `ParsedSlot`, `FormatCodecError`, and typed hydrators preserve modeled states; covered by [`src/formats.rs`](../src/formats.rs) and [`src/snapshot.rs`](../src/snapshot.rs). The q-only path retains the tmux 3.4/3.5 status ceiling. | Formats, snapshots, winlinks, and queries | `implemented` |
| `parse_output` public decoder | The Python helper exposes raw parsed dictionaries. | A public decoder or raw-row consumer remains deferred until discovery defines its output and error surface; the root error has no format-row variant. | Discovery, traversal, refresh, and environment resolution | `planned` |
| `fetch_objs` | Ordered raw rows; optional native `-f`; any stderr raises `LibTmuxException`. Malformed filters can produce an indistinguishable empty result. | Private query execution and row decoding in `internal/listing.rs`, with a format plan per profile and `-f` predicate pushdown so tmux filters rows server-side. Exercised through every public listing. | Formats, snapshots, winlinks, and queries | `implemented` |
| `fetch_obj` | Exactly one raw row. Missing target raises `TmuxObjectDoesNotExist`. Duplicate winlinks prefer the active row, otherwise the lowest window index. | Point lookup pushes the id down as a `-f` predicate, then prefers the link the window is current through and breaks a tie on the lowest index. Activity belongs to the link rather than the window, so taking whichever row tmux listed first would pick by session name. Covered by [`tests/hierarchy.rs`](../tests/hierarchy.rs). | Formats, snapshots, winlinks, and queries | `implemented` |
| Public `refresh()` behavior driven by `Obj._refresh` | Only nonempty returned keys overwrite the object, so a field that becomes empty can remain stale. | Replace the complete snapshot atomically in `refresh(&mut self)` and return an independent value from `refreshed(&self)`. | Discovery, traversal, refresh, and environment resolution | `planned` |
### Format field matrix
The checked catalog below is the complete 178-field Python parity boundary,
not the complete tmux format table. It records callback semantics rather than
name-prefix guesses. The six Python-table floor corrections are
`client_uid`, `client_user`, `next_session_id`, `pane_start_path`, `uid`,
and `user`: each first appears in tmux 3.3 rather than 3.2a.
The static callbacks and four list-command contexts were audited at every
supported release pin:
| tmux | Commit | Static callbacks | Sessions | Windows | Panes | Clients |
| --- | --- | --- | --- | --- | --- | --- |
| 3.2a | `3b929f3` | [`format.c`](https://github.com/tmux/tmux/blob/3b929f3/format.c) | [source](https://github.com/tmux/tmux/blob/3b929f3/cmd-list-sessions.c) | [source](https://github.com/tmux/tmux/blob/3b929f3/cmd-list-windows.c) | [source](https://github.com/tmux/tmux/blob/3b929f3/cmd-list-panes.c) | [source](https://github.com/tmux/tmux/blob/3b929f3/cmd-list-clients.c) |
| 3.3 | `87fe00e` | [`format.c`](https://github.com/tmux/tmux/blob/87fe00e/format.c) | [source](https://github.com/tmux/tmux/blob/87fe00e/cmd-list-sessions.c) | [source](https://github.com/tmux/tmux/blob/87fe00e/cmd-list-windows.c) | [source](https://github.com/tmux/tmux/blob/87fe00e/cmd-list-panes.c) | [source](https://github.com/tmux/tmux/blob/87fe00e/cmd-list-clients.c) |
| 3.4 | `9ae69c3` | [`format.c`](https://github.com/tmux/tmux/blob/9ae69c3/format.c) | [source](https://github.com/tmux/tmux/blob/9ae69c3/cmd-list-sessions.c) | [source](https://github.com/tmux/tmux/blob/9ae69c3/cmd-list-windows.c) | [source](https://github.com/tmux/tmux/blob/9ae69c3/cmd-list-panes.c) | [source](https://github.com/tmux/tmux/blob/9ae69c3/cmd-list-clients.c) |
| 3.5 | `ac44566` | [`format.c`](https://github.com/tmux/tmux/blob/ac44566/format.c) | [source](https://github.com/tmux/tmux/blob/ac44566/cmd-list-sessions.c) | [source](https://github.com/tmux/tmux/blob/ac44566/cmd-list-windows.c) | [source](https://github.com/tmux/tmux/blob/ac44566/cmd-list-panes.c) | [source](https://github.com/tmux/tmux/blob/ac44566/cmd-list-clients.c) |
| 3.6 | `0dac7fe` | [`format.c`](https://github.com/tmux/tmux/blob/0dac7fe/format.c) | [source](https://github.com/tmux/tmux/blob/0dac7fe/cmd-list-sessions.c) | [source](https://github.com/tmux/tmux/blob/0dac7fe/cmd-list-windows.c) | [source](https://github.com/tmux/tmux/blob/0dac7fe/cmd-list-panes.c) | [source](https://github.com/tmux/tmux/blob/0dac7fe/cmd-list-clients.c) |
| 3.7 | `81f88f8` | [`format.c`](https://github.com/tmux/tmux/blob/81f88f8/format.c) | [source](https://github.com/tmux/tmux/blob/81f88f8/cmd-list-sessions.c) | [source](https://github.com/tmux/tmux/blob/81f88f8/cmd-list-windows.c) | [source](https://github.com/tmux/tmux/blob/81f88f8/cmd-list-panes.c) | [source](https://github.com/tmux/tmux/blob/81f88f8/cmd-list-clients.c) |
Caller-owned registrations were checked at the same pins. The `line`
registration comes from the four list-command sources in each audit row. The
three command-list fields come from `cmd-list-keys.c` in
[3.2a](https://github.com/tmux/tmux/blob/3b929f3/cmd-list-keys.c),
[3.3](https://github.com/tmux/tmux/blob/87fe00e/cmd-list-keys.c),
[3.4](https://github.com/tmux/tmux/blob/9ae69c3/cmd-list-keys.c),
[3.5](https://github.com/tmux/tmux/blob/ac44566/cmd-list-keys.c), and
[3.6](https://github.com/tmux/tmux/blob/0dac7fe/cmd-list-keys.c), then
`cmd-list-commands.c` in
[3.7](https://github.com/tmux/tmux/blob/81f88f8/cmd-list-commands.c).
`current_file` comes from `cfg.c` in
[3.2a](https://github.com/tmux/tmux/blob/3b929f3/cfg.c),
[3.3](https://github.com/tmux/tmux/blob/87fe00e/cfg.c),
[3.4](https://github.com/tmux/tmux/blob/9ae69c3/cfg.c),
[3.5](https://github.com/tmux/tmux/blob/ac44566/cfg.c),
[3.6](https://github.com/tmux/tmux/blob/0dac7fe/cfg.c), and
[3.7](https://github.com/tmux/tmux/blob/81f88f8/cfg.c). The copy-mode fields
come from `window-copy.c` in
[3.2a](https://github.com/tmux/tmux/blob/3b929f3/window-copy.c),
[3.3](https://github.com/tmux/tmux/blob/87fe00e/window-copy.c),
[3.4](https://github.com/tmux/tmux/blob/9ae69c3/window-copy.c),
[3.5](https://github.com/tmux/tmux/blob/ac44566/window-copy.c),
[3.6](https://github.com/tmux/tmux/blob/0dac7fe/window-copy.c), and
[3.7](https://github.com/tmux/tmux/blob/81f88f8/window-copy.c).
At all six pins, the list calls pass these unchanged `format_defaults`
contexts: Sessions `(NULL, s, NULL, NULL)`, Windows
`(NULL, s, wl, NULL)`, Panes `(NULL, s, wl, wp)`, and Clients
`(c, NULL, NULL, NULL)`. `format_defaults` fixes the original row type
before deriving missing Session, winlink, or Pane context. Every audited
`list-clients` skips an unattached Client before that call, so all emitted
Client rows have sound derived Session, Window, and Pane contexts. Technical
profile admission is therefore broader than placement in an intrinsic
`*Info` value. In particular, `client_mode_format` ignores its context and
returns the global `window_client_mode.default_format`.
<!-- BEGIN CHECKED FORMAT CATALOG -->
| field | owner | context | profiles | minimum | decoder | empty | placement |
| --- | --- | --- | --- | --- | --- | --- | --- |
| `active_window_index` | session | session | all | 3.2a | u32 | required | catalog-only |
| `alternate_saved_x` | pane | pane | all | 3.2a | u32 | required | pane-info |
| `alternate_saved_y` | pane | pane | all | 3.2a | u32 | required | pane-info |
| `bracket_paste_flag` | pane | pane | all | 3.7 | bool | required | pane-info |
| `buffer_name` | buffer | buffer | none | 3.2a | text | required | catalog-only |
| `buffer_sample` | buffer | buffer | none | 3.2a | text | available | catalog-only |
| `buffer_size` | buffer | buffer | none | 3.2a | u64 | required | catalog-only |
| `client_activity` | client | client | clients | 3.2a | timestamp | required | client-info |
| `client_cell_height` | client | client | clients | 3.2a | u32 | absent | client-info |
| `client_cell_width` | client | client | clients | 3.2a | u32 | absent | client-info |
| `client_control_mode` | client | client | clients | 3.2a | bool | required | client-info |
| `client_created` | client | client | clients | 3.2a | timestamp | required | client-info |
| `client_discarded` | client | client | clients | 3.2a | u64 | required | client-info |
| `client_flags` | client | client | clients | 3.2a | text | available | client-info |
| `client_height` | client | client | clients | 3.2a | u32 | absent | client-info |
| `client_key_table` | client | client | clients | 3.2a | text | required | client-info |
| `client_last_session` | client-attachment | client | clients | 3.2a | text | absent | catalog-only |
| `client_mode_format` | mode | none | all | 3.2a | text | required | catalog-only |
| `client_name` | client | client | clients | 3.2a | text | required | client-info |
| `client_pid` | client | client | clients | 3.2a | u32 | required | client-info |
| `client_prefix` | client | client | clients | 3.2a | bool | required | client-info |
| `client_readonly` | client | client | clients | 3.2a | bool | required | client-info |
| `client_session` | client-attachment | client | clients | 3.2a | text | absent | catalog-only |
| `client_termfeatures` | client | client | clients | 3.2a | text | available | client-info |
| `client_termname` | client | client | clients | 3.2a | text | available | client-info |
| `client_termtype` | client | client | clients | 3.2a | text | available | client-info |
| `client_tty` | client | client | clients | 3.2a | text | available | client-info |
| `client_uid` | client | client | clients | 3.3 | u32 | absent | client-info |
| `client_user` | client | client | clients | 3.3 | text | absent | client-info |
| `client_utf8` | client | client | clients | 3.2a | bool | required | client-info |
| `client_width` | client | client | clients | 3.2a | u32 | required | client-info |
| `client_written` | client | client | clients | 3.2a | u64 | required | client-info |
| `command_list_alias` | command | command | none | 3.2a | text | available | catalog-only |
| `command_list_name` | command | command | none | 3.2a | text | required | catalog-only |
| `command_list_usage` | command | command | none | 3.2a | text | available | catalog-only |
| `config_files` | server | none | all | 3.2a | text | available | catalog-only |
| `copy_cursor_line` | copy-mode | copy-mode | none | 3.2a | text | available | catalog-only |
| `copy_cursor_word` | copy-mode | copy-mode | none | 3.2a | text | available | catalog-only |
| `copy_cursor_x` | copy-mode | copy-mode | none | 3.2a | i32 | required | catalog-only |
| `copy_cursor_y` | copy-mode | copy-mode | none | 3.2a | i32 | required | catalog-only |
| `current_file` | config | config | none | 3.2a | text | required | catalog-only |
| `cursor_character` | pane | pane | all | 3.2a | text | absent | pane-info |
| `cursor_flag` | pane | pane | all | 3.2a | bool | required | pane-info |
| `cursor_x` | pane | pane | all | 3.2a | u32 | required | pane-info |
| `cursor_y` | pane | pane | all | 3.2a | u32 | required | pane-info |
| `history_bytes` | pane | pane | all | 3.2a | u64 | required | pane-info |
| `history_limit` | pane | pane | all | 3.2a | u32 | required | pane-info |
| `history_size` | pane | pane | all | 3.2a | u32 | required | pane-info |
| `insert_flag` | pane | pane | all | 3.2a | bool | required | pane-info |
| `keypad_cursor_flag` | pane | pane | all | 3.2a | bool | required | pane-info |
| `keypad_flag` | pane | pane | all | 3.2a | bool | required | pane-info |
| `last_window_index` | session | session | all | 3.2a | u32 | required | catalog-only |
| `line` | list-row | list-row | all | 3.2a | u32 | required | catalog-only |
| `mouse_all_flag` | pane | pane | all | 3.2a | bool | required | pane-info |
| `mouse_any_flag` | pane | pane | all | 3.2a | bool | required | pane-info |
| `mouse_button_flag` | pane | pane | all | 3.2a | bool | required | pane-info |
| `mouse_sgr_flag` | pane | pane | all | 3.2a | bool | required | pane-info |
| `mouse_standard_flag` | pane | pane | all | 3.2a | bool | required | pane-info |
| `next_session_id` | server | none | all | 3.3 | session-id | required | catalog-only |
| `origin_flag` | pane | pane | all | 3.2a | bool | required | pane-info |
| `pane_active` | pane | pane | all | 3.2a | bool | required | pane-info |
| `pane_at_bottom` | pane | pane | all | 3.2a | bool | required | pane-info |
| `pane_at_left` | pane | pane | all | 3.2a | bool | required | pane-info |
| `pane_at_right` | pane | pane | all | 3.2a | bool | required | pane-info |
| `pane_at_top` | pane | pane | all | 3.2a | bool | required | pane-info |
| `pane_bg` | pane | pane | all | 3.2a | text | required | pane-info |
| `pane_bottom` | pane | pane | all | 3.2a | i32 | required | pane-info |
| `pane_current_command` | pane | pane | all | 3.2a | text | absent | pane-info |
| `pane_current_path` | pane | pane | all | 3.2a | text | absent | pane-info |
| `pane_dead` | pane | pane | all | 3.2a | bool | required | pane-info |
| `pane_dead_signal` | pane | pane | all | 3.3 | text | absent | pane-info |
| `pane_dead_status` | pane | pane | all | 3.2a | u8 | absent | pane-info |
| `pane_dead_time` | pane | pane | all | 3.3 | timestamp | absent | pane-info |
| `pane_fg` | pane | pane | all | 3.2a | text | required | pane-info |
| `pane_flags` | pane | pane | all | 3.7 | text | available | pane-info |
| `pane_floating_flag` | pane | pane | all | 3.7 | bool | required | pane-info |
| `pane_format` | list-row | format-type | all | 3.2a | bool | required | catalog-only |
| `pane_height` | pane | pane | all | 3.2a | u32 | required | pane-info |
| `pane_id` | pane | pane | all | 3.2a | pane-id | required | pane-info |
| `pane_in_mode` | pane | pane | all | 3.2a | u32 | required | pane-info |
| `pane_index` | pane | pane | all | 3.2a | u32 | required | pane-info |
| `pane_input_off` | pane | pane | all | 3.2a | bool | required | pane-info |
| `pane_last` | pane | pane | all | 3.2a | bool | required | pane-info |
| `pane_left` | pane | pane | all | 3.2a | i32 | required | pane-info |
| `pane_marked` | pane | pane | all | 3.2a | bool | required | pane-info |
| `pane_marked_set` | server | pane | all | 3.2a | bool | required | catalog-only |
| `pane_mode` | pane | pane | all | 3.2a | text | absent | pane-info |
| `pane_path` | pane | pane | all | 3.2a | text | available | pane-info |
| `pane_pb_progress` | pane | pane | all | 3.7 | pane-progress | required | pane-info |
| `pane_pb_state` | pane | pane | all | 3.7 | pane-progress-state | required | pane-info |
| `pane_pid` | pane | pane | all | 3.2a | u32 | required | pane-info |
| `pane_pipe` | pane | pane | all | 3.2a | bool | required | pane-info |
| `pane_pipe_pid` | pane | pane | all | 3.7 | u32 | absent | pane-info |
| `pane_right` | pane | pane | all | 3.2a | i32 | required | pane-info |
| `pane_search_string` | pane | pane | all | 3.2a | text | available | pane-info |
| `pane_start_command` | pane | pane | all | 3.2a | text | available | pane-info |
| `pane_start_path` | pane | pane | all | 3.3 | text | available | pane-info |
| `pane_synchronized` | pane | pane | all | 3.2a | bool | required | pane-info |
| `pane_tabs` | pane | pane | all | 3.2a | text | available | pane-info |
| `pane_title` | pane | pane | all | 3.2a | text | available | pane-info |
| `pane_top` | pane | pane | all | 3.2a | i32 | required | pane-info |
| `pane_tty` | pane | pane | all | 3.2a | text | required | pane-info |
| `pane_width` | pane | pane | all | 3.2a | u32 | required | pane-info |
| `pane_x` | pane | pane | all | 3.7 | i32 | required | pane-info |
| `pane_y` | pane | pane | all | 3.7 | i32 | required | pane-info |
| `pane_z` | pane | pane | all | 3.7 | u32 | required | pane-info |
| `pane_zoomed_flag` | pane | pane | all | 3.7 | bool | required | pane-info |
| `pid` | server | none | all | 3.2a | u32 | required | catalog-only |
| `scroll_position` | copy-mode | copy-mode | none | 3.2a | i32 | required | catalog-only |
| `scroll_region_lower` | pane | pane | all | 3.2a | u32 | required | pane-info |
| `scroll_region_upper` | pane | pane | all | 3.2a | u32 | required | pane-info |
| `search_match` | copy-mode | copy-mode | none | 3.2a | text | absent | catalog-only |
| `selection_end_x` | copy-mode | copy-mode | none | 3.2a | i32 | absent | catalog-only |
| `selection_end_y` | copy-mode | copy-mode | none | 3.2a | i32 | absent | catalog-only |
| `selection_start_x` | copy-mode | copy-mode | none | 3.2a | i32 | absent | catalog-only |
| `selection_start_y` | copy-mode | copy-mode | none | 3.2a | i32 | absent | catalog-only |
| `session_activity` | session | session | all | 3.2a | timestamp | required | session-info |
| `session_alerts` | session | session | all | 3.2a | text | available | catalog-only |
| `session_attached` | session | session | all | 3.2a | u32 | required | session-info |
| `session_attached_list` | session | session | all | 3.2a | text | available | catalog-only |
| `session_created` | session | session | all | 3.2a | timestamp | required | session-info |
| `session_format` | list-row | format-type | all | 3.2a | bool | required | catalog-only |
| `session_group` | session | session | all | 3.2a | text | absent | catalog-only |
| `session_group_attached` | session | session | all | 3.2a | u32 | absent | catalog-only |
| `session_group_attached_list` | session | session | all | 3.2a | text | absent | catalog-only |
| `session_group_list` | session | session | all | 3.2a | text | absent | catalog-only |
| `session_group_many_attached` | session | session | all | 3.2a | bool | absent | catalog-only |
| `session_group_size` | session | session | all | 3.2a | u32 | absent | catalog-only |
| `session_grouped` | session | session | all | 3.2a | bool | required | catalog-only |
| `session_id` | session | session | all | 3.2a | session-id | required | session-info |
| `session_last_attached` | session | session | all | 3.2a | timestamp | absent | session-info |
| `session_many_attached` | session | session | all | 3.2a | bool | required | session-info |
| `session_marked` | session | session | all | 3.2a | bool | required | catalog-only |
| `session_name` | session | session | all | 3.2a | text | required | session-info |
| `session_path` | session | session | all | 3.2a | text | required | session-info |
| `session_stack` | session | session | all | 3.2a | text | required | catalog-only |
| `session_windows` | session | session | all | 3.2a | u32 | required | session-info |
| `socket_path` | server | none | all | 3.2a | text | required | catalog-only |
| `start_time` | server | none | all | 3.2a | timestamp | required | catalog-only |
| `synchronized_output_flag` | pane | pane | all | 3.7 | bool | required | pane-info |
| `uid` | server | none | all | 3.3 | u32 | required | catalog-only |
| `user` | server | none | all | 3.3 | text | absent | catalog-only |
| `version` | server | none | all | 3.2a | text | required | catalog-only |
| `window_active` | window-link | window-link | all | 3.2a | bool | required | catalog-only |
| `window_active_clients` | window | window-link | all | 3.2a | u32 | required | catalog-only |
| `window_active_clients_list` | window | window-link | all | 3.2a | text | available | catalog-only |
| `window_active_sessions` | window | window-link | all | 3.2a | u32 | required | catalog-only |
| `window_active_sessions_list` | window | window-link | all | 3.2a | text | available | catalog-only |
| `window_activity` | window | window | all | 3.2a | timestamp | required | window-info |
| `window_activity_flag` | window-link | window-link | all | 3.2a | bool | required | catalog-only |
| `window_bell_flag` | window-link | window-link | all | 3.2a | bool | required | catalog-only |
| `window_bigger` | client-window-view | client | clients | 3.2a | bool | required | catalog-only |
| `window_cell_height` | window | window | all | 3.2a | u32 | required | window-info |
| `window_cell_width` | window | window | all | 3.2a | u32 | required | window-info |
| `window_end_flag` | window-link | window-link | all | 3.2a | bool | required | catalog-only |
| `window_flags` | window-link | window-link | all | 3.2a | text | available | catalog-only |
| `window_format` | list-row | format-type | all | 3.2a | bool | required | catalog-only |
| `window_height` | window | window | all | 3.2a | u32 | required | window-info |
| `window_id` | window | window | all | 3.2a | window-id | required | window-info |
| `window_index` | window-link | window-link | all | 3.2a | i32 | required | catalog-only |
| `window_last_flag` | window-link | window-link | all | 3.2a | bool | required | catalog-only |
| `window_layout` | window | window | all | 3.2a | text | required | window-info |
| `window_linked` | window-link | window-link | all | 3.2a | bool | required | catalog-only |
| `window_linked_sessions` | window | window-link | all | 3.2a | u32 | required | catalog-only |
| `window_linked_sessions_list` | window | window-link | all | 3.2a | text | required | catalog-only |
| `window_marked_flag` | window-link | window-link | all | 3.2a | bool | required | catalog-only |
| `window_name` | window | window | all | 3.2a | text | available | window-info |
| `window_offset_x` | client-window-view | client | clients | 3.2a | u32 | absent | catalog-only |
| `window_offset_y` | client-window-view | client | clients | 3.2a | u32 | absent | catalog-only |
| `window_panes` | window | window | all | 3.2a | u32 | required | window-info |
| `window_raw_flags` | window-link | window-link | all | 3.2a | text | available | catalog-only |
| `window_silence_flag` | window-link | window-link | all | 3.2a | bool | required | catalog-only |
| `window_stack_index` | window-link | window-link | all | 3.2a | u32 | required | catalog-only |
| `window_start_flag` | window-link | window-link | all | 3.2a | bool | required | catalog-only |
| `window_visible_layout` | window | window | all | 3.2a | text | required | window-info |
| `window_width` | window | window | all | 3.2a | u32 | required | window-info |
| `window_zoomed_flag` | window | window | all | 3.2a | bool | required | window-info |
| `wrap_flag` | pane | pane | all | 3.2a | bool | required | pane-info |
<!-- END CHECKED FORMAT CATALOG -->
## Queries and observable internal containers
Sources: `src/libtmux/_internal/query_list.py`,
`src/libtmux/_internal/sparse_array.py`, and
`tests/_internal/test_query_list.py`. These classes are internal by import
path, but public APIs expose their behavior.
| Python API | Python baseline | Rust target or delta | Delivery slice | Status |
| ----------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------- | --------- |
| `QueryList` ordinary collection behavior | Eager ordered mutable `list` subclass with indexing, slicing, consuming and mutating operations. Its mapping equality path can accept equal-length collections without comparing values. | User-owned ordered `Vec<T>` and slices use standard indexing and iteration without a mutable wrapper or its equality defect; covered by [`tests/query.rs`](../tests/query.rs). | Formats, snapshots, winlinks, and queries | `verified` |
| Public hierarchy listing return types | Public Python hierarchy accessors return ordered `QueryList` values. | Future public hierarchy listings return ordered `Vec<T>` values; no such listing exists yet. | Discovery, traversal, refresh, and environment resolution | `planned` |
| `QueryList.filter` callable and typed local behavior | Stable local filtering by callable, value, or dynamic lookup. Supported suffixes are `eq`, `exact`, `iexact`, `contains`, `icontains`, `startswith`, `istartswith`, `endswith`, `iendswith`, `in`, `nin`, `regex`, and `iregex`. Missing paths are nonmatches; an unknown final suffix falls back to an exact nested path. Invalid regex propagates. | Native `.filter()` handles inline closures and lazy `.matching(FilterExpr)` handles typed portable data without pushdown; covered by [`tests/query.rs`](../tests/query.rs). | Formats, snapshots, winlinks, and queries | `verified` |
| `QueryList.filter` dynamic lookup ingress | Value and `field__operator` lookups are parsed at runtime, including the unknown-suffix fallback. | Dynamic value lookup and `field__operator` parsing remain future CLI, MCP, or configuration ingress. | Discovery, traversal, refresh, and environment resolution | `planned` |
| `QueryList.get` | Exactly one item. Zero raises `ObjectDoesNotExist` unless a default was supplied; multiple always raises `MultipleObjectsReturned`. | Borrowed `exactly_one()` and `one_or_none()` inspect at most two items and return focused source-less errors; covered by [`tests/query.rs`](../tests/query.rs). | Formats, snapshots, winlinks, and queries | `verified` |
| `QueryList.items` | Intended primary-key pairs, but normal returned lists never initialize `pk_key`, so access raises `AttributeError`. | Omit the broken accessor; future object values use typed IDs and ordinary iteration. | Documentation, compatibility, and parity closure | `excluded` |
| `QuerySet`-equivalent native search behavior | Python `search_*` methods send raw tmux `-f`; malformed expressions can look empty. | `FilterExpr` is the local reference value. Future loud `server.query_*` methods may add validated native `-f` pushdown, residual evaluation, ordering, and limits. | Discovery, traversal, refresh, and environment resolution | `planned` |
| `Matcher` and borrowed `QueryIteratorExt` | Public accessors expose ordered local collection behavior through `QueryList`. | `Matcher`, borrowed-only `QueryIteratorExt`, lazy ordered `matching`, and source-less exact cardinality are implemented over ordinary collections; covered by [`tests/query.rs`](../tests/query.rs). | Formats, snapshots, winlinks, and queries | `verified` |
| Typed scalar `FilterExpr` | `QueryList.filter` accepts dynamic values and suffix strings, with Python `re` and lowercase-based comparisons. | Typed handles build ordered, source-less validated expressions; text requires strict candidate UTF-8, including before empty `not_in`, and composition short-circuits left to right; covered by [`tests/query.rs`](../tests/query.rs). | Formats, snapshots, winlinks, and queries | `verified` |
| Portable relation expressions | Nested attribute lookup reads values already present on each Python object. | `ManyRelation::{any, all, none}` and `OneRelation::is` inspect only explicitly hydrated candidate data and perform no I/O; their empty and absent truth tables are covered by [`tests/query.rs`](../tests/query.rs). | Formats, snapshots, winlinks, and queries | `verified` |
| Optional downstream `Filterable` derive | Python discovers dynamic fields from object attributes. | The independent `derive` feature generates stable typed scalar and explicit relation handles for downstream named structs; covered by [`tests/filter_derive.rs`](../tests/filter_derive.rs) and proc-macro UI tests. | Formats, snapshots, winlinks, and queries | `verified` |
| Optional version 1 filter serde | Python has no stable versioned portable filter envelope. | The independent `serde` feature uses closed duplicate-rejecting raw decoding; generic schema structure and typed target/field/enum/integer/regex validation stay distinct; covered by [`tests/filter_serde.rs`](../tests/filter_serde.rs) and [`schema/filter-v1.schema.json`](../schema/filter-v1.schema.json). | Formats, snapshots, winlinks, and queries | `verified` |
| `SparseArray.add`, `append`, `iter_values`, `as_list` | Internal `dict[int, T]` returned by public options/hooks. Append uses max index plus one; value iteration/list conversion sorts by index; normal dict behavior remains visible. | `SparseValues<T>`, backed by `BTreeMap<u32, T>`, with `get`, `first`, `indices`, `values`, `into_values`, and `iter`. `IndexedHooks` is the `TmuxText` alias, since a hook is an array option. | Options, hooks, and advanced command families | `implemented` |
## Options
Sources: `src/libtmux/options.py` and `tests/test_options.py`.
| Python API | Python baseline | Rust target or delta | Delivery slice | Status |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ | --------------------------------------------- | --------- |
| `TerminalOverride`, `TerminalOverrides`, `CommandAliases`, `OptionDict`, `UntypedOptionsDict`, `ExplodedUntypedOptionsDict`, `ExplodedComplexUntypedOptionsDict`, `ConvertedValue`, `ConvertedValues` | Public aliases around nested dictionary, list, scalar, and internal `SparseArray` shapes. | `OptionValue`, `OptionMap`, `SparseValues`, typed terminal overrides, and typed command aliases. | Options, hooks, and advanced command families | `planned` |
| `handle_option_error` | Always raises `UnknownOption`, `InvalidOption`, `AmbiguousOption`, or generic `OptionError` from stderr text. Its return annotation is misleading. | Folded into `Error::refused`, so every option path classifies without a separate call. | Options, hooks, and advanced command families | `implemented` |
| `convert_value` | Pure scalar conversion: positive digit strings become integers, exact `on` and `off` become bools, and other values remain unchanged. | `OptionValue::parse_scalar`. | Options, hooks, and advanced command families | `planned` |
| `convert_values` | Mutates one dictionary, list, or `SparseArray` level in place despite its recursive wording. | Owned recursive conversion without caller mutation. | Options, hooks, and advanced command families | `planned` |
| `parse_options_to_dict` | Reads zero or more flat rows. Uses `shlex` with split-on-first-space fallback, maps bare keys to `None`, and lets the last duplicate win. | Lossless option-row parser returning `Result`. | Options, hooks, and advanced command families | `planned` |
| `explode_arrays` | Converts indexed names to sparse arrays; forced unindexed values use index zero. Parse failures warn and preserve or fall back. | Typed sparse parser with explicit parse diagnostics. | Options, hooks, and advanced command families | `planned` |
| `explode_complex` | Special decoding for terminal features, terminal overrides, and command aliases. Malformed elements warn and are skipped or preserved. | Typed decoders with structured errors or diagnostics. | Options, hooks, and advanced command families | `planned` |
| `OptionsMixin`, `OptionsMixin.__init__`, `default_option_scope` | Public mixin and scope contract exposed by `Server`, `Session`, `Window`, and `Pane`. | Inherent option methods on each handle, sharing `internal::options`. Nothing to import. | Options, hooks, and advanced command families | `implemented` |
| `set_option`, `unset_option` | Return the same object. Bool values become `on` or `off`; stderr is classified into option exceptions. Deprecated `g` warns and aliases `global_`. | `set_option` and `unset_option` on `Server`, `Session`, `Window`, and `Pane`, with typed scope and `g` folded into the scope; covered by [`tests/options.rs`](../tests/options.rs). | Options, hooks, and advanced command families | `implemented` |
| `show_options` | One converted dictionary with zero or more entries. Stderr is ignored, so failure may look empty. | `options() -> Result<BTreeMap<String, OptionValue>>` on every scope, decoded by declared kind and loud on refusal; reports what is set at that scope rather than what is inherited; covered by [`tests/options.rs`](../tests/options.rs). | Options, hooks, and advanced command families | `implemented` |
| `show_option` | One scalar, sparse or complex collection, or `None`. Stderr is classified; indexed and inherited values are interpreted. | `typed_option(name) -> Result<Option<OptionValue>>`; covered by [`tests/options.rs`](../tests/options.rs). | Options, hooks, and advanced command families | `implemented` |
## Hooks
Sources: `src/libtmux/hooks.py` and `tests/test_hooks.py`.
| Python API | Python baseline | Rust target or delta | Delivery slice | Status |
| --------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | ------------------------------------------------ | --------- |
| `HookDict`, `HookValues` | Public dictionary/list/dictionary-or-`SparseArray` aliases. | `IndexedHooks`, a sparse index-to-command map, because tmux keeps the gaps; values are `TmuxText`; covered by [`tests/options.rs`](../tests/options.rs). | Options, hooks, and advanced command families | `implemented` |
| `HooksMixin`, `HooksMixin.__init__`, `default_hook_scope` | Public mixin and scope contract exposed by `Server`, `Session`, `Window`, and `Pane`. | Inherent hook methods on each handle, sharing the same option paths, since tmux stores hooks in the option tables. | Options, hooks, and advanced command families | `implemented` |
| `HooksMixin.hooks` | Annotated with internal `Hooks`; the mixin initializer creates it, but concrete handle constructors do not call that initializer, so the attribute is generally absent. | Omit the broken compatibility attribute. | Documentation, compatibility, and parity closure | `excluded` |
| `run_hook`, `set_hook`, `unset_hook` | Return the same object; stderr is classified through option exceptions. `set_hook(g=...)` warns. Hook support is documented from 3.1; window and pane scope flags require 3.2 and are warn-ignore below. | `set_hook` and `unset_hook` on each scope; `run_hook` remains out, as a library has no use for firing one; covered by [`tests/options.rs`](../tests/options.rs). | Options, hooks, and advanced command families | `implemented` |
| `show_hooks` | One dictionary with zero or more indexed hook names and string or integer values. Stderr is ignored and malformed or bare rows are skipped, so failure may look empty. | `hooks() -> Result<BTreeMap<String, IndexedHooks>>` on `Server` and `Session` only: tmux does not enumerate window or pane hooks, so a listing there could answer nothing but empty. Loud on failure; covered by [`tests/options.rs`](../tests/options.rs). | Options, hooks, and advanced command families | `implemented` |
| `show_hook` | One string, integer, sparse array, or `None`. Indexed queries return one slot; stderr is classified. | `hook(name) -> Result<Option<IndexedHooks>>` on every scope, read through the name-filtered listing tmux answers everywhere; covered by [`tests/options.rs`](../tests/options.rs). | Options, hooks, and advanced command families | `implemented` |
| `set_hooks` | Returns the same object. Lists receive sequential indices; dictionaries and sparse arrays preserve indices. Optional clear happens before sequential nontransactional writes, so failure can leave partial state. | `set_hooks(name, &IndexedHooks, ReplaceMode)` on each scope, sent as one tmux invocation rather than one per index. That costs one process instead of several but is not atomic: tmux applies a shared invocation in order and stops at the first refusal, so a rejected entry leaves the ones before it written. Documented on the method. Covered by [`tests/options.rs`](../tests/options.rs). | Options, hooks, and advanced command families | `implemented` |
| Hook-name versions | The wrapper accepts open hook names and lets tmux reject them. `client-active` and `window-resized` appear at 3.3; `pane-title-changed`, theme hooks, and `command-error` appear at 3.5. | Descriptor-backed capability checks where a known hook is requested; retain a raw-name escape hatch. | Options, hooks, and advanced command families | `planned` |
## Server
Sources: `src/libtmux/server.py`, `docs/api/libtmux.server.md`,
`tests/test_server.py`, and `tests/test_from_env.py`.
| Python API | Python baseline | Rust target or delta | Delivery slice | Status |
| ------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- | ------------- |
| `Server(...)` | Creates one inert handle without a subprocess. Socket precedence is path, name, then factory; `on_init` runs synchronously; unknown keyword arguments are ignored; invalid colors and unusable names fail later in `cmd()`. | `ServerBuilder` with typed socket selection, eager conflict, color, and single-component socket-name validation, and no open keywords or callback; covered by [`tests/server_command.rs`](../tests/server_command.rs). | Foundation | `implemented` |
| `socket_name`, `socket_path`, `config_file`, `colors`, `tmux_bin` | Public mutable command configuration. | Immutable `Core` command configuration created by the builder, with getters; covered by [`tests/server_command.rs`](../tests/server_command.rs). | Foundation | `implemented` |
| `default_option_scope`, `default_hook_scope` | Mutable defaults inherited by option and hook operations. | Typed immutable scope defaults on the concrete handle. | Options, hooks, and advanced command families | `planned` |
| `child_id_attribute`, `formatter_prefix` | Public class strings left from earlier relational-object machinery. | Omit obsolete implementation metadata. | Documentation, compatibility, and parity closure | `excluded` |
| `from_env` | Pure `$TMUX` parse returning one unverified Server. Missing, empty, or malformed values raise `NotInsideTmux`. | `Server::from_env`. | Discovery, traversal, refresh, and environment resolution | `implemented` |
| `__enter__`, `__exit__` | Enter returns the Server. Exit calls `is_alive()` and then `kill()`; swallowed liveness errors can silently skip cleanup. | `with_server` or explicit guard; ordinary `Drop` is not destructive. | Discovery, traversal, refresh, and environment resolution | `implemented` |
| `is_alive`, `raise_if_dead` | One bool swallowing every exception, or unit with missing-executable and subprocess errors preserved. | Compatibility `is_alive()` plus primary `check_alive() -> Result<()>`. | Discovery, traversal, refresh, and environment resolution | `implemented` |
| `cmd` | One raw result with socket, config, color, and optional target flags. Ordinary tmux stderr remains data. | `Server::cmd(Command) -> Result<CommandResult, Error>`; covered by [`tests/server_command.rs`](../tests/server_command.rs). | Foundation | `implemented` |
| `attached_sessions` | Ordered `QueryList`, zero or more. It derives from `sessions`, so every `LibTmuxException` becomes empty. | `attached_sessions()` lenient and `try_attached_sessions()` loud. | Discovery, traversal, refresh, and environment resolution | `implemented` |
| `sessions` | Ordered typed collection, zero or more. Every `LibTmuxException`, including executable and permission failures, becomes empty. | `Server::sessions` lenient and `Server::try_sessions` loud, returning ordered `Vec<Session>`; covered by [`src/server.rs`](../src/server.rs) doctests and [`src/snapshot.rs`](../src/snapshot.rs) real-tmux tests. | Discovery, traversal, refresh, and environment resolution | `implemented` |
| `clients` | Ordered typed collection, zero or more. Every `LibTmuxException`, including executable and permission failures, becomes empty. | `Server::clients` and `Server::try_clients`; covered by [`tests/commands.rs`](../tests/commands.rs). | Discovery, traversal, refresh, and environment resolution | `implemented` |
| `windows`, `panes` | Ordered winlink-preserving collections, zero or more. Only recognized absent-daemon or missing-socket errors become empty; other errors propagate. | Consistent lenient accessor and loud `try_*` form; intentional uniform delta. | Discovery, traversal, refresh, and environment resolution | `implemented` |
| `search_sessions`, `search_windows`, `search_panes` | Native raw `-f`, ordered zero or more. Absent daemon becomes empty, other failures propagate, and malformed filters can look empty. | Compatibility lenient/loud pairs over the typed query infrastructure; explicit evaluation remains loud. | Discovery, traversal, refresh, and environment resolution | `implemented` |
| `has_session` | One bool; validates the name and optionally forces exact matching. Ordinary nonzero status, including a dead server, becomes false; launch failures propagate. | `has_session(&SessionName) -> Result<bool>`. | Discovery, traversal, refresh, and environment resolution | `implemented` |
| `kill`, `kill_session` | Unit or the same Server. `kill` ignores recognized already-dead errors. `kill_session` performs no documented name validation and accepts integers. | Loud unit operations with typed targets. | Object mutations and interactions | `implemented` |
| `new_session` | Exactly one hydrated Session. Validates explicit names, detects collisions, optionally kills the old session, and raises on stderr. Extra args and kwargs are ignored. It temporarily mutates process-global `$TMUX`. | `new_session(NewSessionOptions) -> Result<Session>`; command-local environment only and reject unknown options. | Object mutations and interactions | `implemented` |
| `run_shell` | Foreground returns stdout lines; background returns `None`; stderr raises. `cwd` requires 3.4, `show_stderr` 3.6, and positional args 3.7; unsupported options warn and disappear. | `RunShellOutput::{Foreground, Background}` and capability errors. | Options, hooks, and advanced command families | `implemented` |
| `wait_for` | Unit; default can block indefinitely. Lock, unlock, and set actions are independent booleans without mutual-exclusion validation. | Async `wait_for(channel, WaitAction)` with cancellation and deadline support. | Options, hooks, and advanced command families | `implemented` |
| `bind_key`, `unbind_key` | Unit; stderr raises. `unbind_key(None, all_keys=False)` is forwarded for tmux to reject. | Typed `BindKeyOptions` and `UnbindKey::{One, All}`. | Options, hooks, and advanced command families | `implemented` |
| `list_keys`, `list_commands` | Zero or more raw strings; stderr raises. `list_keys(format_=...)` requires 3.7 and is warn-ignore below. | Loud raw listing methods; capability error for requested unsupported format. | Options, hooks, and advanced command families | `implemented` |
| `lock_server`, `start_server` | Unit; stderr raises. Lock requires an attached client. | `Server::lock()` and `Server::start()`. | Object mutations and interactions | `implemented` |
| `server_access` | Returns access-rule lines only in list mode, otherwise `None`. Hard error below 3.3; read-only plus write raises `ValueError`. | `access_rules()`, `grant_access(user, AccessMode)`, and `revoke_access(user)`, all refusing below tmux 3.3 with `Error::UnsupportedCapability`. `AccessMode` is an enum rather than two flags, so tmux's exclusive `-r`/`-w` pair cannot both be passed: the contradiction Python raises `ValueError` for is unrepresentable. Covered by [`tests/commands.rs`](../tests/commands.rs). | Options, hooks, and advanced command families | `implemented` |
| `refresh_client`, `suspend_client`, `lock_client` | Unit and requires a usable client. Clipboard refresh requires 3.7 and is warn-ignore below. | Client-targeted loud methods with capability errors. | Object mutations and interactions | `implemented` |
| `detach_client`, `detach_all_clients` | Unit. Detaches one named or most-recent client, or all other clients while preserving one. | `detach_client` and `detach_other_clients`. | Object mutations and interactions | `implemented` |
| `confirm_before` | Unit and always background. Hard minimum 3.3; confirmation key and default-yes require 3.4 and are warn-ignore below. | `confirm_before(ConfirmOptions)` with capability errors. | Options, hooks, and advanced command families | `implemented` |
| `command_prompt` | Unit and always background. Hard minimum 3.3; literal input requires 3.6; backspace-exit and no-freeze require 3.7; unsupported flags warn and disappear. | `command_prompt(PromptOptions)` with typed modes and capability errors. | Options, hooks, and advanced command families | `implemented` |
| `display_menu` | Unit; requires a TTY-backed client. Choice and style flags require 3.4, mouse 3.5, and are warn-ignore below. `stay_open` is forwarded without its documented preflight. | Structured menu items and options with centralized capability validation. | Options, hooks, and advanced command families | `implemented` |
| `show_messages` | Zero or more raw strings; stderr raises. Default mode requires a current client. | `messages(MessageView) -> Result<Vec<String>>`. | Options, hooks, and advanced command families | `implemented` |
| `display_message` | Returns lines only when `get_text=True`, otherwise `None`. Stderr emits `UserWarning` instead of raising. `no_expand` requires 3.4 and is warn-ignore below. | Split formatting from display; both return loud results. | Options, hooks, and advanced command families | `implemented` |
| `show_prompt_history`, `clear_prompt_history` | Zero or more strings or unit; hard minimum 3.3; stderr raises. | `prompt_history(PromptKind)` and `clear_prompt_history()`, both refusing below tmux 3.3 with `Error::UnsupportedCapability`. The kind is required rather than defaulted: asking without one returns every kind at once, which is a different question. Verified against 3.2a, 3.3a, and 3.7b; covered by [`tests/commands.rs`](../tests/commands.rs). | Options, hooks, and advanced command families | `implemented` |
| `set_buffer`, `show_buffer`, `delete_buffer` | Unit, one newline-joined string, or unit; stderr raises. Joining loses whether a final newline existed. | Buffer methods using bytes or lossless text. | Options, hooks, and advanced command families | `implemented` |
| `save_buffer`, `load_buffer`, `list_buffers` | Unit, unit, or zero or more raw strings; paths expand `~`; stderr raises. Malformed native filters can look empty. | `Path` arguments and typed buffer queries. | Options, hooks, and advanced command families | `implemented` |
| `if_shell`, `source_file` | Unit; stderr raises. Background `if_shell` reports enqueue success rather than branch completion. | Typed requests that represent enqueued state. | Options, hooks, and advanced command families | `implemented` |
| `list_clients` | Zero or more raw client lines with loud errors, overlapping the typed lenient `clients` property. | `list_clients_raw`; typed `clients` remains primary. | Options, hooks, and advanced command families | `implemented` |
| `switch_client`, `attach_session` | Unit; validate session names. Despite an optional annotation, `attach_session(None)` always raises `BadSessionName`. | Require a typed `SessionTarget`. | Object mutations and interactions | `implemented` |
| `__eq__`, `__repr__` | Equality compares only socket name and path, so default-server handles compare equal. | Equality and hashing over normalized `ServerIdentity`; sanitized `Debug`; covered by [`tests/server_command.rs`](../tests/server_command.rs). | Foundation | `implemented` |
| `kill_server`, `get_by_id`, `where`, `find_where`, `list_sessions`, `children` | Public names whose only behavior is raising `DeprecatedError`. | Omit. | Documentation, compatibility, and parity closure | `excluded` |
`Server` also exposes the environment, option, and hook capabilities listed
under their owning components.
## Session
Sources: `src/libtmux/session.py`, `docs/api/libtmux.session.md`,
`tests/test_session.py`, and `tests/test_from_env.py`.
| Python API | Python baseline | Rust target or delta | Delivery slice | Status |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | --------------------------------------------------------- | --------- |
| `Session(...)`, `server` | Public dataclass can be constructed without an ID and with every raw `Obj` field. | `Session`, an internally hydrated handle over `SessionId`, `Arc<Core>`, and an owned snapshot; covered by [`tests/hierarchy.rs`](../tests/hierarchy.rs). | Discovery, traversal, refresh, and environment resolution | `implemented` |
| `__enter__`, `__exit__` | Enter returns the Session. Exit kills only when the name exists and `has_session()` returns true; liveness errors can skip cleanup. | `Server::with_session`; ordinary `Drop` is not destructive. | Discovery, traversal, refresh, and environment resolution | `implemented` |
| `refresh` | Mutates in place and returns `None`. Missing ID raises `ValueError`; vanished target and server failures propagate. Empty fields can remain stale. | `Session::refresh(&mut self)` and `Session::refreshed(&self)`, replacing the snapshot atomically; covered by [`tests/hierarchy.rs`](../tests/hierarchy.rs). | Discovery, traversal, refresh, and environment resolution | `implemented` |
| `from_session_id`, `from_env` | Exactly one Session. `from_env` follows the live pane instead of the stale session ID stored in `$TMUX`. | `Server::session_by_id`, because a lookup needs the connection the server owns, and `Session::from_env`, which resolves through `TMUX_PANE`; covered by [`tests/mutations.rs`](../tests/mutations.rs) and [`tests/hierarchy.rs`](../tests/hierarchy.rs). | Discovery, traversal, refresh, and environment resolution | `implemented` |
| `windows`, `panes` | Ordered `QueryList`, zero or more; Python propagates every fetch error. | Lenient accessors and loud `try_windows()` or `try_panes()`; intentional uniform delta. | Discovery, traversal, refresh, and environment resolution | `implemented` |
| `search_windows`, `search_panes` | Ordered native-filtered lists; errors propagate and malformed filters can look empty. | `search_windows`/`search_panes` lenient and `try_search_*` loud, taking the same `Matcher` a listing takes rather than a second query language. Filtering is client-side, consistent with `.matching()`; the expression stays compilable to a tmux `-f` predicate, so pushing one down later changes the cost and not the answer. Covered by [`tests/filter_hierarchy.rs`](../tests/filter_hierarchy.rs). | Discovery, traversal, refresh, and environment resolution | `implemented` |
| `cmd` | One raw result targeting the Session ID by default. An ID-less Session omits the target and can become server-scoped. | `Session::cmd`, placing `-t` after the subcommand rather than appending it: tmux stops reading flags at the first positional, so an appended target is taken as text and the command succeeds having acted on something else. Covered by [`tests/commands.rs`](../tests/commands.rs). | Discovery, traversal, refresh, and environment resolution | `implemented` |
| `lock_session`, `detach_client` | Unit; stderr raises. Detach affects every client attached to the Session. | `lock()` and `detach_clients()`. Detaching a session nobody is attached to succeeds: tmux reports it as a failure, but the state asked for already holds. Covered by [`tests/control.rs`](../tests/control.rs). | Object mutations and interactions | `implemented` |
| `last_window`, `next_window`, `previous_window`, `select_window` | Exactly one newly active Window. Command errors and zero or multiple active-window errors propagate. | `next_window`/`previous_window`/`last_window` return `Result<Option<Window>>`: tmux reports "nowhere to go" as a command failure, but a one-window session having no next window is an ordinary state, so it is absence rather than an error. `select` on the window itself covers `select_window`. Covered by [`tests/hierarchy.rs`](../tests/hierarchy.rs). | Object mutations and interactions | `implemented` |
| `active_window` | Exactly one Window or `NoActiveWindow`/`MultipleActiveWindows`. | `active_window() -> Result<Window>`. | Discovery, traversal, refresh, and environment resolution | `implemented` |
| `active_pane` | Zero or one Pane after resolving the active Window; active-window cardinality errors propagate. | `active_pane() -> Result<Option<Pane>>`. | Discovery, traversal, refresh, and environment resolution | `implemented` |
| `attach` | Returns the same Session; blocks; stderr raises. A flag string is incorrectly expanded character by character. | `attach(AttachOptions) -> Result<()>` with typed client flags. | Object mutations and interactions | `planned` |
| `kill` | Unit; stderr raises. Group kill requires 3.7 and is warn-ignore below. | `Session::kill`, consuming the handle; covered by [`tests/mutations.rs`](../tests/mutations.rs). | Object mutations and interactions | `implemented` |
| `switch_client`, `rename_session` | Return the same Session. Rename validates, executes, then refreshes; refresh can fail after the rename succeeded. | `Session::rename` refreshes the handle and reports a post-rename refresh failure distinctly; `Client::switch_to` moves a client. Covered by [`tests/mutations.rs`](../tests/mutations.rs) and [`tests/commands.rs`](../tests/commands.rs). | Object mutations and interactions | `implemented` |
| `new_window` | Exactly one Window. Actual default `attach=False` creates it detached despite contradictory prose. Direction, target, and index options can overlap. | `new_window(NewWindowOptions)` with one placement enum and explicit selection. | Object mutations and interactions | `implemented` |
| `kill_window` | Unit. `None` means current Window; integers are session-qualified; strings pass through. | Typed `WindowTarget` with an explicit `Current` variant. | Object mutations and interactions | `implemented` |
| `id`, `name` | Synchronous aliases for optional raw `session_id` and `session_name`. | `Session::id` returns the unconditional typed `SessionId`; `Session::name` returns `Option<&TmuxText>` because a tmux name need not be UTF-8. Raw aliases omitted. | Discovery, traversal, refresh, and environment resolution | `implemented` |
| `__eq__`, `__repr__` | Equality compares only the optional Session ID, ignoring Server identity; two ID-less Sessions compare equal. | Equality and hashing over `(ServerIdentity, SessionId)`. | Discovery, traversal, refresh, and environment resolution | `implemented` |
| `attached_pane`, `attached_window`, `attach_session`, `kill_session`, `get`, `__getitem__`, `get_by_id`, `where`, `find_where`, `list_windows`, `children` | Public names whose only behavior is raising `DeprecatedError`. | Omit. | Documentation, compatibility, and parity closure | `excluded` |
`Session` also exposes the environment, option, and hook capabilities listed
under their owning components.
## Window
Sources: `src/libtmux/window.py`, `docs/api/libtmux.window.md`,
`tests/test_window.py`, and `tests/test_resolution.py`.
| Python API | Python baseline | Rust target or delta | Delivery slice | Status |
| --------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- | --------------------------------------------------------- | --------- |
| `Window(...)`, `server` | Public raw dataclass with optional ID and every `Obj` field. | `Window`, a hydrated handle carrying the winlink it was discovered through; covered by [`tests/hierarchy.rs`](../tests/hierarchy.rs). | Discovery, traversal, refresh, and environment resolution | `implemented` |
| `__enter__`, `__exit__` | Enter returns the Window. Exit queries its parent Session and kills it if present; query or kill errors can propagate. | `Session::with_window`; no async cleanup in ordinary `Drop`. | Discovery, traversal, refresh, and environment resolution | `implemented` |
| `refresh`, `from_window_id`, `from_env` | Mutating unit or exactly one constructor. Missing ID raises `ValueError`; vanished target and server errors propagate. | `Window::refresh`, `Window::refreshed`, `Server::window_by_id`, and `Window::from_env`; covered by [`tests/mutations.rs`](../tests/mutations.rs) and [`tests/hierarchy.rs`](../tests/hierarchy.rs). | Discovery, traversal, refresh, and environment resolution | `implemented` |
| `session` | Exactly one live canonical parent; errors propagate. | `Window::session`, re-reading tmux so a moved window reports where it is now; covered by [`tests/hierarchy.rs`](../tests/hierarchy.rs). | Discovery, traversal, refresh, and environment resolution | `implemented` |
| `linked_sessions` | Deduplicated ordered `QueryList`, zero or more. Any list error becomes empty; Sessions that disappear between snapshots are dropped. | `linked_sessions()` lenient and `try_linked_sessions()` loud. | Discovery, traversal, refresh, and environment resolution | `implemented` |
| `panes` | Ordered `QueryList`, zero or more; Python propagates list errors. | Lenient `panes()` and loud `try_panes()`; intentional uniform delta. | Discovery, traversal, refresh, and environment resolution | `implemented` |
| `search_panes` | Ordered native-filtered list; malformed filter can look empty and list errors propagate. | `search_windows`/`search_panes` lenient and `try_search_*` loud, taking the same `Matcher` a listing takes rather than a second query language. Filtering is client-side, consistent with `.matching()`; the expression stays compilable to a tmux `-f` predicate, so pushing one down later changes the cost and not the answer. Covered by [`tests/filter_hierarchy.rs`](../tests/filter_hierarchy.rs). | Discovery, traversal, refresh, and environment resolution | `implemented` |
| `cmd` | One raw result targeting the Window ID by default. | `Window::cmd`, placing `-t` after the subcommand rather than appending it: tmux stops reading flags at the first positional, so an appended target is taken as text and the command succeeds having acted on something else. Covered by [`tests/commands.rs`](../tests/commands.rs). | Discovery, traversal, refresh, and environment resolution | `implemented` |
| `active_pane` | Zero or one active Pane; relationship errors propagate. | `active_pane() -> Result<Option<Pane>>`. | Discovery, traversal, refresh, and environment resolution | `implemented` |
| `select_pane`, `last_pane` | Zero or one newly selected Pane; command and relationship errors propagate. | `last_pane() -> Result<Option<Pane>>`, absence for "no last pane" on the same reasoning; `select` on the pane covers `select_pane`. Covered by [`tests/hierarchy.rs`](../tests/hierarchy.rs). | Object mutations and interactions | `implemented` |
| `split` | Exactly one tiled Pane, delegated to the active or first Pane. No Panes can raise `IndexError`. Optional empty/style/border/message/keep flags require 3.7 and are warn-ignore below. | `split(SplitPaneOptions) -> Result<Pane>`. | Object mutations and interactions | `implemented` |
| `new_pane` | Exactly one floating Pane; hard minimum 3.7 through `Pane.new_pane`. | `new_pane(FloatingPaneOptions)` with a capability error. | Object mutations and interactions | `implemented` |
| `resize` | Returns a refreshed Window. Direction without amount raises a validation exception; stderr raises. | Typed resize request. | Object mutations and interactions | `implemented` |
| `select_layout`, `next_layout`, `previous_layout` | Return the same Window; stderr raises. Explicit layout plus a layout flag raises `ValueError`. | Typed `LayoutAction`; loud result. | Object mutations and interactions | `implemented` |
| `link`, `unlink` | Unit; stderr raises. | `Window::link_to` and `Window::unlink`, taking a typed `Session`; covered by [`tests/mutations.rs`](../tests/mutations.rs). | Object mutations and interactions | `implemented` |
| `rotate` | Returns the same Window; stderr raises. | `rotate(Rotation)`, where `Up` and `Down` undo each other. Covered by a runnable example on the method. | Object mutations and interactions | `implemented` |
| `respawn`, `swap` | Unit; stderr raises. Swap refreshes both Python Window objects after the command. | Loud methods returning refreshed handles where the updated state matters. | Object mutations and interactions | `implemented` |
| `display_message` | Returns lines only when `get_text=True`, otherwise `None`; stderr warns rather than raises. `no_expand` requires 3.4 and is warn-ignore below. | Split in two: `format(template) -> Result<TmuxText>` reads, `display(message) -> Result<()>` shows. Both loud, and `display` succeeds with nobody attached, having shown it to nobody. Covered by [`tests/commands.rs`](../tests/commands.rs). | Options, hooks, and advanced command families | `implemented` |
| `rename_window`, `move_window`, `select` | Return a refreshed Window; stderr raises. | Loud operations returning a refreshed handle or unit where identity is unchanged. | Object mutations and interactions | `implemented` |
| `kill` | Unit; optional all-except behavior; stderr raises. | `Window::kill`, consuming the handle; covered by [`tests/mutations.rs`](../tests/mutations.rs). | Object mutations and interactions | `implemented` |
| `new_window` | Creates and returns a sibling Window through the parent Session. The public `start_directory` annotation incorrectly permits only `None`. | `new_window(NewWindowOptions)` with `Option<PathBuf>`. | Object mutations and interactions | `implemented` |
| `id`, `name`, `index`, `height`, `width` | Synchronous raw snapshot strings or `None`. | Typed synchronous getters. | Discovery, traversal, refresh, and environment resolution | `implemented` |
| `__eq__`, `__repr__` | Equality compares only Window ID, ignoring Server identity. | Equality and hashing over `(ServerIdentity, WindowId)`. | Discovery, traversal, refresh, and environment resolution | `implemented` |
| `set_window_option`, `show_window_options`, `show_window_option` | Working deprecated aliases that warn and delegate; return the same Window, a dictionary, or one value/`None`. | Omitted as duplicate names. `Window::set_option`, `Window::options`, `Window::get_option`, and `Window::typed_option` are the primary spelling. Covered by [`tests/options.rs`](../tests/options.rs). | Documentation, compatibility, and parity closure | `implemented` |
| `split_window`, `attached_pane`, `select_window`, `kill_window`, `get`, `__getitem__`, `get_by_id`, `where`, `find_where`, `list_panes`, `children` | Public names whose only behavior is raising `DeprecatedError`. | Omit. | Documentation, compatibility, and parity closure | `excluded` |
`Window` also exposes the option and hook capabilities listed under their
owning components.
## Pane
Sources: `src/libtmux/pane.py`, `docs/api/libtmux.pane.md`,
`tests/test_pane.py`, `tests/test_pane_capture_pane.py`, and
`tests/test_resolution.py`.
| Python API | Python baseline | Rust target or delta | Delivery slice | Status |
| ------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | --------------------------------------------------------- | --------- |
| `Pane(...)`, `server` | Public raw dataclass with optional ID and every `Obj` field. | Hydrated handle with `PaneInfo`, typed ID, and retained winlink context. | Discovery, traversal, refresh, and environment resolution | `implemented` |
| `__enter__`, `__exit__` | Enter returns the Pane. Exit resolves the parent and kills the Pane if still present; query or kill errors can propagate. | `Window::with_pane`; no async cleanup in ordinary `Drop`. | Discovery, traversal, refresh, and environment resolution | `implemented` |
| `refresh`, `from_pane_id`, `from_env` | Mutating unit or exactly one constructor. Missing ID, vanished target, and server errors propagate. | `refresh`, `refreshed`, `from_id`, and `from_env`. | Discovery, traversal, refresh, and environment resolution | `implemented` |
| `window`, `session` | Exactly one live parent. Session resolution goes through Window to avoid stale Session snapshots. | Async loud relationship methods. | Discovery, traversal, refresh, and environment resolution | `implemented` |
| `cmd` | One raw result targeting the Pane ID by default. | `Pane::cmd`, placing `-t` after the subcommand rather than appending it: tmux stops reading flags at the first positional, so an appended target is taken as text and the command succeeds having acted on something else. Covered by [`tests/commands.rs`](../tests/commands.rs). | Discovery, traversal, refresh, and environment resolution | `implemented` |
| `resize` | Returns a refreshed Pane. Validates direction/amount and digit-or-percentage values; stderr raises. | Typed resize builder. | Object mutations and interactions | `implemented` |
| `capture_pane` | Returns stdout lines unless writing to a buffer, then `None`. Stderr is ignored. `trim_trailing` requires 3.4, `mode_screen` 3.6, and hyperlinks/line numbers/line flags 3.7; unsupported flags warn and disappear. | `CaptureOutput::{Lines, BufferWritten}` with loud errors and capability checks. | Object mutations and interactions | `implemented` |
| `send_keys` | Unit; stderr is ignored. Missing command requires reset, repeat, or copy-mode behavior or raises `ValueError`. Client/key-name options require 3.4 and are warn-ignore below. | `send_keys(SendKeysOptions) -> Result<()>`; mark input sensitive and redact diagnostics. | Object mutations and interactions | `implemented` |
| `enter` | Returns the same Pane and sends Enter through the non-loud key path. | Loud `enter()`. | Object mutations and interactions | `implemented` |
| `display_message` | Returns lines only when `get_text=True`, otherwise `None`; stderr warns. `no_expand` requires 3.4 and `update_pane` 3.6; unsupported flags warn and disappear. | Split in two: `format(template) -> Result<TmuxText>` reads, `display(message) -> Result<()>` shows. Both loud, and `display` succeeds with nobody attached. Covered by [`tests/commands.rs`](../tests/commands.rs). | Options, hooks, and advanced command families | `implemented` |
| `kill`, `select` | Unit or refreshed Pane; stderr raises. | Corresponding loud methods. | Object mutations and interactions | `implemented` |
| `split` | Exactly one tiled Pane. Size plus percentage raises `ValueError`; stderr raises; malformed output can raise `IndexError` or `KeyError`. Empty/style/border/message/keep options require 3.7 and are warn-ignore below. | Typed split builder with explicit parse and capability errors. | Object mutations and interactions | `implemented` |
| `new_pane` | Exactly one floating Pane; hard minimum 3.7. | Capability-checked floating-pane builder. | Object mutations and interactions | `implemented` |
| `set_width`, `set_height`, `set_title` | Return a refreshed Pane; validation and stderr errors propagate. | Typed resize and title methods. | Object mutations and interactions | `implemented` |
| `display_popup` | Unit and requires an attached client. Conflicting close modes raise `ValueError`. Title/border/style/environment/no-border require 3.3; close-on-key and no-keys require 3.6; unsupported flags warn and disappear. | Typed popup options and capability errors. | Options, hooks, and advanced command families | `implemented` |
| `paste_buffer` | Unit; stderr raises. `no_vis` requires 3.7 and is warn-ignore below. | Loud typed paste options. | Options, hooks, and advanced command families | `implemented` |
| `pipe` | Unit; `command=None` stops piping; stderr raises. | `pipe(Option<Command>)`. | Object mutations and interactions | `implemented` |
| `copy_mode` | Unit; stderr raises. `page_down` requires 3.5 and is warn-ignore below. | Typed copy-mode action with a capability error. | Options, hooks, and advanced command families | `implemented` |
| `clock_mode`, `display_panes`, `choose_buffer`, `choose_client`, `choose_tree`, `customize_mode`, `find_window`, `send_prefix` | Unit; stderr raises. Several commands require a usable attached client. | Loud methods with typed choice and mode options. | Options, hooks, and advanced command families | `implemented` |
| `respawn` | Unit; stderr raises. | `respawn(RespawnPaneOptions)`. | Object mutations and interactions | `implemented` |
| `move`, `join` | Unit; accept Pane, Window, or string targets; stderr raises; Python snapshots are not refreshed. | Typed destination target and refreshed relationship result or explicit stale-handle contract. | Object mutations and interactions | `implemented` |
| `break_pane` | Exactly one Window; stderr raises. Raw version exactly 3.7 receives a placeholder-name workaround before an optional rename; 3.7a and later do not. | `break_pane` with the exact raw-version workaround selected by capabilities. | Object mutations and interactions | `implemented` |
| `swap` | Unit; invalid option combinations raise `LibTmuxException`; stderr raises; snapshots are not refreshed. | Typed mutually exclusive swap options. | Object mutations and interactions | `implemented` |
| `clear_history` | Unit; stderr raises. Hyperlink reset requires 3.4 and is warn-ignore below. | Capability-checked clear options. | Object mutations and interactions | `implemented` |
| `clear`, `reset` | Return the same Pane. `clear` sends literal `reset` plus Enter; `reset` sends a semicolon chain. Neither checks command errors. | Loud methods using structural command chains, not literal separators. | Object mutations and interactions | `implemented` |
| `id`, `index`, `height`, `width`, `title` | Synchronous raw snapshot strings or `None`. | Typed synchronous getters. | Discovery, traversal, refresh, and environment resolution | `implemented` |
| `at_top`, `at_bottom`, `at_left`, `at_right` | Synchronous bools produced by comparing the raw snapshot value with `"1"`. | Typed bool getters. | Discovery, traversal, refresh, and environment resolution | `implemented` |
| `__eq__`, `__repr__` | Equality compares only Pane ID, ignoring Server identity. | Equality and hashing over `(ServerIdentity, PaneId)`. | Discovery, traversal, refresh, and environment resolution | `implemented` |
| `select_pane`, `split_window`, `get`, `__getitem__`, `resize_pane` | Public names whose only behavior is raising `DeprecatedError`. | Omit. | Documentation, compatibility, and parity closure | `excluded` |
`Pane` also exposes the option and hook capabilities listed under their owning
components.
## Client
Sources: `src/libtmux/client.py`, `docs/api/libtmux.client.md`,
`tests/test_client.py`, and `tests/test_control_mode.py`.
| Python API | Python baseline | Rust target or delta | Delivery slice | Status |
| ----------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- | --------------------------------------------------------- | --------- |
| `Client(...)`, `server`, inherited `Obj` fields | Public dataclass constructor. `client_name` is stable identity; Session, Window, and Pane fields are attachment snapshots. | `Client`, with a nonoptional identity and an immutable snapshot; covered by [`tests/commands.rs`](../tests/commands.rs), which reaches the attached case through a control-mode client. | Discovery, traversal, refresh, and environment resolution | `implemented` |
| Generated `__eq__`, `__repr__` | Equality compares the entire dataclass snapshot rather than stable identity. | Equality and hashing over `(ServerIdentity, client_name)`. | Discovery, traversal, refresh, and environment resolution | `planned` |
| `refresh` | Mutates in place and returns `None`. Missing name raises `ValueError`; vanished target and server errors propagate; empty fields can remain stale. | `Client::refresh` and `Client::refreshed`; covered by [`tests/commands.rs`](../tests/commands.rs). | Discovery, traversal, refresh, and environment resolution | `implemented` |
| `from_client_name` | Exactly one Client; missing target and server failures propagate. | `Client::from_name` or `Server::client`. | Discovery, traversal, refresh, and environment resolution | `planned` |
| `attached_session` | Re-reads tmux on every access. Returns one Session or `None` when detached, gone, or stale; connection errors can propagate. | `attached_session() -> Result<Option<Session>>`. Blocked on a modelling decision rather than mechanism: `client_session` is owned by `ClientAttachment` rather than `Client` in the format catalog, so it is deliberately absent from the client snapshot. Deciding whether an attachment is part of a client's identity comes before exposing it. | Discovery, traversal, refresh, and environment resolution | `planned` |
| `attached_window` | Returns the attached Session's active Window or `None`; active-window errors may propagate. | `attached_window() -> Result<Option<Window>>`. | Discovery, traversal, refresh, and environment resolution | `planned` |
| `attached_pane` | Returns the active Pane of the attached Session's current Window, not per-client focus; zero or one, with relationship errors preserved. | `attached_pane() -> Result<Option<Pane>>` with the distinction documented. | Discovery, traversal, refresh, and environment resolution | `planned` |
## Test support
Sources: `src/libtmux/test/`, `src/libtmux/pytest_plugin.py`,
`docs/api/testing/`, `tests/test/`, `tests/test_pytest_plugin.py`, and
`tests/test_control_mode.py`.
| Python API | Python baseline | Rust target or delta | Delivery slice | Status |
| ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- | ------------- |
| `TEST_SESSION_PREFIX` | Fixed prefix for randomized test Session and Window names. | No public constant. `unique_name(prefix)` takes the prefix, so a caller that wants one says so rather than inheriting it. | Object mutations and interactions | `excluded` |
| `RETRY_TIMEOUT_SECONDS`, `RETRY_INTERVAL_SECONDS` | Import-time environment-configured int and float defaults. Invalid environment text raises during import. | `retry_until(Duration, condition)` and `RetryTimeout`, taking the policy as an argument rather than reading import-time environment globals, so two tests in one process cannot disagree about it. | Documentation, compatibility, and parity closure | `implemented` |
| `EnvironmentVarGuard`, `__enter__`, `__exit__` | Context manager over process-global environment. Exit restores values recorded by the guard; concurrent environment mutation is unsafe. | No equivalent; crate code and test support use command-local environment changes. | Documentation, compatibility, and parity closure | `implemented` |
| `EnvironmentVarGuard.set`, `unset` | Unit operations recording enough original state for context exit. | No equivalent. Mutating this process's environment to influence a tmux server is a global side effect two concurrent tests cannot share; the fixture configures the server instead. | Documentation, compatibility, and parity closure | `excluded` |
| `RandomStrSequence`, `characters`, `__iter__`, `__next__` | Iterator returning eight distinct sampled characters per call. Fewer than eight source characters raises `ValueError`. | Private collision-resistant naming for object-scoped test helpers; no public iterator. | Object mutations and interactions | `implemented` |
| `namer` | Global mutable `RandomStrSequence` instance. | No global mutable singleton. | Object mutations and interactions | `implemented` |
| `get_test_session_name` | Loops until `Server.has_session()` is false. It can loop indefinitely, and a failed liveness check can be mistaken for uniqueness. | Bounded unique-name generation on an isolated Server. | Discovery, traversal, refresh, and environment resolution | `implemented` |
| `get_test_window_name` | Loops until local Window filtering is empty. `prefix=None` is rejected only by `assert`. | Validated prefix and bounded generation. | Discovery, traversal, refresh, and environment resolution | `implemented` |
| `retry_until` | Calls a synchronous predicate until true. Timeout raises `WaitTimeout` or returns false; uses wall clock and blocking sleep; predicate exceptions propagate. | `libtmux::test::retry_until`, using a monotonic deadline and async predicate. | Documentation, compatibility, and parity closure | `implemented` |
| `temp_session`, `temp_window` | Synchronous context managers yielding exactly one object, generating a name when absent, and finally killing only when still present. Cleanup query or kill errors can propagate. | Scoped async test helpers using the same supervised cleanup path as production scopes. | Object mutations and interactions | `implemented` |
| `config_file` fixture | Session-scoped `.tmux.conf` containing `set -g base-index 1`. | Owned empty configuration inside `TestServer`; no fixture injection. Window and pane indexes retain tmux defaults instead of forcing base index 1. Covered by [`tests/test_server.rs`](../tests/test_server.rs). | Foundation | `implemented` |
| `home_path`, `home_user_name`, `user_path`, `zshrc` fixtures | Session-scoped home, user, shell, and configuration values. | No equivalent. `TestServer` does not replace `HOME`, and callers own their paths. | Documentation, compatibility, and parity closure | `excluded` |
| `clear_env` fixture | Deletes most environment variables through pytest's monkeypatch except a broad allowlist. | Ordinary environment inheritance with command-local removal of `TMUX` and `TMUX_PANE` and a deterministic `TERM`; covered by [`tests/test_server.rs`](../tests/test_server.rs). | Foundation | `implemented` |
| `server` fixture | One isolated socket-name Server. Finalization best-effort kills the daemon and unlinks the socket. | Public `libtmux::test::TestServer` under `test-support`; covered by [`tests/test_server.rs`](../tests/test_server.rs). | Foundation | `implemented` |
| `session_params` fixture | Empty dictionary override hook passed to Session creation. | `NewSessionOptions` passed to `TestServer::session`, so the shape is typed rather than an override hook. | Object mutations and interactions | `implemented` |
| `session` fixture | Ensures an anchor Session, removes old prefixed Sessions, creates one randomized Session, and best-effort switches a client. | `TestServer::session` as the factory and `Server::with_session` as the scoped form, which kills what it made whether the body succeeded or failed. | Object mutations and interactions | `implemented` |
| `control_mode` fixture | Callable returning internal `ControlMode`. The context manager spawns a real attached control client, polls registration, exposes `server`, `session`, `client_name`, and `stdout`, then terminates with bounded kill fallback. | `libtmux::control::ControlMode` under the `control-mode` feature, split into a sender and a `Stream` of events; covered by [`tests/control.rs`](../tests/control.rs). Python's fixture exposes raw stdout, where this parses the protocol. | Object mutations and interactions | `implemented` |
| `TestServer` fixture | Capitalized pytest fixture returning a `functools.partial`, not a class. Each call creates a uniquely named Server and registers cleanup. | A real `libtmux::test::TestServer` type owning an explicit socket path and lifecycle cleanup; covered by [`tests/test_server.rs`](../tests/test_server.rs). | Foundation | `implemented` |
| `USING_ZSH` | Import-time public-looking bool, not documented as a fixture or helper. | No equivalent, and no detection either: the fixture pins `default-shell`, so there is no ambient shell to report. That is what keeps a suite's timing independent of whose machine it runs on. | Documentation, compatibility, and parity closure | `excluded` |
Python provides only `server` and `session` hierarchy-object fixtures.
`window` and `pane` are doctest namespace values, not pytest fixtures.
## Intentional Rust deltas
These deltas preserve effects and information while rejecting Python shapes
that are unsound, ambiguous, or specific to dynamic language mechanics.
| Python behavior | Intentional Rust behavior | Delivery slice | Status |
| ----------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- | ------------- |
| Options and hooks return display-quoted strings that callers re-parse. | Values are read through `show-options -v`, which prints stored bytes verbatim. The listing form is names only, because tmux renders values bare, double quoted, or single quoted depending on content and re-parsing it would be guesswork. | Options, hooks, and advanced command families | `implemented` |
| An unset option and an unknown option are one failure. | Both report `None`, decided by tmux's two rules: a built-in option always exists and prints nothing when unset, while a user option exists only while set. The `@` prefix decides which applies, so no error text is parsed. | Options, hooks, and advanced command families | `implemented` |
| Creating an object returns a handle that must be looked up again to be useful. | Creation hydrates from the creating command's own `-P -F` output, so it costs one round trip. Every projection field, including winlink fields, resolves in that context. | Object mutations and interactions | `implemented` |
| `refresh_client` and object refresh share the word refresh. | The tmux redraw is `Client::redraw`. `refresh` means "re-read the snapshot" on every handle, so the two are not given one name. | Object mutations and interactions | `implemented` |
| Background `run_shell` reports success for the command. | `spawn_shell` returns unit. tmux accepting a background command says nothing about whether it later succeeds, so reporting success would be a claim the crate cannot support. | Options, hooks, and advanced command families | `implemented` |
| `new_session` may attach, and new windows and panes take the selection. | Sessions are always created detached, and windows and panes are not selected unless asked. A library must not seize the caller's terminal or move their selection while building a workspace. | Object mutations and interactions | `implemented` |
| Option values are strings the caller converts by hand. | `TmuxText::as_flag` and `TmuxText::parse` give every scope typed decoding without adding methods per type, and `as_flag` returns `None` outside tmux's flag vocabulary rather than reading arbitrary text as false. | Options, hooks, and advanced command families | `implemented` |
| Test helpers pick random names and retry with fixed sleeps. | `unique_name` combines the process id with a counter, needing no random source and no collision check, and `retry_until` polls an observable condition against a deadline. | Documentation, compatibility, and parity closure | `implemented` |
| Synchronous raw command API. | `Server::cmd` is async. No parallel synchronous facade; covered by [`tests/server_command.rs`](../tests/server_command.rs). | Foundation | `implemented` |
| A selector-free raw command reads the live process `TMUX` value, and tmux splits it at the first comma. | `Server` captures the effective endpoint once, right-splits inherited `TMUX`, and dispatches that captured path explicitly; covered by private tests in [`src/target.rs`](../src/target.rs) and [`src/internal/core.rs`](../src/internal/core.rs). | Foundation | `implemented` |
| Synchronous hierarchy API. | Live handle I/O is async; snapshot getters remain synchronous. | Discovery, traversal, refresh, and environment resolution | `planned` |
| Exceptions and stringly typed command targets. | Foundation `Error`, validated IDs, and scope-specific command targets; covered by [`tests/version.rs`](../tests/version.rs) and [`tests/target.rs`](../tests/target.rs). | Foundation | `implemented` |
| Dynamic local query cardinality exceptions. | Borrowed `QueryIteratorExt::exactly_one` and `one_or_none` inspect at most two items and return source-less `ExactlyOneError` or `MultipleItemsError`; covered by [`tests/query.rs`](../tests/query.rs). | Formats, snapshots, winlinks, and queries | `verified` |
| Overlapping mutation options. | Consuming typed builders that reject invalid combinations. | Object mutations and interactions | `planned` |
| UTF-8 text command results with replacement escapes and normalized lines. | Public `CommandResult` preserves authoritative raw bytes and makes decoding explicit; covered by [`tests/server_command.rs`](../tests/server_command.rs) and private tests in [`src/command.rs`](../src/command.rs). | Foundation | `implemented` |
| Version comparison strips suffixes and invents ordering for `master` and an OpenBSD fallback. | Exact release suffix ordering is retained; development identifiers are minimum-capable but not invented releases; covered by [`tests/version.rs`](../tests/version.rs). | Foundation | `implemented` |
| Raw command diagnostics can retain executable argv. | Command arguments carry diagnostic sensitivity, and summaries omit sensitive bytes and lengths; covered by [`tests/command.rs`](../tests/command.rs). | Foundation | `implemented` |
| Raw process output can enter result diagnostics. | Public result getters expose raw output explicitly while `Debug` omits it; covered by [`tests/server_command.rs`](../tests/server_command.rs) and private tests in [`src/command.rs`](../src/command.rs). | Foundation | `implemented` |
| Raw process output can enter executor errors and tracing. | Errors and tracing omit raw output and retain only sanitized request context; covered by private executor tests in [`src/internal/subprocess.rs`](../src/internal/subprocess.rs). | Foundation | `implemented` |
| Pane input and environment values can enter diagnostic surfaces. | Object operations classify those values as sensitive before command construction. | Object mutations and interactions | `planned` |
| Prompt and buffer values can enter diagnostic surfaces. | Advanced command builders classify those values as sensitive before command construction. | Options, hooks, and advanced command families | `planned` |
| Session, Window, and Pane equality ignore Server identity; Client compares its full snapshot. | Handle equality and hashing use normalized Server identity plus stable object identity. | Discovery, traversal, refresh, and environment resolution | `planned` |
| Refresh mutates only returned nonempty fields and can retain stale values. | Refresh atomically replaces the complete snapshot; cloned handles retain independent snapshots. | Discovery, traversal, refresh, and environment resolution | `planned` |
| `new_session` temporarily deletes process-global `TMUX`, so it may route differently from raw commands on the same `Server`. | Domain operations reuse the captured `ServerIdentity` and never mutate process-global connection state. | Object mutations and interactions | `planned` |
| Hierarchy collections have inconsistent failure contracts. | Every hierarchy collection has a lenient accessor and loud `try_*` form. | Discovery, traversal, refresh, and environment resolution | `planned` |
| Python `QueryList` is mutable and has equality and `items()` defects. | Rust omits the wrapper and uses user-owned ordered collections, native iteration, typed local expressions, and exact cardinality; covered by [`tests/query.rs`](../tests/query.rs). | Formats, snapshots, winlinks, and queries | `verified` |
| Python `QueryList` accepts dynamic suffixes and falls back from an unknown suffix to a nested exact lookup. | Dynamic value lookup, unknown-suffix handling, and `field__operator` parsing remain future ingress behavior rather than part of typed Rust authoring. | Discovery, traversal, refresh, and environment resolution | `planned` |
| Python case-insensitive query suffixes compare `str.lower()` results. | Rust scalar `*_ignore_case` operators use `caseless` 0.2.2 Unicode 16.0 default case folding without normalization, so `Straße` and `STRASSE` match in Rust but not Python; covered by [`tests/query.rs`](../tests/query.rs). | Formats, snapshots, winlinks, and queries | `verified` |
| Python string-RHS `in` tests whether the right-hand string occurs inside the candidate, while list-RHS `in` tests membership. | Rust `is_in` and `not_in` authoring accepts any `IntoIterator`; the version 1 wire requires an array, a scalar string is never membership, and `contains` is explicit substring matching; covered by [`tests/query.rs`](../tests/query.rs) and [`tests/filter_serde.rs`](../tests/filter_serde.rs). | Formats, snapshots, winlinks, and queries | `verified` |
| Python regular expressions use `re`, including constructs unsupported by Rust's linear-time engine. | Rust regex syntax is authoritative. Python-valid look-around `a(?=b)` and backreference `(a)\1` fail as source-less, redacted `InvalidRegex` through authoring and serde ingress; covered by [`tests/query.rs`](../tests/query.rs) and [`tests/filter_serde.rs`](../tests/filter_serde.rs). | Formats, snapshots, winlinks, and queries | `verified` |
| Python's version table defaults `client_uid`, `client_user`, `next_session_id`, `pane_start_path`, `uid`, and `user` to 3.2a. | Rust gates all six at their actual tmux 3.3 floor and omits them from 3.2a plans; covered by release-floor tests in [`src/formats.rs`](../src/formats.rs). | Formats, snapshots, winlinks, and queries | `verified` |
| Unsupported object-mutation flags often emit a warning and disappear. | A requested unsupported capability returns `Error::UnsupportedCapability`. | Object mutations and interactions | `planned` |
| Unsupported advanced-command flags often emit a warning and disappear. | A requested unsupported capability returns `Error::UnsupportedCapability`. | `Error::UnsupportedCapability`, checked before dispatch rather than left to tmux: tmux usually accepts an unknown flag and ignores it, which turns "your tmux is too old" into "the command did nothing". A development build carries no numbered release to compare and is taken at its word. Covered by [`tests/commands.rs`](../tests/commands.rs). | `implemented` |
| Option and hook dictionaries, mutable flag maps, sentinel defaults, and mixins. | Typed values, private exhaustive flag conversion, builder defaults, and inherent methods. | Options, hooks, and advanced command families | `planned` |
| Python context managers perform synchronous destructive cleanup. | Explicit async scoped operations await cleanup; ordinary cloneable handles do not perform I/O in `Drop`. | Discovery, traversal, refresh, and environment resolution | `planned` |
| Deprecated public names mostly raise immediately. | Always-failing compatibility names are omitted. Working option aliases are replaced by the primary inherent API. | Documentation, compatibility, and parity closure | `planned` |
| `FORMAT_SEPARATOR` is process-global and configurable at import time. | Private q framing is collision-safe and has no global setting; covered by [`src/formats.rs`](../src/formats.rs). The q-only parser cannot become `verified` until version-aware tmux 3.4/3.5 recovery passes pinned end-to-end fixtures. | Formats, snapshots, winlinks, and queries | `implemented` |
| Pytest fixture injection and implicit daemon cleanup. | Optional `test-support` exposes an owned `TestServer` with explicit and `Drop` cleanup; covered by [`tests/test_server.rs`](../tests/test_server.rs). | Foundation | `implemented` |
| Global test-object naming and synchronous temporary-object contexts. | Object-scoped test helpers use private unique naming and explicit async scopes. | Object mutations and interactions | `planned` |
## Ambiguous public boundaries
These rows require a deliberate closure decision. They are not implementation
evidence unless their status and Rust treatment record that decision.
| Boundary | Pinned evidence and interpretation | Planned Rust treatment | Delivery slice | Status |
| --------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------ | ---------- |
| `Client` policy-table omission | `Client` is in root `__all__` and has an API page, but `docs/project/public-api.md` omits it from the core table. | `Client`, exported from the crate root and documented with the other handles. | Documentation, compatibility, and parity closure | `implemented` |
| `libtmux.formats` | The mechanical rule in `docs/topics/public-vs-internal.md` makes a non-underscore module public, but the API index and project public-API table omit it. | Exclude the ambiguous Python namespace promise. Preserve its observable behavior through the specific format rows, public `TmuxText`, and private checked catalog; omit duplicate legacy lists. | Documentation, compatibility, and parity closure | `excluded` |
| `:private-members:` on object API pages | Autoclass pages render underscore helpers such as option parsing and legacy `_list_*` methods. Their names and module paths remain underscore-prefixed. | Private helpers stay private. What a caller cannot reach is not documented as though they could. | Documentation, compatibility, and parity closure | `excluded` |
| `QueryList` | Import path is internal, but public accessors return it and API documentation links `filter()` and `get()`. | Exclude the public wrapper type. User-owned `Vec<T>` and slices plus native iteration, `Matcher`, `FilterExpr`, and `QueryIteratorExt` preserve implemented local behavior; covered by [`tests/query.rs`](../tests/query.rs). | Formats, snapshots, winlinks, and queries | `excluded` |
| `SparseArray` | Import path is internal, but public option and hook APIs return it. | Export the value behavior as `SparseValues`, not the internal Python class shape. | Options, hooks, and advanced command families | `planned` |
| `ControlMode` | Internal type returned by a documented public pytest fixture. | Expose only `libtmux::test::AttachedClient`; do not freeze a persistent executor API. | Object mutations and interactions | `planned` |
| `HooksMixin.hooks` | Public annotation refers to an internal type, while ordinary concrete handles generally lack the instance attribute. | Not ported. The hook operations are kept; the attribute whose annotation names an internal type is not. | Documentation, compatibility, and parity closure | `excluded` |
| `USING_ZSH` | Non-underscore module data in `pytest_plugin.py`, but absent from fixture and helper documentation. | No equivalent. A caller chooses shell configuration explicitly, and the fixture pins it rather than reading the ambient one. | Documentation, compatibility, and parity closure | `excluded` |
| Root metadata from `__about__` | The source module is underscore-prefixed, but selected dunders are explicitly re-exported from the root. | Preserve package metadata in Cargo; expose neither the internal module nor Python dunder constants. | Foundation | `excluded` |
| Imported names and module loggers | Public modules lack broad `__all__` declarations, but autodoc does not treat imported dependencies or `logger` as authored public capabilities. | Imported bindings and loggers are not part of the surface, so they are neither re-exported nor documented. | Documentation, compatibility, and parity closure | `excluded` |
| Deprecated methods | Most public names are unconditional `DeprecatedError` stubs; Window's three option aliases still delegate with warnings. | Names that only ever fail are not carried over, and neither are duplicate option aliases. | Documentation, compatibility, and parity closure | `excluded` |
| Source and documentation mismatches | `Server.attach_session(None)` is invalid, `Server.kill_session` lacks documented validation, `Session.new_window` prose conflicts with its detached default, `Session.attach(flags_)` splits strings into characters, and `Window.new_window` has a `start_directory` annotation defect. | Typed inputs remove the ambiguity rather than reproducing it, so there is no mismatch left to document. | Documentation, compatibility, and parity closure | `excluded` |
## Advancement rule
A row may move from `planned` only when its Rust symbol is present, its public
documentation names the same behavior and gate, and focused evidence exercises
its return cardinality, tmux effect, and error path. It reaches `verified` only
after the owning delivery slice's full gate passes. Test names and links are
added at that point; this baseline inventory does not invent future evidence.