Skip to content

Full-history conversation outline for the thread TOC minimap - #399

Merged
brsbl merged 1 commit into
get-bb:mainfrom
brsbl:toc-full-history-minimap
Jun 25, 2026
Merged

brsbl merged 1 commit into
get-bb:mainfrom
brsbl:toc-full-history-minimap

Conversation

@brsbl

@brsbl brsbl commented Jun 25, 2026

Copy link
Copy Markdown
Collaborator

What & why

The table-of-contents minimap previously listed only the currently-loaded timeline window, so on a long thread it was incomplete until you scrolled older pages in. This makes it reflect the whole thread, and lets any entry jump to its message — auto-loading older pages as needed.

Builds on the recently-landed right-centered minimap + min-3-user-messages gating + near-bottom active detection (kept as-is).

How

  • New GET /threads/:id/conversation-outline — a lightweight list of every user/agent message (id, role, clamped preview, attachment counts). It reuses the same buildThreadTimelineFromEvents projection as the timeline over the full event set, so each outline item's id is identical to its timeline row's id. That identity is what makes scroll-spy highlighting and click-to-jump work. The handler memoizes per (thread, maxSeq); the client query is invalidated by the same realtime events-appended signal as the timeline window.
  • Minimap renders from the outline (falling back to the loaded window until it loads). Clicking an entry whose message isn't paginated in yet auto-paginates older pages until the row appears, then scrolls to it — bounded by a hard cap, resilient to pagination errors, and stops if you switch threads mid-jump. The tick rail is bounded + scrollable so long threads don't overflow.

Testing

  • Full-repo typecheck: all packages pass. Lint clean.
  • @bb/app: 1062 tests pass (incl. a new ThreadTableOfContents jsdom suite covering full-history rendering, attachment-only labels, jump-to-loaded, auto-paginate-to-unloaded, and the no-older-pages case — merged with the existing findActiveItemIds scroll-spy tests).
  • @bb/server: 800 tests pass (incl. a new conversation-outline integration test: a segmentLimit=1 page shows only the last turn while the outline returns all messages, ids match the timeline window, plus empty-thread and attachment-only-without-path-leak cases).

🤖 Generated with Claude Code

The table-of-contents minimap previously listed only the currently-loaded
timeline window, so on a long thread it was incomplete until you scrolled
older pages in. Make it reflect the whole thread and let any entry jump to
its message.

Add GET /threads/:id/conversation-outline: a lightweight list of every
user/agent message (id, role, clamped preview, attachment counts). It reuses
the same buildThreadTimelineFromEvents projection as the timeline over the
full event set, so each outline item id is identical to the timeline row it
represents — that identity is what lets the minimap scroll-spy the loaded
window and jump to a message once it is paginated in. The handler memoizes per
(thread, maxSeq); the query is invalidated by the same realtime events-appended
signal as the timeline window.

The minimap renders from the outline (falling back to the loaded window until
it loads). Clicking an entry whose message isn't loaded yet auto-paginates
older pages until the row appears, then scrolls to it (bounded, and resilient
to pagination errors / thread switches mid-jump). The tick rail is bounded and
scrollable so long threads don't overflow.

Builds on upstream's right-centered minimap + min-3-user-messages gating and
near-bottom active detection.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@brsbl
brsbl merged commit 5d48dcd into get-bb:main Jun 25, 2026
5 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.

1 participant