feat: Add Non-polling Waiters (Deterministic Channels & Delta-Polling)
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 38/100
Research direction
Start by reading the linked libtmux-mcp implementations in wait_for_tools.py and pane_tools/wait.py, then inspect libtmux's Server, Pane, and ControlMode entry points. Done means defining and validating both proposed waiter APIs, including channel timeouts and absolute-grid delta matching, while treating the Control Mode listener as future scope.
Written by the indexing model from the issue text.
Description
As libtmux has evolved with the 0.57.0 "Neo" ORM parity, we've solved the N+1 problem for object hydration. However, synchronizing with terminal output still largely relies on client-side loop polling via capture_pane().
We propose introducing a two-tier waiter system modeled after the patterns battle-tested in libtmux-mcp. This brings "Wait, Don't Poll" semantics natively to libtmux.
1. Best-of-Breed: Deterministic Channel Sync (Server.wait_for_channel)
For commands where the user controls the execution, we should avoid scraping scrollback entirely and rely on tmux's native OS-level IPC blocks.
- The Concept: Bracket shell commands with
tmux wait-for -S <channel>and block thelibtmuxclient until the signal fires. - libtmux-mcp Prior Art: See
wait_for_tools.pywhich implementswait_for_channelviasubprocess.run(timeout=timeout). - tmux Internals: This leverages tmux's
cmd-wait-for.c(tmux/tmux@18ddda4), allowing the Python thread to sleep completely until tmux wakes it. - Proposed API:
pane.send_keys("pytest; tmux wait-for -S tests_done") server.wait_for_channel("tests_done", timeout=60.0)
2. Intelligent Fallback: Delta Polling (Pane.wait_for_text)
When observing third-party output (where we can't inject a signal), we must poll. However, naive capture_pane loops often match stale screen paint. We need Absolute Grid Anchoring.
- The Concept: At entry, snapshot the grid's absolute baseline (
history_size + cursor_y). On each tick, capture only the rows below this absolute anchor to ensure we strictly match new text. - libtmux-mcp Prior Art: See
pane_tools/wait.pyfor the anchor math and scrollback limit protections. - tmux Internals: This approach is grounded in how tmux defines the grid (see
format_cb_history_bytesandformat_cb_history_sizeinformat.cat 3.2a). It ensures compatibility withgrid_collect_historyandclear-historyshifts. - Proposed API:
# Under the hood, this will use Neo-style batch hydration # to fetch `#{history_size}|#{cursor_y}` in a single IPC turn. pane.wait_for_text("READY", timeout=8.0)
3. Future Scope: Control Mode Listener
A long-term architectural goal could involve spawning a background tmux -C client (as currently used in libtmux testing via ControlMode) to listen for %output or %pane-mode-changed streams, offering a completely event-driven API.
- Dominant language
- Python
- Stars
- 1.2k
- Forks
- 127
- Avg merge
- 2h 13m
- Merged PRs (30d)
- 1
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from tmux-python/libtmux
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
tmux-python/libtmux#759 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
tmux-python/libtmux#745 · 2 comments ·
-
enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
tmux-python/libtmux#744 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
tmux-python/libtmux#731 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
tmux-python/libtmux#654 ·
All issues in tmux-python/libtmux
Similar issues
-
documentation help wanted
Difficulty 2/5 1-3 hours Newbie friendliness 90/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 90/100
simonw/sqlite-utils#872 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100