Skip to content

trunk-merge/pr-3631/00d7dda2-545c-435f-843e-50d19face148#3729

Closed
trunk-io[bot] wants to merge 19 commits into
mainfrom
trunk-merge/pr-3631/00d7dda2-545c-435f-843e-50d19face148
Closed

trunk-merge/pr-3631/00d7dda2-545c-435f-843e-50d19face148#3729
trunk-io[bot] wants to merge 19 commits into
mainfrom
trunk-merge/pr-3631/00d7dda2-545c-435f-843e-50d19face148

Conversation

@trunk-io

@trunk-io trunk-io Bot commented Jul 22, 2026

Copy link
Copy Markdown
Trunk Merge Pull Request Banner

This pull request was created and is being managed by Trunk Merge.

This pull request is based on the main branch at SHA 5599f918b5bb91fe4438465073f84ce6f2b2f543.

See more details here.

When CI completes, this pull request will be closed automatically.

Pull Requests Being Tested

This pull request is testing the changes from pull request 3631.

pauldambra and others added 19 commits July 21, 2026 14:59
Add a marker rail in the scrollbar gutter of both conversation views (the
legacy ConversationView and the new ChatThread). Each user message gets a
darker marker positioned at its scroll offset; clicking jumps to the message
and hovering shows its first few words as a tooltip.

The native browser scrollbar can't be colored per-message or given click
handlers/tooltip points, so this is a thin absolutely-positioned rail beside
the scroll area instead.

- New scrollbar-rail/ module: MessageScrollbarRail (presentation) +
  useMessageRailMarkers (measures rendered user-message rows and computes
  fractional positions; interpolates unmeasured/virtualized rows between
  measured neighbours).
- Legacy ConversationView: VirtualizedList exposes its scroll + content
  elements via the imperative handle; the rail mounts in the container over
  the scrollbar gutter.
- New ChatThread: a ThreadScrollbarRail locates the quill scroller viewport +
  content via a hidden probe (same pattern as StickyHeaderOverlay) and mounts
  the rail inside ChatMessageScroller.

Generated-By: PostHog Code
Task-Id: a950f289-b4c3-472e-b375-0799e0cbf8a4
Add `MessageScrollbarRail.stories.tsx` with two scenes:

- `Pure`: the rail in isolation with a hand-built marker set, for reviewing
  marker sizing/spacing and the active state.
- `ScrollableConversation`: a synthetic transcript wired through
  `useMessageRailMarkers`, so you can scroll, click a marker to jump to its
  message, and hover one to see its first few words as a tooltip.

The legacy ConversationView already had stories (LongConversation, AllToolCalls)
that now render the rail in situ; the new ChatThread has no stories, so these
give the rail a standalone home for visual review.

Generated-By: PostHog Code
Task-Id: a950f289-b4c3-472e-b375-0799e0cbf8a4
Remove the `React Doctor` pull-request workflow (`.github/workflows/react-doctor.yml`) and its dedicated comment formatter (`.github/scripts/react-doctor-comment.mjs`).

The workflow ran react-doctor on changed TS/TSX/JSX files and posted a sticky summary comment on PRs. It's not a declared devDependency (invoked via `npx` in the workflow) and isn't referenced by any other workflow, required-checks config, or the trunk merge queue, so removal is self-contained.

The only remaining mention is a code comment in ChatThread.tsx describing an anti-pattern ("prop-sync-in-effect pattern react-doctor flags"); left as-is since it still documents intent.

Generated-By: PostHog Code
Task-Id: a950f289-b4c3-472e-b375-0799e0cbf8a4
CI fixes for the scrollbar marker rail PR.

- `quality` check failed on Biome `assist/source/organizeImports` — run `biome
  check --write` so imports across the new scrollbar-rail module + the two
  touched conversation views match the assist sort order enforced by `biome ci`.
- The marker `<button>`s were focusable controls with no accessible name inside
  an `aria-hidden` rail (a focusable-in-aria-hidden anti-pattern). Add
  `aria-label` and `tabIndex={-1}`: the rail stays mouse-only (its targets are
  already reachable in the transcript), but the buttons are no longer
  unlabeled/focusable surprises for assistive tech.

`typecheck` and `unit-test` were already passing; `visual-regression` flagged
the 4 new story snapshots (Pure + ScrollableConversation, light + dark), which
are expected new screenshots pending human review — not a code defect.

Generated-By: PostHog Code
Task-Id: a950f289-b4c3-472e-b375-0799e0cbf8a4
The scroll viewport in the ScrollableConversation story was `h-full` and in
normal flow inside `relative flex-1`, so without `min-h-0` the flex child grew
to the full content height (~15,000px) instead of the viewport height. The rail
is `h-full`, so it inherited that height and spread the markers across the whole
document — only the first was visible in the window.

Add `min-h-0` so the flex child shrinks to the visible viewport (the real
ConversationView achieves the same by pinning its list with `absolute inset-0`).
The rail is now viewport-height and all 10 markers tile within view.

Generated-By: PostHog Code
Task-Id: a950f289-b4c3-472e-b375-0799e0cbf8a4
Generated-By: PostHog Code
Task-Id: 9a68b219-d8a9-45af-ae6c-3f9b1b19e7b0
4 updated
Run: 925dc45b-9dab-4332-8c13-77e829b57a3f

Co-authored-by: pauldambra <984817+pauldambra@users.noreply.github.com>
Generated-By: PostHog Code
Task-Id: 9a68b219-d8a9-45af-ae6c-3f9b1b19e7b0
Generated-By: PostHog Code
Task-Id: 9a68b219-d8a9-45af-ae6c-3f9b1b19e7b0
Collapse a JSX element onto one line so `biome ci` passes formatting.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
4 updated
Run: 5c72beed-851f-4266-9d48-8750405a5f9c

Co-authored-by: pauldambra <984817+pauldambra@users.noreply.github.com>
Generated-By: PostHog Code
Task-Id: 106723a6-379c-4fdb-bde2-78568beacdfd
Generated-By: PostHog Code
Task-Id: 106723a6-379c-4fdb-bde2-78568beacdfd
Generated-By: PostHog Code
Task-Id: 106723a6-379c-4fdb-bde2-78568beacdfd
Address qa/codex P2: measure() ran one querySelector per user message on
every scroll event, which in long threads is hundreds/thousands of
synchronous DOM lookups per frame. Collect rendered rows with a single
querySelectorAll pass indexed by id, and coalesce observer/scroll-driven
measures to at most one per animation frame.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Generated-By: PostHog Code
Task-Id: 106723a6-379c-4fdb-bde2-78568beacdfd
Generated-By: PostHog Code
Task-Id: 9a68b219-d8a9-45af-ae6c-3f9b1b19e7b0
2 updated
Run: b53b6164-a29a-4b6c-997e-d464d1a1d695

Co-authored-by: pauldambra <984817+pauldambra@users.noreply.github.com>
@github-actions

Copy link
Copy Markdown

React Doctor found no issues in the changed files. 🎉

Reviewed by React Doctor for commit 5d9ffb2.

@trunk-io trunk-io Bot closed this Jul 22, 2026
@trunk-io
trunk-io Bot deleted the trunk-merge/pr-3631/00d7dda2-545c-435f-843e-50d19face148 branch July 22, 2026 21:35
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