Add project file picker (⌘P) and project content search (⇧⌘F) - #4855
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 keybindings, RPC endpoints, UI components, and backend search functionality. New feature capabilities of this scope 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 |
- Share command palette behavior across file and content search - Add consistent keyboard shortcut footers
- Extract shared input, panel, and keyboard-hint layout - Reuse it for project file and content search dialogs
Avoid reserving a status row before a search query is entered
205e885 to
6fc40cb
Compare
6fc40cb to
205e885
Compare
# Conflicts: # apps/web/src/components/CommandPalette.tsx
…ined-pull-requests # Conflicts: # apps/web/src/components/CommandPalette.logic.ts # apps/web/src/components/CommandPalette.tsx # apps/web/src/state/queries.ts
…ined-pull-requests # Conflicts: # docs/user/keybindings.md
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 051e319. Configure here.
Main landed the project file picker and content search (pingdotgg#4855), which adds project RPCs beside this branch's. Every conflict was a keep-both: - rpc.ts, RpcAuthorization.ts: projectsSearchContents sits alongside projectsGetDetails and projectsUpdateSettings in the method map, the RPC export list, and the scope map. - ws.ts, contracts/project.ts: import lists gain both sides' symbols. - contracts/project.test.ts: main's search-input describe block joins this branch's project-details fixtures. - SidebarV2: the thread row keeps main's aria-busy for title regeneration and this branch's sidebar-v2-thread-card class. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
27 commits from main, including the ⌘P file picker / ⇧⌘F content search (#4855), thread content search (#4959), sidebar title regeneration (#4810), image-paste compression (#4967), and the docs restructure (#4807). Notable resolutions beyond keep-both: - Thread content search is ported to the v2 surface: searchThreads joins ORCHESTRATION_V2_WS_METHODS/rpc/auth scopes, and the SQL now UNIONs orchestration_v2_projection_messages so current threads are searchable, not just legacy-projected ones. - Title regeneration's server half lived in the v1 ProviderCommandReactor this branch deletes, so the capability is deliberately not advertised: clients hide the action, the contract/UI code stays intact, and the input field is accepted as a documented no-op. TODO(orchestration-v2): port regeneration to the v2 runtime. - Main's 035_ProjectionThreadTitleRegeneration migration collided with this branch's 035-043 range; renumbered to 044. - Mobile activity grouping keeps this branch's runId/prominence semantics while adopting main's O(1) trailing-group optimization (prominence tracked in a flag instead of a per-append scan). - v1-only startup tests from main (heartbeat/auto-bootstrap against the deleted reactor-era services) are dropped; their v2 equivalents already cover the ordered startup phases. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
## What's Changed * docs: split user and maintainer docs, fix 100+ stale claims by @t3dotgg in pingdotgg/t3code#4807 * fix(web): server updates no longer look like warnings by @t3dotgg in pingdotgg/t3code#4992 * fix(connect): reboots no longer strand the relay link, 403s now say why by @t3dotgg in pingdotgg/t3code#4988 * Add project file picker (⌘P) and project content search (⇧⌘F) by @jakeleventhal in pingdotgg/t3code#4855 * Check for mobile app updates on launch by @juliusmarminge in pingdotgg/t3code#4958 **Full Changelog**: pingdotgg/t3code@v0.0.32-nightly.20260730.956...v0.0.32-nightly.20260730.957 Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.32-nightly.20260730.957

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
New workspace content index and grep path add server CPU/memory and search correctness surface (whole-word, regex, multi-byte ranges). Overlay and file-reveal logic are broad UI changes; keybinding backfill fix is low-risk but touches persisted config.
Overview
Adds ⌘P file picker and ⇧⌘F project content search as modes of the same global overlay as ⌘K, with one reducer so modes cannot stack and re-pressing a shortcut toggles or switches mode.
Server: New
projects.searchContentsRPC and orchestration read auth; workspace indexes split into paths vs content keys (content indexing only for grep). Path search supports optionalkindfiltering and shared query normalization; content search usesFileFinder.grepwith time budget, per-file match caps, and post-filter whole-word boundaries (Unicode-aware). Index warmup useswaitForIndexReadyinstead of pollingisScanning. Default keybinding backfill no longer truncates user rules when at max entries.Web:
ProjectFilePickerandProjectContentSearchDialogshareCommandPaletteContentchrome;useActiveProjectTargetresolves workspace + thread for both. Results open viarightPanelStore.openFilewith optional line reveal; file tree syncs selection/reveal without echo-opens. SharedgetSyntaxHighlighterPromiseandRenderErrorBoundaryfor search result highlighting. New defaults:filePicker.toggle(mod+p),projectSearch.toggle(mod+shift+f).Reviewed by Cursor Bugbot for commit 1d4e0f3. 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
⌘P) that searches server-indexed project files with fuzzy highlighting, and a content search dialog (⇧⌘F) that searches file contents with case-sensitive, whole-word, and regex options with syntax-highlighted results.SearchOverlayMode('command' | 'files' | 'content') to the command palette state; pressingEscapeinfilesorcontentmode returns to'command'mode instead of closing the overlay.projects.searchContentsWebSocket RPC backed by a new'content'variantWorkspaceSearchIndexusingFileFinder.grepwith smart-case, whole-word Unicode filtering, time-budgeted pagination, and byte-to-string range mapping.ProjectSearchEntriesInputto allow empty queries (for frecency-ordered results) and an optionalkindfilter ('file' | 'directory'); addsProjectSearchContentsInput/Result/Errorcontract types.FileBrowserPanelto reveal and center the file opened from the picker, with retry logic and scroll-guard inuseFileLineRevealto prevent snap-back.useHandleNewThreadnow spreadsworkspaceContextdirectly — if it isnullorundefinedat runtime the spread will throw, whereas previously it silently produced an empty object.Macroscope summarized 1d4e0f3.