Skip to content

refactor(tui): persist group expansion and exact scroll anchors - #48489

Merged
jlongster merged 3 commits into
v2from
tree-navigation
Sep 23, 2026
Merged

jlongster merged 3 commits into
v2from
tree-navigation

Conversation

@jlongster

@jlongster jlongster commented Sep 11, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Refactored to the agreed exact-target model:

  • Scroll anchors identify a PartRef or group ID, plus a screen offset. Whole non-assistant messages use a canonical UI body PartRef.
  • Group IDs derive from the first descendant’s message ID + part ID + group kind + nesting level (top level is 0). No projection-owned identity reconciliation.
  • Tabs retain each session’s anchor and group expansion state in memory, clearing them on tab close.
  • Recursive group views render from saved expansion state, then register actual parts and group headers.
  • No automatic expansion, reveal flag, reveal loop, depth-ranked candidates, or group-as-message fallback.
  • Expansion/collapse saves state immediately and updates the anchor after layout.
  • Restoration locates the exact mounted target and applies its offset; existing bottom-padding support preserves offsets in short transcripts.

Fetching and boundary completion are explicitly deferred to the next PR. A change to the first member changes the group ID; unavailable targets use the existing missing-anchor fallback.

Verification

  • TUI typecheck passes
  • Full TUI suite: 1368 passed, 4 skipped, 0 failed
  • Final focused anchor/group/tab tests: 45 passed
  • 201/201 baseline screenshot pairs match for the existing presentation (84 grouped, 84 ungrouped, 33 disclosure states)
  • Tests cover composite PartRef keys, canonical message refs, deterministic group IDs, append/prepend behavior, replacement cleanup, nested expansion retention and exact target geometry
  • Full-app tests cover no automatic expansion, closed-summary restoration, retained expanded state, offsets within later parts of a message, and short transcripts at 48/80/120-column coverage
  • Drive explicitly verified no automatic expansion, manual expansion, tab switching and restored expanded/collapsed states with exact offset preservation

Updated implementation: b087728684. Local work log: /tmp/opencode/grouped-timeline-work-log.md. Final demo captures: /tmp/opencode/anchor-state-fixed/run-6c96b6e1-b9da-45fd-a3c0-a64f74ebc586/generation-0/ (copying to /mnt/mail currently hangs).

@jlongster jlongster changed the title refactor(tui): render nested groups with message anchors refactor(tui): persist group expansion and exact scroll anchors Sep 11, 2026
@jlongster

Copy link
Copy Markdown
Contributor Author

Rebased onto latest v2 (3584eca0eb). Resolved conflicts were the upstream theme-token renames (default→base, subdued→muted, raise(surface.offset)→decrease(raised.base)) and the removed preview-tab mechanism in session-tabs.tsx.

Deterministic pixel comparison: v2 vs this branch

Built a new Drive fixture with 9 dense sessions (mixed thought/tool messages, groups spanning messages, tools between groups, failures inside groups, 18-tool exploration runs, 9-thought runs, generic/web/execute tools, notices + compaction, and a 14-turn history that exercises tail-first backfill). Both builds run the identical script; the only variable is the checkout.

Profile Frames Identical
Grouped, thinking hidden — 3 widths × top/bottom + sequential disclosure clicks 88 88
Ungrouped, thinking shown — 3 widths × top/bottom 54 54

142/142 pixel-identical. Full RGBA comparison, no masks or tolerances.

Two earlier runs showed divergent frames in the two longest sessions; investigating each showed same content at a different scroll offset — the harness's "settled" check was passing mid-backfill after ctrl+g. Tightened the harness to pin the session title to the top before every click. No code change was needed; the divergence did not reproduce once the harness was deterministic.

Added session-backfill-disclosure.test.tsx to lock in the one scenario the earlier matrix never combined: clicking a thought group that was mounted by backfill.

Full TUI suite on the rebased branch: 1367 pass, 2 skip, 0 fail. Typecheck passes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant