Skip to content

harness: enqueue follow-up does not scroll so the new queued row is visible #696

Description

@btipling

Summary

Enqueueing a follow-up while Busy (▶ / Ctrl+Enter) does not bring the new queued row into view. The composer may clear, but the canvas stays where it was, so it looks like the send was a no-op.

Idle send already follows: a new user row lands in the transcript and stick-to-bottom runs. Queue appends have no equivalent follow.

Observed

  1. Start a turn so the harness is Busy.
  2. Scroll the transcript up (or already have 3+ items in the queue band).
  3. Type a follow-up and ▶ / Ctrl+Enter.

Actual: composer text disappears (or stays if the queue is full). No new transcript row. The queue band either appears off the operator’s focus at the bottom chrome, or the new FIFO row sits below the 3-row window. Nothing in the scrolled view changes.

Expected: the newly queued item is on-screen — same “I sent something” feedback as idle send.

Likely seam

Submit-queue band (native/harness/src/ui/queue_band.zig, plan #664):

  • Rows paint FIFO 0..n-1 (newest last).
  • Band height is header + min(n, QUEUE_BAND_MAX_ROWS) (QUEUE_BAND_MAX_ROWS = 3). Extra rows live in state.queue_list_scroll.
  • Nothing calls scroll.scrollToBottom(&state.queue_list_scroll) on enqueue. Item 4+ is appended below the visible window.

Transcript stick-to-bottom (native/harness/src/ui.zig, plan #135 / #131 / #251) only follows user_sent / hydrate / near-bottom. Enqueue does not change msg_count, so a scrolled-up transcript never moves. The band is outside the transcript scroller (above the composer); if the operator’s eyes are on old messages, the only tell is a cleared composer.

Full-queue reject already paints · full in EMBER (#666). The empty “nothing happened” case is a successful enqueue with no follow.

Goal

  • After a successful enqueue, the new queue row is visible without the operator hunting for it.
  • At minimum: queue_list_scroll follows the newest row when n > QUEUE_BAND_MAX_ROWS.
  • Also worth doing: treat enqueue like send for transcript follow (scroll the transcript to bottom) so attention is at the live turn + queue chrome. Idle send already does this for user_sent.
  • Failed enqueue (blank / full) must stay a no-op on scroll — composer text stays, · full is the signal.

Non-goals

  • Putting queued text into the transcript ring (FIFO stays Wasm-ephemeral, above the composer).
  • Changing QUEUE_BAND_MAX_ROWS / MAX_ITEMS (16).
  • Auto-promote / drain behavior.

Related

  • native/harness/src/ui/queue_band.zig — list + queue_list_scroll, no follow on append
  • native/harness/src/ui/state.zigqueue_list_scroll
  • native/harness/src/ui/scroll.zigscrollToBottom (used for transcript only)
  • native/harness/src/ui.zig — stick-to-bottom; user_sent does not include enqueue
  • native/harness/src/ui/composer.zigsubmitOrEnqueueenqueueFromUi
  • docs/harness-limits.md — Submit queue: compact list, extra rows scroll

Suggested next: enqueue a 4th item with the list scrolled to the top; then enqueue the first item of a turn while the transcript is scrolled up. Both should leave the new row on-screen.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingharnessHarness / agent UIui

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions