Skip to content

fix(desktop): resolve bot review comments on profile tests

MacroscopeApp / Macroscope - Effect Service Conventions failed Aug 14, 2026 in 2m 51s

Effect Service Conventions: 1 issue found

apps/desktop/src/shell/DesktopShellEnvironment.test.ts:377 — assert.equal(env.PATH, "${mockDir}") cannot hold. When skipProfile is taken, installWindowsEnvironment assigns config.env.PATH = staticPaths.value, and staticPaths merges knownWindowsCliDirs(config.env) (the four USERPROFILE-derived directories seeded by this test) ahead of the original PATH entry. Asserting that the quoted entry is still present (includes) covers the intent without depending on the merge order.

No other convention violations were found in the changed scope.

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.

Conventions verified as satisfied

  • Imports: both touched files use namespace subpath imports (import * as FileSystem from "effect/FileSystem"), matching the rest of the repository; no consolidated named imports from "effect".
  • Dependency acquisition: installWindowsEnvironment declares FileSystem.FileSystem in its Effect.fn.Return requirements and acquires it with yield* FileSystem.FileSystem; make still resolves the service from the environment and layer remains the canonical export. No module globals, ManagedRuntime.make, or runPromise were introduced.
  • Test seams: providing a stub FileSystem through Effect.provideService in runShellEnvironment is a legitimate test-only injection; production construction is unchanged.
  • Error handling: Effect.catchIf((err) => err.reason._tag === "NotFound", ...) is a genuine structural predicate on the underlying platform error code and matches existing usage (T3ProjectFileLoader.ts, DesktopBackendConfiguration.ts). The surrounding Effect.orElseSucceed intentionally collapses the whole channel to a boolean, consistent with the exists probe at line 559 of the same file.
  • Test error construction: stubs now use the typed PlatformError.systemError({ _tag: "NotFound", module, method, pathOrDescriptor }) constructor, matching repository-wide usage.
  • Change discipline: the comment documenting why the two PowerShell probes run concurrently was retained, and the new tests are focused on the behavior change rather than restating the refactor.

Behavioral trace of the four new tests

  1. quotes and no fnm — nodeFound = true, profileMentionsFnm = false, probes skipped; PATH assertion is wrong (reported).
  2. profile references fnm — profileMentionsFnm = true, both probes run, FNM_DIR hydrated; assertions hold.
  3. profile exists without fnm — probes skipped; assertion holds.
  4. node in knownWindowsCliDirs — LOCALAPPDATA expands to ...\Programs\nodejs, probes skipped, PATH contains nodejs; assertions hold.

🔍 Agent activity — 1 tool call

💭 Checking the current state of the PR at commit 0249c45 to see what issues were flagged in previous runs and reviewing the files now. Looking at the catchIf usage at line 417-420, it's checking for a structural predicate on the underlying error — specifically err.reason._tag === "NotFound" — which aligns with the convention for this pattern. Now moving on to review the test file. The test count is now at 354. I'm checking the order of Effect operations — specifically whether provideService for FileSystem followed by provide for NodeServices causes conflicts. The key insight is that once FileSystem is provided through provideService, that requirement is satisfied, so the subsequent provide call won't override it but rather supplies the remaining dependencies. Now I'm verifying the mock FileSystem cast and the PlatformError.systemError constructor — whether it accepts the right parameters and if the error structure has the expected reason._tag property in Effect v4. The error handling approach is consistent with the repo's conventions—using catchIf for structural predicates like checking error tags, then orElseSucceed to intentionally collapse the error channel into a success case, which aligns with existing patterns in the file. For the test setup, the mockFs cast with as unknown as FileSystem.FileSystem is a pragmatic choice for a test double, though the repo typically spreads the real service and overrides specific methods. The current approach works fine for focused behavior tests. The service layering with provideService followed by provide(NodeServices.layer) needs careful ordering—I should verify that FileSystem gets properly resolved before downstream dependencies try to use it. I need to check the rest of the file to see how the layer and FileSystem requirement are defined in the make section. Looking at the Effect conventions in the code, the production setup properly injects FileSystem through the environment in make. For the diff itself, I'm checking for convention violations: the catchIf with a structural predicate on the error tag is allowed, orElseSucceed wrapping the generator is legitimate, and I'm starting to examine the test mock setup. The test uses a partial FileSystem stub cast with as unknown as, which isn't forbidden by the conventions. The key question is whether providing FileSystem outside the layer still reaches it — and yes, since Effect.provide(DesktopShellEnvironment.layer) leaves FileSystem as an unmet requirement in the outer context, a later provideService call satisfies it. But I need to check the ordering: when provideService(FileSystem, fs) is applied before Effect.provide(NodeServices.layer), and NodeServices.layer also provides FileSystem, I'm wondering how Effect merges these contexts... Actually, in Effect v4, provideService wraps the effect and adds the service at that point, so the inner provideService takes precedence when the outer layer is applied. That's correct. Now I'm checking whether the tests actually pass logically — specifically whether the mock behavior aligns with what the code expects. The first test sets PATH with quotes and USERPROFILE, merges known directories with PATH, then iterates through them stripping quotes. The exists mock returns true for any path containing "node.exe", so the first directory should find it. For the profile check, readFile fails with NotFound, which gets caught and returns false, so skipProfile becomes true and config.env.PATH gets set to the merged static paths. But here's the issue: mergePaths combines the known Windows CLI directories with the original PATH value, so the final PATH would include all those directories plus the original quoted path. The test then asserts that env.PATH equals just the quoted temp path, which would fail because mergePaths produces a longer concatenated string. I need to check what mergePaths actually does — whether it deduplicates or normalizes paths. Also, config.env is actually process.env in the implementation, so the test's use of withProcessEn... I'm seeing that the test is checking whether the PATH environment variable gets set correctly after filtering out known Windows CLI directories, but the assertion is expecting only the mock temp directory to remain, which doesn't match what's actually being constructed. The test itself appears to be flawed. Looking at test 4, I'm checking how the PATH gets built when LOCALAPPDATA is set to the mock temp directory, which should contribute additional Node.js and Volta paths to the environment. I'm realizing the issue might be with how the layer is constructed — make reads process.env when the layer is built, but withProcessEnv sets process.env before the effect runs, so there's a timing mismatch between when the environment is captured and when it's actually used. Looking at the other conventions: Effect.all with concurrency options is fine, there's some minor duplication in how staticPaths gets computed, and the profile file reading with timeout handling looks correct. I should check whether Effect.catchIf on the file system read is the right approach here. The mock setup using as unknown as follows the repo's testing idiom, so that's not a violation. And checkProfileMentionsFnm correctly returns true when USERPROFILE is missing. The real issue I'm circling back to is whether that first test assertion aligns with the change discipline requirement — if backend behavior is changing, the test needs to be focused and specific about what's actually being validated. Let me trace through the actual execution: mergePaths with the Windows config, APPDATA and LOCALAPPDATA undefined, but USERPROFILE set to "C:\Users\test" produces 4 directory entries joined by semicolon. After trimNonEmpty, that becomes the first element of staticPaths. So the assertion expecting env.PATH === '"C:\\mock\\temp"' would definitely fail because the path now includes those Windows directories. That's a concrete problem with the test. I should suggest a fix that checks whether the quoted mock directory is actually present in the PATH instead of expecting an exact match. For the second test around line 402-407, I need to verify the profile probe command includes the "-NoProfile" flag when loadProfile is false, and that both test cases correctly identify the command type as StandardCommand. Checking whether commands.length === 2 holds in test 2 — the readWindowsEnvironment function loops through shell candidates until it gets non-empty output, and since the handler returns envOutput for any command, it breaks after the first one, so two calls to readWindowsEnvironment means two commands total. That checks out. Test 1's assertion that commands.length === 0 also holds. Now I need to verify the Effect.prov... Writing effect provider chain... So FileSystem.FileSystem is the established pattern in this codebase for typing. Looking at the broader context, other modules do pass fileSystem: FileSystem.FileSystem as parameters to helper functions, which is an accepted practice — but the new diff doesn't introduce any such parameters in production code. The real issue that stands out is the failing assertion in the first test, though I'm wondering if that actually falls under the scope of Effect Service Conventions or if it's something else entirely. The failing assertion does seem worth flagging though. The instructions are clear about reporting concrete violations in the changed scope, and a test with an incorrect assertion arguably isn't a valid focused test if the backend behavior has changed. That's distinct from the earlier comments about types and imports. I should also consider whether the as unknown as cast for the stub is worth mentioning — it's the accepted way to create partial stubs in this repo, unlike the as any patterns flagged in previous runs, so that's probably fine to leave alone. The test file is definitely in scope for the check, and I can see the assertion on line 377 is newly added. The production behavior around the skip path and FNM_DIR looks intentional by design, so no concern there. I'll post a single inline comment on that assertion line and mark it as a failure.

1. modify_pr — One finding: the new Windows fast-path test asserts PATH is left untouched, but the fast path rewrites it with the merged static paths. Everything else (namespace subpath imports, FileSystem.FileSystem acquired from the environment in make, the structural reason._tag catchIf, and the typed PlatformError.systemError stubs) now matches the repository's Effect service conventions.


Agent Credits: 125 credits