# libtmux_mcp.tools.pane_tools.wait_for_text

- **Module:** libtmux_mcp.tools.pane_tools
- **Package:** libtmux-mcp
- **Language:** Python
- **Kind:** function
- **Source:** https://github.com/tmux-python/libtmux-mcp/blob/4daddc0dfca96c43bf521d818bf91564e1434760/src/libtmux_mcp/tools/pane_tools/wait.py#L455
- **Page:** https://libtmux.org/en/py/stable/mcp/reference/libtmux_mcp-tools-pane_tools-wait_for_text/

```
libtmux_mcp.tools.pane_tools.wait_for_text(
    patterns: list[str] | None = None,
    stop: list[str] | None = None,
    regex: bool = False,
    pane_id: str | None = None,
    session_name: str | None = None,
    session_id: str | None = None,
    window_id: str | None = None,
    timeout: float = 8.0,
    interval: float = 0.05,
    match_case: bool = False,
    socket_name: str | None = None,
    ctx: Context | None = None,
) -> WaitForTextResult
```

Wait for NEW output in a tmux pane, then return.

Polls until one of ``patterns`` appears on a line written *after*
this call starts, one of ``stop`` appears (immediate failure exit),
or the timeout expires. Pass ``patterns=null`` to wait for any new
output at all. Use this instead of polling ``capture_pane`` in a
loop.

Pre-existing scrollback is never matched, and neither is paint left
below the cursor at entry — only rows written after the call began
count. If a pattern was already on screen the result says so via
``matched_at_entry``.

**Last resort: reserve for output you did not author.** Commands
you send are AUTHORED — use ``run_command`` (returns exit status)
or compose [`; tmux wait-for -S <channel>`](/en/tmux/latest/manual/wait-for/) with ``wait_for_channel``
instead, both cheaper and exact. For unattributable recurring
prompts or background log lines, bracket your own command with a
unique sentinel (``cmd; echo __WAIT_$RANDOM__``) and wait for that.

``stop`` is the cheap way to avoid burning the whole budget: pass
the failure markers you already know (``"error:"``, ``"FAILED"``,
``"Traceback"``) and a failed run returns in milliseconds instead
of at the ceiling.

The server caps ``timeout``. An over-large value is not an error —
the wait returns at the ceiling and reports ``effective_timeout``.

### Notes

**Matching happens in Python, never in tmux.** Patterns are never
interpolated into a tmux format string: tmux's format parser treats
``#`` and ``}`` structurally, so an ordinary regex quantifier
corrupts field parsing and a pattern ending in ``#`` swallows the
rest of the format. Only fixed literal formats reach tmux.

**Every tmux call is timeout-bounded.** Reads are spawned with
``asyncio.create_subprocess_exec`` and bounded against the wait's
own deadline, rather than going through libtmux's untimed
``Popen.communicate()``. Nothing in this path runs on a worker
thread, so a wedged tmux server can neither pin the event loop nor
hang interpreter shutdown.

**Alternate screen / pagers suppress matching.** Inside ``less`` or
any full-screen program, [`capture-pane`](/en/tmux/latest/manual/capture-pane/) returns the program's
painted rows, so matching them would report text the program had
already drawn. Matching is skipped for as long as the alternate
screen lasts and the result comes back as ``alternate_screen``
rather than ``timeout`` — read the screen, don't retry the wait.

**Scrollback rollover detection is partial.** The tool raises when
``hsize`` shrinks below the entry value ([`clear-history`](/en/tmux/latest/manual/clear-history/), and any
rollover whose dip is observable between polls). It does not
reliably detect ``grid_collect_history`` trim during continuous
output; a runtime ``ctx.warning`` fires when sampled state enters
the trim-risk band. Use ``wait_for_channel`` when correctness
matters more than convenience.

## Parameters

- `patterns` (`list[str] | None`): Success patterns; the first one to match ends the wait.
Literal text unless ``regex=True``. Omit or pass ``null`` to
wait for any new output.
- `stop` (`list[str] | None`): Failure patterns. A hit ends the wait immediately with
``outcome="stopped"`` and ``found=false``; ``matched_index``
says which entry fired.
- `regex` (`bool`): Interpret ``patterns`` and ``stop`` as regular expressions.
Default False (literal text).
- `pane_id` (`str | None`): Pane ID (e.g. '%1').
- `session_name` (`str | None`): Session name for pane resolution.
- `session_id` (`str | None`): Session ID (e.g. '$1') for pane resolution.
- `window_id` (`str | None`): Window ID for pane resolution.
- `timeout` (`float`): Requested seconds to wait. Default 8.0. Clamped by server
policy; see ``effective_timeout`` in the result.
- `interval` (`float`): Seconds between polls. Default 0.05 (50ms). Minimum 0.01.
- `match_case` (`bool`): Whether to match case. Default False (case-insensitive).
- `socket_name` (`str | None`): tmux socket name.
- `ctx` (`Context | None`): FastMCP context; when injected the tool reports progress to the
client. Omitted in tests.

## Returns

WaitForTextResult
    Match outcome, a bounded tail of what the pane printed, and the
    timeout actually enforced.
