Skip to content

fix(composer): scope skill discovery to workspace - #8528

Closed
D3OXY wants to merge 3 commits into
pingdotgg:mainfrom
D3OXY:d3oxy/fix/workspace-skill-picker
Closed

D3OXY wants to merge 3 commits into
pingdotgg:mainfrom
D3OXY:d3oxy/fix/workspace-skill-picker

refactor(server): acquire skill query services from Effect

41b3e29
Select commit
Loading
Failed to load commit list.
MacroscopeApp / Macroscope - Effect Service Conventions succeeded Aug 29, 2026 in 1m 24s

Effect Service Conventions: no violations found

All clear

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.

Reviewed the Effect-related changes in this PR against the service conventions:

  • apps/server/src/provider/providerSkills.ts now acquires ProviderInstanceRegistry and ProjectionSnapshotQuery via yield* and exposes both in the R channel of Effect.fn.Return, resolving the hand-rolled dependency-injection issue flagged on the previous run (cdc67b2). The ws.ts handler supplies those requirements from services already acquired in the enclosing layer, which is a legitimate boundary.
  • New modules (providerSkillsCache.ts, skillInvocations.ts, Layers/codexSkillInvocations.ts, Drivers/CursorSkills.ts) are pure helpers/caches rather than services; all use namespace imports from effect/* subpaths and declare their FileSystem/Path/spawner requirements in the effect environment instead of taking service instances as constructor parameters.
  • CodexSessionRuntimeUnknownSkillError uses Schema.TaggedErrorClass with a structured names attribute and derives message from it; the adapter translation in CodexAdapter.ts wraps it in ProviderAdapterValidationError while preserving cause. Skill read failures in Claude/Cursor/Grok adapters keep the underlying error as cause and add path context.
  • No new consolidated import { ... } from "effect", no new ManagedRuntime.make, runPromise/runPromiseExit, or Layer.succeed hiding runtime-backed work outside tests and existing SDK callback boundaries.
  • No new FooShape interfaces, compatibility re-export shims, or renamed make/layer exports.

🔍 Agent activity — 5 tool calls

💭 Checking the current diff for providerSkills.ts confirms the earlier issue with acquiring from the environment is now resolved. I'm moving on to review the other new files—providerSkillsCache.ts, skillInvocations.ts, codexSkillInvocations.ts, CursorSkills.ts, and the client-side providerSkills.ts—for convention adherence. The error classes and adapters look reasonable: CodexSessionRuntimeUnknownSkillError uses tagged error schema appropriately, CodexAdapter maps runtime errors to validation errors with causes attached, and the driver's optional skill-listing method is constructed with dependencies already provided. I don't see obvious issues with the cache setup either, and I'm now checking how ws.ts handles providing the ProviderInstanceRegistry service after acquiring it from the environment. This raises a question about whether re-providing services manually in the handler is consistent with the rest of the file's conventions -- it seems like a legitimate pattern for RPC handlers even if a bit redundant, so I want to compare it against how other handlers in ws.ts are structured before drawing a conclusion.

1. git_tools — Effect.provideService(",|provideService(ProjectionSnapshotQuery

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

💭 That finding looks resolved now. Let me check the ws.ts handler that re-provides services, comparing it against how other handlers manage their service requirements.

3. git_tools — provideService

💭 This is the only place re-providing services this way, but since the requirements come from the effect's R channel and are provided from services already acquired within the same layer, it doesn't violate the convention that targets factories accepting service instances. It's a bit verbose but fine—not something I'd flag. Checking the imports and new code across the other files: CursorSkills.ts, ClaudeSkills.ts, and CodexSessionRuntime.ts all look consistent, with the new tagged error class following the same pattern as its siblings. In CodexAdapter.ts, the new private Schema.is constant isn't exported directly like the rule suggests, but it matches the existing pattern already used elsewhere in the file for similar predicates, so it's consistent with established conventions rather than a new violation. I'm also checking whether the PR introduced any new catchTags usage versus the existing if-chain pattern in mapCodexRuntimeError, along with the error modeling in skillInvocations.ts and ClaudeAdapter.ts, both of which reuse existing error types appropriately. Then I look at CursorProvider.ts's positional parameter usage and confirm that discoverGrokSkills is already being imported correctly in GrokSkills. ts, plus that the mobile and web providerSkills state hooks follow standard React patterns. Finally, I'm scanning for any new files that might be using Layer.succeed, ManagedRuntime, or runPromise in ways that bypass the runtime, verifying that makeProviderSkillsCache's typing is correct with no unresolved requirements or errors, and checking how CodexDriver's skills cache lookup handles discoverCodexSkills. The spawner service is acquired from the environment and re-provided to a sub-effect, which is a legitimate pattern. ClaudeDriver does something similar for FileSystem/Path, and CursorAdapter follows the same approach with the FileSystem service acquired within scope. I'm also verifying the schema filter usage, checking that Effect.fn.Return usage matches repo conventions, and looking at whether touched files use consolidated named imports from "effect".

4. git_tools — from "effect";

5. git_tools — runPromise|ManagedRuntime.make

💭 No new violations there since the ClaudeAdapter's runPromiseWith is a pre-existing SDK boundary. I'm checking the contracts schemas and confirming the codexSkillInvocations module is a clean pure helper with proper named imports, then looking at providerSkillsCache to see how it constructs the cache generically. I'm satisfied the make function isn't a service so it's fine. Looking at ProviderInstance.listSkillsForCwd, it swallows errors into an Option at construction, but that actually aligns with the rule endorsing Option-based unavailability modeling rather than violating it, so I'm not flagging it. I also check the test mocks for ProviderInstanceRegistry and Layer.mock usage, both fine, then move to scanning client-side web/mobile code for any Effect-related concerns. The mobile and web state files for providerSkills are byte-identical duplicates, which isn't itself an Effect-convention violation even though it's odd duplication. I confirm no new shape types were introduced beyond the existing ClaudeAdapterShape, CursorAdapterShape, and OpenCodeRuntimeShape, and that CodexSessionRuntimeUnknownSkillError doesn't need an underlying cause since it's a plain validation error. I also check the redundant-discriminator concern for ProviderAdapterValidationError's multi-value operation field and find it consistent with pre-existing patterns, then start examining how ClaudeAdapter's prepareSkillPrompt yields its validation error. The Effect.fn.Return type signature in CursorSkills.ts correctly declares FileSystem and Path as dependencies, and CursorProvider's checkCursorProviderStatus now properly passes those through when calling discoverCursorSkills. With no new violations found and the earlier issue resolved, I need to decide how to format my response given the conflict between instructions to output "All clear" as plain text versus the schema requiring JSON — I'll go with a JSON response indicating success with an "All clear" summary. Doing one more pass over files I haven't fully reviewed yet: skillInvocations.ts, the CursorAdapter changes, and confirming ClaudeAdapter's discoverSkills properly stores results in session context. I also check that OpenCodeProvider's loadOpenCodeInventoryForCwd correctly acquires OpenCodeRuntime and OpenCodeServerOwner from the environment — that looks right. I'm confident there are no findings to report.


Agent Credits: 92 credits

Token usage: 8 uncached input · 270,454 cache-read input · 95,925 cache-write input · 5,424 output
Agent Credits may also include non-token charges from external tools such as web research.