-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCHANGES
More file actions
191 lines (145 loc) · 9.76 KB
/
CHANGES
File metadata and controls
191 lines (145 loc) · 9.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# Changelog
## libtmux-mcp 0.1.x (unreleased)
<!-- KEEP THIS PLACEHOLDER - DO NOT REMOVE OR MODIFY THIS LINE -->
_Notes on upcoming releases will be added here_
<!-- END PLACEHOLDER - ADD NEW CHANGELOG ENTRIES BELOW THIS LINE -->
### What's new
#### New tool: `respawn_pane`
Restart a wedged pane in place — preserves `pane_id` and the window layout (the alternative `kill_pane` + `split_window` invalidates pane references and rearranges the window). Required `pane_id`; optional `kill` (default true), `shell`, `start_directory`, `environment`. Refuses to respawn the MCP server's own pane, mirroring the existing `kill_*` self-guards. Annotations honestly mark it `destructiveHint=true` / `idempotentHint=false` while staying in the `mutating` tier so default-profile agents can use it for shell recovery. Audit log redacts the `shell` argument and digests `environment` values (keys stay visible). (#27)
#### New tools: `get_session_info`, `get_window_info`
Targeted single-object metadata reads — no more `list_*` + filter when you have an ID. Completes the four-level `get_*_info` hierarchy (server / session / window / pane); buffers, hooks, and options have existing read paths and are deliberately excluded. (#27)
#### New dev script: `scripts/mcp_swap.py`
Point Claude / Codex / Cursor / Gemini at a local checkout in one command. `just mcp-use-local` rewrites each CLI's global config to run the local repo via `uv`; `just mcp-revert` restores from a timestamped backup. `just mcp-detect` and `just mcp-status` report install state. Atomic writes, `--dry-run` mode, per-CLI state file, env preservation on replacement, layout-shape guard before mutating Claude's per-project config. Scope is global configs only — see `scripts/README.md`. (#27)
### Documentation
- {ref}`safety` adds a {tooliconl}`respawn-pane` "Footgun" subsection alongside {tooliconl}`pipe-pane` and {tooliconl}`set-environment`: `kill=true` default, non-idempotent retries, explicit-`pane_id` requirement, OS-process-table visibility for `shell` / `environment`. The macOS `TMUX_TMPDIR` caveat is rewritten to reflect shipped behaviour — tmux's three-step socket-path resolution is documented, so operators no longer need to set `TMUX_TMPDIR` explicitly to chase a problem that's already solved. (#27)
- LLM-facing discoverability tightened: {tooliconl}`display-message` retitled "Evaluate tmux Format String" with a docstring that leads with read-only format expansion (the tool wraps `display-message -p` but `-p` expands rather than displays), {tooliconl}`pipe-pane` leads with the `/tmp/pane.log` logging use case, and the server instructions explain why hooks are read-only and why there is no `list_buffers` tool. The `socket_name` contract is tightened to acknowledge {tooliconl}`list-servers` as the documented exception. (#27)
- Topic pages added for {tooliconl}`respawn-pane`, {tooliconl}`get-session-info`, and {tooliconl}`get-window-info`. (#27)
### API decisions (pre-release)
- {tooliconl}`respawn-pane` settles on `shell` (renamed from `shell_command`) to align with {tooliconl}`split-window` and upstream `Pane.respawn(shell=)`, and drops the `session_name` / `session_id` / `window_id` resolver fallbacks — the runtime guard rejected any call missing `pane_id` anyway. Validation now lives at the FastMCP schema boundary. (#27)
## libtmux-mcp 0.1.0a3 (2026-04-19)
_Post-0.1.0a2 smoke-test fixes and `libtmux` floor bump_
### Dependencies
- Minimum `libtmux>=0.55.1` (was `>=0.55.0`). 0.55.1 ships the
pytest-plugin socket-reaper fix
([tmux-python/libtmux#661](https://github.com/tmux-python/libtmux/pull/661))
so `libtmux_test*` daemons and socket files no longer leak under
`/tmp/tmux-<uid>/` during test runs. Downstream effect: no local
conftest reaper is needed in libtmux-mcp — the upstream fixtures
self-clean.
### Fixes
- Pane `is_caller` annotation no longer false-positives across tmux
sockets. `_serialize_pane`, `snapshot_pane`, and `search_panes` all
compared `pane.pane_id == TMUX_PANE` without verifying the caller's
socket, so a caller on socket A pane `%0` was marked `is_caller=True`
for any `%0` on any other server. The annotation now reuses
`_caller_is_on_server` (the same socket-scoped comparator used by
the self-kill guard) via the new `_compute_is_caller` helper
(#22, fixes #19).
- {tooliconl}`wait-for-channel` and {tooliconl}`signal-channel` no
longer block the FastMCP event loop. Both were sync `def` handlers
running `subprocess.run(timeout=N)` on the main loop — for the
duration of the wait the server could not service other tool calls,
MCP pings, or client cancellations. Ported to `async def` +
{func}`asyncio.to_thread`, matching the pattern already used by
{tooliconl}`wait-for-text` / {tooliconl}`wait-for-content-change`
(#21, fixes #18).
## libtmux-mcp 0.1.0a2 (2026-04-19)
_FastMCP alignment: new tools, prompts, and middleware (#15)_
### Breaking changes
- {tooliconl}`search-panes` now returns
{class}`~libtmux_mcp.models.SearchPanesResult` instead of
`list[`{class}`~libtmux_mcp.models.PaneContentMatch``]`. Matches
moved to `.matches`; new `truncated`, `truncated_panes`,
`total_panes_matched`, `offset`, `limit` fields enable pagination.
Migrate `for m in search_panes(...)` →
`for m in search_panes(...).matches`.
- Minimum `fastmcp>=3.2.4` (was `>=3.1.0`). Required for
{class}`~libtmux_mcp.middleware.ReadonlyRetryMiddleware` and
per-parameter input-schema descriptions.
### What's new
**New tools**
- Discovery: {tooliconl}`list-servers`.
- Waits: {tooliconl}`wait-for-text`,
{tooliconl}`wait-for-content-change`, {tooliconl}`wait-for-channel`,
{tooliconl}`signal-channel`. All bounded, emit
`ctx.report_progress` / `ctx.warning`, and propagate
{exc}`asyncio.CancelledError` cleanly.
- Buffers: {tooliconl}`load-buffer`, {tooliconl}`paste-buffer`,
{tooliconl}`show-buffer`, {tooliconl}`delete-buffer`.
Agent-namespaced as `libtmux_mcp_<uuid>_<name>` to prevent
collisions; leaked buffers GC'd on graceful shutdown.
- Hooks (read-only): {tooliconl}`show-hook`, {tooliconl}`show-hooks`.
- Panes / windows: {tooliconl}`snapshot-pane`, {tooliconl}`pipe-pane`,
{tooliconl}`display-message`, {tooliconl}`paste-text`,
{tooliconl}`select-pane`, {tooliconl}`swap-pane`,
{tooliconl}`select-window`, {tooliconl}`move-window`,
{tooliconl}`enter-copy-mode`, {tooliconl}`exit-copy-mode`.
**Prompt recipes**
- Four prompts: `run_and_wait`, `diagnose_failing_pane`,
`build_dev_workspace`, `interrupt_gracefully`. Set
`LIBTMUX_MCP_PROMPTS_AS_TOOLS=1` to expose them as tools for
tools-only MCP clients.
**Middleware stack**
- `TimingMiddleware`, `ErrorHandlingMiddleware`,
{class}`~libtmux_mcp.middleware.AuditMiddleware` (digest-redacted
argument summaries),
{class}`~libtmux_mcp.middleware.SafetyMiddleware` (tier-gated tool
visibility),
{class}`~libtmux_mcp.middleware.ReadonlyRetryMiddleware`
(transparent retry of readonly tools on transient
{exc}`libtmux.exc.LibTmuxException`; mutating tools never retry),
{class}`~libtmux_mcp.middleware.TailPreservingResponseLimitingMiddleware`
(trims oversized output from the head so the active prompt
survives).
**Bounded outputs**
- {tooliconl}`capture-pane`, {tooliconl}`snapshot-pane`,
{tooliconl}`show-buffer` accept `max_lines` (default 500) with
tail-preserving truncation and typed `content_truncated` /
`content_truncated_lines` signals. Pass `max_lines=None` to opt
out.
**Other**
- Tool input schemas carry per-parameter `description` fields
auto-extracted from NumPy-style docstrings.
- Lifespan startup probe fails fast with {exc}`RuntimeError` if
`tmux` is missing on `PATH`.
- {attr}`~libtmux_mcp.models.SessionInfo.active_pane_id` surfaces the
pane id returned by {tooliconl}`create-session`.
### Fixes
- {tooliconl}`search-panes` neutralizes tmux format-string injection
in the regex fast path.
- macOS `TMUX_TMPDIR` self-kill guard: resolves the server socket via
`tmux display-message #{socket_path}` before env-based
reconstruction; basename-match fallback closes the launchd
divergence gap.
- `build_dev_workspace` prompt uses the real tool parameter names
(`session_name=`, `pane_id=`, `direction=`) and no longer waits for
shell prompts after launching screen-grabbing programs (`vim`,
`watch`, `tail -f`). New `log_command` parameter replaces the
Linux-only `/var/log/syslog` default.
- `ReadonlyRetryMiddleware` retry warnings log under
`libtmux_mcp.retry`.
### Documentation
- New per-tool pages: `buffers.md`, `hooks.md`, `waits.md`,
`tools/index.md`. `panes.md` documents the `SearchPanesResult`
migration. `safety.md` covers the macOS `TMUX_TMPDIR` caveat, the
audit log, `pipe_pane`, and `set_environment`.
## libtmux-mcp 0.1.0a1 (2026-04-13)
### What's new
- New pane tools: `snapshot_pane`, `wait_for_content_change`, `select_pane`, `swap_pane`, `pipe_pane`, `display_message`, `enter_copy_mode`, `exit_copy_mode`, and `paste_text` (#11)
- New session tool: `select_window` — navigate by ID, index, or direction (#11)
- New window tool: `move_window` — reorder within a session or move across sessions (#11)
- New models: `PaneSnapshot` and `ContentChangeResult` (#11)
### Documentation
- Visual improvements to API docs from [gp-sphinx](https://gp-sphinx.git-pull.com)-based Sphinx packages (#10)
- Bump gp-sphinx docs stack to v0.0.1a8 (#14)
## libtmux-mcp 0.1.0a0 (2026-03-22)
### New features
- Initial release as standalone package
- MCP tools across 6 modules (server, session, window, pane, options, environment)
- `tmux://` URI resources for browsing tmux hierarchy
- Safety tier middleware (`readonly`, `mutating`, `destructive`)
- Socket isolation via `LIBTMUX_SOCKET` / `LIBTMUX_SOCKET_PATH` env vars
- Agent self-awareness via `TMUX_PANE` detection
- Server caching with `is_alive()` eviction
- Pydantic models for all tool outputs
- Full type safety (mypy strict)