Skip to content

fix(app): anchor revealed tools under the sticky headers - #53832

Merged
Hona merged 4 commits into
anomalyco:v2from
Hona:reveal-scroll
Oct 8, 2026
Merged

Hona merged 4 commits into
anomalyco:v2from
Hona:reveal-scroll

Conversation

@Hona

@Hona Hona commented Oct 8, 2026 •

Copy link
Copy Markdown
Member

Picking a shell in the N running menu opens its Used group and the shell, then scrolls to it. When the group was far above or taller than the screen, the shell landed off-screen.

Before After

Why it missed

revealPart aimed at the wrong thing at the wrong time:

  • It centered the whole group row, not the shell. A 43-tool group is taller than the viewport, so its center is far from the shell.
  • scrollToIndex aims once. The group expands, the shell loads output, and rows above get measured after that, so the target moved after the scroll ended.

Fix: anchor the shell's top edge

The shell's top edge is the one stable point: its own growth (expanding, streaming output) extends downward. The reveal sets a scroll anchor on it, the same idea as CSS scroll anchoring, but for a tool inside a virtualized row.

flowchart TD
  R[reveal] --> B["batch: open group + shell, anchor = row key + part ID"]
  B --> M["rangeExtractor keeps the anchored row rendered → shell is in the DOM now"]
  M --> Z["resizeItem(row, offsetHeight) → timeline has its opened height now"]
  Z --> U[onUnpin] --> P[pinAnchor]
  RO["any row size commit (ResizeObserver → resizeItem batch)"] --> P
  P --> S["scroll so shell top = its scroll-margin-top"]
  X["wheel · touch · pointer · scroll key · scrollbar · other navigation · pinned"] --> REL[release anchor]
Loading
  • Synchronous first jump. The anchored row is forced into the virtualizer range, like the active message row already is. Changing rangeExtractor re-runs solid-virtual's setOptions computed, so the shell renders in the same tick, wherever it is.

  • Real geometry before aiming. Until its ResizeObserver delivers, the opened row keeps its collapsed size. The timeline may not scroll at all yet (unpin() ignores a timeline that cannot scroll) or ends above the shell. Committing the measured size first fixes both:

    const opened = virtualContent?.querySelector<HTMLElement>(`[data-index="${found.index}"]`)
    
    if (opened) resizeItem(found.index, opened.offsetHeight)
    input.onUnpin()
    pinAnchor()
  • Event-driven, not timed. Every committed row size change re-pins the anchor in the resizeItem microtask, before paint. It covers rows above being measured and siblings above the shell inside the group growing.

  • Reaching the end does not resume following. Aiming at a shell near the end lands on the end of the timeline. handleListScroll would treat that as "follow new content again", and the next streamed part would scroll the shell away:

    if (maxScroll <= 1 || (atEnd && arrived && !rendering.anchor)) input.onPin()
  • Released by intent. User scroll input, other navigation (prepareNavigation), or any explicit pin (for example, a session switch) releases it. The anchor never fights the user.

  • Where "top" is. scroll-margin-top: var(--sticky-accordion-top) on tool-part-wrapper. The page header and the stuck Used N header already set that variable, so the shell lands just under them, not behind them.

Route reveals (picking the parent's shell from inside a subagent) use the same path.

@Hona
Hona requested a review from Brendonovich as a code owner October 8, 2026 01:39
Copilot AI balanced review requested due to automatic review settings October 8, 2026 01:39

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@Hona
Hona enabled auto-merge (squash) October 8, 2026 01:47
@Hona
Hona disabled auto-merge October 8, 2026 01:48
@Hona Hona changed the title fix(app): land revealed tools under the sticky headers fix(app): anchor revealed tools under the sticky headers Oct 8, 2026
@Hona
Hona enabled auto-merge (squash) October 8, 2026 02:26
@Hona
Hona disabled auto-merge October 8, 2026 02:48
@Hona
Hona merged commit 3b684ac into anomalyco:v2 Oct 8, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants