Skip to content

Refactor workspace reads to Effect FileSystem#4050

Draft
cursor[bot] wants to merge 2 commits into
mainfrom
cursor/idiomatic-effect-patterns-839d
Draft

Refactor workspace reads to Effect FileSystem#4050
cursor[bot] wants to merge 2 commits into
mainfrom
cursor/idiomatic-effect-patterns-839d

Conversation

@cursor

@cursor cursor Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

What Changed

  • Replaced the workspace read path's node:fs/promises and Effect.tryPromise calls with the injected Effect FileSystem service.
  • Used scoped Effect file handles, File.stat, File.readAlloc, and Option for empty reads.
  • Converted the focused test suite to @effect/vitest assertions, asserted normalized PlatformError data, and added preview-limit coverage.

Why

The read path bypassed an Effect service that was already injected and used by the write path. Keeping filesystem work inside Effect makes resource safety, structured failures, and layer-based testing consistent end-to-end.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • No UI changes

Validation:

  • pnpm exec vp test run src/workspace/WorkspaceFileSystem.test.ts (10 passed)
  • pnpm exec vp check (0 errors; 9 pre-existing warnings)
  • pnpm exec vp run typecheck (15 tasks passed)
Open in Web View Automation 

Note

Refactor workspace readFile to use Effect FileSystem service APIs

  • Replaces manual node:fs/promises calls (open/stat/read/close) with FileSystem.open, FileSystem.stat, and handle.readAlloc from the Effect platform, using Effect.scoped for automatic resource cleanup.
  • Adds a new test case verifying that readFile returns at most the 1 MiB preview limit, sets byteLength to the full file size, and marks truncated: true.
  • Behavioral Change: I/O failures are now wrapped as WorkspaceFileSystemOperationError with a PlatformError (including a reason tag such as NotFound) in the cause field, rather than raw Node.js errors.
📊 Macroscope summarized ea7294b. 1 file reviewed, 0 issues evaluated, 0 issues filtered, 0 comments posted

🗂️ Filtered Issues

No issues evaluated.

cursoragent and others added 2 commits July 16, 2026 16:06
Co-authored-by: Julius Marminge <juliusmarminge@users.noreply.github.com>
Co-authored-by: Julius Marminge <juliusmarminge@users.noreply.github.com>
@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Jul 16, 2026
const stat = yield* Effect.tryPromise({
try: () => handle.stat(),
catch: (cause) =>
return yield* Effect.scoped(

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 workspace/WorkspaceFileSystem.ts:182

When the file handle close fails, readFile now throws an untyped defect instead of a WorkspaceFileSystemOperationError with operation close. The old code wrapped handle.close() failures in a typed error; Effect.scoped delegates cleanup to FileSystem.open's finalizer, which runs Effect.orDie(nodeClose(fd)), so a close failure terminates the effect as a defect rather than through the service's advertised error channel. Consider using Effect.acquireRelease (or Effect.acquireUseRelease) with an explicit close error mapping so close failures remain typed errors.

🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file @apps/server/src/workspace/WorkspaceFileSystem.ts around line 182:

When the file handle close fails, `readFile` now throws an untyped defect instead of a `WorkspaceFileSystemOperationError` with operation `close`. The old code wrapped `handle.close()` failures in a typed error; `Effect.scoped` delegates cleanup to `FileSystem.open`'s finalizer, which runs `Effect.orDie(nodeClose(fd))`, so a close failure terminates the effect as a defect rather than through the service's advertised error channel. Consider using `Effect.acquireRelease` (or `Effect.acquireUseRelease`) with an explicit `close` error mapping so close failures remain typed errors.

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

Labels

size:M 30-99 changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant