Skip to content

fix(providers): harden Oh My Pi support

MacroscopeApp / Macroscope - Effect Service Conventions failed Aug 25, 2026 in 2m 38s

Effect Service Conventions: 1 issue found

  • apps/server/src/textGeneration/AcpTextGeneration.ts (line 143): uses Effect.catchTag("SchemaError", ...) to recover a statically known tagged failure. Convention requires Effect.catchTags({ ... }), including for a single tag; the Cursor/Grok text-generation code consolidated into this helper previously used Effect.catchTags({ SchemaError: ... }). An inline comment with a suggested fix was posted.

No other violations found in the changed Effect service 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.

Files examined in scope (new/changed Effect service code):

  • apps/server/src/provider/Drivers/OmpDriver.ts — acquires ChildProcessSpawner, HttpClient, ServerSettingsService, and ProviderEventLoggers from the environment via yield*; layout, ProviderDriver shape, and env union match the existing Grok/OpenCode drivers.
  • apps/server/src/provider/Layers/OmpAdapter.ts, OmpProvider.ts — namespace imports from effect/* subpaths, no ManagedRuntime/runPromise/runPromiseExit, no module-global service capture; scope/fiber handling and error wrapping mirror the established ACP adapters (ProviderAdapterProcessError, ProviderAdapterRequestError, ProviderAdapterValidationError with cause preserved).
  • apps/server/src/provider/Services/OmpAdapter.ts — shape interface only, matching the existing CursorAdapterShape/GrokAdapterShape naming anchors; no Context.Service tag is involved, so the "no standalone FooShape" rule does not apply.
  • apps/server/src/provider/acp/OmpAcpSupport.ts, AcpSessionRuntime.ts, AcpRuntimeModel.ts — the childProcessSpawner/Layer.build construction pattern is the pre-existing repository-wide ACP runtime architecture (identical to GrokAcpSupport.ts/CursorAcpSupport.ts), not a new fake-injection seam, so it was not flagged.
  • apps/server/src/textGeneration/AcpTextGeneration.ts, OmpTextGeneration.ts, CursorTextGeneration.ts, GrokTextGeneration.ts — deduplication is mechanical; makeRuntime/prepareRuntime/buildPromptParts are deliberate callback strategies rather than injected owned services. The only finding is the catchTag usage noted above.
  • packages/client-runtime/src/providerCapabilities.ts — pure helpers, no Effect service surface.
  • apps/server/src/serverSettings.ts, apps/server/src/provider/providerMaintenance.ts, ProviderCommandReactor.ts, and mobile/web call sites — no new service definitions, layers, runtimes, or error classes.

🔍 Agent activity — 14 tool calls

💭 I'm scanning the diff for Effect service convention violations, noting the new provider files for the OMP adapter, driver, ACP support, and text generation, plus the client-runtime capabilities file. I'm checking whether OmpAdapter.ts's service shape interface follows the established naming and structure conventions. Since there's no Context.Service tag involved, adding a shape file mirroring existing drivers seems fine and not worth flagging. Now I'm checking the import conventions in OmpAdapter.ts and OmpDriver.ts — verifying whether named imports from effect subpaths like effect/unstable/http and effect/unstable/process match how other drivers in the repo already import HttpClient and ChildProcessSpawner. I'm also looking at how OmpDriver.ts acquires its dependencies via yield* on ChildProcessSpawner, HttpClient, and ServerSettingsService, then passes the spawner and httpClient explicitly into checkProvider and enrichOmpSnapshot — flagging that passing a service instance directly as a function parameter, rather than resolving it via Effect.provideService inside the function, could be a convention violation worth calling out. I should also check the manual layer construction inside makeOmpAcpRuntimeWithSpawn against existing analogous files to see if this is a new pattern or just mirrors what's already there. And AcpTextGeneration.ts introduces makeAcpTextGeneration(config) with deliberate callback strategies for runtime construction, which seems fine, but I want to inspect the repo further to confirm.

1. browse_code — apps/server/src/provider/acp/*.ts

2. browse_code — apps/server/src/provider/**/*.ts

💭 Since the repo follows consistent patterns across Services, Drivers, and Layers, I want to see how existing providers like Grok structure their AcpSupport and Driver files so the new Omp files mirror that same shape, including how enrich functions are implemented.

3. browse_code — apps/server/src/provider/Drivers/GrokDriver.ts

4. browse_code — apps/server/src/provider/acp/GrokAcpSupport.ts

💭 I'm checking whether the new Omp files follow the same patterns as existing code, particularly around whether makeOmpAcpRuntime accepts a service dependency in a way that should be flagged despite mirroring established conventions. Since it exactly mirrors GrokAcpSupport/CursorAcpSupport, flagging it would demand a repo-wide redesign rather than addressing something specific to this PR, so I'm inclined not to flag it here. Now I'm scanning the new Omp files for actual convention violations, like whether error constructions add a detail field that shouldn't be there in certain error paths. The import ordering issue is just a lint style concern, not a real convention violation. I'm scanning through the rest of OmpAdapter.ts and related files—service resolution, error handling with catchCause, the mobile hooks, and the ProviderCommandReactor changes—and nothing stands out as breaking established patterns; it all looks consistent with existing code.

5. browse_code — apps/server/src/provider/Services/GrokAdapter.ts

6. browse_code — apps/server/src/provider/Services/CursorAdapter.ts

💭 No violation there since it's unrelated to the Context.Service tag. I'm confirming the AcpSessionRuntime change adding awaitExit with a proper error mapping looks fine, and the configOptionCurrentValueMatches extraction into AcpRuntimeModel is also fine. Moving on to check the next new file. Now I'm looking at the shared factory that builds a text generation service around a runtime callback, noting it uses a named type import from AcpSessionRuntime rather than a namespace import. I'm weighing whether this violates the namespace-import convention, since the guideline allows named imports for pure helpers or standalone types but expects namespace imports at service boundaries — and AcpSessionRuntime looks like a service module, so this might be worth flagging. I'm also comparing this against OmpAcpSupport, which does use a namespace import for AcpSessionRuntime, and against the CursorTextGeneration and GrokTextGeneration refactors, which drop several unused imports and consolidate to a clean named import for CursorSettings and TextGenerationError from the contracts package. Also, I'm checking whether the error message change in GrokTextGeneration matters — previously a runtime-start failure mapped to "Grok ACP text generation failed," but now it maps to "Failed to start Grok ACP for text generation," while the model-selection error stays the same. I need to figure out whether these messages are caller-visible (surfaced through the UI or an API boundary) since that would mean they count as behavior that should be preserved during a structural refactor, so I want to check what Cursor's equivalent failure message actually does today. Checking further, I confirm prepareRuntime is inside the timed block, which is fine. But I notice AcpTextGeneration.ts uses Effect.catchTag("SchemaError", ...) — this directly violates the convention requiring Effect.catchTags for statically known tagged failures, even for a single tag, and explicitly forbidding catchTag. The original CursorTextGeneration/GrokTextGeneration files used Effect.catchTags({ SchemaError: ... }), so this is a real regression introduced by the consolidation. I should flag this and also check whether any other new code in these files similarly misuses catchTag.

7. git_tools — Effect.catchTag(

8. browse_code — apps/server/src/textGeneration/AcpTextGeneration.ts

💭 I'm confirming that AcpTextGeneration.ts:143 swapped catchTags for catchTag, which is a rule violation since the guideline explicitly forbids using catchTag. There are other legacy catchTag usages elsewhere in the repo, but this one was newly introduced in the changed code, so it counts. I'm also checking other new files for problems: OmpAdapter.ts's finalizer uses Effect.catch legitimately since it's intentionally handling the whole error channel. TextGenerationError's detail field is pre-existing, providerCapabilities.ts looks like a fine pure helper, and OmpProvider.ts's httpClient parameter shape matches what GrokProvider already does.

9. git_tools — httpClient: HttpClient.HttpClient

10. browse_code — apps/server/src/textGeneration/GrokTextGeneration.ts

💭 The mapError closures passed as config fit the existing reusable strategy pattern used elsewhere, so I'm not flagging those either. I'm now checking whether OmpAdapter's error handling copies cause.message directly into a detail field, which the convention flags as a violation when it's then used to build the wrapper message. I want to compare this against how GrokAdapter handles the same pattern before deciding if it's actually non-conforming.

11. git_tools — detail: cause.message

💭 The one real finding is that Effect.catchTag at AcpTextGeneration.ts:143 needs to become Effect.catchTags({ SchemaError: ... }). Now I want to scan OmpAdapter.ts and OmpAcpSupport.ts fully for other issues like service smuggling via Layer.succeed, or misuse of ManagedRuntime and runPromise.

12. git_tools — runPromise|ManagedRuntime|Layer.succeed|catchIf|catchTag

13. git_tools — export

💭 With just one finding, I'll post an inline review comment on the new file at the line handling the SchemaError catch tag, using side RIGHT since it's a newly added line, and include a suggested replacement spanning that hunk. Drafting suggestion replacement... I'll submit the review as a comment with this one finding, titled "Effect Service Conventions: 1 issue found."

14. modify_pr — One convention issue found in the extracted ACP text-generation helper. Everything else in the new Oh My Pi driver/adapter/ACP support follows the existing provider service conventions (namespace imports from effect/* subpaths, yield*-based dependency acquisition in the driver, no runtime boundaries inside services).


Agent Credits: 216 credits