@@ -36,43 +36,61 @@ _Future release notes will be placed here_
3636
3737### Features
3838
39- - Control-mode–first engine protocol (experimental): adds structured command results,
40- notification parsing (layout changes, unlinked windows, client detach/session change,
41- session rename, paste-buffer events), and stats while keeping existing
42- ` Server/Session/Window/Pane.cmd ` return type (` tmux_cmd ` ) stable. (#605 )
43- - Control mode engine's internal connection session is now automatically filtered from
44- ` Server.sessions ` and ` Server.has_session() ` , making engine choice transparent to
45- users. Advanced users can access all sessions via ` Server._sessions_all() ` . (#605 )
46- - ` ControlModeEngine ` accepts optional ` internal_session_name ` and ` attach_to `
47- parameters for advanced session management scenarios. (#605 )
48- - ` Server.connect() ` : New convenience method for session management. Returns an
49- existing session if found, otherwise creates a new detached session. Simplifies
50- common session reuse patterns and works transparently with both subprocess and
51- control-mode engines.
52- - Control-mode diagnostics: bounded notification queue with drop counting,
53- richer exceptions (` ControlModeTimeout ` , ` ControlModeProtocolError ` ,
54- ` ControlModeConnectionError ` , ` SubprocessTimeout ` ), and documented retry/timeout
55- behaviour. Control sandbox pytest fixture provides a hermetic control-mode server
56- for integration tests.
39+ #### Control mode engine (experimental) (#605 )
40+ - Control-mode–first engine stack with structured ` CommandResult ` , notification parsing
41+ (%layout-change, unlinked window add/close/rename, client session change/detach, paste buffer),
42+ and stats, while keeping the public ` cmd ` API returning ` tmux_cmd ` .
43+ - Internal control session is automatically filtered from ` Server.sessions ` /
44+ ` Server.has_session() ` ; advanced users can inspect all sessions via
45+ ` Server._sessions_all() ` .
46+ - ` ControlModeEngine ` accepts ` internal_session_name ` (default ` libtmux_control_mode ` )
47+ and ` attach_to ` for advanced connection strategies.
48+
49+ Example:
5750
58- ### Compatibility
51+ ``` python
52+ from libtmux._internal.engines.control_mode import ControlModeEngine
53+ from libtmux.server import Server
54+
55+ engine = ControlModeEngine(command_timeout = 5 )
56+ server = Server(engine = engine)
57+ session = server.new_session(session_name = " ctrl" )
58+ for notif in engine.iter_notifications(timeout = 0.1 ):
59+ print (notif.kind, notif.data)
60+ ```
5961
60- - Control mode's internal session is now automatically filtered from user-facing APIs.
61- Code that previously filtered ` libtmux_control_mode ` manually can be simplified.
62- APIs remain unchanged for tmux command return objects; new metadata is attached for
63- advanced users. (#605 )
64- - ` -e KEY=VAL ` environment propagation for ` new-session ` , ` new-window ` , and
65- ` split-window ` requires tmux 3.2 or newer. Older tmux versions ignore ` -e ` ; libtmux
66- logs a warning and skips env-specific tests in that configuration.
67- - Control-mode ` capture-pane ` trims trailing whitespace-only lines to align with
68- subprocess behaviour; explicit range flags (` -S/-E ` ) remain exact.
62+ #### Convenience APIs (#605 )
63+ - ` Server.connect() ` returns an existing session or creates a new detached one,
64+ working with both subprocess and control-mode engines.
6965
70- ### Testing
66+ #### Diagnostics and resilience (#605 )
67+ - Bounded notification queue with drop counting; exposed via engine stats.
68+ - Expanded exceptions: ` ControlModeTimeout ` , ` ControlModeProtocolError ` ,
69+ ` ControlModeConnectionError ` , ` SubprocessTimeout ` ; documented retry/timeout behaviour.
70+ - Control-mode capture-pane trims trailing whitespace-only lines to mirror subprocess
71+ semantics; first capture after send-keys briefly retries to avoid prompt races.
72+
73+ #### Testing utilities (#605 )
74+ - Control sandbox fixture provides a hermetic control-mode tmux server (isolated HOME,
75+ TMUX_TMPDIR, unique socket); handy for integration-style tests.
76+ Example:
77+
78+ ``` python
79+ @pytest.mark.engines ([" control" ])
80+ def test_control_sandbox (control_sandbox ):
81+ with control_sandbox as server:
82+ out = server.cmd(" display-message" , " -p" , " hi" )
83+ assert out.stdout == [" hi" ]
84+ ```
85+
86+ ### Compatibility
7187
72- - ` uv run ruff check . --fix --show-fixes `
73- - ` uv run ruff format . `
74- - ` uv run mypy `
75- - ` uv run py.test `
88+ - Control mode internal session filtering is engine-driven; callers no longer need
89+ to manually exclude ` libtmux_control_mode ` . APIs stay unchanged; additional metadata
90+ is attached for advanced users. (#605 )
91+ - ` -e KEY=VAL ` propagation for ` new-session ` , ` new-window ` , ` split-window ` requires
92+ tmux 3.2+. Older tmux ignores ` -e ` ; libtmux warns and env-specific tests skip in
93+ that configuration. (#605 )
7694
7795## libtmux 0.47.0 (2025-11-01)
7896
0 commit comments