Skip to content

feat(app): add prompt navigation rail to the session timeline - #57869

Open
tomlin7 wants to merge 1 commit into
anomalyco:devfrom
tomlin7:prompt-navigator
Open

tomlin7 wants to merge 1 commit into
anomalyco:devfrom
tomlin7:prompt-navigator

Conversation

@tomlin7

@tomlin7 tomlin7 commented Oct 21, 2026 •

Copy link
Copy Markdown

Issue for this PR

Closes #57866

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

Long sessions have no landmarks between turns. This adds a compact prompt navigator in the gutter beside the timeline scrollbar: one bar per user prompt, the prompt being read highlighted, click to jump.

The rail reuses what the timeline already has. Prompts come from the projected row list; bar positions come from the virtualizer's measurements. Clicking scrolls to start - topOffset(), so the prompt lands below the sticky header. If the reader is pinned at the bottom, the newest prompt is current; otherwise the current prompt is the last one whose row starts at or below the fold. Wheel input over the rail is forwarded to the timeline, so scrolling past it does not dead-end.

Spacing stays in a centered 240px band: the slot is min(10, 240 / promptCount), and the bar shrinks to 1px when that gets too dense. Inactive bars are 16x2 at text-faint, the current bar is 24x2 at text-base, and hover uses text-muted. The rail is hidden below an 840px container width, where there is no gutter, and for sessions with fewer than two prompts. It also stays hidden during the cold bottom mount.

I used the existing session.timeline.* i18n namespace and left the server untouched: no new requests, endpoints, or message-index API.

Related: #52500 and #54088 cover a left-edge rail built on MessageNav with hover previews. This is the right-edge variant from #57334 (closed as duplicate), kept deliberately small: it only knows about prompts already projected in the timeline and adds no server surface.

How did you verify your code works?

  • bun typecheck in packages/app
  • bun run lint:changed (0 problems)
  • bunx playwright test e2e/regression/timeline-geometry.spec.ts --project=chromium (9 passed)
  • bunx playwright test e2e/regression/session-panel-scrollbar.spec.ts --project=chromium (2 passed)
  • The new keeper test jumps from bar 3 to msg_00002_history_a_user, asserts the row is in the viewport with the highlight on the clicked bar, and asserts the rail disappears at 700px.

Screenshots / recordings

prompt_navigator.webm

The rail is on the right, with the fifth prompt highlighted after clicking it:

Prompt navigation rail

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

Added by the opencode bot (AI-generated).

Related: #52500

@opencode-agent opencode-agent Bot 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.

The rail works as described. I ran it in Chromium with seeded history: clicking a bar puts that prompt just below the header and highlights it, scrolling the wheel over the rail moves the timeline, and the newest bar is highlighted while you're at the bottom. bun run typecheck in packages/app and the two timeline e2e specs (11 tests) pass.

Public API: unchanged. The only additions are two app-only English i18n keys.

For maintainers: this is a smaller, client-only alternative to the left-edge turn navigator in #54088. That design was ported to beta, and #57737 proposes removing it there, so which design to keep is still open.

Concerns:

  • The rail only covers prompts that have already loaded. In long sessions the numbering and bar positions change as older history loads (inline comment).
  • packages/app/AGENTS.md asks for a before/after benchmark when timeline code changes. This PR adds work on every scroll event, so please share those numbers.

Related: #52500

Before

After

type="button"
class="group flex w-7 cursor-pointer items-center justify-end focus-visible:outline focus-visible:outline-2 focus-visible:outline-v2-border-border-strong focus-visible:outline-offset-2"
style={{ height: `${slot()}px` }}
aria-label={language.t("session.timeline.jumpToPrompt", { index: index + 1 })}

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.

index + 1 counts only prompts already loaded in the timeline. Older history loads in pages as you near the top (onHistoryScroll in interaction.ts), so in a long session "Jump to prompt 1" is not the first prompt of the session. Every label and bar position also changes when a page loads. Clicking the top bar scrolls near the top, which loads older history, so the bars move under the cursor right after the click. Could the rail say that more prompts exist above, or avoid numbering that implies the full session? Alternatively, keep the clicked bar steady while history loads.

@Feelings0220

Copy link
Copy Markdown

Hi — I use the Windows desktop client and this is exactly the navigation affordance I miss in long sessions.

I noticed this branch is now ~1,640 commits behind dev, and virtualizer.tsx has been refactored since (follow state machine, cold mount, @tanstack/solid-virtual), so I ported the rail onto current dev (6a89e9f) as a small, self-contained change:

  • prompt-rail.tsx + .css keep the same design: one bar per user prompt, the prompt being read highlighted, click to jump, hidden when there is no gutter.
  • virtualizer.tsx derives prompt rows from the current timeline projection and uses measurementsCache / scrollToOffset; the old onUnpin() is now follow.dispatch({ type: "detach" }).
  • The rail uses a named container query on the timeline root, so it follows the panel width rather than the window.
  • Added an e2e test to timeline-geometry.spec.ts. packages/app typecheck passes and the new test passes.

Before I open a PR: is the right-edge prompt rail still a direction you want? I saw the earlier turn navigator was removed (#57737) and #52500 is still waiting on design approval, so I don't want to add noise if the placement/interaction has already been decided against. I'm happy to adjust the placement (left edge), defaults, or scope.

If useful, I can push the branch to a fork and link it here.

@opencodejr opencodejr Bot mentioned this pull request Nov 10, 2026

This branch has not been deployed

No deployments
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.

[FEATURE]: right-edge prompt navigation rail in the session timeline

2 participants