Skip to content

fix(server): resolve Claude SDK executable path on Windows npm installs - #3740

Merged
juliusmarminge merged 7 commits into
pingdotgg:mainfrom
nsxdavid:fix/windows-claude-sdk-executable-path
Jul 20, 2026
Merged

juliusmarminge merged 7 commits into
pingdotgg:mainfrom
nsxdavid:fix/windows-claude-sdk-executable-path

Merge branch 'main' into fix/windows-claude-sdk-executable-path

b213574
Select commit
Loading
Failed to load commit list.
MacroscopeApp / Macroscope - Effect Service Conventions succeeded Jul 18, 2026 in 2m 5s

Effect Service Conventions: No issues found

No Effect service convention violations found in the changed scope.

The new apps/server/src/provider/Drivers/ClaudeExecutable.ts follows the established patterns:

  • Namespace imports for Effect modules (effect/Context, effect/Effect) and Node builtins; named imports for the HostProcessPlatform and SpawnExecutableResolution service tags, matching the ~30 existing consumers across apps/server.
  • ClaudeExecutableFileCheck uses Context.Reference with a defaultValue, mirroring its sibling services HostProcessPlatform and SpawnExecutableResolution in @t3tools/shared; it is a legitimate, explicitly overridable test seam rather than hidden/fake dependency injection.
  • resolveClaudeSdkExecutablePath acquires its dependencies from the environment via yield* and takes only pure configuration (binaryPath: string, environment), not service instances.
  • No ManagedRuntime.make, runPromise/runPromiseExit, or Layer.succeed misuse; no new error types requiring Schema.TaggedErrorClass review.
  • The added test file covers genuine new backend behavior (Windows launcher-shim resolution) and uses Effect.provideService seams for platform, command resolution, and file existence.

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:

  • apps/server/src/provider/Drivers/ClaudeExecutable.ts (new)
  • apps/server/src/provider/Drivers/ClaudeExecutable.test.ts (new)
  • apps/server/src/provider/Layers/ClaudeAdapter.ts (call site)
  • apps/server/src/provider/Layers/ClaudeProvider.ts (call site)

Context verified: packages/shared/src/hostProcess.ts and packages/shared/src/shell.ts define HostProcessPlatform and SpawnExecutableResolution via Context.Reference with default values, the same pattern the new ClaudeExecutableFileCheck follows. Named-import style for these tags is consistent with all existing consumers in the repo, so it is not flagged. The call-site changes in ClaudeAdapter.ts and ClaudeProvider.ts simply consume the new helper by yielding it and passing pure config; no violations.


🔍 Agent activity — 2 tool calls

💭 I'm examining the new ClaudeExecutable.ts file to check for Effect service convention violations. The module introduces an injectable service ClaudeExecutableFileCheck using Context.Reference and exports a function to resolve the Claude SDK executable path. The imports follow proper namespace conventions with subpath imports from effect and Node modules. Now I'm checking whether the named imports from @t3tools/shared/hostProcess and @t3tools/shared/shell should be namespace imports instead. The convention allows named imports when accessing service tags from external packages, so this appears acceptable. I need to dig deeper into how ClaudeExecutableFileCheck is being used as a dependency injection seam and whether it violates any core conventions. Looking at isExistingFile - it's a synchronous file check wrapped in a Context.Reference with a defaultValue, which serves as a test seam. This is actually a legitimate callback strategy rather than a hidden dependency in a Layer implementation, so it should be fine. Similarly, SpawnExecutableResolution is a service used in tests that returns the resolved command, which follows the same pattern. The resolveClaudeSdkExecutablePath function takes pure configuration inputs (binaryPath and environment) and uses Effect.fn to yield services from the environment, which is correct. The warning log includes file paths in its payload, which aren't sensitive data, so that's acceptable. Now I need to trace through how SpawnExecutableResolution is actually defined and used to verify there's no real violation here. Looking at the key requirement about applying checks when a pull request creates or consumes an Effect service—this module introduces a Context.Reference service called ClaudeExecutableFileCheck, but it's not a full service module with the typical Context.Service, make, and layer exports. It's more of a helper module that provides utilities. I should examine how other modules in the codebase handle similar patterns, particularly looking at the shared/shell and hostProcess modules to understand the conventions better.

1. github_api_read_only — Show me the definition of SpawnExecutableResolution in @t3tools/shared/shell and HostProcessPlatform in @t3tools/shared/hostProcess. How are they defined as Effect services (Context.Reference, Context.Tag, Context.Service)? Provide the full source.

💭 The ClaudeExecutableFileCheck follows the established pattern for Context.Reference services with default values, which aligns with how the codebase handles these dependencies. The module's use of namespace imports for effect modules and named imports for service references is consistent with existing conventions, so this is a valid test seam. Now I need to review the changes in ClaudeAdapter.ts and ClaudeProvider.ts to check for any violations. The ExecutableFileCheck callback is a valid test seam pattern, and the imports follow the codebase conventions—these are service tags where named imports are acceptable. I should verify how existing code imports these same modules to ensure consistency.

2. github_api_read_only — How is HostProcessPlatform from @t3tools/shared/hostProcess and SpawnExecutableResolution from @t3tools/shared/shell imported by other consumers in apps/server (named import vs namespace import)? Show example import statements from existing files.

💭 The import style aligns with the rest of the codebase, and the new module follows the same Context.Reference pattern as existing ones. The service tag mirrors the naming conventions of similar tags, and there are no violations of the error handling or dependency injection patterns used throughout.


Agent Credits: 77 credits