Files
orca/src
Brennan Bensonandgsxdsm 5f845b6024 feat(native-chat): open a subagent from the agents strip (#38640)
* feat(native-chat): open a subagent from the agents strip

Clicking an agent in the strip above the composer now opens its
activity in place in the conversation: the transcript expands the
"Kicked off" list and the child's section and lands on its newest
activity. A child with no activity yet lands on its entry; one whose
spawn is older than the loaded window pages history in (abandoned by
a reader scroll, never past the latest /clear). Stop stays its own
button; command and monitor rows are unchanged.

The transcript's navigation (rail picks, diff reveals and now subagent
reveals) moves into one hook sharing one cancellable history loop.

Supersedes #38470.

Co-authored-by: gsxdsm <gsxdsm@users.noreply.github.com>

* fix(native-chat): find a rowless sibling's entry in the row its roster folds into

Siblings' roster items fold into the first sibling's row, so a later
sibling's own roster item id names a row that is never drawn; a reveal
of that agent before its first activity paged all history and landed
nothing. Resolve the drawn row naming the agent instead.

Co-authored-by: gsxdsm <gsxdsm@users.noreply.github.com>

* test(native-chat): check where a strip reveal lands

Measure the landing: the end of the child's newest drawn row reaches
the bottom of the view, past an open sibling's rows. Fails if the
reveal does not scroll, aligns the row's start, or picks the child's
first row. The reader-scroll cancel now holds a real page in flight.

Co-authored-by: gsxdsm <gsxdsm@users.noreply.github.com>

* fix(native-chat): keep an end-aligned reveal pinned while rows above it measure

The virtualizer reconciles a jump only until it holds for a frame, and
size changes are compensated only for rows wholly above the viewport.
An end-aligned reveal lands with the visible rows above its target
still at their estimates; when they measure taller, the target's end
was pushed below the view (seen in QA on a first click into a closed
roster). While an end-aligned jump is held, compensate growth in the
target and every row above it; a reader scroll ends the hold.

Co-authored-by: gsxdsm <gsxdsm@users.noreply.github.com>

* fix(native-chat): end a reveal's end pin when the reader acts on the content

The held end alignment compensated growth above its row until the next
scroll; Enter on a disclosure above the revealed row then scrolled what
the reader had just opened out of view. A key on the content now hands
the view back, as a press already did. Pin the late-measure test to the
one row it grows.

Co-authored-by: gsxdsm <gsxdsm@users.noreply.github.com>

* fix(native-chat): hold a reveal's end pin by row identity

The end pin held a slot index; a section closing or a sibling's new row
before it shifted indexes, so growth of an unrelated row could move the
view. Hold the row's key, resolve its index once per measurement pass,
and let go when the row is no longer drawn. Any key on the transcript
now releases the pin, including a cancelled Space.

Co-authored-by: gsxdsm <gsxdsm@users.noreply.github.com>

* fix(native-chat): find a held end row in one read while it stays put

The key lookup walked the measurements once per resize, so a streaming
revealed row cost work growing with the transcript every frame. Read
the held index first and scan only when rows moved before it, keeping
the found index. Pass the strip its session's tasks as one prop.

Co-authored-by: gsxdsm <gsxdsm@users.noreply.github.com>

* fix(native-chat): rebase the virtualizer target when the reader takes an end landing

Co-authored-by: gsxdsm <gsxdsm@users.noreply.github.com>

---------

Co-authored-by: gsxdsm <gsxdsm@users.noreply.github.com>
2026-11-05 22:21:28 -08:00
..