Skip to content

feat(web): add built-in thread search - #5562

Closed
Noojuno wants to merge 594 commits into
pingdotgg:t3code/codex-turn-mappingfrom
Noojuno:t3code/thread-search-v2
Closed

Noojuno wants to merge 594 commits into
pingdotgg:t3code/codex-turn-mappingfrom
Noojuno:t3code/thread-search-v2

Conversation

@Noojuno

@Noojuno Noojuno commented Aug 7, 2026 •

Copy link
Copy Markdown
Contributor

Long threads make it difficult to find an earlier message or plan, especially inside a collapsed run or attempt.

Add find-in-thread to the orchestration V2 web and desktop UI. Open it with ⌘/Ctrl+F or Find in current thread in the command palette. Next/previous controls move between highlighted matches and reveal collapsed content. Closing search clears highlights and restores folding. Search covers loaded messages and plans; load earlier history to include older turns. Terminal and preview shortcuts are preserved.

Search colours are editable under Advanced → Search in the theme editor. VS Code and Open VSX imports preserve current/other find-match colours, composite transparent backgrounds, and provide readable text fallbacks. The search bar is opaque and follows the shared control corner radius.

Targets t3code/codex-turn-mapping and preserves V2 run/attempt ownership, timeline projection, history controls, attachments, and citations. Includes the search refinements from the separate main PR #10439.

Visual verification

Fresh captures from this V2 branch, using isolated synthetic data.

Default appearance (no custom theme)

Search navigation and closing — 15 seconds. Light mode first; dark mode starts at 0:07.5.

default-verification.mp4
Light mode Dark mode
V2 search with default light appearance V2 search with default dark appearance

Imported themes and live editing

Search colour editing, cancelling, and match navigation — 15 seconds. Light mode first; dark mode starts at 0:06.4. Cancel restores the imported colours.

theme-verification.mp4
Light mode Dark mode
Imported VS Code theme V2 search with imported light find colours V2 search with imported dark find colours
Advanced theme editor V2 light theme search controls and live purple highlights V2 dark theme search controls and live green highlights

Keybindings settings

Chat: Find is listed as ⌘F on macOS (Ctrl+F on Windows/Linux), with !terminalFocus && !previewFocus.

Light mode Dark mode
V2 keybindings settings in light mode V2 keybindings settings in dark mode
Before and after the search styling refinements

The before image is the earlier V2 PR build, not a base-branch build.

Before After
Earlier V2 search with low-contrast highlights and rounded translucent bar Updated V2 search with readable highlights and opaque control-radius bar

Verification

  • 303 focused tests passed, covering V2 search/timeline behavior, keybindings, theme editing/imports, Open VSX colour extraction, and shared/mobile palettes.
  • Web and shared-package typechecks passed. Targeted formatting/lint passed with existing warnings; React Doctor found no new issues.
  • Browser-verified default and imported light/dark search, next/previous, closing, theme JSON import, live colour changes, Cancel, and keybindings settings. The bar and its buttons use an 8px radius. Shortcut handlers were exercised through dispatched events; native keyboard interception was not tested.
  • Folded V2 run/attempt ownership is covered by focused tests; the new browser fixture contains ordinary messages. Web/desktop share the UI; native desktop/mobile and remote/relay connections were not exercised. No provider or wire-contract changes in this port.

Model: GPT-6 via Codex.

Note

Add built-in thread search to chat timeline

  • Adds a find bar (ThreadFindBar.tsx) that searches user messages, assistant messages, and proposed plans in the active thread, with next/previous navigation via buttons or Enter/Shift+Enter and close via Escape
  • Binds chat.find to Mod+F (active outside terminal and preview focus) and adds a command palette entry to open find for the current thread
  • Highlights matches in the timeline using the CSS Custom Highlight API via useThreadFindHighlights, which paints active and inactive matches separately and repaints on DOM changes
  • Adds shared case-insensitive search utilities (findThreadSearchOccurrences, splitThreadSearchText, foldThreadSearchCase) in threadSearch.ts that handle Unicode-safe case folding
  • Expands collapsed user-message bodies and proposed plans during find mode so hidden content is searchable; terminal-context inline labels are excluded from search text
  • Adds search-match and active-search-match color roles to all built-in palettes, the theme editor, and VS Code/Open VSX theme imports, with readable foreground derivation for each background
  • Risk: MessagesTimeline now expands collapsed content and hides collapse controls while find mode is active; check CollapsibleUserMessageBody and ProposedPlanCard for unexpected layout shifts when findActive is true
📊 Macroscope summarized 0090fb5. 22 files reviewed, 4 issues evaluated, 2 issues filtered, 2 comments posted

🗂️ Filtered Issues

apps/web/src/components/chat/threadFind.ts — 1 comment posted, 2 evaluated, 1 filtered
  • line 33: searchableThreadEntryText removes every occurrence of an inline terminal label with replaceAll, although the renderer replaces only the occurrence(s) consumed for the appended terminal contexts. For example, a prompt containing two literal @zsh:1 strings with one zsh lines 1 context renders the second string as visible message text, but search removes both and cannot find it. This makes visible user-message text unsearchable. [ Already posted ]
apps/web/src/components/chat/threadFindHighlights.ts — 0 comments posted, 1 evaluated, 1 filtered
  • line 56: collectThreadFindRanges searches each rendered DOM text node independently, whereas navigation counts occurrences in the entry's single source string. A query spanning a Markdown-rendered node boundary (for example text separated by an inline formatting element) is counted by the thread search but cannot produce a range here; its active match remains null, so it is neither highlighted nor revealed. Markdown also makes occurrence numbering diverge from the raw assistant source used by navigation. [ Already posted ]

@coderabbitai

coderabbitai Bot commented Aug 7, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: c74b3f3e-397a-4eb4-9168-8f87cde39e20

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XL 500-999 changed lines (additions + deletions). labels Aug 7, 2026
Comment thread apps/web/src/components/chat/threadFindHighlights.ts
Comment thread apps/web/src/lib/visibleMessageText.ts
@Noojuno
Noojuno force-pushed the t3code/thread-search-v2 branch from 6fa14b2 to 8a32a65 Compare August 7, 2026 05:12
@juliusmarminge
juliusmarminge force-pushed the t3code/codex-turn-mapping branch from 25de21d to 0af2a6e Compare August 7, 2026 12:10
@Noojuno
Noojuno force-pushed the t3code/thread-search-v2 branch from 8a32a65 to 2f88a04 Compare August 7, 2026 12:27
@Noojuno
Noojuno marked this pull request as ready for review August 7, 2026 12:33
Comment thread apps/web/src/components/chat/threadFind.ts
Comment thread apps/web/src/components/chat/ThreadFindBar.tsx
@Noojuno
Noojuno force-pushed the t3code/thread-search-v2 branch from 2f88a04 to 54feee9 Compare August 7, 2026 12:40
Comment thread apps/web/src/index.css
Comment thread apps/web/src/components/chat/MessagesTimeline.tsx
@macroscopeapp

macroscopeapp Bot commented Aug 7, 2026 •

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR introduces a substantial, cross-cutting thread-search capability with new production UI, timeline navigation, rendering/highlighting behavior, theme integration, and a new default mod+f shortcut. It also has unresolved correctness risks involving Markdown-only matches and draft-thread command-palette behavior.

Not approved because:

  • 2 blocking correctness issues found at or above your repo's Minimum Blocking Severity

Adjust the Minimum Blocking Severity for this repo — including turning it Off — in Settings. You can add or adjust custom eligibility rules. Learn more.

@Noojuno
Noojuno force-pushed the t3code/thread-search-v2 branch from 54feee9 to 91bc8e4 Compare August 7, 2026 12:59

@cursor cursor 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.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 91bc8e4. Configure here.

Comment thread apps/web/src/components/chat/ThreadFindBar.tsx Outdated
Comment thread apps/web/src/components/chat/ThreadFindBar.tsx
@juliusmarminge
juliusmarminge force-pushed the t3code/codex-turn-mapping branch 7 times, most recently from 519c42a to 4c55679 Compare August 17, 2026 10:28
@juliusmarminge
juliusmarminge force-pushed the t3code/codex-turn-mapping branch 8 times, most recently from 490318a to 373612e Compare August 30, 2026 00:13
variant="default"
role="search"
aria-label="Find in thread"
className="absolute top-[calc(100%+0.5rem)] right-0 z-40 h-9 w-[min(24rem,calc(100vw-1.5rem))] bg-popover shadow-sm dark:bg-popover [-webkit-app-region:no-drag]"

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.

Shared primitives: this overrides InputGroup’s height and base surface at the call site. Add a size/popover variant in ui/input-group and use that here.

Suggested fix: No diff — this requires extending the shared primitive.

Posted via Macroscope — UI Consistency

);
}
if (entry.message.role !== "assistant") return null;
return entry.message.text || (entry.message.streaming ? "" : "(empty response)");

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.

🟡 Medium chat/threadFind.ts:38

Assistant entries produce phantom matches for text that exists only in Markdown syntax or link URLs: searching private-token in [documentation](https://example.com/private-token) adds a result, but the renderer displays only documentation, so navigation finds no highlight and scrolls to an unhighlighted row. Search the same rendered-text representation used by highlighting instead of raw entry.message.text.

🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/web/src/components/chat/threadFind.ts around line 38:

Assistant entries produce phantom matches for text that exists only in Markdown syntax or link URLs: searching `private-token` in `[documentation](https://example.com/private-token)` adds a result, but the renderer displays only `documentation`, so navigation finds no highlight and scrolls to an unhighlighted row. Search the same rendered-text representation used by highlighting instead of raw `entry.message.text`.

},
});

if (activeThread || activeDraftThread) {

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.

🟡 Medium components/CommandPalette.tsx:1678

The “Find in current thread” action is available for an unsaved draft, but selecting it closes the palette without opening search. requestThreadFindOpen() requires activeThreadKey, which is null when only activeDraftThread exists; restrict this action to activeThread or add draft-thread search support.

🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/web/src/components/CommandPalette.tsx around line 1678:

The “Find in current thread” action is available for an unsaved draft, but selecting it closes the palette without opening search. `requestThreadFindOpen()` requires `activeThreadKey`, which is null when only `activeDraftThread` exists; restrict this action to `activeThread` or add draft-thread search support.

@juliusmarminge
juliusmarminge force-pushed the t3code/codex-turn-mapping branch 11 times, most recently from 600a8a5 to d8c75ec Compare September 15, 2026 00:23
@juliusmarminge
juliusmarminge force-pushed the t3code/codex-turn-mapping branch 2 times, most recently from 463d0c6 to e10a1e2 Compare September 15, 2026 06:28
@juliusmarminge

Copy link
Copy Markdown
Member

Built-in thread search is already on the branch (packages/client-runtime/src/state/threadSearch.ts + mobile/web surfaces). Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL 500-999 changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants