Skip to content

Use Effect FileSystem in workspace services#3535

Draft
cursor[bot] wants to merge 4 commits into
mainfrom
cursor/idiomatic-effect-patterns-d60d
Draft

Use Effect FileSystem in workspace services#3535
cursor[bot] wants to merge 4 commits into
mainfrom
cursor/idiomatic-effect-patterns-d60d

Conversation

@cursor

@cursor cursor Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

What Changed

  • Reworked WorkspaceFileSystem.readFile to use Effect FileSystem realpath/open/stat/read APIs instead of node:fs/promises wrapped in Effect.tryPromise.
  • Reworked WorkspaceEntries.browse to use Effect FileSystem.readDirectory/stat and structured PlatformError handling for permission-denied directory reads.
  • Updated workspace tests to assert structured PlatformError causes and override the file-system service capability instead of mocking node:fs/promises.

Why

These changes make the workspace subsystem more idiomatic Effect: I/O now flows through Effect services, errors stay structured, and tests can override the granular file-system capability without module mocks.

UI Changes

Not applicable; no UI changes.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes
  • I included a video for animation/interaction changes
Open in Web View Automation 

Note

Replace Node.js fs/promises with Effect FileSystem in workspace services

  • WorkspaceFileSystem.ts replaces NodeFSP calls with Effect FileSystem for realPath, open, stat, and read in readFile, using Effect.scoped instead of manual acquire/release.
  • WorkspaceEntries.ts replaces NodeFSP.readdir with fileSystem.readDirectory + per-entry fileSystem.stat to filter for directories; only PermissionDenied errors return an empty listing — other failures surface as WorkspaceEntriesReadDirectoryError.
  • Tests updated to inject a custom FileSystem layer and assert PlatformError causes (e.g. NotFound, PermissionDenied) instead of Node.js ErrnoException codes.
  • Behavioral Change: errors from file/directory operations now carry PlatformError as the wrapped cause rather than Node.js errors, changing the error structure visible to callers.

Macroscope summarized 40624c1.

cursoragent and others added 4 commits June 23, 2026 16:08
Co-authored-by: Julius Marminge <juliusmarminge@users.noreply.github.com>
Co-authored-by: Julius Marminge <juliusmarminge@users.noreply.github.com>
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:L 100-499 changed lines (additions + deletions). labels Jun 23, 2026

@macroscopeapp macroscopeapp 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.

One Effect convention issue found: use Effect.catchTags rather than Effect.catchTag for handling statically known tagged failures.

Posted via Macroscope — Effect Service Conventions

Comment on lines +191 to 202
Effect.catchTag("PlatformError", (cause) =>
cause.reason._tag === "PermissionDenied"
? Effect.succeed([])
: Effect.fail(
new WorkspaceEntriesReadDirectoryError({
cwd: input.cwd,
partialPath: input.partialPath,
parentPath,
cause,
}),
),
),

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.

Use Effect.catchTags({ ... }) instead of Effect.catchTag for known tagged failures (the convention applies even when handling a single tag). The branch on cause.reason._tag for PermissionDenied remains a valid structural check inside the handler.

Suggested change
Effect.catchTag("PlatformError", (cause) =>
cause.reason._tag === "PermissionDenied"
? Effect.succeed([])
: Effect.fail(
new WorkspaceEntriesReadDirectoryError({
cwd: input.cwd,
partialPath: input.partialPath,
parentPath,
cause,
}),
),
),
Effect.catchTags({
PlatformError: (cause) =>
cause.reason._tag === "PermissionDenied"
? Effect.succeed([])
: Effect.fail(
new WorkspaceEntriesReadDirectoryError({
cwd: input.cwd,
partialPath: input.partialPath,
parentPath,
cause,
}),
),
}),

Posted via Macroscope — Effect Service Conventions

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: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