Skip to content

wait_for_content_change: surface pane death and respawn as ToolError for parity with wait_for_text #53

@tony

Description

@tony

Type: enhancement · Tier: deferred · Tool: wait_for_content_change

Problem

wait_for_text raises ToolError when the pane dies (#{pane_dead}=1), is respawned (#{pane_pid} changes), or has its history shrunk (clear-historyhistory_size drops below entry baseline). wait_for_content_change does none of this — it polls capture_pane() until content differs or timeout. If the pane dies mid-wait, the tool returns changed=False after the full timeout instead of surfacing the lifecycle event.

An agent using wait_for_content_change to confirm "the pane is doing something" has no signal that the underlying process has exited or been swapped. Same footgun the wait_for_text lifecycle detection was added to address — different tool, identical mechanism.

Proposed fix

Read a small per-tick state snapshot via one display-message round-trip:

"#{pane_pid}|#{pane_dead}"

Cache baseline_pid at entry. Re-read each tick. Raise ToolError on:

  • state.pane_dead == True — "pane {pane_id} died during wait" (same message/shape as wait_for_text)
  • state.pane_pid != baseline_pid — "pane {pane_id} was respawned during wait (pid X -> Y)"

No baseline-anchor math needed. wait_for_content_change's "any change anywhere" semantics are unaffected — the lifecycle check is orthogonal to the capture-diff comparison the tool already does.

Source pointers at tmux SHA 134ba6c

  • #{pane_dead} and #{pane_pid} are stable format strings (see format.c)
  • Same detection path wait_for_text already uses — verified via test_wait_for_text_raises_on_pane_death and test_wait_for_text_raises_on_pane_respawn

Trade-offs

  • Adds one display-message round-trip per tick to wait_for_content_change (currently the tool issues only capture_pane per tick). The cost is symmetric with wait_for_text — same number of subprocesses per poll.
  • Adds two regression tests (death + respawn) mirroring the existing wait_for_text ones.

Recommendation

Defer until an agent flow asks for it OR a small refactor opportunistically lands the parity. Filed as a deferred enhancement so the inconsistency doesn't get lost. The downstream wait_for_text PR documents the gap by analogy; this issue is the standalone tracking point.

Why this is non-duplicative

Cross-checked against the deferred wait-family issues (#50, #51, #52) and libtmux #671:

None of those address wait_for_content_change lifecycle parity.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions