Add project file picker (⌘P) and project content search (⇧⌘F) - #4855
Add project file picker (⌘P) and project content search (⇧⌘F)#4855jakeleventhal wants to merge 9 commits into
Conversation
Combines and supersedes pingdotgg#3985 and pingdotgg#4007 with a unified global search overlay: the command palette host now owns three mutually exclusive modes — command (mod+k), file picker (mod+p), and content search (mod+shift+f) — behind a single reducer and keydown dispatcher, so the surfaces never stack and shortcuts switch modes in place. Server: WorkspaceSearchIndex routes kind-filtered entry search to fff fileSearch/directorySearch and adds grep-backed searchContents with case/whole-word/regex options, punctuation-safe whole-word boundaries, and byte-to-string match range mapping; content indexing is enabled for workspace indexes. New projects.searchContents RPC with read-scope auth and structured errors that never leak query text. Web: shared useActiveProjectTarget hook resolves the active thread/draft workspace for both overlays; results open through the right-panel openFile path (with line reveal for content matches), and the file explorer reveals and selects the opened file. Shared Shiki highlighter promise cache and RenderErrorBoundary are extracted from ChatMarkdown and reused for syntax-highlighted search result lines. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
ApprovabilityVerdict: Needs human review This PR introduces two new user-facing features (⌘P file picker and ⇧⌘F content search) with new UI components, new RPC endpoints, new keyboard shortcuts, and search index changes. New features with significant new capability warrant human review. You can customize Macroscope's approvability policy. Learn more. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6a16c6c293
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
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. Comment |
Server - Whole-word matching now greps the bare pattern and filters match ranges by VS Code-style word boundaries, fixing widened highlight spans and dropped adjacent occurrences that consuming (?:^|\W) boundaries caused - Cap grep matches per file (100) so one dense file cannot fill the page - Split the workspace index into path-only and content variants; content indexing now initializes only when content search is used - Entries search accepts an empty query (bounded frecency-ordered listing); content search queries preserve whitespace on the wire - Startup keybinding backfill appends only the defaults that fit instead of evicting the user's oldest custom rules Web - File line reveal retries until contents and line metrics exist and briefly guards the target scroll position against programmatic resets, fixing content-search results opening at the top of the file - Explorer reveal expands slash-keyed directory ancestors, keeps the drag controller's selection cache fresh, and no longer closes an active tree search when the selection originated inside the tree - Content search gates Enter while results are stale and renders result rows in growing windows instead of mounting all 500 at once - File picker's empty state uses the bounded file-only server search (recent files first) instead of transferring the full listing - Command palette exposes "Go to file" and "Search project contents" actions and resolves shortcuts with the complete when-clause context - Content search atoms moved out of the shared client-runtime surface (web-only); dropped the unconsumed EnvironmentApi.searchContents Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Pushed 0f7ccee addressing the review feedback: Server
Web
Also fixed a bug found in manual testing: opening a content-search result could land at the top of the file instead of the matched line. The line reveal now retries until file contents and line metrics are hydrated (previously an early post-render could clamp against empty contents, scroll to line 1, and mark the request handled) and briefly guards the target scroll position against late programmatic resets from the editable editor, cancelling on real user input. Validation: workspace typecheck clean, 🤖 Generated with Claude Code |
Summary
Combines and supersedes #3985 and #4007, rebuilt from scratch against current main.
Why one PR
The two originals overlapped heavily (
WorkspaceSearchIndex,WorkspaceEntries, keybindings, contracts,queries.ts) but made opposite hosting choices: #3985 put the file picker inside the command palette host while #4007 put content search insideChatViewwith its own keydown handling and duplicated project resolution. This PR unifies them:reduceCommandPaletteUiState) owns open/mode state for all three overlays — they can never stack, re-pressing a mode's shortcut closes it, pressing a different one switches in placecommandPalette.toggle/filePicker.toggle/projectSearch.toggleuseActiveProjectTarget()hook resolves the active thread/draft → project workspace for both surfaces; both open results viarightPanelStore.openFile(threadRef, path, line?)ChatViewneeded zero changes (line reveal already existed on main)Implementation
Server
WorkspaceSearchIndex.searchaccepts an optionalkindfilter and routes to ffffileSearch/directorySearchso file-only queries are filtered before truncation; all fff calls share onerunSearcherror wrappersearchContentsbacked byFileFinder.grepwith a 250ms time budget; whole-word wrapping falls back to explicit non-word boundaries for punctuation-edged queries (e.g.foo-) in both literal and regex modes, and byte offsets are mapped to string indices for highlightingdisableContentIndexing: false)projects.searchContentsRPC with orchestration read scope and structured errors that carry query length, never query textWeb
ProjectFilePickerpreserves server ranking and computes subsequence highlight indices client-side with the same query normalization the server appliesProjectContentSearchDialogstate resets by unmount/keying instead of effects; regex-error and truncation states surfaced in the status linegetSyntaxHighlighterPromise+RenderErrorBoundaryextracted fromChatMarkdown;HighlightedSearchLinesplits Shiki tokens around match rangesFileBrowserPanelreveals/expands/selects the file open in the preview pane without echoing a synthetic openuseComposerPathSearchgeneralized touseProjectPathSearch(configurable limit + kind, debounce-aware pending state)Command naming follows the existing toggle family:
filePicker.toggle(mod+p) andprojectSearch.toggle(mod+shift+f), both documented indocs/user/keybindings.md.Validation
vp run typecheck— passes workspace-widevp check— 0 errors; one fewer lint warning than mainapps/websuite: 188 files / 1,676 tests; contracts + shared + client-runtime: 1,006 testshéllo wörld) range mapping, plus the ported gitignore, case-sensitivity, truncation, and punctuation whole-word regressionsCloses #3985. Closes #4007.
🤖 Generated with Claude Code
Note
Medium Risk
Adds substantial workspace search and grep logic on the server plus new RPC surface; UI changes are localized to overlays and file panel sync with moderate integration scope.
Overview
Adds ⌘P file picker and ⇧⌘F project content search as modes of the same global overlay stack as ⌘K, with new shortcuts
filePicker.toggleandprojectSearch.toggle.Server: New
projects.searchContentsRPC andWorkspaceSearchIndex.searchContents(grep with time budget, per-file caps, post-filter whole-word matching). Path search supports optionalfile/directorykind filtering and separatepathsvscontentindex variants (content indexing only on the content index).Web:
ProjectFilePickerandProjectContentSearchDialogresolve the active project viauseActiveProjectTarget()and open results throughrightPanelStore.openFile. The file tree reveals the open preview file; line reveal in the preview is more reliable (centered scroll + short guard against snap-back). Shared Shiki highlighting viagetSyntaxHighlighterPromiseandRenderErrorBoundary.Other: Keybinding default backfill no longer truncates user rules when at max entries.
Reviewed by Cursor Bugbot for commit bca349b. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Add project file picker (⌘P) and project content search (⇧⌘F) to the command palette
mod+p/filePicker.toggle) rendered inside the command dialog when infilesmode, with fuzzy match highlighting and frecency-ordered empty-query results backed by the existingsearchEntriesRPC.mod+shift+f/projectSearch.toggle) with case-sensitive, whole-word, and regex options, incremental rendering, and keyboard navigation; results open the selected file in the right panel.WorkspaceSearchIndexwith a newsearchContentsmethod that pages through grep results with a time budget, per-file match cap, whole-word post-filtering (including astral-plane characters), and byte-to-string index mapping.projects.searchContentsWebSocket RPC (requiringAuthOrchestrationReadScope) with a newProjectSearchContentsErrorerror type.CommandPalettestate is refactored into areduceCommandPaletteUiStatereducer managing three mutually exclusive overlay modes:command,files, andcontent.FileBrowserPanelnow syncs with the externally opened file path, expanding ancestors and centering the row without re-triggering file open.useNewThreadHandlernow directly spreadsworkspaceContextinstead ofworkspaceContext ?? {}; ifworkspaceContextis null at runtime the spread will throw rather than silently use an empty object.Macroscope summarized bca349b.