Skip to content

feat(files): folder operations for the File block, and folders as scope - #7388

Closed
mzxchandra wants to merge 11 commits into
stagingfrom
feat/file-folder-operations
Closed

feat(files): folder operations for the File block, and folders as scope#7388
mzxchandra wants to merge 11 commits into
stagingfrom
feat/file-folder-operations

Conversation

@mzxchandra

Copy link
Copy Markdown
Contributor

Replaces #7377, which is the same change spread over 11 commits and two staging merges. Reviewers were reading a diff-of-diffs and finding issues in the fixes rather than in the change; this is one commit against current staging.

What

Adds folder operations to file_v5 and the agent tool surface, and makes a folder a scope on the file operations that already existed rather than a second set of operations beside them.

New operations: List, Create Folder, Move Folder, Delete Folder, Restore Folder, Move File.

List answers "what is in here" — subfolders and files together, direct children by default, whole subtree under Recursive, subject to Max Depth and Search. Entries are a discriminated union on kind; the listing is capped with a truncated flag rather than unbounded now that it includes files.

Read / Get Content / Compress / Append gain an optional Folder above their file picker. It narrows what the picker offers; on the three read operations it also stands for that folder's files when none are picked, resolved at run time so a file added later is included. Append only narrows the picker — but the folder does travel when the advanced entry supplies a name rather than an id, because a name is only unique inside a folder.

Write gains a folder destination, above File Name, because it names where before what.

Where to spend attention

Path handling. Two spellings circulate: the stored display path, which backslash-escapes a slash inside a folder name (Reports/Q3\/Q4), and the canonical percent-encoded path the tools take (/Reports/Q3%2FQ4). A folder genuinely named Q3/Q4 is one level in both and two if either is split on /. folderPathSegments picks the parser by the leading slash; resolveFolderIdsForPaths, isFileInFolderScope and selectDirectoryEntries are pure and tested against that case. Where a folder is known, resolution goes by id and never builds a path-shaped reference.

Delete's recursive is a guard, not a scope. Without it, deleting a non-empty folder fails, and it is user-only so a model asked to "clean up" cannot set it on a guess. Deliberately the inverse of the read family's Include Subfolders, which is a scope and defaults on.

The authz widening. Five operations move from copilot-only delegation to also admit the executor — files.list and files.folders.list for file_list, and files.folders.update / delete / restore for their tools. Principal kinds are unchanged and copilot keeps everything it had; the only delta is delegatedServices gaining 'executor', without which a workflow run cannot reach these at all.

Canonical pairs. Every folder field is a single-select tree paired with a manual text entry. The pair is load-bearing, not a convenience: < reference autocomplete comes from TagDropdown, which scans for the last < before the cursor, so it can only live on a text surface. The one folder field that never travels (the picker-narrowing scope) deliberately has no pair.

Known costs, already argued

  • list reads the workspace's full folder and file lists and filters in memory, matching ~10 existing callers of listAllWorkspaceFiles. Output is capped with truncated; the read is not. queryWorkspaceFilePage is the paged alternative, worth doing across all callers rather than only this one.
  • Knowledge and table folder trees have no realtime broadcast, so they wait out their stale time; only workspace files invalidate live.
  • Recursive folder listing exists in staging's knowledge and table application layers but is unreachable through their public query schemas. Real, but not this change's to fix — flagged to those slices.

Testing

tsc clean; 4209 tests across blocks, tools/file, lib/internal/file, lib/workspace-files, lib/workflows; all 45 audits; check:api-validation; check:client-boundary; biome.

Coverage is deliberately weighted at the wiring, because that is where this change broke repeatedly: a contract accepting a field is not the same as the operation reading it. Tests assert a folder-only read expands, a missing folder refuses rather than reading nothing, write lands in the chosen folder and still lands at root without one, an ambiguous name inside a scope refuses instead of picking, and a folder named Q3/Q4 survives both scope resolution and overwrite lookup.

Browser end-to-end is in progress against this branch.

Adds folder operations to file_v5 and the agent tool surface, and makes a folder
a scope on the file operations that already existed rather than a second set of
operations beside them.

New operations: List, Create Folder, Move Folder, Delete Folder, Restore Folder,
and Move File. List answers "what is in here" — subfolders and files together,
direct children by default, the whole subtree under Recursive, subject to Max
Depth and Search. Entries are a discriminated union on kind, and the listing is
capped with a truncated flag rather than unbounded now that it includes files.

Read, Get Content, Compress and Append gain an optional Folder above their file
picker. It narrows what the picker offers; on the three read operations it also
stands for that folder's files when none are picked, resolved when the workflow
runs so a file added later is included. Append only narrows the picker, but the
folder does travel when the advanced entry supplies a name rather than an id,
because a name is only unique inside a folder. Write gains a folder destination,
placed above File Name because it names where before it names what.

Two things are worth a reviewer's attention.

Path handling. Two spellings circulate: the stored display path, which
backslash-escapes a slash inside a folder name, and the canonical
percent-encoded path the tools take. A folder genuinely named "Q3/Q4" is one
level in both and two if either is split on "/". folderPathSegments picks the
parser by the leading slash the canonical form always carries, and
resolveFolderIdsForPaths, isFileInFolderScope and selectDirectoryEntries are
pure and tested against exactly that case. Where a folder is known, the code
resolves by id and never builds a path-shaped reference at all.

Delete Folder's recursive flag is a guard, not a scope. Without it, deleting a
non-empty folder fails, and it is user-only so a model asked to clean up a
folder cannot set it on a guess. This is deliberately the inverse of the read
family's Include Subfolders, which is a scope and defaults on.

Five file operations widen from copilot-only delegation to admit the executor,
each justified by a tool in this change: files.list and files.folders.list for
file_list, and files.folders.update / delete / restore for their tools. Principal
kinds are unchanged and copilot keeps every operation it had.
@vercel

vercel Bot commented Sep 2, 2026

Copy link
Copy Markdown

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

1 Skipped Deployment
Project Deployment Actions Updated
docs Skipped Skipped Sep 2, 2026 9:03am UTC

Request Review

@greptile-apps

greptile-apps Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR expands the File block and agent tool surface with folder-aware file operations and folder scopes.

  • Adds listing, creation, movement, deletion, and restoration of folders, plus file movement.
  • Adds folder-scoped read, content extraction, compression, append, and write behavior.
  • Introduces canonical folder-path parsing, directory selection, realtime invalidation, UI selectors, contracts, generated tool metadata, documentation, and focused tests.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
apps/sim/blocks/blocks/file.ts Extends File block configuration and parameter mapping with folder operations and folder-scoped file inputs.
apps/sim/lib/internal/file/operations.ts Wires folder-aware file behavior and new folder-management operations into internal execution.
apps/sim/lib/workspace-files/application/workspace-file-folders.ts Implements the workspace application layer for creating, moving, deleting, and restoring file folders.
apps/sim/lib/workspace-files/folder-path-selection.ts Resolves canonical folder paths and evaluates file membership in folder scopes.
apps/sim/lib/workspace-files/directory-listing.ts Produces bounded folder-and-file directory listings with recursive depth and search controls.
apps/sim/app/workspace/[workspaceId]/hooks/use-workspace-invalidation-room.ts Reference-counts shared realtime room subscriptions so sibling consumers do not leave prematurely.
apps/sim/blocks/blocks/file-folders.test.ts Exercises File block folder-operation mapping and validates mapped payloads against real contract schemas.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  UI[File block and agent tools] --> Contract[File operation contracts]
  Contract --> Executor[Internal file executor]
  Executor --> Paths[Canonical folder path resolution]
  Paths --> Operations[Workspace file and folder operations]
  Operations --> Storage[Workspace files and folders]
  Storage --> Realtime[Workspace invalidation events]
  Realtime --> UI
Loading

Reviews (4): Last reviewed commit: "fix(files): scope the picker from either..." | Re-trigger Greptile

Comment thread apps/sim/blocks/blocks/file-folders.test.ts

@cubic-dev-ai cubic-dev-ai 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.

All reported issues were addressed across 46 files

Re-trigger cubic

Comment thread apps/sim/lib/workspace-files/application/workspace-file-folders.ts Outdated
Comment thread apps/sim/tools/file/compress.ts
Comment thread apps/sim/lib/api/contracts/tools/file.ts
Comment thread apps/sim/lib/internal/file/operations.ts
Comment thread apps/sim/lib/internal/file/operations.ts Outdated
Comment thread apps/sim/lib/workspace-files/folder-display-path.ts
Comment thread apps/sim/lib/workspace-files/application/workspace-file-folders.test.ts Outdated
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
…s.test.ts

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
@mzxchandra

Copy link
Copy Markdown
Contributor Author

@greptile

@mzxchandra

Copy link
Copy Markdown
Contributor Author

@cubic review

@cubic-dev-ai

cubic-dev-ai Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

@cubic review

@mzxchandra I have started the AI code review. It will take a few minutes to complete.

@cubic-dev-ai cubic-dev-ai 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.

Review completed against the latest diff

Fix all with cubic | Re-trigger cubic

Comment thread apps/sim/lib/internal/file/operations.ts
@mzxchandra

Copy link
Copy Markdown
Contributor Author

@greptile

@mzxchandra

Copy link
Copy Markdown
Contributor Author

@cubic review

@cubic-dev-ai

cubic-dev-ai Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

@cubic review

@mzxchandra I have started the AI code review. It will take a few minutes to complete.

@cubic-dev-ai cubic-dev-ai 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.

All reported issues were addressed across 48 files

Fix all with cubic | Re-trigger cubic

Comment thread apps/sim/blocks/blocks/file.ts
@mzxchandra

Copy link
Copy Markdown
Contributor Author

@greptile

@mzxchandra

Copy link
Copy Markdown
Contributor Author

@cubic review

@cubic-dev-ai

cubic-dev-ai Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

@cubic review

@mzxchandra I have started the AI code review. It will take a few minutes to complete.

@cubic-dev-ai cubic-dev-ai 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.

No issues found across 48 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Re-trigger cubic

@icecrasher321

Copy link
Copy Markdown
Collaborator

Will merge downstream one directly into staging

@waleedlatif1
waleedlatif1 deleted the feat/file-folder-operations branch September 3, 2026 05:45
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.

2 participants