Skip to content

feat(app): add find bar to session timeline - #48470

Closed
cdz620 wants to merge 3 commits into
anomalyco:devfrom
cdz620:session-find
Closed

cdz620 wants to merge 3 commits into
anomalyco:devfrom
cdz620:session-find

Conversation

@cdz620

@cdz620 cdz620 commented Sep 11, 2026

Copy link
Copy Markdown

Issue for this PR

N/A - small UX gap: the session transcript has no in-page search. (Resubmission of #48088, which was auto-closed for a template issue; this version also fixes two things found after the first submission.)

Type of change

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

What does this PR do?

Adds mod+f in-page search to the session timeline (app and desktop UI).

The timeline is virtualized, so matches are computed from row data (user/assistant text, reasoning, tool call inputs, error rows, plus the projected message text that V2 sessions carry on the message itself) instead of the DOM. The active match scrolls into view through the virtualizer, and rendered hits are highlighted with the CSS Custom Highlight API under the same opencode-find names and colors the pierre file viewer already uses. Highlights rebuild as rows mount and unmount while scrolling.

The timeline registers as a find host in the existing pierre file-find registry (new registerFindHost / activateFindHost exports), so mod+f / mod+g routing is shared with the file viewer and only one find bar is active at a time; file tabs keep their existing behavior and win via defaultPrevented. The bar is the existing FileSearchBar component with the existing ui.fileSearch.* i18n keys, so no new strings. Shortcuts follow the platform convention (Cmd on macOS, Ctrl elsewhere) so plain Ctrl+F keeps its native cursor-forward behavior.

One non-obvious fix: bottom-follow is paused synchronously (new onPauseScroll prop wired to autoScroll.pause) before navigating to a match, otherwise anchor-bottom resize handlers race the find scroll and pull the viewport back down.

How did you verify your code works?

  • New find.test.ts covers search-text extraction and match computation. Full app unit suite passes except one pre-existing i18n failure that also fails on dev.
  • Interactive verification in Chromium against bun dev + a local server with seeded sessions:
    • mod+f opens the bar even while the composer is focused; counts show n/m, 0/0 on no match.
    • Enter / shift+Enter cycle with wrap-around; mod+g / mod+shift+g navigate while open.
    • In a 77-row session, searching an off-screen match scrolled from the bottom to the exact row with the hit highlighted in view.
    • Ctrl+F on macOS does not open the bar (cursor-forward preserved); Cmd+F opens it, Cmd+G navigates.
    • Escape closes the bar and clears all highlights.

Screenshots / recordings

Happy to attach a recording on request; verified interactively as described above.

Checklist

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

Add mod+f in-page search for the session transcript. Matches are computed
from row data (user/assistant text, reasoning, tool inputs, errors) so the
virtualized timeline can scroll off-screen matches into view, then rendered
hits are highlighted with the CSS Custom Highlight API. Enter / shift+Enter
and mod+g / mod+shift+g cycle matches, Escape closes.

The pierre file-find host registry is exported so the timeline joins the
existing mod+f routing and only one find bar is active at a time. Bottom
follow is paused synchronously before navigating so anchor-bottom resize
handlers cannot race the find scroll.
V2 sessions carry the prompt on the session message rather than only in
projected parts, so user rows could miss matches. Include the projected
user/shell message text for user rows alongside part text.
Find shortcuts now follow the platform convention (Cmd on macOS, Ctrl
elsewhere) in both the timeline handler and the shared find-host
registry, so plain Ctrl+F / Ctrl+G keep their native emacs-style
behavior on macOS instead of opening the find bar.
hunterchristian added a commit to chipp-ai/opencode that referenced this pull request Sep 23, 2026
Search within the current session's message history -- open with
<leader>f or /find (alias /search), type a query, step between
matches with Enter/Shift+Enter, Esc to close.

Ported from upstream anomalyco#4714 (67 reactions/35
comments). Unusually, the relevant PRs (anomalyco#45037, anomalyco#48470) were still
open and unreviewed rather than bot-closed -- but neither actually
targets the TUI: both add Cmd/Ctrl+F search to the web/desktop
timeline instead. anomalyco#45037's approach (reusing the file viewer's search
by scanning the rendered page) can't carry over to a terminal UI.
anomalyco#48470's approach -- find matches directly from message data (text,
reasoning, tool inputs, error rows), then scroll to the hit -- doesn't
depend on a browser, so its matching logic (partSearchText,
findMatches) is ported directly into a new
packages/tui/src/util/session-find.ts. Its browser-only parts (DOM
highlighting, the web find-bar, file-viewer shortcut sharing) have no
TUI equivalent and were rewritten as a real terminal find-bar
component plus new match-navigation and scroll-target logic.

Four new overridable keybinds (session_find <leader>f,
session_find_next/previous/close). Matched parts get a highlighted
background, stronger on the current match; a collapsed "Thought"
block auto-opens while it holds the current match.

Known gaps: word-level highlighting only works in user messages
(assistant/reasoning/tool rows highlight as a whole block -- the
terminal renderer can't highlight part of a markdown block); tool
output isn't searched, only tool inputs, matching anomalyco#48470's own
choice; a match inside a hidden/collapsed region is counted but has
nothing on screen to jump to; only the current session is searched,
no cross-session search; keybinds docs and generated SDK types don't
list the new keys yet.

New packages/tui/test/util/session-find.test.ts (11 tests, adapted
from anomalyco#48470's own test file) and packages/tui/test/cli/tui/
session-find.test.tsx (2 tests rendering the real find bar). Verified
against this fork's current dev, including the expandable-pasted-
text-placeholders feature which touches two of the same files with
no conflict: bun typecheck clean; full packages/tui suite 228 pass.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
@thdxr

thdxr commented Oct 10, 2026

Copy link
Copy Markdown
Member

This branch has been upgraded to V2. We're no longer taking PRs for V1. If you think this is still relevant, please port it over and open it for V2.

— from 𝕺𝖕𝖊𝖓𝕮𝖔𝖉𝖊

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.

2 participants