Skip to content

Require tmux 3.3a before workspace effects - #1092

Draft
tony wants to merge 15 commits into
masterfrom
bump-min-tmux-000
Draft

tony wants to merge 15 commits into
masterfrom
bump-min-tmux-000

Conversation

@tony

@tony tony commented Oct 17, 2026 •

Copy link
Copy Markdown
Member

Require tmux 3.3a before workspace imports, callbacks, scripts, or shell setup. The version check covers the selected daemon, or the executable for a cold socket, so a newer client cannot authorize an older server. Direct builder and freezer entries check their supplied target's server.

Version check failures produce a nonzero CLI error. Help, version information, diagnostics, and workspace conversion remain usable without tmux; diagnostics record unavailable queries without starting a daemon. Documentation and CI use the same minimum, with 3.2a and 3.3 retained as refusal lanes.

The package requires libtmux~=0.63.0, the first series with the libtmux._internal.support module tmuxp now imports; ~=0.62.0 was satisfied by the released 0.62.0, which has no backend, and would have excluded 0.63. Until that release exists the lock pins libtmux's hook-free, cached version-check head (f6e4630a). tmuxp has no version probe of its own; the version check delegates to libtmux, and a builder checks its server once per build rather than on every window and pane hook.

Merge and release order: libtmux 0.63.0 is released first, from #779 and #780. This PR requires libtmux~=0.63.0, which no installer can satisfy until then, so it merges only after that release, in the same change that drops the development [tool.uv.sources] pin. Nothing in this PR tags or releases. Use uv sync --locked until the matching registry release pair is published. Individual optional operations receive their own requirements in the optional-operation policy.

Validation:

  • Full suites on tmux 3.3a and 3.7d each report 925 passes and two skips. Native 3.2a and 3.3 cases prove refusal before imports and effects, including cold sockets and supplied targets.
  • A built wheel with libtmux 0.61 refuses before custom imports while help works. Installed-pair checks use the immutable dependency without PYTHONPATH.
  • Formatting, lint, mypy, the documented docs build, and wheel/sdist builds pass. Strict docs retain the existing baseline warnings.

All eight hosted tmux cells pass at the final core head 44da4788 (run), after the pin moved to the renamed version-check module: six supported cells from 3.3a through master and the two unsupported-release refusal cells. The negative jobs initially stopped at locked installation because their environment omitted the lockfile's three-day dependency cutoff. The narrow workflow follow-up supplies that same cutoff: an isolated install fails without it and succeeds with it, leaving the lockfile unchanged. Both local refusal lanes also pass their 12 cases. The previous head's hosted run also passed. The version check module passes locally against the new pin; a build of two windows and three panes checks its server exactly once, and checking on every hook again fails that test. The plugin's tmux version and debug-info no longer call the deprecated libtmux.common version helpers.

Closes #1090.

tony added 7 commits October 17, 2026 02:12
The workspace version check depends on the coordinated libtmux source. Select the immutable libtmux 0.62 source through uv and its lockfile.
The pinned libtmux narrows the constructor of its missing-object exception to a typed query keyword. Forward that keyword from SessionMissingWorkspaceException instead of arbitrary keywords, so the workspace exception keeps constructing against the new contract.
why: A current executable can connect to an older daemon. Workspace
imports and callbacks must wait until the selected endpoint qualifies.

what:
- Check the backend and actual endpoint before external code or effects
- Honor the server of a supplied session or window at direct entries
- Report version check failures without changing existing lookup errors
- Keep help, conversion and diagnostics usable without a checked tmux
- Test old daemons, cold executables, supplied targets and import order
why: Upgrading an executable does not upgrade a running daemon.
Users need the endpoint requirement and coordinated installation path.

what:
- Document tmux 3.3a including its patch letter across support surfaces
- Explain source-pinned installation and daemon replacement behavior
- Describe diagnostic errors, scripts and readiness boundaries
why: Existing workspaces may still target a daemon below the new
minimum after the executable has been upgraded.

what:
- Describe saving sessions and restarting or selecting a fresh daemon
- Explain locked source installation and configuration-only commands
why: Supported operation coverage starts at 3.3a while older releases
still need proof that the version check stops before imports and callbacks.

what:
- Retain the floor, modern and master operation lanes
- Build 3.2a and 3.3 for focused negative version tests
why: The endpoint minimum changes loading, freezing and shell usage.
Release notes must identify the transition and the migration route.

what:
- Record the concrete before and after tmux requirements
- Explain endpoint refusal and commands available without tmux
@codecov

codecov Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 81.42857% with 13 lines in your changes missing coverage. Please review.
✅ Project coverage is 82.44%. Comparing base (fa1bd94) to head (44da478).
⚠️ Report is 10 commits behind head on master.

Files with missing lines Patch % Lines
src/tmuxp/cli/debug_info.py 67.64% 9 Missing and 2 partials ⚠️
src/tmuxp/util.py 84.61% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1092      +/-   ##
==========================================
- Coverage   82.55%   82.44%   -0.11%     
==========================================
  Files          31       31              
  Lines        2768     2826      +58     
  Branches      518      525       +7     
==========================================
+ Hits         2285     2330      +45     
- Misses        346      357      +11     
- Partials      137      139       +2     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

why: Locked refusal lanes lost the global three-day cutoff in CI,
     so dependency sync failed before reaching native version tests.

what:
- Set UV_EXCLUDE_NEWER to the lockfile span for both refusal lanes.
- Preserve the immutable dependency resolution and locked install.
tony added 6 commits October 17, 2026 03:48
Move the coordinated libtmux source pin to the revision whose version probe
uses run-shell -C instead of display-message, so no user hook fires before a
refusal. tmuxp has no version probe of its own: the version check delegates to
libtmux's support module. uv.lock changes only the two rev references.
`libtmux~=0.62.0` was satisfied by the released 0.62.0, which has no version-check
module, and a 0.63 release would have been excluded by the compatible-release
range, so no release could satisfy both. libtmux 0.63 is the series that
carries libtmux._internal.support, so require `~=0.63.0`. The `[tool.uv.sources]` git
pin stays as the development path until libtmux 0.63.0 is released and moves
to libtmux's version-check head (f6e4630a1). uv.lock changes only the two
rev references and `uv lock --check` passes.

Release order: libtmux 0.63.0 first, then drop the source pin here.
util._require_backend probed libtmux._internal.support and an integer policy
marker through importlib. Import libtmux._internal.support instead and check
the selected daemon with server_version(); a libtmux without the module is
refused before custom code runs. The workspace builder also ran the version
check on every window, pane and option hook; it now checks a server once per
builder and checks again only when a direct entry supplies a different one,
which keeps the guarantee that a supplied session or window of an older daemon
is refused before any callback.

Tests: the missing-backend test hides libtmux._internal.support; a build of two
windows and three panes checks its server exactly once. Checking on every hook
again makes the second test see six extra checks. The version check module
passes (20 cases) with the native 3.2a lane; ruff and mypy are clean.
Describe the dependency as libtmux 0.63 or newer, the development pin as
temporary, and the order: release libtmux first, then drop the source pin and
merge this change.
State that this release requires libtmux 0.63 or newer and that a checkout
installs with uv sync --locked until that release exists. Keep the migration
note separate from runtime changes.
Add the Minimum libtmux entry in the repository's usual form and note the
once-per-build version check. Keep the release note separate from runtime changes.
@tony
tony force-pushed the bump-min-tmux-000 branch from 6d89492 to bfab78b Compare October 17, 2026 12:40
why: libtmux.common.get_version() now warns with DeprecationWarning because it
reads the client executable, not the daemon a Server talks to.
what:
- Build the plugin's tmux version from server_version(Server()), stripping
  letter suffixes as get_version() did
- Reach libtmux's version check through the guarded backend import
@tony
tony force-pushed the bump-min-tmux-000 branch from bfab78b to 44da478 Compare October 17, 2026 17:56

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Require tmux 3.3a for core operations

1 participant