Skip to content

wait_for_text: optional include_baseline_row=True for in-place row writes #51

@tony

Description

@tony

Type: enhancement · Tier: deferred · Tool: wait_for_text

What's happening

wait_for_text deliberately skips the cursor row at entry via:

start_line = baseline_abs - state.history_size + 1

The + 1 avoids false-matching the row the cursor sat on at entry — typically the prompt line that contains the typed command echo (which already includes the pattern as a substring). This is the documented "same-row blind spot."

But this means several common CLI output shapes are invisible to the wait:

  • printf OK (no trailing newline — stays on the cursor row)
  • \\r-progress updates and spinners (rewrite the same row)
  • Single-line status redraws (cursor returns to column 0 and overwrites)
  • Some prompt redraws that paint over the prompt line

Why anchor invariance holds for the baseline row

tmux's screen_write_reverseindex only scrolls within [s->rupper, s->rlower] via grid_view_scroll_region_down, which is pure grid_move_lines — no hsize change. \\r rewriting also doesn't touch hsize. So the absolute baseline anchor (hs0 + cy0) remains pointing at the same grid row even when that row is repainted; we just don't capture it.

Proposed surface

wait_for_text(pattern=\"OK\", include_baseline_row=True)

When set, the implementation:

  1. At entry: capture the baseline row's current content (one extra capture-pane -S cy0 -E cy0).
  2. Each tick: re-capture the baseline row and diff against the entry snapshot.
  3. Match the pattern against the diff (i.e., the bytes that changed), not the whole row.

This avoids false-matching the typed echo (which is in the entry snapshot and therefore not in the diff) while picking up legitimate same-row writes.

Trade-offs

  • Adds one display-message / capture-pane round-trip at entry (small).
  • Adds row-content comparison per tick (cheap).
  • Diff predicate has to handle the wraparound case for narrow panes where the "baseline row" might itself wrap.
  • New public parameter on a stable-feeling API. Worth the surface only if real agent flows hit the limitation.

Recommendation

Defer until a real agent flow asks for it. Today the documented escape hatch is wait_for_content_change for "any change anywhere" and the sentinel pattern for "a unique marker I authored." If/when same-row writes become the question, this is the cleanest answer.

References

  • tmux reverse-index (no hsize touch): screen-write.c#L1419
  • tmux scroll-region-down (pure grid_move_lines): grid-view.c#L127
  • Current docstring of the blind spot: see wait_for_text Notes section

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions