Repository navigation
Description
Current preparation status — 2026-11-01. Seven independent PRs are open across Python and TypeScript, with every required hosted check passing at their recorded heads; the existing Python ownership PR is reused. Each new PR builds from current master with sibling branches absent. This records PR preparation and bounded qualification, not completion of the feature train. Every unresolved canonical issue remains open.
Verified bases: Python 886b1cd4862cbddcadffe3d82db0495f4e0594f8; TypeScript d2b149beddb84326d79d3fabbdb99429646f22e5. No new generic engine contracts or merge dependencies were added. Python seconds/code-point counts and TypeScript milliseconds/UTF-16 or filtered-UTF-8 units remain explicitly named by each API.
| Canonical scope | Action and evidence | Remaining |
|---|---|---|
| Opt-in command deadline | Prepared PR #807 · PASS at 6b928758 · evidence |
Async and broader roadmap stay open. |
| Native async cancellation | Keep canonical gap · PARTIAL · evidence | Extract canonical engine values and prove native cleanup independently. |
| Ordinary channel deadline | Prepared PR #809 · PASS at 04148dd9 · evidence |
Keep broader channel/cancellation requirements. |
| Borrowed-server survival | Reuse PR #728 · PARTIAL broader verification · evidence | Existing PR remains open; broader local suite has baseline failures. |
| Connected-daemon admission | Keep canonical gap · UNVERIFIED · evidence | Selected-backend admission and daemon replacement remain unqualified. |
| Visible/cooperative waits | Keep canonical gap · PARTIAL · evidence | Worker cleanup and selected observer route fail stronger controls. |
| Immutable capture cursor | Keep canonical gap · PARTIAL · evidence | Reset/gap/unknown, lifetime and serialization qualification. |
| Trim ambiguity evidence | Prepared PR #808 · PASS at a16ccaf5 · evidence |
Runtime diagnostic classification and qualified counter handling. |
| Immutable pane value | Prepared PR #810 · PASS at 041e23da · evidence |
Graph, serialization and wider observations stay open. |
| Retained wait evidence | Keep canonical gap · PARTIAL · evidence | Bounded existing-path wait and retained typed causes/no-sample evidence. |
| Bounded recorder | Keep canonical gap · UNVERIFIED · evidence | Declared sources, redaction, eviction and export remain unverified. |
| Owned byte subscription | Keep canonical gap · PARTIAL · evidence | Wrong-daemon observation; owned native cleanup/queue qualification. |
| Sampled text frames | Keep canonical gap · PARTIAL · evidence | Nested mutation and cleanup/routing failures; independent text-only driver. |
| Qualified cells | Keep canonical gap · PARTIAL · evidence | Qualified grammar plus immutable values and hard transport bounds. |
| Ordered pane operations | Keep canonical gap · PARTIAL · evidence | Native attributed outcomes and independently bounded lifecycle. |
| Exact owned create/reuse | Keep canonical gap · PARTIAL · evidence | Concurrent disposition and replacement-safe cleanup on master. |
| Lease qualification | Keep canonical gap · PARTIAL · evidence | Cross-process arbitration and suspension remain unverified. |
The remaining helpers receive concrete qualification findings rather than a production PR under the limited delivery rule. Current-master TypeScript probes retain the original three failures (mutable frames, pending disposal, stringified errors); private repairs pass all 16 declared assertions on Bun 1.4.2 and emitted Node 22.23.3 with the recorded tmux 3.8a binary. The first Node bundle had a missing-fixture packaging failure before feature assertions; that failure remains recorded, and the identical fixture was placed beside the moved bundle without changing assertions or timers.
The refreshed Python private consumer passes its 13 declared cases, while stronger controls fail native worker cleanup, selected-engine observer routing and nested frame immutability. Earlier 12-trial receipts remain tied to their original hashes; the changed current Python prototype was tested separately. No prototype PASS is treated as merged implementation. Local complete Python suites retain the same 18 failures reproduced on unchanged master; new PR-head hosted lanes pass.
No new issues, closures or merge dependencies result from this pass. No macOS jobs, runners, fixture lanes, debugging or qualification work are added; existing support and coverage remain, and unrun behavior is UNVERIFIED without becoming a gate. Python's core minimum stays 3.2a; its minimum-version issue #777 and proposal PR #779 are outside scope. NEVER write to tmux/tmux; references use pinned source code only.
Linked trackers: Python roadmap, Python project, environment profiles, TypeScript roadmap, TypeScript project. Each gap has its canonical issue or explicit research owner; no aliases become extra feature requests.
Context
The previous issues #630, #631, #632, and #633 came from local worktree experiments and should be treated as one consolidated roadmap with core libtmux API work.
This issue is the canonical tracker for Agentic/DX improvements across:
- core API contracts
- async support direction
- concurrency/state semantics
- engine/backend architecture
Goal
Strengthen API contracts and machine-readable behavior for agent-safe automation without fragmenting the project into parallel tracks.
Low-lift ideas
- Publish explicit stable API boundary and deprecation schedule (safe public imports and behaviors).
- Add a concise exception/error contract table for command failures.
- Publish sync-vs-async parity notes (supported / planned / out-of-scope).
- Define/document engine selection semantics and baseline capability fields.
Medium-lift ideas
- Add contract tests for public behavior and tmux-version compatibility.
- Add async cancellation/timeout/backpressure semantics and tests.
- Clarify concurrency/state refresh guarantees for pane/window/session objects.
- Add shared response/event parsing contracts across subprocess/control-mode backends.
High-lift ideas
- Publish machine-readable capability metadata (tmux version matrix + backend capabilities).
- Add versioned structured contracts for machine output/diagnostics.
- Add inspect/plan-style, non-mutating orchestration preview interfaces.
Done when
- Public API and compatibility expectations are explicit.
- Async + concurrency + backend behaviors are documented and regression-tested.
- Automation clients can rely on stable, machine-readable contracts.
Consolidation note
Supersedes and consolidates:
-
[Agentic DX] Async prototype roadmap (libtmux-asyncio-2-chatgpt-2025-10x) #630
-
[Agentic DX] Async prototype roadmap (libtmux-asyncio-psycopg) #631
-
[Agentic DX] Async prototype roadmap (libtmux-asyncio-sqlalchemy) #632
-
[Agentic DX] Engine/control-mode roadmap (libtmux-control-mode-2025-10x-chatgpt) #633
-
[Agentic DX] Rust acceleration roadmap (libtmux-rust prototype) #634
Delivery plan
The independent-PR contract below supersedes any earlier implication of a required merge sequence.
Deliver rmux-inspired helpers through stock tmux capabilities, with explicit observation, cancellation, ownership, and recovery contracts. Track the work in the libtmux project. This plan reuses twelve existing issues and adds six focused proposals.
| Area | Deliverable | Issues |
|---|---|---|
| Foundation | Optional deadlines, async cancellation, attributed replies, ownership, and capability admission | #689, #732, #724, #778 |
| Observation | Current-screen predicates, cooperative completion, future bytes, capture cursors, and immutable values | #673, #800, #740, #671, #370 |
| Composition | Sampled surfaces, qualified cells, ordered multi-pane results, and retained wait diagnostics | #801, #802, #803, #584 |
| Creation | Create/reuse disposition and cleanup of resources created by the operation | #804 |
| Retention and lifecycle | Recording with coverage boundaries; experimental session leases | #420, #805 |
| Qualification | Controlled fixtures, application adapters, and best-effort user environments | #456 |
Work can proceed independently where its required contract exists. Text surfaces do not wait for styled cells. A minimal immutable observation can unblock wait diagnostics before a full snapshot graph. The cancellation and reply-correlation slice of #689 can land before its broader workspace, lazy-operation, and MCP work.
- Settle the command deadline, cancellation, unknown-outcome, and owned-client cleanup contract in Operationalize typed operations and engines (follow-up to #688) #689; expose bounded channel waits through
Server.wait_for()has no timeout, so a pane that never signals hangs forever #732. - Resolve existing server ownership in
Server.__exit__kills any live server, including one it did not start #724 and independent feature admission in Gate unsafe optional tmux features independently #778. - Deliver byte-preserving subscriptions in Observe pane output as bytes with explicit subscription gaps #800 and state the distinct observation/completion guarantees in feat: Add Non-polling Waiters (Deterministic Channels & Delta-Polling) #673.
- Deliver capture cursors in feature: upstream capture_since #740 with Investigate libtmux-side trim detection for scrollback consumers #671's explicit loss and uncertainty behavior.
- Deliver immutable observation values in Snapshot / frame dataclass #370 and retained timeout diagnostics in Waiter v3.0: Requirements #584.
- Deliver sampled
surface_streamframes in Add sampledsurface_streamframes with explicit resets #801; add qualified styled cells through Expose typed cell captures for qualified tmux export formats #802. - Deliver ordered
PaneSetresults and bounded any/all waits in AddPaneSetoperations with per-target outcomes #803. - Deliver owned create/reuse and compensating cleanup in Create or reuse tmux resources with explicit cleanup ownership #804.
- Specify recording coverage, retention, and persistence in
record(),.stop(): capture and for object info #420; qualify optional leases separately in Qualify token-fenced leases for owned tmux sessions #805. - Publish the environment qualification and counterexamples in Bullet proofing for
capture_pane#456 with each implementation's supported profile.
Research basis and limits
The audit classified 558 explicit rmux SDK declarations into 22 capability families. That inventory includes constructors and conversions; it is not a target of 558 Python methods. Source evidence is pinned to rmux 1f4571e7, tmux 3.8 at 7f2a35ad, and the Python baseline at 886b1cd4.
Local prototypes exercised Python and TypeScript against tmux 3.8 and a pinned development checkout, with twelve declared trials. Those are exploratory observations, not public implementation acceptance: the fixtures and results must be included in reviewable implementation work before closing these issues. The stronger TypeScript byte-identity contract failed through its decoded string stream; that belongs in the TypeScript port. Engine cancellation implementations were inspected, but their suites were not rerun for this planning audit.
The source evidence establishes different guarantees:
- rmux retains a bounded output ring. A Python recorder can retain what it observes after installation; it cannot recreate bytes that nobody retained.
- rmux registers an observer at the same locked boundary as capture. Separate tmux capture and metadata commands provide sampled observations, even when metadata matches before and after.
- rmux recovery includes pending bytes, active and saved attributes, cursor state, and parser state. Exported visible cells do not provide every state needed to interpret the next byte.
- tmux's diagnostic grid route bypasses ordinary text-history selection. Cell parsing therefore needs format qualification and honest resource limits.
- rmux's state journal and lease handlers own server-side state. Library implementations need explicit observer coverage and ownership qualification.
Neither bounded in-memory retention nor a captured frame establishes durability across arbitrary daemon restarts. Disk recording can preserve acknowledged records under a specified storage policy; missing observations remain gaps. Quiet output, a matched prompt, and successful key submission do not establish command completion in an arbitrary shell.
The train covers library work using current tmux capabilities. Complete hidden-state export, replay of never-recorded bytes, browser authentication/sharing, and a native Windows PTY backend remain outside this delivery scope. No upstream tracker changes are part of this work.
Disposition of all 22 capability families
| Audited family | Owner or disposition | Scope in this train |
|---|---|---|
| Connection, startup, capabilities | #689, #778 | Engine ownership, deadlines, daemon/engine admission, observer epochs |
| Session ensure, reuse, tags | #804 | Creation disposition and exact identity; tags do not prove ownership |
| Discovery, tags, stale identities | #803, #804; existing query APIs | Freeze selection where required, preserve duplicates, reject stale/wrong-server identity |
| Launch, respawn, layout builders | #804; #689 workspace work | Reuse primitive operations; compensate only owned resources; no arbitrary shell rollback |
| Future byte and text matching | #800, #673 | Arm before trigger, bytes before decoding, cross-chunk matching, explicit loss |
| Visible text, regex, absence, any/all | #673, #803 | Predicate over an identified observation; absence is not historical absence |
| Quiet, stable, load state | #673, #456 | Declare observed fields and interval; application readiness remains conditional |
| Pane/process exit and command completion | #673, #732 | Separate pane process outcome from a cooperative command signal; missed status stays unknown |
| Raw output, line streams, bounded collection | #800, #420 | Live bytes, explicit line-tail policy, bounded queues, optional retained collection |
| Captures, regions, screenshots, cells | #370, #802 | Text first; qualified cell adapter; no universal native-state export claim |
| Text locators, filters, assertions | #673, #802; #645 as adjacent search work | Read-only predicates/regions are enabled; a full locator/action DSL is a later consumer |
| Keyboard, mouse, fill, detach helpers | Existing input API, #803 for broadcast; qualified adapters later | Submission success only; no universal fill or focus/processing guarantee |
| PaneSet batches, any/all, cleanup | #803, #804 | Per-target outcomes, bounded concurrency, losing-wait cleanup, ownership separate |
| Surface and rendered streams | #801 | Sampled current view, local revision, coalescing, reset; cells optional |
| Raw replay, recovery keyframes, reducers | #420; exact hidden-state recovery excluded | Replay only retained observations; no reconstruction of missing bytes or full parser state |
| State journals and lifecycle revisions | #420, #800 | Journal observed changes and gaps; not every overwritten server state |
| Ownership guards, leases, preserve, signals | #724, #804, #805 | Explicit ownership first; experimental fenced lease last |
| Foreground process and command metadata | Existing formats; #712 for spawn provenance; qualified adapter later | Preserve observed source/unknown values; no new universal process-truth API |
| Bounded action/input/snapshot traces | #420, #584 | Opt-in bounded diagnostics; persistence depends on sink contract |
| Browser sharing, permissions, expiry | Separate service, outside train | Terminal APIs can support a service; Python helper issues should not absorb browser authentication |
| Native Windows endpoint and PTY | Different backend, outside train | WSL qualification cannot establish native Windows support |
| Value types, diagnostics, conversions, command DTOs | #689, #370, #584 | Native Python types; avoid importing wire-only aliases without a consumer |
Independent PR delivery and compatibility
Each bounded deliverable gets a minimal PR against master that builds, tests, and provides useful behavior with every other feature branch absent. Parent issues organize the work; cross-links identify shared contracts and later integration points. They do not impose a PR merge order.
Use existing trunk primitives and a small private adapter where a shared implementation has not landed. Do not import unmerged modules, vendor the engine framework, add another public CommandRequest or CommandResult, or require a foundation PR before delivering a helper. A needed public symbol has one owning issue; other features consume a narrow structural contract or preserve a private representation until a public consumer needs it.
Preserve these contracts across all PRs:
- Existing synchronous methods, blocking defaults, return values, and exception behavior remain compatible. Deadlines are opt-in; async cancellation stays on explicit async operations.
- At the engine boundary, preserve request argv, explicit connection ownership, timeout/input semantics, raw return code and output, and one attributable result per request. Reuse the selected engine's canonical request/result classes when available. Do not infer success from the mere presence of output or silently change the engine's error policy.
- At the operation layer, map outcomes to
complete,failed,skipped, orunknown. Cancellation before submission isskippedwith a reason; an uncertain submitted mutation isunknown. Keep the underlying engine result available and never retry an uncertain mutation automatically. - Preserve bytes before decoding; scope identity to the server and pane lifetime; distinguish unsupported or unknown capabilities; invalidate observer continuity on loss. Sampled captures cannot become exact replay or complete terminal checkpoints through an adapter.
- Cleanup affects only positively owned resources. Borrowed engines and servers remain usable; cancellation of a client does not imply cancellation of the pane's process.
- Snapshot values are immutable; text offsets and terminal columns remain distinct. Optional future data needs a compatible extension path. Serialized records carry a version and an explicit policy for unknown event kinds and fields.
Before implementation, record the exact reviewed engine-ops, request-timeout, async-subprocess, and hardening refs and compare their real interfaces. Resolve differences in a contract note; an old issue's illustrative type or exception name is not an authoritative interface. Tests for each PR should validate its adapter against that recorded contract without requiring another feature PR to be installed.
The independence gate is a fresh checkout of the PR's actual master base plus only that PR's changes. Verify its focused tests, types, docs, and an end-to-end consumer there. Prove the critical test fails when its protection is removed. A sidecar check against the selected engine implementation is integration evidence, not a build dependency. Test interacting features once both exist, without making every unrelated pair a prerequisite.
Trim each first PR to the useful slice below. Keep the remaining issue criteria open and explicit. Later PRs may use functionality already merged into master; they must not depend on another unmerged branch.
| Issue | First independently useful PR | Later scope retained on the issue |
|---|---|---|
| #689 | Extract the smallest additive command-deadline/cancellation contract that preserves the classic facade; reconcile existing candidate PRs before creating another | Broader engine families, operations, workspace, lazy planning, and MCP |
| #732 | Add an optional deadline to the existing channel wait using an owned, bounded invocation | Route through a shared engine implementation when it is already available |
| #724 | Correct server-scope ownership with a regression proving a borrowed server survives | New owned-resource abstractions |
| #778 | Specify and expose optional-feature admission for the current daemon/engine; test refusal before effect | Register independently delivered feature adapters as they become available |
| #673 | Add bounded visible-text predicates and cooperative completion over existing primitives | Future-byte predicates, broader adapters, and richer composition |
| #740 | Add an immutable capture cursor with conservative reset/gap/unknown results | Additional qualified continuity aids |
| #671 | Document and reproduce trim ambiguity, with a narrow diagnostic classification where evidence permits | Integration into capture consumers once their APIs are on trunk |
| #370 | Add an immutable pane observation with explicit sampled provenance | Full hierarchical snapshots and richer frame adapters |
| #584 | Add immutable retained wait evidence and focused failure formatting to an existing wait path | Integration into later wait APIs and optional full snapshots |
| #420 | Add a bounded recorder for a declared observation source using existing capture/producer interfaces | Raw-stream integration, persistent sinks, and crash qualification |
| #800 | Add an owned byte-preserving subscription with readiness, bounded queues, gaps, and cleanup | Shared-engine integration and additional consumers |
| #801 | Add text-only sampled full frames, an initial reset, revisions, and close/cancellation using existing capture | Output-driven wakeups, patches, and styled cells |
| #802 | Add qualified cell parsing and direct capture into feature-owned immutable cell values | Surface and locator consumers |
| #803 | Add ordered multi-pane captures and explicit input submission with per-target outcomes | Any/all waits and additional bounded-concurrency policies |
| #804 | Add exact session create/reuse disposition and cleanup of sessions the helper created, without relying on the legacy server context manager | Multi-step builders and optional leases |
| #805 | Qualify an experimental lease on a session created by this helper using existing primitives | Integration with owned-create helpers after they land; stronger guarantees only with evidence |
#629 and #456 coordinate the roadmap and environment qualification. They do not require umbrella implementation PRs. Each feature PR carries its own controlled-fixture tests, declared environment limits, and relevant documentation. A passing first slice does not close the issue while deferred acceptance criteria remain.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsIn Progress
Activity
[-][Agentic DX] libtmux core: low-to-high lift API contract roadmap[/-][+][Agentic DX] libtmux: consolidated roadmap (core + async + engines)[/+]capture_pane#456Server.__exit__kills any live server, including one it did not start #724PaneSetoperations with per-target outcomes #803