{"version":3,"file":"mcpProjection.cjs","names":["Type","Errors","Check"],"sources":["../../src/schemas/mcpProjection.ts"],"sourcesContent":["import type { Context } from '@deepseek-ai/cordis';\nimport { type Static, Type } from 'typebox';\nimport { Check, Errors } from 'typebox/value';\n\n/** Schema revision of the neutral MCP projection shared across DoomPi packages. */\nexport const DOOM_MCP_PROJECTION_VERSION = 1 as const;\n\n/** The portable MCP document revision represented by `agent-plugin-v1`. */\nexport const AGENT_PLUGIN_MCP_SCHEMA_URL = 'https://agent-plugins.org/schemas/1.0.0/mcp.schema.json' as const;\n\n/** Cordis service name for the immutable MCP projection of one Pi session. */\nexport const DOOM_MCP_PROJECTION_SERVICE = 'doom/mcp-projection';\n\nexport const DoomMcpProjectionAllowlistSchema = Type.Object(\n  {\n    servers: Type.Optional(Type.Array(Type.String({ minLength: 1 }))),\n    proxy: Type.Optional(Type.Array(Type.String({ minLength: 1 }))),\n  },\n  { additionalProperties: false },\n);\n\nexport const DoomMcpNativeProjectionSourceSchema = Type.Object(\n  {\n    sourceId: Type.String({ minLength: 1 }),\n    owner: Type.Union([Type.Literal('repository'), Type.Literal('plugin')]),\n    format: Type.Literal('native'),\n    configPath: Type.String({ minLength: 1 }),\n    contentDigest: Type.String({ minLength: 1 }),\n  },\n  { additionalProperties: false },\n);\n\nexport const DoomMcpAgentPluginProjectionSourceSchema = Type.Object(\n  {\n    sourceId: Type.String({ minLength: 1 }),\n    owner: Type.Literal('plugin'),\n    format: Type.Literal('agent-plugin-v1'),\n    configPath: Type.String({ minLength: 1 }),\n    contentDigest: Type.String({ minLength: 1 }),\n    pluginId: Type.String({ minLength: 1 }),\n    pluginRoot: Type.String({ minLength: 1 }),\n    pluginDataDirectory: Type.String({ minLength: 1 }),\n    mcpSchemaUrl: Type.Literal(AGENT_PLUGIN_MCP_SCHEMA_URL),\n  },\n  { additionalProperties: false },\n);\n\n/** One native Doom layer or one portable Agent Plugin MCP document. */\nexport const DoomMcpProjectionSourceSchema = Type.Union([\n  DoomMcpNativeProjectionSourceSchema,\n  DoomMcpAgentPluginProjectionSourceSchema,\n]);\n\nexport const DoomMcpProjectionSchema = Type.Object(\n  {\n    version: Type.Literal(DOOM_MCP_PROJECTION_VERSION),\n    enabled: Type.Boolean(),\n    /** Content identity supplied by the projection producer. */\n    fingerprint: Type.String({ minLength: 1 }),\n    repoRoot: Type.String({ minLength: 1 }),\n    stagingDirectory: Type.String({ minLength: 1 }),\n    generatedConfigPath: Type.Optional(Type.String({ minLength: 1 })),\n    sources: Type.Array(DoomMcpProjectionSourceSchema),\n    allowlist: Type.Optional(DoomMcpProjectionAllowlistSchema),\n  },\n  { additionalProperties: false },\n);\n\ntype DeepReadonly<TValue> = TValue extends (...args: never[]) => unknown\n  ? TValue\n  : TValue extends readonly (infer TItem)[]\n    ? readonly DeepReadonly<TItem>[]\n    : TValue extends object\n      ? { readonly [TKey in keyof TValue]: DeepReadonly<TValue[TKey]> }\n      : TValue;\n\nexport type DoomMcpProjectionAllowlist = DeepReadonly<Static<typeof DoomMcpProjectionAllowlistSchema>>;\nexport type DoomMcpNativeProjectionSource = DeepReadonly<Static<typeof DoomMcpNativeProjectionSourceSchema>>;\nexport type DoomMcpAgentPluginProjectionSource = DeepReadonly<Static<typeof DoomMcpAgentPluginProjectionSourceSchema>>;\nexport type DoomMcpProjectionSource = DeepReadonly<Static<typeof DoomMcpProjectionSourceSchema>>;\nexport type DoomMcpProjectionSourceFormat = DoomMcpProjectionSource['format'];\nexport type DoomMcpProjection = DeepReadonly<Static<typeof DoomMcpProjectionSchema>>;\n\nexport interface DoomMcpProjectionService {\n  readonly sessionId: string;\n  readonly generation: string;\n  getSnapshot(): DoomMcpProjection;\n}\n\nexport interface DoomMcpProjectionServiceInput {\n  readonly sessionId: string;\n  readonly generation: string;\n  readonly projection: DoomMcpProjection;\n}\n\nexport interface DisabledDoomMcpProjectionInput {\n  readonly repoRoot: string;\n  readonly stagingDirectory: string;\n}\n\nfunction deepFreeze<TValue>(value: TValue): DeepReadonly<TValue> {\n  if (typeof value !== 'object' || value === null || Object.isFrozen(value)) {\n    return value as DeepReadonly<TValue>;\n  }\n  for (const child of Object.values(value)) deepFreeze(child);\n  return Object.freeze(value) as DeepReadonly<TValue>;\n}\n\nfunction projectionError(value: unknown): Error {\n  const [first] = Errors(DoomMcpProjectionSchema, value);\n  return new Error(`Invalid Doom MCP projection${first ? ` at ${first.instancePath || '/'}: ${first.message}` : ''}`);\n}\n\n/** Runtime guard used when a projection crosses a JSON persistence boundary. */\nexport function isDoomMcpProjection(value: unknown): value is DoomMcpProjection {\n  return Check(DoomMcpProjectionSchema, value);\n}\n\n/**\n * Builds the explicit fail-closed state used when a Doom session has no MCP\n * projection. The root and staging path remain visible for diagnostics, while\n * the empty source list prevents an MCP consumer from falling back to cwd.\n */\nexport function createDisabledDoomMcpProjection({\n  repoRoot,\n  stagingDirectory,\n}: DisabledDoomMcpProjectionInput): DoomMcpProjection {\n  return deepFreeze({\n    version: DOOM_MCP_PROJECTION_VERSION,\n    enabled: false,\n    // Staging is per-process mutable state and must not change content identity\n    // when a synced projection is rebased into a private run directory.\n    fingerprint: JSON.stringify({ version: DOOM_MCP_PROJECTION_VERSION, enabled: false, repoRoot }),\n    repoRoot,\n    stagingDirectory,\n    sources: [],\n  });\n}\n\n/** Creates a generation-bound, immutable Cordis service value. */\nexport function createDoomMcpProjectionService({\n  sessionId,\n  generation,\n  projection,\n}: DoomMcpProjectionServiceInput): DoomMcpProjectionService {\n  if (!sessionId) throw new Error('Doom MCP projection service requires a session id');\n  if (!generation) throw new Error('Doom MCP projection service requires a generation');\n  if (!isDoomMcpProjection(projection)) throw projectionError(projection);\n\n  const snapshot = deepFreeze(structuredClone(projection)) as DoomMcpProjection;\n  return Object.freeze({\n    sessionId,\n    generation,\n    getSnapshot: () => snapshot,\n  });\n}\n\n/** Reads the MCP projection provider from one Doom session's Cordis root. */\nexport function readDoomMcpProjectionService(root: Context): DoomMcpProjectionService | undefined {\n  return root.get(DOOM_MCP_PROJECTION_SERVICE) as DoomMcpProjectionService | undefined;\n}\n\n/** Reads the MCP projection provider or reports that the Doom session is incomplete. */\nexport function requireDoomMcpProjectionService(root: Context): DoomMcpProjectionService {\n  const service = readDoomMcpProjectionService(root);\n  if (!service) throw new Error('Doom MCP projection is unavailable. Load the DoomPi Config core.');\n  return service;\n}\n"],"mappings":"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"}