Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,20 @@ $ tmuxp@next load yoursession
_Notes on the upcoming release will go here._
<!-- END PLACEHOLDER - ADD NEW CHANGELOG ENTRIES BELOW THIS LINE -->

### What's new

#### Experimental chain builder (opt-in) (#1054)

tmuxp now registers an experimental
{class}`~tmuxp.workspace.builder.chain.ChainWorkspaceBuilder`, selectable with
`workspace_builder: chain`, that describes the whole window/pane tree in one plan
and resolves it in the fewest tmux invocations. It depends on libtmux's chain API
(libtmux#685), which is unreleased and absent from published libtmux builds, so
the builder is non-functional until that API ships: loading a workspace that
selects it raises {exc}`~tmuxp.exc.WorkspaceBuilderImportError`. The builder
module imports cleanly without the API. See {ref}`custom-workspace-builders` for
details.

## tmuxp 1.73.0 (2026-06-28)

tmuxp 1.73.0 makes the workspace build step pluggable and tunable. A workspace can now build through a third-party builder selected by registered entry-point name or Python import path, and a new `workspace_builder_options` catalog controls the pane-readiness wait per workspace. The built-in builder stays the default, so existing workspaces keep working — though the new `pane_readiness: auto` default skips the prompt wait on non-zsh shells. See {ref}`custom-workspace-builders` for the guide.
Expand Down
16 changes: 16 additions & 0 deletions docs/internals/api/workspace/builder/chain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Chain builder - `tmuxp.workspace.builder.chain`

:::{warning}
The chain builder is **experimental** and depends on libtmux's unreleased chain
API (libtmux#685). That API is absent from published libtmux builds, so
selecting `workspace_builder: chain` raises
{exc}`~tmuxp.exc.WorkspaceBuilderImportError` until it ships. The module itself
imports cleanly without the API.
:::

```{eval-rst}
.. automodule:: tmuxp.workspace.builder.chain
:members:
:show-inheritance:
:undoc-members:
```
8 changes: 8 additions & 0 deletions docs/internals/api/workspace/builder/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ The contract a builder must satisfy — `tmuxp.workspace.builder.protocol`.
Builder selection and trusted import paths — `tmuxp.workspace.builder.registry`.
:::

:::{grid-item-card} Chain builder (experimental)
:link: chain
:link-type: doc
Experimental builder over libtmux's unreleased chain API —
`tmuxp.workspace.builder.chain`.
:::

::::

```{toctree}
Expand All @@ -37,4 +44,5 @@ Builder selection and trusted import paths — `tmuxp.workspace.builder.registry
classic
protocol
registry
chain
```
21 changes: 21 additions & 0 deletions docs/topics/custom-workspace-builders.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,26 @@ covers what `tmuxp load` drives:
The contract is synchronous today. It is shaped so an async builder can be added
later as an additive extension without changing this surface.

## Experimental chain builder

tmuxp ships an experimental
{class}`~tmuxp.workspace.builder.chain.ChainWorkspaceBuilder` that describes the
whole window/pane tree in one plan and resolves it in the fewest tmux
invocations, instead of one subprocess per `new-window` / `split-window`. Select
it by name like any other registered builder:

```yaml
workspace_builder: chain
```

:::{warning}
The chain builder depends on libtmux's chain API (libtmux#685), which is
**unreleased** and absent from published libtmux builds. The builder module
imports cleanly without it, but selecting `workspace_builder: chain` and loading
the workspace raises {exc}`~tmuxp.exc.WorkspaceBuilderImportError` until that API
ships. It is non-functional today and provided as scaffolding only.
:::

## Pane readiness

tmuxp waits for a pane's shell prompt before dispatching layout and commands,
Expand Down Expand Up @@ -186,6 +206,7 @@ For builders that live in a trusted directory, build the `sys.path` sandbox with
## Reference

- {class}`~tmuxp.workspace.builder.classic.ClassicWorkspaceBuilder`
- {class}`~tmuxp.workspace.builder.chain.ChainWorkspaceBuilder` (experimental)
- {class}`~tmuxp.workspace.builder.protocol.WorkspaceBuilderProtocol`
- {func}`~tmuxp.workspace.builder.registry.resolve_builder_class`
- {class}`~tmuxp.workspace.options.PaneReadiness`
6 changes: 6 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ tmuxp = 'tmuxp:cli.cli'

[project.entry-points."tmuxp.workspace_builders"]
classic = "tmuxp.workspace.builder.classic:ClassicWorkspaceBuilder"
chain = "tmuxp.workspace.builder.chain:ChainWorkspaceBuilder"

[dependency-groups]
dev = [
Expand Down Expand Up @@ -154,6 +155,11 @@ omit = [
"pkg/*",
"*/log.py",
"docs/_ext/*",
# Experimental chain builder: its plan-building methods require the
# unreleased libtmux._experimental.chain API (libtmux#685) and cannot
# execute on released libtmux, so they are not measurable yet. Remove
# this once that API ships and the builder becomes testable.
"*/workspace/builder/chain.py",
]

[tool.coverage.report]
Expand Down
7 changes: 7 additions & 0 deletions src/tmuxp/workspace/builder/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,16 @@

``WorkspaceBuilder`` remains importable here as a backwards-compatible alias of
:class:`~tmuxp.workspace.builder.classic.ClassicWorkspaceBuilder`.

The experimental
:class:`~tmuxp.workspace.builder.chain.ChainWorkspaceBuilder` is also exported.
Its module imports cleanly even when libtmux's unreleased chain API
(libtmux#685) is absent; the missing API surfaces only when its ``build()`` runs.
"""

from __future__ import annotations

from tmuxp.workspace.builder.chain import ChainWorkspaceBuilder
from tmuxp.workspace.builder.classic import (
ClassicWorkspaceBuilder,
get_default_columns,
Expand All @@ -31,6 +37,7 @@

__all__ = [
"WORKSPACE_BUILDERS_GROUP",
"ChainWorkspaceBuilder",
"ClassicWorkspaceBuilder",
"WorkspaceBuilder",
"WorkspaceBuilderProtocol",
Expand Down
Loading
Loading