{"version":3,"file":"policy-CY0iV4HF.mjs","names":[],"sources":["../src/tool/manifest.ts","../src/tool/policy.ts"],"sourcesContent":["import type { ToolDef } from '@open-pencil/core/tools'\nimport { ALL_TOOLS, toolChangesDocument, isToolExposed } from '@open-pencil/core/tools'\n\nimport type {\n  ToolAvailability,\n  ToolCapability,\n  ToolDescriptor,\n  ToolEffect\n} from '#mcp/tool/metadata'\n\nexport function coreToolEffect(def: ToolDef): ToolEffect {\n  return toolChangesDocument(def) ? 'write' : 'read'\n}\n\nexport function coreToolCapabilities(def: ToolDef): ToolCapability[] {\n  return [...def.capabilities]\n}\n\nexport function coreToolAvailability(def: ToolDef): ToolAvailability {\n  return def.availability\n}\n\nfunction coreToolDescriptor(def: ToolDef): ToolDescriptor {\n  return {\n    name: def.name,\n    description: def.description,\n    effect: coreToolEffect(def),\n    availability: coreToolAvailability(def),\n    capabilities: coreToolCapabilities(def),\n    enabled: true\n  }\n}\n\nexport function getMCPToolDefinitions() {\n  return ALL_TOOLS.filter((def) => isToolExposed(def, 'mcp'))\n}\n\nexport function createToolDescriptors(filesystemEnabled: boolean): ToolDescriptor[] {\n  const descriptors = getMCPToolDefinitions().map(coreToolDescriptor)\n  descriptors.push(\n    {\n      name: 'list_documents',\n      description:\n        'List open OpenPencil documents/tabs with their IDs, file paths, current pages, and pages.',\n      effect: 'read',\n      availability: 'default',\n      capabilities: ['document:read'],\n      enabled: true\n    },\n    {\n      name: 'save_file',\n      description:\n        'Save the current document to disk. An optional path must stay inside the configured MCP root.',\n      effect: 'write',\n      availability: 'default',\n      capabilities: ['document:read', 'filesystem:write'],\n      enabled: true\n    },\n    ...(filesystemEnabled\n      ? [\n          {\n            name: 'open_file',\n            description: 'Open a .fig or .pen file from inside the configured MCP root.',\n            effect: 'read',\n            availability: 'filesystem',\n            capabilities: ['filesystem:read', 'document:read'],\n            enabled: true\n          } satisfies ToolDescriptor,\n          {\n            name: 'new_document',\n            description:\n              'Create a new empty document with an optional save path inside the configured MCP root.',\n            effect: 'write',\n            availability: 'filesystem',\n            capabilities: ['document:write', 'filesystem:write'],\n            enabled: true\n          } satisfies ToolDescriptor\n        ]\n      : []),\n    {\n      name: 'close_file',\n      description:\n        'Close an open document tab. With unsaved changes it fails unless unsaved is \"save\" or \"discard\"; it never prompts in the app.',\n      effect: 'write',\n      availability: 'default',\n      capabilities: ['document:write', 'filesystem:write'],\n      enabled: true\n    },\n    {\n      name: 'activate_document',\n      description:\n        'Bring an open document tab to the front in the app, optionally switching it to a page.',\n      effect: 'read',\n      availability: 'default',\n      capabilities: ['document:read'],\n      enabled: true\n    },\n    {\n      name: 'undo',\n      description:\n        \"Undo the newest change made through MCP or the CLI in a document. Fails if the newest change was made in the editor, so the user's work is never reverted.\",\n      effect: 'write',\n      availability: 'default',\n      capabilities: ['document:write'],\n      enabled: true\n    },\n    {\n      name: 'redo',\n      description:\n        'Redo the newest change undone through MCP or the CLI. Fails if the newest undone change was made in the editor.',\n      effect: 'write',\n      availability: 'default',\n      capabilities: ['document:write'],\n      enabled: true\n    },\n    {\n      name: 'get_settings',\n      description:\n        'Read editor settings: appearance (theme, language, animations, accent color), snapping, canvas rendering, recovery, AI chat, and design check preferences.',\n      effect: 'read',\n      availability: 'default',\n      capabilities: ['settings:read'],\n      enabled: true\n    },\n    {\n      name: 'update_settings',\n      description:\n        'Change editor settings with a partial object shaped like get_settings output. Returns the applied patch. Credentials, models, MCP connections, storage, and tool access are not exposed.',\n      effect: 'write',\n      availability: 'default',\n      capabilities: ['settings:write'],\n      enabled: true\n    },\n    {\n      name: 'get_codegen_prompt',\n      description:\n        'Get design-to-code generation guidelines. Call before generating frontend code.',\n      effect: 'read',\n      availability: 'default',\n      capabilities: [],\n      enabled: true\n    }\n  )\n  return descriptors\n}\n","import { compact, uniq } from 'es-toolkit/array'\n\nimport type { ToolDescriptor, ToolPolicy } from '#mcp/tool/metadata'\nimport { isSelectionScopeTool, parseToolScope } from '#mcp/tool/scope'\n\nexport function parseDisabledTools(value: string | undefined): string[] {\n  if (!value) return []\n  return uniq(compact(value.split(',').map((name) => name.trim())))\n}\n\nexport function isToolEnabled(descriptor: ToolDescriptor, policy: ToolPolicy): boolean {\n  if (policy.scope === 'selection' && !isSelectionScopeTool(descriptor.name)) return false\n  if (policy.disabledTools.includes(descriptor.name)) return false\n  return descriptor.availability !== 'eval' || policy.allowEval\n}\n\nexport function applyToolPolicy(\n  descriptors: readonly ToolDescriptor[],\n  policy: ToolPolicy\n): ToolDescriptor[] {\n  return descriptors.map((descriptor) => ({\n    ...descriptor,\n    enabled: isToolEnabled(descriptor, policy)\n  }))\n}\n\nexport function serializeDisabledTools(names: readonly string[]): string {\n  return names.join(',')\n}\n\nexport function readToolPolicyFromEnv(env: NodeJS.ProcessEnv = process.env): ToolPolicy {\n  return {\n    allowEval: env.OPENPENCIL_MCP_EVAL === '1',\n    disabledTools: parseDisabledTools(env.OPENPENCIL_MCP_DISABLED_TOOLS),\n    scope: parseToolScope(env.OPENPENCIL_MCP_SCOPE)\n  }\n}\n"],"mappings":"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"}