/** * Shared agent-root resolution. * * `agent-settings.ts` and `mcp-config.ts` both need to resolve a per-agent * root directory (e.g., `.claude` for `claude-code`, `.cursor` for `cursor`) * to compose agent-specific config paths (`/settings.json`, * `/mcp.json`). * * Resolution rules (with `exactOptionalPropertyTypes: true`, the descriptor * shape `rootDir?: string | undefined` distinguishes three states): * * 1. `descriptor.rootDir` is a `string` — use it directly. * 2. `descriptor.rootDir` is explicitly `undefined` (key present but * nullish) — the agent has opted out of native-config scanning. Return * `Option.none()` and the scanners SHALL skip this agent. * 3. `descriptor.rootDir` is omitted entirely — use the first segment of * `descriptor.skills.dir` when the Skill surface exists. This handles * platform-native separators and collapses `.` segments through the Path * service's normalization. * 4. If there is no Skill surface, or the heuristic produces nothing, fall * back to `.${descriptor.id}`. * * The heuristic-fallback path emits a one-time `scanner-config` diagnostic * warning per scanner instance per agent so agent maintainers see a nudge * to set `rootDir` explicitly. Collisions detected at construction time * also warn through the same `scanner-config` code. */ import * as Effect from "effect/Effect"; import * as Option from "effect/Option"; import type * as Path from "effect/Path"; import type { AgentDescriptor } from "../../../agents/types.js"; import type { Diagnostics } from "../diagnostics.js"; /** * Per-instance state shared across the scanners that resolve agent roots. * Both `mcp-config` and `agent-settings` share one tracker so a single * heuristic-fallback warning per agent fires across both scanners (rather * than once each). * * Construction is cheap: a `Set` allocated by the live layer and * passed to both scanners. */ export interface AgentRootResolverState { readonly heuristicWarned: Set; } export declare const makeAgentRootResolverState: () => AgentRootResolverState; /** * Resolve the per-agent root directory for one descriptor. Returns * `Option.none()` when the agent has explicitly opted out of native-config * scanning (descriptor's `rootDir` is `undefined`); returns * `Option.some(segment)` otherwise. * * The result is intentionally a relative segment, not an absolute path: * each caller resolves the per-file path differently (`mcp.json` vs * `settings.json`), and the join concern stays at the call site. */ export declare const agentRootSegment: (path: Path.Path, descriptor: AgentDescriptor, diagnostics: Diagnostics, state: AgentRootResolverState) => Effect.Effect>; /** * Detect cases where two or more registry descriptors resolve to the same * `agentRootSegment`. The detection runs once at construction time (per * `WorkspaceReadModelLive` instance); each collision emits a * `scanner-config` diagnostic warning. The function does NOT throw and * does NOT skip scanning — callers continue to scan; the warning is the * signal. * * The check uses the same resolution rules as `agentRootSegment` but * inlined to avoid producing fallback warnings during collision checking * (the heuristic-fallback warning fires once per agent on first scanner * use; running it during collision detection would race with normal * scanner emission). Agents that opt out (`rootDir: undefined`) are * excluded from collision checking entirely. */ export declare const detectAgentRootCollisions: (path: Path.Path, descriptors: ReadonlyArray, diagnostics: Diagnostics) => Effect.Effect; //# sourceMappingURL=agent-root.d.ts.map