Full-history conversation outline for the thread TOC minimap - #399
Merged
Merged
Conversation
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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
GET /threads/:id/conversation-outline— a lightweight list of every user/agent message (id,role, clampedpreview, attachment counts). It reuses the samebuildThreadTimelineFromEventsprojection as the timeline over the full event set, so each outline item'sidis identical to its timeline row'sid. 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 realtimeevents-appendedsignal as the timeline window.Testing
ThreadTableOfContentsjsdom suite covering full-history rendering, attachment-only labels, jump-to-loaded, auto-paginate-to-unloaded, and the no-older-pages case — merged with the existingfindActiveItemIdsscroll-spy tests).segmentLimit=1page 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