Repository navigation
Conversation
why: Pane capture can finish before the shell executes a sent command. The environment and capture tests must observe the expected output. what: - Wait for the initial prompt and exact command output - Bound polling instead of relying on an immediate read or fixed sleep
why: Examples need ordinary tmux defaults and external test isolation. Cleanup must retain its accepted target and expose failures for retry. what: - Capture endpoint, executable and child environment when constructing a Server, with explicit selectors ahead of environment defaults - Add generation-bound ownership for servers, sessions, windows and panes, including bounded cleanup and paired body/cleanup errors - Keep plain Server contexts borrowed and use owners for object scopes - Test unchanged examples under external socket defaults and document the Python 3.11 floor, changed defaults and remaining lifecycle work
why: Creation could return a tmux ID and then fail during snapshot decoding or context entry, leaving the resource behind. A later daemon at the same endpoint could also be accepted as the original creation. what: - Retain daemon and object receipts on the creating connection - Roll back failed materialization against the recorded generation - Preserve receipt bytes across client timeout and interruption - Expose failed rollback owners without replacing the original error - Refuse replacement daemons before returning or entering the scope
why: The lifecycle changes do not require raising the Python floor or removing the reference detail and cleanup examples users already have. what: - Restore Python 3.10 metadata, typing fallbacks and lock branches - Use conditional exception-group support and compatible error notes - Restore context-method reference sections and cleanup doctests - Keep unrelated typing and lint cleanup outside the lifecycle diff - Verify examples without requiring pidfd support from the interpreter
why: A descendant retaining an output pipe makes the post-timeout communicate call wait beyond the command deadline. Receipt capture must still finish before creation rollback handles an interruption. what: - Give draining and reaping finite cleanup intervals - Let the receipt worker observe main-thread interruption between reads - Retain partial output, text decoding and paired failures - Test inherited pipes and real creation rollback on Python 3.10 and 3.12
why: A pipe-reader close failure can replace an interruption and skip client reaping. A close failure inside communicate can also discard output already captured before the timeout. what: - Retain the latest captured output across drain and close failures - Close the remaining reader and attempt the bounded client wait - Preserve the original failure alongside each cleanup failure - Exercise both readers with timeout, interruption and inherited pipes
why: A close error during the final subprocess drain can discard a receipt received after the preceding timeout snapshot, preventing rollback of a known creation. what: - Retain bytes with a selector reader before closing output streams - Keep bounded cancellation cleanup, grouped errors and client reaping - Exercise late output with both reader errors, timeout and Ctrl-C
why: Examples need to reuse matching tmux resources while cleaning up only the objects they create. Server discovery must be bounded and must not change the daemons it finds. what: - Add created-or-reused results for servers, sessions, windows and panes - Bind creation receipts and rollback to the accepted daemon identity - Add bounded socket discovery with explicit diagnostics - Use printable receipt fields under non-UTF-8 tmux client locales - Preserve Python 3.10, existing docstrings and doctest expectations
why: Captured client configuration does not require removing the existing private hook accessor or its documentation. what: - Restore the original helper and docstring verbatim - Keep its name separate from the captured executable backing field - Preserve endpoint defaults, capability checks and Python 3.10 support
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #771 +/- ##
==========================================
+ Coverage 52.37% 55.38% +3.00%
==========================================
Files 26 28 +2
Lines 3729 4478 +749
Branches 747 861 +114
==========================================
+ Hits 1953 2480 +527
- Misses 1472 1655 +183
- Partials 304 343 +39 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
why: Copied examples should work with an existing daemon or start one through the public API, without requiring cleanup ownership. what: - Return the ordinary server after verified startup or reuse - Add an imported workspace example that leaves its resources available - Test absent/running endpoints, preserved state and startup failures - Keep lifecycle examples and existing compatibility documentation
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Ordinary imported examples can call
Server().ensure_running()against their normal tmux endpoint, whether a daemon already exists or needs to start. The same program runs in tests with socket defaults supplied throughLIBTMUX_SOCKET_PATHorLIBTMUX_SOCKET_NAME; the external harness owns isolation and final cleanup. The README and Sphinx quickstart show the completeexamples/workspace.pyprogram, which creates or reuses a session and window and leaves them available.ensure_running()returns the same ordinary server handle without requiring a cleanup owner. It preserves an existing daemon's sessions, options and environment. A new daemon remains available before session creation, and startup adds no bootstrap session. Normal tmux configuration can create its own sessions. Each server captures its endpoint, executable and child environment at construction, so later environment changes do not redirect its commands.Ownership, discovery and find or create
resource.own()accepts destruction responsibility for an existing server, session, window or pane. Cleanup retains the accepted daemon generation and object ID, checks that generation inside tmux's destructive dispatch, preserves body and cleanup failures, and permits retry. Session, window and pane contexts use this behavior. The existing session-cleanup example remains a separate demonstration.Server.discover()performs bounded, non-starting probes of selected socket directories and returns borrowed servers with diagnostics and truncation status. Find-or-create methods returnFoundOrCreated: its.valueis the ordinary object, while entering the result as a scope requests cleanup of a proven creation. Reused matches remain borrowed. Session/window names and pane-local keys match literal values; ambiguity raises. Child lookup and creation use separate commands, so callers requiring uniqueness must serialize competing creators.Creation records receipts before decoding snapshots. Failed readback, context entry, name checks or generation checks roll back the recorded resource against its creating daemon. Nonzero client status, timeout and interruption preserve readable receipts. Failed rollback exposes a retry owner through
CreationCleanupError; missing or invalid receipts reportUnknownCreation. Server startup uses a per-call proof to distinguish creation from reuse. Receipts and discovery probes retain printable framing under non-UTF-8 tmux client locales.Compatibility and documentation
Python 3.10 remains the minimum. Paired failures use the conditional
exceptiongroupdependency below Python 3.11. Existing conditional typing imports, classifiers, lint/type targets and tmux feature gates remain.All 866 original docstring examples retain source, expected output, exception text and flags. All 427 original library docstrings remain: 416 are identical and eleven contain documented lifecycle clarifications. The ensure-server addition preserves all 516 incoming documentation-string expressions and 1,541 incoming doctest examples. The original
_tmux_binhelper and its documentation remain intact.Behavior changes to review: a plain
Servercontext leaves the daemon alive; whole-daemon destruction requires explicit ownership. Explicit socket paths must be absolute, ambiguous explicit selectors raise, andtmux_binis a read-only captured path. Creation and adoption reserve@libtmux_owner_generation; a malformed existing value fails ownership acceptance.Validation
Remaining work
Keep this PR in draft. The legacy Unicode snapshot parser retains its non-UTF-8 limitation; the repaired receipt protocol does not establish every object API under the C locale. Creation deadlines apply per command or identity step, and snapshot queries retain their existing timeout behavior.
The full library suite, installed-package validation for this revision, every supported tmux patch release and the nine-dimension acceptance assessment remain pending. Plain Markdown, Astro Markdown/MDX, Sphinx reStructuredText/MyST and Python doctest remain in the shared integration scope; the native source-binding adapters are under separate review. The external runner is tracked in libtmux/docs#138. No merge or package release is included.
Continues the work and discussion in #769 on
lifecycle-mvp.