Skip to content

feat(web): create folders from the add-project path picker#3723

Draft
O4FDev wants to merge 1 commit into
pingdotgg:mainfrom
O4FDev:feat/picker-create-folder
Draft

feat(web): create folders from the add-project path picker#3723
O4FDev wants to merge 1 commit into
pingdotgg:mainfrom
O4FDev:feat/picker-create-folder

Conversation

@O4FDev

@O4FDev O4FDev commented Jul 6, 2026

Copy link
Copy Markdown

Summary

Adds the ability to create folders while browsing in the add-project path picker, without immediately adding them as a project.

Previously, typing a non-existent path and pressing Enter always created the directory and added it as a project. There was no way to create intermediate folders and keep browsing.

What's included

  • New filesystem.createDirectory RPC (contracts, server, client-runtime)
  • Picker shows Create folder "name" when the typed leaf has no exact match
  • Shift+Enter creates the folder and navigates into it (browse only)
  • Enter unchanged: create folder and add as project (or clone destination)
  • Footer hint and empty-state copy for discoverability

Design notes

  • Directory creation is server-side via WorkspaceEntries.createDirectory (parent must exist; idempotent if the folder already exists)
  • Uses AuthOrchestrationOperateScope for the new RPC
  • Client-only picker UX; no orchestration/project schema changes

Testing

  • vp check — pass
  • vp run typecheck — pass
  • Unit tests: filesystem.test.ts, WorkspaceEntries.test.ts, CommandPalette.logic.test.ts
  • Manual: desktop dev (bun run dev:desktop) — create folder via Shift+Enter, navigate in, then add project with Enter

Note

Medium Risk
Adds an authenticated but operate-scoped RPC that performs real mkdir on the host filesystem; path rules mirror browse, but misuse or bugs could still create directories outside user intent.

Overview
Introduces filesystem.createDirectory through contracts, client-runtime, WorkspaceEntries, and WebSocket RPC ( AuthOrchestrationOperateScope ), with typed failures mapped to client-facing errors.

The add-project path browser can show Create folder "name" when the typed leaf has no exact match; Shift+Enter (or the list action) creates the directory and refreshes browse into it, while Enter still adds the path as a project or clone destination. Footer and empty-state copy document the shortcut.

Server createDirectory reuses browse path resolution, requires an existing parent directory, is idempotent when the target is already a directory, and rejects files / missing parents / races (EEXIST).

Reviewed by Cursor Bugbot for commit bcccbf6. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Add folder creation to the add-project path picker in the command palette

  • Adds a filesystem.createDirectory RPC across contracts, server, and client, with typed input/result schemas and structured failure codes in filesystem.ts.
  • Implements WorkspaceEntries.createDirectory on the server, resolving paths, checking parent existence, and mapping mkdir errors to tagged error types.
  • Extends the command palette browse view to show a 'Create folder' action item (or Shift+Enter) when the query doesn't match an existing entry; on success, the palette navigates into the new folder.
  • Errors surface as toast notifications; the submit button reflects the busy state during creation.
📊 Macroscope summarized bcccbf6. 7 files reviewed, 0 issues evaluated, 0 issues filtered, 0 comments posted

🗂️ Filtered Issues

No issues evaluated.

Add a filesystem.createDirectory RPC and surface it in the browse picker
so users can create a missing folder and keep browsing without immediately
adding it as a project. The picker shows a Create folder action when the
typed leaf name has no exact match, Shift+Enter creates and navigates into
the folder, and Enter still adds or clones the project as before.
@coderabbitai

coderabbitai Bot commented Jul 6, 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

Run ID: 2f9e611f-258b-47e5-8243-c32156d791b1

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
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Jul 6, 2026

@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 2 potential issues.

Fix All in Cursor

❌ 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 bcccbf6. Configure here.

partialPath: input.partialPath,
directoryPath: resolvedDirectoryPath,
}),
),

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.

EEXIST breaks directory idempotency

Medium Severity

The createDirectory function can incorrectly fail with path_already_exists when a directory is created by another process between its initial stat check and the mkdir call. This breaks its intended idempotent behavior, causing RPC failures even when the directory exists.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit bcccbf6. Configure here.

? {
emptyStateMessage:
"Press Enter to create this folder and add it as a project.",
}

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.

Clone step hides folder hint

Medium Severity

During the clone destination step, the empty-state copy always says to press Enter to clone, even when a new folder name is typed and the footer shows Shift+Enter to create a folder. The browseCreateFolderName branch never runs because the confirm-step branch is checked first, so clone browsing never gets the Shift+Enter vs Enter guidance this PR added elsewhere.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit bcccbf6. Configure here.

@O4FDev O4FDev marked this pull request as draft July 6, 2026 00:11
@O4FDev

O4FDev commented Jul 6, 2026

Copy link
Copy Markdown
Author

Doing some further testing, it seems fine so far

Comment on lines +65 to +73
if (
folderName.length === 0 ||
input.exactEntry !== null ||
input.isBrowsePending ||
input.relativePathNeedsActiveProject ||
input.browseParentPath === null ||
input.browseParentPath === undefined ||
input.browseParentPath.length === 0
) {

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.logic.ts:65

getBrowseCreateFolderName returns "." and ".." as valid folder names. When the user types .. (or a query whose leaf is ..), the create-folder action navigates to the parent directory via appendBrowsePathSegment(..., "..") instead of creating a new folder — it performs the wrong operation and succeeds without creating anything. Consider rejecting ".", "..", and empty segments so these inputs do not produce a create-folder item.

Suggested change
if (
folderName.length === 0 ||
input.exactEntry !== null ||
input.isBrowsePending ||
input.relativePathNeedsActiveProject ||
input.browseParentPath === null ||
input.browseParentPath === undefined ||
input.browseParentPath.length === 0
) {
const folderName = input.browseFilterQuery.trim();
if (
folderName.length === 0 ||
folderName === "." ||
folderName === ".." ||
input.exactEntry !== null ||
input.isBrowsePending ||
input.relativePathNeedsActiveProject ||
input.browseParentPath === null ||
input.browseParentPath === undefined ||
input.browseParentPath.length === 0
) {
🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/web/src/components/CommandPalette.logic.ts around lines 65-73:

`getBrowseCreateFolderName` returns `"."` and `".."` as valid folder names. When the user types `..` (or a query whose leaf is `..`), the create-folder action navigates to the parent directory via `appendBrowsePathSegment(..., "..")` instead of creating a new folder — it performs the wrong operation and succeeds without creating anything. Consider rejecting `"."`, `".."`, and empty segments so these inputs do not produce a create-folder item.

@macroscopeapp

macroscopeapp Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

1 blocking correctness issue found. This PR introduces a new feature (folder creation in path picker) with ~550 lines of new logic across server and client. Three unresolved medium-severity bugs have been identified: a race condition in directory creation, missing UI hints during clone, and acceptance of ./.. as folder names.

You can customize Macroscope's approvability policy. Learn more.

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

Labels

size:L 100-499 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant