Add project file picker - #3985
Conversation
|
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:
✨ Finishing Touches🧪 Generate unit tests (beta)
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 |
ApprovabilityVerdict: Needs human review 1 blocking correctness issue found. This PR introduces a new file picker feature with new UI components and keybindings. Additionally, unresolved review comments identify a critical bug: removing 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: 72f5b0e988
ℹ️ 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".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0765a5faad
ℹ️ 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".
| { key: "mod+-", command: "preview.zoomOut", when: "previewFocus" }, | ||
| { key: "mod+0", command: "preview.resetZoom", when: "previewFocus" }, | ||
| { key: "mod+k", command: "commandPalette.toggle", when: "!terminalFocus" }, | ||
| { key: "mod+p", command: "filePicker.toggle", when: "!terminalFocus" }, |
There was a problem hiding this comment.
Preserve existing mod+p bindings
When an existing keybindings config already uses mod+p globally (or with another broader when clause), startup still treats this new default as non-conflicting because the sync check only skips rules with the exact same shortcut and raw when string, then appends the missing default. Since resolveShortcutCommand scans later rules first, the appended filePicker.toggle rule will silently steal those users' mod+p shortcut outside terminal focus. Please avoid backfilling this default when an existing rule can overlap the same shortcut context, or choose an unassigned default.
Useful? React with 👍 / 👎.
| }, [keybindings, terminalOpen, toggleOpen]); | ||
| }, [keybindings, terminalOpen, toggleCommand, toggleFiles]); | ||
|
|
||
| return ( |
There was a problem hiding this comment.
🔴 Critical components/CommandPalette.tsx:382
The CommandPalette component no longer renders OpenAddProjectCommandPaletteProvider, but its children (which include AppSidebarLayout and route Outlet) still consume the OpenAddProjectCommandPalette context via useOpenAddProjectCommandPalette(). That hook throws when the context value is absent, so authenticated app-shell routes crash during render instead of displaying the UI. Consider re-wrapping children in OpenAddProjectCommandPaletteProvider (passing openAddProject) before rendering CommandDialog.
🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/web/src/components/CommandPalette.tsx around line 382:
The `CommandPalette` component no longer renders `OpenAddProjectCommandPaletteProvider`, but its `children` (which include `AppSidebarLayout` and route `Outlet`) still consume the `OpenAddProjectCommandPalette` context via `useOpenAddProjectCommandPalette()`. That hook throws when the context value is absent, so authenticated app-shell routes crash during render instead of displaying the UI. Consider re-wrapping `children` in `OpenAddProjectCommandPaletteProvider` (passing `openAddProject`) before rendering `CommandDialog`.
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.
Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 276a18d. Configure here.
| clearOpenIntent={clearOpenIntent} | ||
| /> | ||
| </CommandDialog> | ||
| </ComposerHandleContext> |
There was a problem hiding this comment.
Add-project provider removal crashes shell
High Severity
Removing OpenAddProjectCommandPaletteProvider causes useOpenAddProjectCommandPalette to access a null context. This leads to crashes in the authenticated app shell when components like Sidebar or DraftHeroHeadline mount, and breaks external 'Add project' entry points.
Reviewed by Cursor Bugbot for commit 276a18d. Configure here.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 276a18ddfe
ℹ️ 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".
| return ( | ||
| <OpenAddProjectCommandPaletteProvider openAddProject={openAddProject}> | ||
| <ComposerHandleContext value={composerHandleRef}> | ||
| <CommandDialog open={state.open} onOpenChange={setOpen}> | ||
| {children} | ||
| <CommandPaletteDialog | ||
| open={state.open} | ||
| openIntent={state.openIntent} | ||
| setOpen={setOpen} | ||
| clearOpenIntent={clearOpenIntent} | ||
| /> | ||
| </CommandDialog> | ||
| </ComposerHandleContext> | ||
| </OpenAddProjectCommandPaletteProvider> | ||
| <ComposerHandleContext value={composerHandleRef}> | ||
| <CommandDialog open={state.open} onOpenChange={setOpen}> |
There was a problem hiding this comment.
Restore the add-project context provider
Wrapping children directly in ComposerHandleContext removes the only OpenAddProjectCommandPaletteProvider, while Sidebar, DraftHeroHeadline, and NoProjectsHero still call useOpenAddProjectCommandPalette(). That hook now receives the context's null default and throws during normal authenticated app rendering, preventing the web shell from loading; retain the provider around this subtree or migrate all consumers in the same change. The required integrated web verification for this user-visible change should cover this render path.
AGENTS.md reference: AGENTS.md:L10-L14
Useful? React with 👍 / 👎.
|
Closing in favor of #4855 |


Summary
filePicker.togglekeybindingImplementation
The picker reuses the existing command palette primitives and workspace search endpoint. Server result ordering is preserved, while the client matcher is intentionally limited to a linear pass that computes highlight positions and filters non-file entries.
Validation
pnpm exec vp test apps/web/src/components/files/ProjectFilePicker.logic.test.ts apps/web/src/components/CommandPalette.logic.test.ts apps/web/src/keybindings.test.ts packages/contracts/src/keybindings.test.ts apps/server/src/keybindings.test.ts(81 tests)pnpm exec vp checkpnpm exec vp run typecheckNote
Add project file picker triggered by
mod+pkeybindingProjectFilePickercomponent that lets users search and open project files via a fuzzy-matched dialog with highlighted results.mod+popens the file picker;mod+kopens the command palette. Both are managed by a newreduceCommandPaletteUiStatereducer in CommandPalette.logic.ts withcommandandfilesmodes.kindfilter (file|directory) to constrain results.useProjectPathSearchgeneralizes the existing composer path search hook to support variable limits and kind filtering;useComposerPathSearchdelegates to it unchanged.filePicker.toggleis added toSTATIC_KEYBINDING_COMMANDSand documented in keybindings.md.📊 Macroscope summarized 276a18d. 1 file reviewed, 0 issues evaluated, 0 issues filtered, 0 comments posted
🗂️ Filtered Issues
No issues evaluated.
Note
Medium Risk
Touches workspace search/index behavior and a new global shortcut; removing
OpenAddProjectCommandPaletteProviderfromCommandPalettemay break sidebar/draft “add project” unless the provider is wired elsewhere.Overview
Adds a project file picker opened with
mod+p(filePicker.toggle), alongside the existing command palette onmod+k. The shared command dialog now tracks acommandvsfilesmode and rendersProjectFilePickerin files mode, with UI state centralized inreduceCommandPaletteUiState.ProjectFilePickersearches the active project workspace (index listing when the query is empty; debounced server search when not), applies client-side file-only fuzzy matching with highlighted name/path matches, and opens the selection via the same right-panel file action as the Files sidebar.Server/API: project search accepts optional
kind: 'file' | 'directory';WorkspaceSearchIndexroutes tofileSearch/directorySearch/mixedSearchso file-only queries are limited before truncation. Query normalization uses sharednormalizeSearchQuery(including stripping leading@./).useProjectPathSearchgeneralizes composer path search (configurable limit + kind);useComposerPathSearchdelegates to it. Keybindings and docs registerfilePicker.toggle.Reviewed by Cursor Bugbot for commit 276a18d. Bugbot is set up for automated code reviews on this repo. Configure here.