Skip to content

feat(files): folders, multiselect, vfs update#4572

Open
icecrasher321 wants to merge 58 commits into
stagingfrom
feat/workspace-files-folders
Open

feat(files): folders, multiselect, vfs update#4572
icecrasher321 wants to merge 58 commits into
stagingfrom
feat/workspace-files-folders

Conversation

@icecrasher321
Copy link
Copy Markdown
Collaborator

@icecrasher321 icecrasher321 commented May 12, 2026

Summary

Add folders, multiselect for files, update VFS to work with this.

Type of Change

  • New feature

Testing

Tested manually

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

@vercel
Copy link
Copy Markdown

vercel Bot commented May 12, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped May 15, 2026 6:30am

Request Review

@cursor
Copy link
Copy Markdown

cursor Bot commented May 12, 2026

PR Summary

Medium Risk
Moderate risk due to broad refactors of multiple API routes (files, workflows, folders, credentials, schedules, MCP) to delegate core logic to orchestration helpers, which could subtly change validation, permissions, and side effects (telemetry/audit). New file-folder endpoints and zip download add new paths that need coverage for limits and access control.

Overview
Adds first-class workspace file folders and bulk file actions: new APIs to list/create/update/delete/restore folders, move or bulk-archive selected files/folders, and download selections as a size/count-limited zip.

Updates existing file upload/manage flows to be folder-aware (folder metadata on presigned/register/formdata upload; file/manage gains move and path-based folder creation) and introduces new files UI primitives (selection action bar, delete confirmation, context menu) plus Resource table support for shift-select and row drag/drop.

Refactors several existing endpoints (credentials, folders, workflows, schedules, tables/knowledge restores, MCP server/tool routes, workspace API key create, v1 file delete) to call perform* orchestration functions and standardize error-to-HTTP status mapping, removing inline DB/mutation logic (and some route-level audit/telemetry handling).

Reviewed by Cursor Bugbot for commit a3d1010. Configure here.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 12, 2026

Greptile Summary

This PR adds folder support, multi-select, and drag-and-drop to the workspace files view, alongside a comprehensive VFS update. It introduces new API routes, a new workspace_file_folders DB table with a self-referential FK, and a full lifecycle/orchestration layer.

  • Files manager overhaul: workspace-file-folder-manager.ts handles folder CRUD, path computation, move/archive/restore — all guarded by pg_advisory_xact_lock inside transactions.
  • VFS update: materializeFiles now populates folderPath as a separate field, and buildWorkspaceMd groups files under folder headings. Archived file-folders are included in the recently-deleted VFS section.
  • UI overhaul: files.tsx gains breadcrumb navigation, folder rows, multi-select, drag-and-drop, action bar, and context menus.

Confidence Score: 5/5

Safe to merge — all critical concerns from earlier review rounds are fully addressed in the latest commit.

All previously flagged issues (advisory-lock placement, 23505 mapping to clean 409s, restoreWorkspaceFileFolder nulling out parentId when parent is still archived, VFS folderPath field separation, download-route error leak) have been resolved. Remaining feedback is performance and UX polish that does not block correctness for normal usage paths.

workspace-file-folder-manager.ts — updateWorkspaceFileFolder still resolves the return path via per-ancestor SELECTs; files.tsx — stale folderId URL shows an empty table without redirecting

Important Files Changed

Filename Overview
apps/sim/lib/uploads/contexts/workspace/workspace-file-folder-manager.ts New file implementing all folder CRUD, move, archive, and restore logic. Advisory locks inside transactions address concurrent mutation concerns. updateWorkspaceFileFolder still returns via mapFolderWithPath (N+1 per-ancestor SELECT pattern), whereas getWorkspaceFileFolder was updated to use buildWorkspaceFileFolderPathMap.
apps/sim/lib/workspace-files/orchestration/file-folder-lifecycle.ts Clean orchestration layer; all typed error classes properly caught and mapped to conflict/not_found/internal codes. Audit events emitted for all operations.
apps/sim/app/api/workspaces/[id]/files/download/route.ts New download-as-zip route with path deduplication, safeZipPath sanitization, and file-count/byte-size guards. Catch block returns hardcoded error string (no leak).
apps/sim/app/workspace/[workspaceId]/files/files.tsx Large UI refactor. currentFolderId from URL has no redirect guard when the folder no longer exists.
packages/db/schema.ts Adds workspace_file_folders table with self-referential parentId FK ON DELETE SET NULL, partial unique index for active folders, and folderId FK on workspace_files.
apps/sim/lib/copilot/vfs/workspace-vfs.ts VFS now stores files at files/{folderPath}/{name}/meta.json and returns folderPath as a separate field. buildWorkspaceMd correctly groups files by folderPath.
apps/sim/app/api/workspaces/[id]/files/move/route.ts Move route with proper permission checks, typed error mapping (conflict→409, not_found→404, validation→400), and PostHog events.
apps/sim/lib/api/contracts/workspace-file-folders.ts New contract file with Zod schemas for all folder endpoints. queryIdListSchema handles comma-separated strings and arrays.

Reviews (16): Last reviewed commit: "improve error codes" | Re-trigger Greptile

Comment thread apps/sim/lib/uploads/contexts/workspace/workspace-file-folder-manager.ts Outdated
Comment thread apps/sim/app/api/workspaces/[id]/files/move/route.ts
Comment thread packages/db/schema.ts
Comment thread apps/sim/app/workspace/[workspaceId]/files/files.tsx
Comment thread apps/sim/app/workspace/[workspaceId]/files/files.tsx
@icecrasher321
Copy link
Copy Markdown
Collaborator Author

@greptile

@icecrasher321
Copy link
Copy Markdown
Collaborator Author

bugbot run

Comment thread apps/sim/lib/uploads/contexts/workspace/workspace-file-folder-manager.ts Outdated
Comment thread apps/sim/app/workspace/[workspaceId]/files/files.tsx
Comment thread apps/sim/hooks/queries/workspace-file-folders.ts
Comment thread apps/sim/lib/uploads/client/download.ts Outdated
@icecrasher321
Copy link
Copy Markdown
Collaborator Author

@greptile

@icecrasher321
Copy link
Copy Markdown
Collaborator Author

bugbot run

Comment thread apps/sim/lib/uploads/contexts/workspace/workspace-file-manager.ts Outdated
Comment thread apps/sim/app/api/workspaces/[id]/files/folders/[folderId]/route.ts
@icecrasher321
Copy link
Copy Markdown
Collaborator Author

@greptile

@icecrasher321
Copy link
Copy Markdown
Collaborator Author

bugbot run

Comment thread apps/sim/app/workspace/[workspaceId]/files/files.tsx
Comment thread apps/sim/app/api/workspaces/[id]/files/download/route.ts
Comment thread apps/sim/lib/uploads/contexts/workspace/workspace-file-manager.ts Outdated
@icecrasher321
Copy link
Copy Markdown
Collaborator Author

bugbot run

@icecrasher321
Copy link
Copy Markdown
Collaborator Author

@greptile

Comment thread apps/sim/app/workspace/[workspaceId]/files/files.tsx
Comment thread apps/sim/app/workspace/[workspaceId]/files/files.tsx Outdated
Comment thread apps/sim/app/api/workspaces/[id]/files/download/route.ts
@icecrasher321
Copy link
Copy Markdown
Collaborator Author

bugbot run

@icecrasher321
Copy link
Copy Markdown
Collaborator Author

@greptile

Comment thread apps/sim/app/workspace/[workspaceId]/files/files.tsx
Comment thread apps/sim/lib/uploads/contexts/workspace/workspace-file-manager.ts
@icecrasher321
Copy link
Copy Markdown
Collaborator Author

bugbot run

@waleedlatif1
Copy link
Copy Markdown
Collaborator

@greptile

@waleedlatif1
Copy link
Copy Markdown
Collaborator

@cursor review

Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 90a6050. Configure here.

@icecrasher321
Copy link
Copy Markdown
Collaborator Author

@greptile

@icecrasher321
Copy link
Copy Markdown
Collaborator Author

bugbot run

Comment thread apps/sim/app/api/workspaces/[id]/files/download/route.ts
Comment thread apps/sim/app/api/mcp/servers/route.ts Outdated
Comment thread apps/sim/app/api/folders/route.test.ts
@icecrasher321
Copy link
Copy Markdown
Collaborator Author

bugbot run

@icecrasher321
Copy link
Copy Markdown
Collaborator Author

@greptile

Comment thread apps/sim/app/api/folders/route.ts
@icecrasher321
Copy link
Copy Markdown
Collaborator Author

bugbot run

@icecrasher321
Copy link
Copy Markdown
Collaborator Author

@greptile

Copy link
Copy Markdown

@cursor cursor Bot left a comment

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 and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit a3d1010. Configure here.

return NextResponse.json(
{ success: false, error: result.error },
{ status: result.errorCode === 'conflict' ? 409 : 400 }
)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Folder endpoints return 400 for internal server errors

Medium Severity

The workspace file folder error-status mapping defaults to 400 for unknown or internal errorCode values, unlike the sibling file endpoints (e.g. performRenameWorkspaceFile) that correctly default to 500. If the orchestration layer returns an unexpected internal error, the client receives a 400 Bad Request instead of 500 Internal Server Error, misattributing the fault to the client and making debugging harder.

Additional Locations (2)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit a3d1010. Configure here.

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.

3 participants