Skip to content

Add in-chat search with Ctrl+F / Cmd+F - #701

Open
gen4sp wants to merge 2 commits into
alphaXiv:mainfrom
gen4sp:codex/chat-find
Open

gen4sp wants to merge 2 commits into
alphaXiv:mainfrom
gen4sp:codex/chat-find

Conversation

@gen4sp

@gen4sp gen4sp commented Oct 17, 2026 •

Copy link
Copy Markdown

Closes #700

Summary

  • Add a chat-header Find button and Ctrl+F / Cmd+F shortcut scoped to the focused main or side chat, with highlighted results, a match counter, wrapping Enter / Shift+Enter navigation, and Escape-to-close without interrupting the running turn.
  • Search case-insensitive literal text across inline Markdown formatting and offscreen messages in the current branch. Find temporarily mounts the full branch; closing it restores virtualization. Closed disclosures expose only their visible summary to search, and results refresh when transcript text or disclosure visibility changes.
  • Reveal selected matches in nested output and code scroll containers, vertically and horizontally, before positioning the chat viewport.
  • Add translations for all supported locales, jsdom regression coverage, and the regenerated ui/dist bundle.

Test plan

  • node --test --experimental-strip-types ui/tests/*.test.mjs — 324 tests passed.
  • Regression tests reproduced both review findings before the fixes: hidden matches in closed disclosures and vertically clipped output. All 8 search tests pass after the fixes, including nested disclosures, reopening/closing, inline formatting, and nested scroll visibility on both axes.
  • pnpm build in ui/ — localization validation, TypeScript checking, and production bundle passed.
  • pnpm install --frozen-lockfile --offline --ignore-scripts in ui/ passed.
  • node ui/scripts/check-styles.mjs and cargo fmt --all --check passed.
  • Browser checks of the initial implementation in an isolated dev slot: Ctrl+F and Cmd+F; a 240-message transcript with 120 matches spanning plain, bold, and inline-code text; offscreen results; next/previous wraparound; literal punctuation; no-result state; independent side-chat search; Escape and restored virtualization.

Add scoped transcript search with highlighted matches, result navigation, and safe Escape handling for main and side chats. Include localization, regression tests, and the rebuilt UI bundle.

Refs alphaXiv#700
@greptile-apps

greptile-apps Bot commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 3/5

[Medium impact] Adds in-chat search UI and text-matching logic.

Fix hidden and clipped search results before merging.

Findings

  1. P1 Search selects hidden text ▶
  2. P1 Output matches stay clipped ▶
Fix with agent prompt
### Issue 1
ui/src/chatSearch.ts:45-48
`transcriptSearchRanges` includes text inside closed `<details>` elements. Resolved plans and questions keep their bodies mounted without `hidden`, `inert`, or `aria-hidden`, so invisible text contributes matches. Selecting those matches does not reveal them because search never opens the disclosure. Skip non-summary content inside closed `<details>` elements, and include it after expansion.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

### Issue 2
ui/src/components/ChatSearch.tsx:79-85
Match navigation scrolls the chat vertically but only scrolls nested containers horizontally. Shell output and expanded error details use `TOOL_OUTPUT_CLASS_NAME`, which limits their height and enables vertical scrolling. A match below that container's visible area stays clipped even after search selects it. Scroll nested vertical containers to reveal the match before positioning it in the chat.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Summary

Adds in-chat search for main and side chats, with keyboard shortcuts, highlighted matches, wrapping navigation, and translated controls.

  • Chat users can find matches in the focused conversation.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A["Find button or Ctrl/Cmd+F"] --> B["Open search and mount full branch"]
  B --> C["Read transcript text"]
  C --> D["Build and highlight matches"]
  D --> E["Select next or previous match"]
  E --> F["Scroll chat and nested horizontal areas"]
  B --> G["Close search"]
  G --> H["Restore virtualization and focus"]
Loading

Reviews (1) · Last reviewed commit: "feat(ui): add in-chat search with Ctrl+F..." · Reviewed by Greptile

Comment thread ui/src/chatSearch.ts
Comment on lines +45 to +48
acceptNode(node) {
if (node instanceof Element) {
if (node.matches(EXCLUDED)) return NodeFilter.FILTER_REJECT;
return node.tagName === "BR" ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;

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.

P1 Search selects hidden text

transcriptSearchRanges includes text inside closed <details> elements. Resolved plans and questions keep their bodies mounted without hidden, inert, or aria-hidden, so invisible text contributes matches. Selecting those matches does not reveal them because search never opens the disclosure. Skip non-summary content inside closed <details> elements, and include it after expansion.

Prompt To Fix With AI
This is a comment left during a code review.
Path: ui/src/chatSearch.ts
Line: 45-48

Comment:
**Search selects hidden text**

`transcriptSearchRanges` includes text inside closed `<details>` elements. Resolved plans and questions keep their bodies mounted without `hidden`, `inert`, or `aria-hidden`, so invisible text contributes matches. Selecting those matches does not reveal them because search never opens the disclosure. Skip non-summary content inside closed `<details>` elements, and include it after expansion.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Comment thread ui/src/components/ChatSearch.tsx Outdated
Comment on lines +79 to +85
scroll.scrollTop += rect.top - viewport.top - (scroll.clientHeight - rect.height) / 2;
// Code blocks can scroll horizontally without moving the chat pane.
for (let parent = range.startContainer.parentElement; parent && parent !== scroll; parent = parent.parentElement) {
if (parent.scrollWidth <= parent.clientWidth || !/(auto|scroll)/.test(getComputedStyle(parent).overflowX)) continue;
const match = range.getBoundingClientRect();
const bounds = parent.getBoundingClientRect();
parent.scrollLeft += match.left - bounds.left - (parent.clientWidth - match.width) / 2;

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.

P1 Output matches stay clipped

Match navigation scrolls the chat vertically but only scrolls nested containers horizontally. Shell output and expanded error details use TOOL_OUTPUT_CLASS_NAME, which limits their height and enables vertical scrolling. A match below that container's visible area stays clipped even after search selects it. Scroll nested vertical containers to reveal the match before positioning it in the chat.

Prompt To Fix With AI
This is a comment left during a code review.
Path: ui/src/components/ChatSearch.tsx
Line: 79-85

Comment:
**Output matches stay clipped**

Match navigation scrolls the chat vertically but only scrolls nested containers horizontally. Shell output and expanded error details use `TOOL_OUTPUT_CLASS_NAME`, which limits their height and enables vertical scrolling. A match below that container's visible area stays clipped even after search selects it. Scroll nested vertical containers to reveal the match before positioning it in the chat.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Exclude hidden content of closed details while retaining the visible first summary. Reveal matches in nested vertical and horizontal scroll containers before positioning the chat viewport.

Add jsdom regression tests for disclosure visibility, nested scrolling, and inline matching; rebuild the embedded UI bundle.

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.

Add in-chat search with Ctrl+F / Cmd+F

1 participant