Skip to content

fix(media): open workspace media links in the file viewer

MacroscopeApp / Macroscope - Effect Service Conventions succeeded Sep 1, 2026 in 2m 13s

Effect Service Conventions: no issues found

No Effect service convention violations found in this pull request's changed TypeScript.

The prior finding on apps/server/src/http.ts (untyped Effect.tryPromise for the descriptor stat) has been addressed: statMediaFile in apps/server/src/assets/MediaFile.ts now wraps the failure in a Schema.TaggedErrorClass (MediaFileStatError) carrying path and the original cause.

Details

Note

Your check run agent prompt is: .macroscope/check-run-agents/effect-service-conventions.md
More information about how Check Run Agents work can be found in our Help Center.

Files examined for this check:

  • apps/server/src/assets/MediaFile.ts — namespace subpath imports (effect/Effect, effect/Schema, @effect/platform-node/NodeStream); Schema.TaggedErrorClass failures with structured path plus preserved cause; Effect.acquireRelease correctly scopes the descriptor; the @effect-diagnostics nodeBuiltinImport:off directive has an adjacent justification comment.
  • apps/server/src/assets/AssetAccess.ts — the new media-file branch of issueAssetUrl and resolveAsset construct existing tagged asset errors at the failure boundary and map underlying failures as cause; no service-instance injection, module globals, ManagedRuntime.make, or runPromise introduced.
  • apps/server/src/http.ts — assetFileResponse acquires FileSystem.FileSystem from the environment and routes descriptor metadata through the tagged statMediaFile helper.
  • apps/server/src/assets/AssetAccess.test.ts, apps/server/src/http.test.ts — filesystem swaps are legitimate test seams; the diagnostic suppression carries an explanation.
  • Client changes (apps/web/src/assets/assetUrls.ts, apps/mobile/src/state/assets.ts, both use-atom-query-runner.ts, packages/contracts/src/assets.ts, packages/shared/src/filePreview.ts) contain no Effect service definitions or runtime boundaries requiring changes under these conventions.

🔍 Agent activity — 9 tool calls

💭 Let me check the current head versions of the changed Effect-related files—MediaFile.ts, AssetAccess.ts, and http.ts—since my earlier statMediaFile finding was already addressed.

1. browse_code — apps/server/src/assets/MediaFile.ts

2. browse_code — apps/server/src/http.ts

💭 With that finding resolved, I'm now scanning MediaFile.ts for any remaining convention issues in the current diff — checking the namespace imports, the tagged error classes with path and cause, and the diagnostics directive comment. Nothing stands out as a clear violation here. I'm also checking AssetAccess.test.ts for the explanation comment, and looking at the release logic in openMediaFile — the Effect.promise call on file handle close seems acceptable since close errors become defects. I'm noting that openMediaFile returns an acquireRelease requiring a Scope, and confirming that issueAssetUrl scopes it properly while resolveAsset holds the descriptor for the request scope instead — this doesn't look like a genuine scope leak or service convention problem. The streamMediaFile function is a plain function so it's out of scope for Effect conventions, and the React hook files in mobile and web look fine too. Errors in AssetAccess.ts are constructed inline and wrapped with Effect.mapError including cause, which checks out. Now I want to narrow my focus specifically to what changed between the last reviewed commit and the current head.

3. git_tools — b45ff76..d84a531

💭 The branch was likely force-pushed or rebased, so I should look at the current head diff to check Effect conventions in the server code, starting with the media-file section of AssetAccess.ts.

4. git_tools — media-file",|openMediaFile|statMediaFile|streamMediaFile

5. browse_code — apps/server/src/assets/AssetAccess.ts

💭 This looks conventional overall. I'm checking resolveAsset's error handling around line 603, which falls back to null after logging the cause with the file path—consistent with existing patterns since paths aren't sensitive credentials. Now moving on to check the mobile/web files for related usage. I'm verifying that the diagnostic suppression comment in AssetAccess.test.ts has proper justification, and confirming the test's use of mocked filesystem and runtime helpers are legitimate test seams rather than production code smells. I'm also checking that promise-based cleanup calls like file handle closing are treated as acceptable finalizers, then scanning the web/mobile changes for any consolidated effect imports.

6. git_tools — from "effect"

7. browse_code — apps/server/src/assets/AssetAccess.ts

💭 I should double check the http.ts route section around 360-390 for HEAD handling and descriptor scope. I also want to verify whether MediaFile.ts errors follow the same "message derived from attributes" pattern as other tagged errors in the repo, like AssetAccess in contracts, by checking a sample such as WorkspaceFileSystem.

8. git_tools — Schema.TaggedErrorClass

💭 I'm noticing most error classes in the repo follow the convention of a message getter, but the new MediaFileOpenError/MediaFileStatError lack one. The style guide requires deriving message from structured attributes rather than storing unstructured messages, but doesn't strictly mandate a getter—and there's precedent like PromptRejectedError omitting one too, so this is worth flagging but not a hard requirement. I'm also weighing whether MediaFileStatError not being exported matters, since it's part of statMediaFile's public error channel and callers can't reference the type—arguably a usability issue, though not an explicit convention violation. Let me check how http.ts handles this new error in its route folding logic.

9. browse_code — apps/server/src/http.ts

💭 I notice the orElseSucceed swallowing the error was pre-existing code, not part of this diff, so a new failure type now flows through it silently but that's not a new concern introduced by this change—no need to flag it. The file handle close in the release path could turn into a defect if it fails during finalization, but that's minor and not on the convention violation list. Checking the new mobile hook using useAtomQueryRunner, I don't see any Effect service issues there either. Overall I'm not finding any genuine convention violations to report—my earlier finding was already fixed, so I should conclude with no findings and avoid posting any comments.


Agent Credits: 175 credits

Token usage: 14 uncached input · 795,032 cache-read input · 184,028 cache-write input · 4,598 output
Agent Credits may also include non-token charges from external tools such as web research.