Wait for channel

tmux’s wait-for command exposes named, server-global channels that clients can signal and block on. These give agents an explicit synchronization primitive — strictly cheaper in agent turns than polling pane content via capture_pane or wait_for_text.

The composition pattern: send_keys a command followed by ; tmux wait-for -S NAME, then call wait_for_channel. Shell ; semantics fire the second statement whether the first succeeds or fails, so the edge-triggered signal never deadlocks the agent on a crashed command.

send_keys(
    pane_id="%1",
    keys="pytest; tmux wait-for -S tests_done",
)
wait_for_channel("tests_done", timeout=60)

The ; tmux wait-for -S NAME suffix is the load-bearing safety contract — wait-for is edge-triggered, so a crash before the signal would deadlock until the wait’s timeout. The shell separator ; runs the next statement unconditionally, so the signal fires on both success and failure paths.

The payload deliberately does not append exit $? — in an interactive shell that exits the shell itself, taking single-pane sessions down with it. If exit-status preservation matters, capture the status out-of-band (e.g. write it to a file the agent reads later, or use a dedicated scratch pane).

wait_for_channel

wait_for_channel
mutating tool
mutating tool
wait_for_channel

Block until a tmux wait-for channel is signalled.

Returns:

str

Use when the shell command can reliably emit the signal (single test runs, build scripts, dev-server boot, anything composable with ; tmux wait-for -S name).

Avoid when the signal cannot be guaranteed — for example, when the command might be killed externally. Use wait_for_text to poll for an output marker instead; state-polling is structurally safer than edge-triggered signalling for fragile commands.

Side effects: Blocks the call up to timeout seconds (default 30). Mandatory subprocess timeout — a crashed signaller raises an ExpectedToolError rather than blocking indefinitely.

Parameters

Parameter

Type

Required

Default

Description

channel

str

yes

Channel name. Must match ^[A-Za-z0-9_.:-]{1,128}$.

timeout

float

no

30.0

Maximum seconds to wait. The underlying tmux wait-for has no built-in timeout — this wrapper enforces it via subprocess.run(timeout=...). Defaults to 30 seconds.

socket_name

str

no

tmux socket name.