@slicemachine/manager 0.25.7-alpha.jp-figma-to-prismic.8 → 0.25.7-alpha.jp-figma-to-slice-1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"CustomTypesManager.js","sources":["../../../../src/managers/customTypes/CustomTypesManager.ts"],"sourcesContent":["import * as t from \"io-ts\";\nimport * as prismicCustomTypesClient from \"@prismicio/custom-types-client\";\nimport {\n\tCustomType,\n\tGroup,\n\tLinkConfig,\n\tNestableWidget,\n\tNestedGroup,\n\tSharedSlice,\n\tUID,\n\ttraverseCustomType,\n\ttraverseSharedSlice,\n} from \"@prismicio/types-internal/lib/customtypes\";\nimport {\n\tCallHookReturnType,\n\tCustomTypeCreateHook,\n\tCustomTypeCreateHookData,\n\tCustomTypeReadHookData,\n\tCustomTypeRenameHook,\n\tCustomTypeRenameHookData,\n\tCustomTypeUpdateHook,\n\tCustomTypeUpdateHookData,\n\tHookError,\n} from \"@slicemachine/plugin-kit\";\nimport { z } from \"zod\";\nimport { query as queryClaude } from \"@anthropic-ai/claude-agent-sdk\";\n\nimport { DecodeError } from \"../../lib/DecodeError\";\nimport { assertPluginsInitialized } from \"../../lib/assertPluginsInitialized\";\nimport { decodeHookResult } from \"../../lib/decodeHookResult\";\nimport fetch from \"../../lib/fetch\";\n\nimport { OnlyHookErrors } from \"../../types\";\nimport { API_ENDPOINTS } from \"../../constants/API_ENDPOINTS\";\nimport { SLICE_MACHINE_USER_AGENT } from \"../../constants/SLICE_MACHINE_USER_AGENT\";\nimport { UnauthorizedError } from \"../../errors\";\nimport { mkdtemp, readFile, rename, rm, writeFile } from \"fs/promises\";\nimport { tmpdir } from \"os\";\nimport path from \"path\";\nimport { randomUUID } from \"crypto\";\nimport { existsSync } from \"fs\";\n\nimport { BaseManager } from \"../BaseManager\";\nimport { CustomTypeFormat } from \"./types\";\n\ntype SliceMachineManagerReadCustomTypeLibraryReturnType = {\n\tids: string[];\n\terrors: (DecodeError | HookError)[];\n};\n\ntype CustomTypesManagerReadAllCustomTypesArgs = {\n\tformat: CustomTypeFormat;\n};\n\ntype SliceMachineManagerReadAllCustomTypeReturnType = {\n\tmodels: { model: CustomType }[];\n\terrors: (DecodeError | HookError)[];\n};\n\ntype SliceMachineManagerReadCustomTypeReturnType = {\n\tmodel: CustomType | undefined;\n\terrors: (DecodeError | HookError)[];\n};\n\ntype SliceMachineManagerPushCustomTypeArgs = {\n\tid: string;\n\tuserAgent?: string;\n};\n\ntype SliceMachineManagerReadCustomTypeMocksConfigArgs = {\n\tcustomTypeID: string;\n};\n\ntype SliceMachineManagerReadCustomTypeMocksConfigArgsReturnType = {\n\t// TODO\n\tmocksConfig?: Record<string, unknown>;\n\terrors: HookError[];\n};\n\ntype SliceMachineManagerUpdateCustomTypeMocksConfigArgs = {\n\tcustomTypeID: string;\n\t// TODO\n\tmocksConfig: Record<string, unknown>;\n};\n\n/** `[field]` or `[group, field]` – path **inside** the Custom Type */\ntype PathWithoutCustomType = [string] | [string, string];\n\ntype SliceMachineManagerUpdateCustomTypeFieldIdChanged = {\n\t/**\n\t * Previous path of the changed field, excluding the custom type id. Can be\n\t * used to identify the field that had an API ID rename (e.g. [\"fieldA\"] or\n\t * [\"groupA\", \"fieldA\"])\n\t */\n\tpreviousPath: PathWithoutCustomType;\n\t/**\n\t * New path of the changed field, excluding the custom type id. Can be used to\n\t * identify the field that had an API ID rename (e.g. [\"fieldB\"] or [\"groupA\",\n\t * \"fieldB\"])\n\t */\n\tnewPath: PathWithoutCustomType;\n};\n\ntype SliceMachineManagerUpdateCustomTypeArgs = CustomTypeUpdateHookData & {\n\tupdateMeta?: {\n\t\tfieldIdChanged?: SliceMachineManagerUpdateCustomTypeFieldIdChanged;\n\t};\n};\n\ntype SliceMachineManagerUpdateCustomTypeMocksConfigArgsReturnType = {\n\terrors: HookError[];\n};\n\ntype CustomTypesMachineManagerDeleteCustomTypeArgs = {\n\tid: string;\n};\n\ntype CustomTypesMachineManagerDeleteCustomTypeReturnType = {\n\terrors: (DecodeError | HookError)[];\n};\n\ntype CustomTypesMachineManagerUpdateCustomTypeReturnType = {\n\terrors: (DecodeError | HookError)[];\n};\n\n/** `[ct, field]` or `[ct, group, field]` – path **with** Custom Type ID */\ntype PathWithCustomType = [string, string] | [string, string, string];\n\ntype CustomTypeFieldIdChangedMeta = {\n\tpreviousPath: PathWithCustomType;\n\tnewPath: PathWithCustomType;\n};\n\ntype LinkCustomType = NonNullable<LinkConfig[\"customtypes\"]>[number];\n\nexport class CustomTypesManager extends BaseManager {\n\tprivate inferSliceAbortControllers = new Map<string, AbortController>();\n\n\tasync readCustomTypeLibrary(): Promise<SliceMachineManagerReadCustomTypeLibraryReturnType> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"custom-type-library:read\",\n\t\t\tundefined,\n\t\t);\n\t\tconst { data, errors } = decodeHookResult(\n\t\t\tt.type({\n\t\t\t\tids: t.array(t.string),\n\t\t\t}),\n\t\t\thookResult,\n\t\t);\n\n\t\treturn {\n\t\t\tids: data[0]?.ids || [],\n\t\t\terrors,\n\t\t};\n\t}\n\n\tasync readAllCustomTypes(\n\t\targs?: CustomTypesManagerReadAllCustomTypesArgs,\n\t): Promise<SliceMachineManagerReadAllCustomTypeReturnType> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst res: SliceMachineManagerReadAllCustomTypeReturnType = {\n\t\t\tmodels: [],\n\t\t\terrors: [],\n\t\t};\n\n\t\tconst { ids, errors } = await this.readCustomTypeLibrary();\n\t\tres.errors = [...res.errors, ...errors];\n\n\t\tif (ids) {\n\t\t\tfor (const id of ids) {\n\t\t\t\tconst { model, errors } = await this.readCustomType({ id });\n\t\t\t\tres.errors = [...res.errors, ...errors];\n\n\t\t\t\tif (model && (!args || args.format === model.format)) {\n\t\t\t\t\tres.models.push({ model });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn res;\n\t}\n\n\tasync createCustomType(\n\t\targs: CustomTypeCreateHookData,\n\t): Promise<OnlyHookErrors<CallHookReturnType<CustomTypeCreateHook>>> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"custom-type:create\",\n\t\t\targs,\n\t\t);\n\n\t\treturn {\n\t\t\terrors: hookResult.errors,\n\t\t};\n\t}\n\n\tasync readCustomType(\n\t\targs: CustomTypeReadHookData,\n\t): Promise<SliceMachineManagerReadCustomTypeReturnType> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"custom-type:read\",\n\t\t\targs,\n\t\t);\n\t\tconst { data, errors } = decodeHookResult(\n\t\t\tt.type({\n\t\t\t\tmodel: CustomType,\n\t\t\t}),\n\t\t\thookResult,\n\t\t);\n\n\t\treturn {\n\t\t\tmodel: data[0]?.model,\n\t\t\terrors,\n\t\t};\n\t}\n\n\t/**\n\t * Update the Content Relationship API IDs for all existing custom types and\n\t * slices. The change is determined by properties inside the `updateMeta`\n\t * property.\n\t */\n\tprivate async updateContentRelationships(\n\t\targs: {\n\t\t\tmodel: CustomType;\n\t\t} & SliceMachineManagerUpdateCustomTypeFieldIdChanged,\n\t): Promise<\n\t\tOnlyHookErrors<CallHookReturnType<CustomTypeUpdateHook>> & {\n\t\t\trollback?: () => Promise<void>;\n\t\t}\n\t> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst {\n\t\t\tmodel,\n\t\t\tpreviousPath: previousFieldPath,\n\t\t\tnewPath: newFieldPath,\n\t\t} = args;\n\n\t\tif (previousFieldPath.join(\".\") !== newFieldPath.join(\".\")) {\n\t\t\tconst { id: ctId } = model;\n\t\t\tconst previousPath: PathWithCustomType = [ctId, ...previousFieldPath];\n\t\t\tconst newPath: PathWithCustomType = [ctId, ...newFieldPath];\n\n\t\t\tconst crUpdates: {\n\t\t\t\tupdatePromise: Promise<{ errors: HookError[] }>;\n\t\t\t\trollback: () => void;\n\t\t\t}[] = [];\n\n\t\t\t// Find existing content relationships that link to the renamed field id in\n\t\t\t// any custom type and update them to use the new one.\n\t\t\tconst customTypes = await this.readAllCustomTypes();\n\n\t\t\tupdateCustomTypeContentRelationships({\n\t\t\t\tmodels: customTypes.models,\n\t\t\t\tonUpdate: ({ previousModel, model: updatedModel }) => {\n\t\t\t\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\t\t\t\tcrUpdates.push({\n\t\t\t\t\t\tupdatePromise: this.sliceMachinePluginRunner?.callHook(\n\t\t\t\t\t\t\t\"custom-type:update\",\n\t\t\t\t\t\t\t{ model: updatedModel },\n\t\t\t\t\t\t),\n\t\t\t\t\t\trollback: () => {\n\t\t\t\t\t\t\tthis.sliceMachinePluginRunner?.callHook(\"custom-type:update\", {\n\t\t\t\t\t\t\t\tmodel: previousModel,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\tpreviousPath,\n\t\t\t\tnewPath,\n\t\t\t});\n\n\t\t\t// Find existing slice with content relationships that link to the renamed\n\t\t\t// field id in all libraries and update them to use the new one.\n\t\t\tconst { libraries } = await this.slices.readAllSliceLibraries();\n\n\t\t\tfor (const library of libraries) {\n\t\t\t\tconst slices = await this.slices.readAllSlicesForLibrary({\n\t\t\t\t\tlibraryID: library.libraryID,\n\t\t\t\t});\n\n\t\t\t\tupdateSharedSliceContentRelationships({\n\t\t\t\t\tmodels: slices.models,\n\t\t\t\t\tonUpdate: ({ previousModel, model: updatedModel }) => {\n\t\t\t\t\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\t\t\t\t\tcrUpdates.push({\n\t\t\t\t\t\t\tupdatePromise: this.sliceMachinePluginRunner?.callHook(\n\t\t\t\t\t\t\t\t\"slice:update\",\n\t\t\t\t\t\t\t\t{ libraryID: library.libraryID, model: updatedModel },\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\trollback: () => {\n\t\t\t\t\t\t\t\tthis.sliceMachinePluginRunner?.callHook(\"slice:update\", {\n\t\t\t\t\t\t\t\t\tlibraryID: library.libraryID,\n\t\t\t\t\t\t\t\t\tmodel: previousModel,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\t\t\t\t\t},\n\t\t\t\t\tpreviousPath,\n\t\t\t\t\tnewPath,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Process all the Content Relationship updates at once.\n\t\t\tconst crUpdatesResult = await Promise.all(\n\t\t\t\tcrUpdates.map((update) => update.updatePromise),\n\t\t\t);\n\n\t\t\tif (crUpdatesResult.some((result) => result.errors.length > 0)) {\n\t\t\t\treturn {\n\t\t\t\t\terrors: crUpdatesResult.flatMap((result) => result.errors),\n\t\t\t\t\trollback: async () => {\n\t\t\t\t\t\tawait Promise.all(crUpdates.map((update) => update.rollback()));\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\treturn { errors: [] };\n\t}\n\n\tasync updateCustomType(\n\t\targs: SliceMachineManagerUpdateCustomTypeArgs,\n\t): Promise<CustomTypesMachineManagerUpdateCustomTypeReturnType> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\t\tconst { model } = args;\n\t\tconst { fieldIdChanged } = args.updateMeta ?? {};\n\n\t\tlet previousCustomType: CustomType | undefined;\n\n\t\tif (fieldIdChanged) {\n\t\t\tconst customTypeRead = await this.readCustomType({ id: model.id });\n\n\t\t\tif (customTypeRead.errors.length > 0) {\n\t\t\t\treturn { errors: customTypeRead.errors };\n\t\t\t}\n\t\t\tif (!customTypeRead.model) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`readCustomType succeeded reading custom type ${model.id} but model is undefined.`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tpreviousCustomType = customTypeRead.model;\n\t\t}\n\n\t\tconst customTypeUpdateResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"custom-type:update\",\n\t\t\t{ model },\n\t\t);\n\n\t\tif (customTypeUpdateResult.errors.length > 0) {\n\t\t\treturn { errors: customTypeUpdateResult.errors };\n\t\t}\n\n\t\tif (previousCustomType && fieldIdChanged) {\n\t\t\tconst crUpdateResult = await this.updateContentRelationships({\n\t\t\t\t...fieldIdChanged,\n\t\t\t\tmodel: previousCustomType,\n\t\t\t});\n\n\t\t\tif (crUpdateResult.errors.length > 0) {\n\t\t\t\t// put the previous custom type back\n\t\t\t\tawait this.sliceMachinePluginRunner?.callHook(\"custom-type:update\", {\n\t\t\t\t\tmodel: previousCustomType,\n\t\t\t\t});\n\t\t\t\t// revert the content relationships updates\n\t\t\t\tawait crUpdateResult.rollback?.();\n\n\t\t\t\treturn { errors: crUpdateResult.errors };\n\t\t\t}\n\t\t}\n\n\t\treturn { errors: [] };\n\t}\n\n\tasync renameCustomType(\n\t\targs: CustomTypeRenameHookData,\n\t): Promise<OnlyHookErrors<CallHookReturnType<CustomTypeRenameHook>>> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"custom-type:rename\",\n\t\t\targs,\n\t\t);\n\n\t\treturn {\n\t\t\terrors: hookResult.errors,\n\t\t};\n\t}\n\n\tasync deleteCustomType(\n\t\targs: CustomTypesMachineManagerDeleteCustomTypeArgs,\n\t): Promise<CustomTypesMachineManagerDeleteCustomTypeReturnType> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst { model, errors: readCustomTypeErrors } = await this.readCustomType({\n\t\t\tid: args.id,\n\t\t});\n\n\t\tif (model) {\n\t\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\t\"custom-type:delete\",\n\t\t\t\t{ model },\n\t\t\t);\n\n\t\t\treturn {\n\t\t\t\terrors: hookResult.errors,\n\t\t\t};\n\t\t} else {\n\t\t\treturn {\n\t\t\t\terrors: readCustomTypeErrors,\n\t\t\t};\n\t\t}\n\t}\n\n\tasync pushCustomType(\n\t\targs: SliceMachineManagerPushCustomTypeArgs,\n\t): Promise<void> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst authenticationToken = await this.user.getAuthenticationToken();\n\t\tconst repositoryName = await this.project.getResolvedRepositoryName();\n\n\t\t// TODO: Handle errors\n\t\tconst { model } = await this.readCustomType({ id: args.id });\n\n\t\tif (model) {\n\t\t\t// TODO: Create a single shared client.\n\t\t\tconst client = prismicCustomTypesClient.createClient({\n\t\t\t\tendpoint: API_ENDPOINTS.PrismicModels,\n\t\t\t\trepositoryName,\n\t\t\t\ttoken: authenticationToken,\n\t\t\t\tfetch,\n\t\t\t\tfetchOptions: {\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t\"User-Agent\": args.userAgent || SLICE_MACHINE_USER_AGENT,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t});\n\n\t\t\ttry {\n\t\t\t\t// Check if Custom Type already exists on the repository.\n\t\t\t\tawait client.getCustomTypeByID(args.id);\n\n\t\t\t\t// If it exists on the repository, update it.\n\t\t\t\tawait client.updateCustomType(model);\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof prismicCustomTypesClient.NotFoundError) {\n\t\t\t\t\t// If it doesn't exist on the repository, insert it.\n\t\t\t\t\tawait client.insertCustomType(model);\n\t\t\t\t} else if (error instanceof prismicCustomTypesClient.ForbiddenError) {\n\t\t\t\t\tthrow new UnauthorizedError(\n\t\t\t\t\t\t\"You do not have access to push types to this Prismic repository.\",\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcause: error,\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// TODO: Remove\n\tasync readCustomTypeMocksConfig(\n\t\targs: SliceMachineManagerReadCustomTypeMocksConfigArgs,\n\t): Promise<SliceMachineManagerReadCustomTypeMocksConfigArgsReturnType> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"custom-type:asset:read\",\n\t\t\t{\n\t\t\t\tcustomTypeID: args.customTypeID,\n\t\t\t\tassetID: \"mocks.config.json\",\n\t\t\t},\n\t\t);\n\t\tconst data = hookResult.data[0]?.data;\n\n\t\t// TODO: Validate the returned data.\n\n\t\tif (data) {\n\t\t\treturn {\n\t\t\t\tmocksConfig: JSON.parse(data.toString()),\n\t\t\t\terrors: hookResult.errors,\n\t\t\t};\n\t\t} else {\n\t\t\treturn {\n\t\t\t\tmocksConfig: undefined,\n\t\t\t\terrors: hookResult.errors,\n\t\t\t};\n\t\t}\n\t}\n\n\t// TODO: Remove\n\tasync updateCustomTypeMocksConfig(\n\t\targs: SliceMachineManagerUpdateCustomTypeMocksConfigArgs,\n\t): Promise<SliceMachineManagerUpdateCustomTypeMocksConfigArgsReturnType> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"custom-type:asset:update\",\n\t\t\t{\n\t\t\t\tcustomTypeID: args.customTypeID,\n\t\t\t\tasset: {\n\t\t\t\t\tid: \"mocks.config.json\",\n\t\t\t\t\tdata: Buffer.from(JSON.stringify(args.mocksConfig, null, \"\\t\")),\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\n\t\treturn {\n\t\t\terrors: hookResult.errors,\n\t\t};\n\t}\n\n\tasync fetchRemoteCustomTypes(): Promise<CustomType[]> {\n\t\tconst authenticationToken = await this.user.getAuthenticationToken();\n\t\tconst repositoryName = await this.project.getResolvedRepositoryName();\n\n\t\tconst client = prismicCustomTypesClient.createClient({\n\t\t\tendpoint: API_ENDPOINTS.PrismicModels,\n\t\t\trepositoryName,\n\t\t\ttoken: authenticationToken,\n\t\t\tfetch,\n\t\t\tfetchOptions: {\n\t\t\t\theaders: {\n\t\t\t\t\t\"User-Agent\": SLICE_MACHINE_USER_AGENT,\n\t\t\t\t},\n\t\t\t},\n\t\t});\n\n\t\treturn await client.getAllCustomTypes();\n\t}\n\n\tasync inferSlice(\n\t\targs: { imageUrl: string; requestId?: string } & (\n\t\t\t| { source: \"upload\" }\n\t\t\t| { source: \"figma\"; libraryID: string }\n\t\t),\n\t): Promise<InferSliceResponse> {\n\t\tconst { source, imageUrl, requestId } = args;\n\n\t\tconst authToken = await this.user.getAuthenticationToken();\n\t\tconst repository = await this.project.getResolvedRepositoryName();\n\n\t\tlet abortController: AbortController | undefined;\n\t\tif (requestId) {\n\t\t\tabortController = new AbortController();\n\t\t\tabortController.signal.addEventListener(\"abort\", () => {\n\t\t\t\tconsole.warn(`inferSlice (${source}) request ${requestId} was aborted`);\n\t\t\t});\n\t\t\tthis.inferSliceAbortControllers.set(requestId, abortController);\n\t\t}\n\n\t\tconsole.info(\n\t\t\t`inferSlice (${source}) started${\n\t\t\t\trequestId ? ` for request ${requestId}` : \"\"\n\t\t\t}`,\n\t\t);\n\t\tconst startTime = Date.now();\n\n\t\ttry {\n\t\t\tif (source === \"figma\") {\n\t\t\t\tconst { libraryID } = args;\n\n\t\t\t\tconst exp =\n\t\t\t\t\tawait this.telemetry.getExperimentVariant(\"llm-proxy-access\");\n\t\t\t\tif (exp?.value !== \"on\") {\n\t\t\t\t\tthrow new Error(\"User does not have access to the LLM proxy.\");\n\t\t\t\t}\n\n\t\t\t\tconst { llmProxyUrl } = z\n\t\t\t\t\t.object({ llmProxyUrl: z.string().url() })\n\t\t\t\t\t.parse(exp.payload);\n\n\t\t\t\tlet tmpDir: string | undefined;\n\t\t\t\ttry {\n\t\t\t\t\tconst config = await this.project.getSliceMachineConfig();\n\n\t\t\t\t\tlet framework:\n\t\t\t\t\t\t| { type: \"nextjs\" | \"nuxt\" | \"sveltekit\"; label: string }\n\t\t\t\t\t\t| undefined;\n\t\t\t\t\tif (config.adapter === \"@slicemachine/adapter-next\") {\n\t\t\t\t\t\tframework = { type: \"nextjs\", label: \"Next.js (React)\" };\n\t\t\t\t\t} else if (\n\t\t\t\t\t\tconfig.adapter === \"@slicemachine/adapter-nuxt\" ||\n\t\t\t\t\t\tconfig.adapter === \"@slicemachine/adapter-nuxt2\"\n\t\t\t\t\t) {\n\t\t\t\t\t\tframework = { type: \"nuxt\", label: \"Nuxt (Vue)\" };\n\t\t\t\t\t} else if (config.adapter === \"@slicemachine/adapter-sveltekit\") {\n\t\t\t\t\t\tframework = { type: \"sveltekit\", label: \"SvelteKit (Svelte)\" };\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!framework) {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\"Could not determine framework from Slice Machine config.\",\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tlet frameworkFileExtension: string | undefined;\n\t\t\t\t\tif (framework.type === \"nextjs\") {\n\t\t\t\t\t\tframeworkFileExtension = \"tsx\";\n\t\t\t\t\t} else if (framework.type === \"nuxt\") {\n\t\t\t\t\t\tframeworkFileExtension = \"vue\";\n\t\t\t\t\t} else if (framework.type === \"sveltekit\") {\n\t\t\t\t\t\tframeworkFileExtension = \"svelte\";\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!frameworkFileExtension) {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\"Could not determine framework from Slice Machine config.\",\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst projectRoot = await this.project.getRoot();\n\t\t\t\t\tconst libraryAbsPath = path.join(projectRoot, libraryID);\n\n\t\t\t\t\ttmpDir = await mkdtemp(\n\t\t\t\t\t\tpath.join(tmpdir(), \"slice-machine-infer-slice-tmp-\"),\n\t\t\t\t\t);\n\t\t\t\t\tconst tmpImagePath = path.join(tmpDir, `${randomUUID()}.png`);\n\t\t\t\t\tconst response = await fetch(imageUrl);\n\t\t\t\t\tif (!response.ok) {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t`Failed to download image: ${response.status} ${response.statusText}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tawait writeFile(\n\t\t\t\t\t\ttmpImagePath,\n\t\t\t\t\t\tBuffer.from(await response.arrayBuffer()),\n\t\t\t\t\t);\n\n\t\t\t\t\tconst queries = queryClaude({\n\t\t\t\t\t\tprompt: `CRITICAL INSTRUCTIONS - READ FIRST:\n\t- You MUST start immediately with Step 1.1. DO NOT read, analyze, or explore any project files first.\n\t- Work step-by-step through the numbered tasks below.\n\t- DO NOT present any summary, explanation, or completion message after finishing.\n\t- DO NOT create TODO lists while performing tasks.\n\t- Keep responses minimal - only show necessary tool calls and brief progress notes.\n\t\n\t# CONTEXT \n\t\n\tThe user wants to build a new Prismic Slice based on a design image they provided.\n\tYour goal is to analyze the design image and generate the JSON model data and boilerplate code for the slice following Prismic requirements.\n\t\n\tYou will work under the slice library at <slice_library_path>, where all the slices are stored.\n\t\n\t# AVAILABLE RESOURCES\n\t\n\t<design_image_path>\n\t${tmpImagePath}\n\t</design_image_path>\n\t\n\t<slice_library_path>\n\t${libraryAbsPath}\n\t</slice_library_path>\n\t\n\t<framework>\n\t${framework.label}\n\t</framework>\n\t\n\t# AVAILABLE TOOLS\n\t\n\tYou have access to specialized Prismic MCP tools for this task:\n\t\n\t<tool name=\"mcp__prismic__how_to_model_slice\">\n\t<description>\n\tProvides detailed guidance on creating Prismic slice models, including field types, naming conventions, and best practices.\n\t</description>\n\t<when_to_use>\n\tCall this tool in Step 2.1 to learn how to structure the slice model data for the design you analysed.\n\t</when_to_use>\n\t</tool>\n\t\n\t<tool name=\"mcp__prismic__how_to_code_slice\">\n\t<description>\n\tProvides guidance on implementing Prismic slice components, including how to use Prismic field components, props structure, and best practices.\n\t</description>\n\t<when_to_use>\n\tCall this tool in Step 2.1 to learn how to properly structure the slice component with Prismic fields.\n\t</when_to_use>\n\t</tool>\n\t\n\t<tool name=\"mcp__prismic__save_slice_data\">\n\t<description>\n\tValidates and saves the slice model data to model.json. This is the ONLY way to create the model file.\n\t</description>\n\t<when_to_use>\n\tCall this tool in Step 2.3 after you have built the complete slice model structure in memory.\n\t</when_to_use>\n\t</tool>\n\t\n\t# TASK REQUIREMENTS\n\t\n\t## Step 1: Gather information from the design image\n\t1.1. Analyse the design image at <design_image_path>.\n\t1.2. Identify all elements in the image that should be dynamically editable (e.g., headings, paragraphs, images, links, buttons, etc.).\n\t1.3. List the slice directories under <slice_library_path>.\n\t1.4. Come up with a unique name for the new slice based on the content of the image and the slice directories.\n\t\n\t## Step 2: Model the Prismic slice\n\t2.1. Call mcp__prismic__how_to_model_slice to learn how to structure the model for this design.\n\t- Make sure the name you use for the new slice does not yet exist in the slice library at <slice_library_path>. If it does, use a different name.\n\t2.2. Build the complete slice JSON model data in memory based on the guidance received and the information extracted from the image.\n\t2.3. Call mcp__prismic__save_slice_data to save the model (DO NOT manually write model.json) in the slice library at <slice_library_path>.\n\t\n\t## Step 3: Code a boilerplate slice component based on the model\n\t3.1. Call mcp__prismic__how_to_code_slice to learn how to properly structure the slice component with Prismic fields.\n\t3.2. Update the slice component code at <slice_library_path>/index.${frameworkFileExtension}, replacing the placeholder code with boilerplate code with the following requirements:\n\t- Must NOT be based on existing slices or components from the codebase.\n\t- Must render all the Prismic components to display the fields of the slice model created at <slice_model_path>.\n\t- Must be a valid ${framework.label} component.\n\t- Must NOT have any styling/CSS. No inlines styles or classNames. Just the skeleton component structure.\n\t- Must NOT use any other custom component or functions from the user's codebase.\n\t- Avoid creating unnecessary wrapper elements, like if they only wrap a single component (e.g., <div><PrismicRichText /></div>).\n\t\n\t## Step 4: Present the newly created slice path\n\t4.1. Present the path to the newly created slice in the following format: <new_slice_path>${libraryAbsPath}/MyNewSlice</new_slice_path>.\n\t- \"MyNewSlice\" must be the name of the directory of the newly created slice.\n\t\n\t# EXAMPLE OF CORRECT EXECUTION\n\t\n\t<example>\n\tAssistant: Step 1.1: Analysing design image...\n\t[reads <design_image_path>]\n\t\n\tStep 1.2: Identifying editable content elements...\n\t[identifies: title field, description field, buttonText field, buttonLink field, backgroundImage field]\n\t\n\tStep 1.3: Listing slice directories under <slice_library_path>...\n\t[lists slice directories: Hero, Hero2, Hero3]\n\t\n\tStep 1.4: Coming up with a unique name for the new slice...\n\t[comes up with a unique name for the new slice: Hero4]\n\t\n\tStep 2.1: Getting Prismic modeling guidance...\n\t[calls mcp__prismic__how_to_model_slice]\n\t\n\tStep 2.2: Building slice model based on guidance and the information extracted...\n\t[creates model with title field, description field, buttonText field, buttonLink field, backgroundImage field]\n\t\n\tStep 2.3: Saving slice model...\n\t[calls mcp__prismic__save_slice_data]\n\t\n\tStep 3.1: Learning Prismic slice coding requirements...\n\t[calls mcp__prismic__how_to_code_slice]\n\t\n\tStep 3.2: Coding boilerplate slice component based on the model...\n\t[updates component with Prismic field components, no styling, no other components]\n\t\n\tStep 4.1: Presenting the path to the newly created slice...\n\t[presents <new_slice_path>${path.join(\n\t\tlibraryAbsPath,\n\t\t\"MyNewSlice\",\n\t)}</new_slice_path>]\n\t\n\t# DELIVERABLES\n\t- Slice model saved to <slice_library_path>/model.json using mcp__prismic__save_slice_data\n\t- Slice component at <slice_library_path>/index.${frameworkFileExtension} updated with boilerplate code\n\t- New slice path presented in the format mentioned in Step 3.1\n\t\n\tYOU ARE NOT FINISHED UNTIL YOU HAVE THESE DELIVERABLES.\n\t\n\t---\n\t\n\tFINAL REMINDERS:\n\t- You MUST use mcp__prismic__save_slice_data to save the model\n\t- You MUST call mcp__prismic__how_to_code_slice in Step 3.1\n\t- DO NOT ATTEMPT TO BUILD THE APPLICATION\n\t- START IMMEDIATELY WITH STEP 1.1 - NO PRELIMINARY ANALYSIS;`,\n\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\tcwd: libraryAbsPath,\n\t\t\t\t\t\t\tstderr: (data) => console.error(\"inferSlice error:\" + data),\n\t\t\t\t\t\t\tmodel: \"claude-haiku-4-5\",\n\t\t\t\t\t\t\tpermissionMode: \"bypassPermissions\",\n\t\t\t\t\t\t\tallowedTools: [\n\t\t\t\t\t\t\t\t\"Bash\",\n\t\t\t\t\t\t\t\t\"Read\",\n\t\t\t\t\t\t\t\t\"FileSearch\",\n\t\t\t\t\t\t\t\t\"Grep\",\n\t\t\t\t\t\t\t\t\"Glob\",\n\t\t\t\t\t\t\t\t\"Task\",\n\t\t\t\t\t\t\t\t\"Edit\",\n\t\t\t\t\t\t\t\t\"Write\",\n\t\t\t\t\t\t\t\t\"MultiEdit\",\n\t\t\t\t\t\t\t\t\"mcp__prismic__how_to_model_slice\",\n\t\t\t\t\t\t\t\t\"mcp__prismic__how_to_code_slice\",\n\t\t\t\t\t\t\t\t\"mcp__prismic__save_slice_data\",\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\tdisallowedTools: [\n\t\t\t\t\t\t\t\t`Edit(**/model.json)`,\n\t\t\t\t\t\t\t\t`Write(**/model.json)`,\n\t\t\t\t\t\t\t\t\"Edit(**/mocks.json)\",\n\t\t\t\t\t\t\t\t\"Write(**/mocks.json)\",\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\tenv: {\n\t\t\t\t\t\t\t\t...process.env,\n\t\t\t\t\t\t\t\tANTHROPIC_BASE_URL: llmProxyUrl,\n\t\t\t\t\t\t\t\tANTHROPIC_CUSTOM_HEADERS:\n\t\t\t\t\t\t\t\t\t`x-prismic-token: ${authToken}\\n` +\n\t\t\t\t\t\t\t\t\t`x-prismic-repository: ${repository}\\n`,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tmcpServers: {\n\t\t\t\t\t\t\t\tprismic: {\n\t\t\t\t\t\t\t\t\ttype: \"stdio\",\n\t\t\t\t\t\t\t\t\tcommand: \"npx\",\n\t\t\t\t\t\t\t\t\targs: [\"-y\", \"@prismicio/mcp-server@0.0.20-alpha.6\"],\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t...(abortController && { abortController }),\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\n\t\t\t\t\tlet newSliceAbsPath: string | undefined;\n\n\t\t\t\t\tfor await (const query of queries) {\n\t\t\t\t\t\tswitch (query.type) {\n\t\t\t\t\t\t\tcase \"result\":\n\t\t\t\t\t\t\t\tif (query.subtype === \"success\") {\n\t\t\t\t\t\t\t\t\tnewSliceAbsPath = query.result.match(\n\t\t\t\t\t\t\t\t\t\t/<new_slice_path>(.*)<\\/new_slice_path>/s,\n\t\t\t\t\t\t\t\t\t)?.[1];\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!newSliceAbsPath) {\n\t\t\t\t\t\tthrow new Error(\"Could not find path for the newly created slice.\");\n\t\t\t\t\t}\n\n\t\t\t\t\tconst model = await readFile(\n\t\t\t\t\t\tpath.join(newSliceAbsPath, \"model.json\"),\n\t\t\t\t\t\t\"utf8\",\n\t\t\t\t\t);\n\n\t\t\t\t\tif (!model) {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\"Could not find model for the newly created slice.\",\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\t// move the screenshot image to the new slice directory\n\t\t\t\t\tawait rename(\n\t\t\t\t\t\ttmpImagePath,\n\t\t\t\t\t\tpath.join(newSliceAbsPath, \"screenshot-default.png\"),\n\t\t\t\t\t);\n\n\t\t\t\t\treturn InferSliceResponse.parse({ slice: JSON.parse(model) });\n\t\t\t\t} finally {\n\t\t\t\t\tif (tmpDir && existsSync(tmpDir)) {\n\t\t\t\t\t\tawait rm(tmpDir, { recursive: true });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst searchParams = new URLSearchParams({ repository });\n\t\t\t\tconst url = new URL(\"./slices/infer\", API_ENDPOINTS.CustomTypeService);\n\t\t\t\turl.search = searchParams.toString();\n\n\t\t\t\tconst response = await fetch(url.toString(), {\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\theaders: { Authorization: `Bearer ${authToken}` },\n\t\t\t\t\tbody: JSON.stringify({ imageUrl }),\n\t\t\t\t\t...(abortController && { signal: abortController.signal }),\n\t\t\t\t});\n\n\t\t\t\tif (!response.ok) {\n\t\t\t\t\tthrow new Error(`Failed to infer slice: ${response.statusText}`);\n\t\t\t\t}\n\n\t\t\t\tconst json = await response.json();\n\n\t\t\t\treturn InferSliceResponse.parse(json);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsole.error(\n\t\t\t\t`inferSlice (${source}) failed${\n\t\t\t\t\trequestId ? ` for request ${requestId}` : \"\"\n\t\t\t\t}`,\n\t\t\t\terror,\n\t\t\t);\n\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\tif (requestId) {\n\t\t\t\tthis.inferSliceAbortControllers.delete(requestId);\n\t\t\t}\n\n\t\t\tconst elapsedTimeSeconds = (Date.now() - startTime) / 1000;\n\t\t\tconsole.info(\n\t\t\t\t`inferSlice took ${elapsedTimeSeconds}s${\n\t\t\t\t\trequestId ? ` for request ${requestId}` : \"\"\n\t\t\t\t}`,\n\t\t\t);\n\t\t}\n\t}\n\n\tasync cancelInferSlice(args: {\n\t\trequestId: string;\n\t}): Promise<{ cancelled: boolean }> {\n\t\tconst { requestId } = args;\n\t\tconst abortController = this.inferSliceAbortControllers.get(requestId);\n\n\t\tif (abortController) {\n\t\t\tabortController.abort();\n\t\t\tthis.inferSliceAbortControllers.delete(requestId);\n\n\t\t\treturn { cancelled: true };\n\t\t}\n\n\t\treturn { cancelled: false };\n\t}\n}\n\ntype InferSliceResponse = z.infer<typeof InferSliceResponse>;\n\nconst InferSliceResponse = z.object({\n\tslice: z.custom().transform((value, ctx) => {\n\t\tconst result = SharedSlice.decode(value);\n\t\tif (result._tag === \"Right\") {\n\t\t\treturn result.right;\n\t\t}\n\t\tctx.addIssue({\n\t\t\tcode: z.ZodIssueCode.custom,\n\t\t\tmessage: `Invalid shared slice: ${JSON.stringify(value, null, 2)}`,\n\t\t});\n\n\t\treturn z.NEVER;\n\t}),\n\tlangSmithUrl: z.string().url().optional(),\n});\n\nfunction updateCRCustomType(\n\targs: { customType: LinkCustomType } & CustomTypeFieldIdChangedMeta,\n): LinkCustomType {\n\tconst previousPath = getPathIds(args.previousPath);\n\tconst newPath = getPathIds(args.newPath);\n\n\tif (!previousPath.customTypeId || !newPath.customTypeId) {\n\t\tthrow new Error(\n\t\t\t`Could not find a customtype id in previousPath (${args.previousPath.join(\n\t\t\t\t\".\",\n\t\t\t)}) and/or newPath (${args.newPath.join(\n\t\t\t\t\".\",\n\t\t\t)}), which should not be possible.`,\n\t\t);\n\t}\n\n\tif (!previousPath.fieldId || !newPath.fieldId) {\n\t\tthrow new Error(\n\t\t\t`Could not find a field id in previousPath (${args.previousPath.join(\n\t\t\t\t\".\",\n\t\t\t)}) and/or newPath (${args.newPath.join(\n\t\t\t\t\".\",\n\t\t\t)}), which should not be possible.`,\n\t\t);\n\t}\n\n\tconst customType = shallowCloneIfObject(args.customType);\n\n\tif (typeof customType === \"string\") {\n\t\t// Legacy format support, we don't have anything to update here.\n\t\treturn customType;\n\t}\n\n\tconst matchedCustomTypeId = customType.id === previousPath.customTypeId;\n\n\treturn {\n\t\t...customType,\n\t\tfields: customType.fields.map((fieldArg) => {\n\t\t\tconst customTypeField = shallowCloneIfObject(fieldArg);\n\n\t\t\t// Regular field\n\t\t\tif (typeof customTypeField === \"string\") {\n\t\t\t\tif (\n\t\t\t\t\tmatchedCustomTypeId &&\n\t\t\t\t\tcustomTypeField === previousPath.fieldId &&\n\t\t\t\t\tcustomTypeField !== newPath.fieldId\n\t\t\t\t) {\n\t\t\t\t\t// The id of the field has changed.\n\t\t\t\t\treturn newPath.fieldId;\n\t\t\t\t}\n\n\t\t\t\treturn customTypeField;\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\tmatchedCustomTypeId &&\n\t\t\t\tcustomTypeField.id === previousPath.fieldId &&\n\t\t\t\tcustomTypeField.id !== newPath.fieldId\n\t\t\t) {\n\t\t\t\t// The id of the field has changed. We don't exit return because there\n\t\t\t\t// might be other fields further down in nested custom types or groups\n\t\t\t\t// that need to be updated.\n\t\t\t\tcustomTypeField.id = newPath.fieldId;\n\t\t\t}\n\n\t\t\t// Group field\n\t\t\tif (\"fields\" in customTypeField) {\n\t\t\t\tif (\n\t\t\t\t\t!previousPath.groupId &&\n\t\t\t\t\t!newPath.groupId &&\n\t\t\t\t\tcustomTypeField.id === previousPath.fieldId &&\n\t\t\t\t\tcustomTypeField.id !== newPath.fieldId\n\t\t\t\t) {\n\t\t\t\t\t// Only the id of the group has changed. Group id is not defined, so\n\t\t\t\t\t// we can return early.\n\t\t\t\t\treturn newPath.fieldId;\n\t\t\t\t}\n\n\t\t\t\tconst matchedGroupId = customTypeField.id === previousPath.groupId;\n\n\t\t\t\tif (\n\t\t\t\t\tpreviousPath.groupId &&\n\t\t\t\t\tnewPath.groupId &&\n\t\t\t\t\tmatchedGroupId &&\n\t\t\t\t\tcustomTypeField.id !== newPath.groupId\n\t\t\t\t) {\n\t\t\t\t\t// The id of the group field has changed, so we update it. We don't\n\t\t\t\t\t// return because there are group fields that may need to be updated.\n\t\t\t\t\tcustomTypeField.id = newPath.groupId;\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\t...customTypeField,\n\t\t\t\t\tfields: customTypeField.fields.map((groupFieldArg) => {\n\t\t\t\t\t\tconst groupField = shallowCloneIfObject(groupFieldArg);\n\n\t\t\t\t\t\t// Regular field inside a group field\n\t\t\t\t\t\tif (typeof groupField === \"string\") {\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tmatchedGroupId &&\n\t\t\t\t\t\t\t\tgroupField === previousPath.fieldId &&\n\t\t\t\t\t\t\t\tgroupField !== newPath.fieldId\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t// The id of the field inside the group has changed.\n\t\t\t\t\t\t\t\treturn newPath.fieldId;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\treturn groupField;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Content relationship field inside a group field\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t...groupField,\n\t\t\t\t\t\t\tfields: updateContentRelationshipFields({\n\t\t\t\t\t\t\t\tcustomtypes: groupField.customtypes,\n\t\t\t\t\t\t\t\tpreviousPath,\n\t\t\t\t\t\t\t\tnewPath,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t};\n\t\t\t\t\t}),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Content relationship field\n\t\t\treturn {\n\t\t\t\t...customTypeField,\n\t\t\t\tcustomtypes: updateContentRelationshipFields({\n\t\t\t\t\tcustomtypes: customTypeField.customtypes,\n\t\t\t\t\tpreviousPath,\n\t\t\t\t\tnewPath,\n\t\t\t\t}),\n\t\t\t};\n\t\t}),\n\t};\n}\n\nfunction updateContentRelationshipFields(args: {\n\tcustomtypes: readonly (\n\t\t| string\n\t\t| {\n\t\t\t\tid: string;\n\t\t\t\tfields: readonly (string | { id: string; fields: readonly string[] })[];\n\t\t }\n\t)[];\n\tpreviousPath: CrUpdatePathIds;\n\tnewPath: CrUpdatePathIds;\n}) {\n\tconst { customtypes, previousPath, newPath } = args;\n\n\treturn customtypes.map((nestedCtArg) => {\n\t\tconst nestedCt = shallowCloneIfObject(nestedCtArg);\n\n\t\tif (\n\t\t\ttypeof nestedCt === \"string\" ||\n\t\t\t// Since we are entering a new custom type, if the previous id\n\t\t\t// doesn't match, we can return early, because it's not the\n\t\t\t// custom type we are looking for.\n\t\t\tnestedCt.id !== previousPath.customTypeId\n\t\t) {\n\t\t\treturn nestedCt;\n\t\t}\n\n\t\treturn {\n\t\t\t...nestedCt,\n\t\t\tfields: nestedCt.fields.map((nestedCtFieldArg) => {\n\t\t\t\tconst nestedCtField = shallowCloneIfObject(nestedCtFieldArg);\n\n\t\t\t\t// Regular field\n\t\t\t\tif (typeof nestedCtField === \"string\") {\n\t\t\t\t\tif (\n\t\t\t\t\t\tnestedCtField === previousPath.fieldId &&\n\t\t\t\t\t\tnestedCtField !== newPath.fieldId\n\t\t\t\t\t) {\n\t\t\t\t\t\t// The id of the field has changed.\n\t\t\t\t\t\treturn newPath.fieldId;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn nestedCtField;\n\t\t\t\t}\n\n\t\t\t\t// Group field\n\n\t\t\t\tif (\n\t\t\t\t\tnestedCtField.id === previousPath.fieldId &&\n\t\t\t\t\tnestedCtField.id !== newPath.fieldId\n\t\t\t\t) {\n\t\t\t\t\t// The id of the field has changed.\n\t\t\t\t\tnestedCtField.id = newPath.fieldId;\n\t\t\t\t}\n\n\t\t\t\t// Further down the path, the field can only be a group field. So if we have\n\t\t\t\t// no group id defined, no need to continue.\n\t\t\t\tif (\n\t\t\t\t\t!previousPath.groupId ||\n\t\t\t\t\t!newPath.groupId ||\n\t\t\t\t\tnestedCtField.id !== previousPath.groupId\n\t\t\t\t) {\n\t\t\t\t\treturn nestedCtField;\n\t\t\t\t}\n\n\t\t\t\tif (nestedCtField.id !== newPath.groupId) {\n\t\t\t\t\t// The id of the group has changed.\n\t\t\t\t\tnestedCtField.id = newPath.groupId;\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\t...nestedCtField,\n\t\t\t\t\tfields: nestedCtField.fields.map((nestedCtGroupFieldId) => {\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tnestedCtGroupFieldId === previousPath.fieldId &&\n\t\t\t\t\t\t\tnestedCtGroupFieldId !== newPath.fieldId\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t// The id of the field inside the group has changed.\n\t\t\t\t\t\t\treturn newPath.fieldId;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn nestedCtGroupFieldId;\n\t\t\t\t\t}),\n\t\t\t\t};\n\t\t\t}),\n\t\t};\n\t});\n}\n\n/**\n * Update the Content Relationship API IDs of a single field. The change is\n * determined by the `previousPath` and `newPath` properties.\n */\nfunction updateFieldContentRelationships<\n\tT extends UID | NestableWidget | Group | NestedGroup,\n>(args: { field: T } & CustomTypeFieldIdChangedMeta): T {\n\tconst { field, ...updateMeta } = args;\n\tif (\n\t\tfield.type !== \"Link\" ||\n\t\tfield.config?.select !== \"document\" ||\n\t\t!field.config?.customtypes\n\t) {\n\t\t// not a content relationship field\n\t\treturn field;\n\t}\n\n\tconst newCustomTypes = field.config.customtypes.map((customType) => {\n\t\treturn updateCRCustomType({ ...updateMeta, customType });\n\t});\n\n\treturn {\n\t\t...field,\n\t\tconfig: { ...field.config, customtypes: newCustomTypes },\n\t};\n}\n\nexport function updateCustomTypeContentRelationships(\n\targs: {\n\t\tmodels: { model: CustomType }[];\n\t\tonUpdate: (model: { previousModel: CustomType; model: CustomType }) => void;\n\t} & CustomTypeFieldIdChangedMeta,\n): void {\n\tconst { models, previousPath, newPath, onUpdate } = args;\n\n\tfor (const { model: customType } of models) {\n\t\tconst updatedCustomType = traverseCustomType({\n\t\t\tcustomType,\n\t\t\tonField: ({ field }) => {\n\t\t\t\treturn updateFieldContentRelationships({\n\t\t\t\t\tfield,\n\t\t\t\t\tpreviousPath,\n\t\t\t\t\tnewPath,\n\t\t\t\t});\n\t\t\t},\n\t\t});\n\n\t\tif (!isEqualModel(customType, updatedCustomType)) {\n\t\t\tonUpdate({ model: updatedCustomType, previousModel: customType });\n\t\t}\n\t}\n}\n\nexport function updateSharedSliceContentRelationships(\n\targs: {\n\t\tmodels: { model: SharedSlice }[];\n\t\tonUpdate: (model: {\n\t\t\tpreviousModel: SharedSlice;\n\t\t\tmodel: SharedSlice;\n\t\t}) => void;\n\t} & CustomTypeFieldIdChangedMeta,\n): void {\n\tconst { models, previousPath, newPath, onUpdate } = args;\n\n\tfor (const { model: slice } of models) {\n\t\tconst updateSlice = traverseSharedSlice({\n\t\t\tpath: [],\n\t\t\tslice,\n\t\t\tonField: ({ field }) => {\n\t\t\t\treturn updateFieldContentRelationships({\n\t\t\t\t\tfield,\n\t\t\t\t\tpreviousPath,\n\t\t\t\t\tnewPath,\n\t\t\t\t});\n\t\t\t},\n\t\t});\n\n\t\tif (!isEqualModel(slice, updateSlice)) {\n\t\t\tonUpdate({ model: updateSlice, previousModel: slice });\n\t\t}\n\t}\n}\n\ninterface CrUpdatePathIds {\n\tcustomTypeId: string;\n\tgroupId: string | undefined;\n\tfieldId: string;\n}\n\nfunction getPathIds(path: PathWithCustomType): CrUpdatePathIds {\n\tif (path.length < 2) {\n\t\tthrow new Error(\n\t\t\t`Unexpected path length ${\n\t\t\t\tpath.length\n\t\t\t}. Expected at least 2 segments (got: ${path.join(\".\")}).`,\n\t\t);\n\t}\n\n\tconst [customTypeId, groupOrFieldId, fieldId] = path;\n\n\treturn {\n\t\tcustomTypeId,\n\t\t/**\n\t\t * Id of a changed group. If it's defined, it means that a group or a field\n\t\t * inside a group had its API ID renamed. It's defined when the path has a\n\t\t * third element (e.g. `[\"customtypeA\", \"groupA\", \"fieldA\"]`).\n\t\t */\n\t\tgroupId: fieldId ? groupOrFieldId : undefined,\n\t\tfieldId: fieldId || groupOrFieldId,\n\t};\n}\n\nfunction isEqualModel<T extends CustomType | SharedSlice>(\n\tmodelA: T,\n\tmodelB: T,\n): boolean {\n\treturn JSON.stringify(modelA) === JSON.stringify(modelB);\n}\n\nfunction shallowCloneIfObject<T>(value: T): T {\n\tif (typeof value === \"object\") {\n\t\treturn { ...value };\n\t}\n\n\treturn value;\n}\n"],"names":["errors","_a","queryClaude","query","path"],"mappings":"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"}
1
+ {"version":3,"file":"CustomTypesManager.js","sources":["../../../../src/managers/customTypes/CustomTypesManager.ts"],"sourcesContent":["import * as t from \"io-ts\";\nimport * as prismicCustomTypesClient from \"@prismicio/custom-types-client\";\nimport {\n\tCustomType,\n\tGroup,\n\tLinkConfig,\n\tNestableWidget,\n\tNestedGroup,\n\tSharedSlice,\n\tUID,\n\ttraverseCustomType,\n\ttraverseSharedSlice,\n} from \"@prismicio/types-internal/lib/customtypes\";\nimport {\n\tCallHookReturnType,\n\tCustomTypeCreateHook,\n\tCustomTypeCreateHookData,\n\tCustomTypeReadHookData,\n\tCustomTypeRenameHook,\n\tCustomTypeRenameHookData,\n\tCustomTypeUpdateHook,\n\tCustomTypeUpdateHookData,\n\tHookError,\n} from \"@slicemachine/plugin-kit\";\nimport { z } from \"zod\";\n\nimport { DecodeError } from \"../../lib/DecodeError\";\nimport { assertPluginsInitialized } from \"../../lib/assertPluginsInitialized\";\nimport { decodeHookResult } from \"../../lib/decodeHookResult\";\nimport fetch from \"../../lib/fetch\";\n\nimport { OnlyHookErrors } from \"../../types\";\nimport { API_ENDPOINTS } from \"../../constants/API_ENDPOINTS\";\nimport { SLICE_MACHINE_USER_AGENT } from \"../../constants/SLICE_MACHINE_USER_AGENT\";\nimport { UnauthorizedError } from \"../../errors\";\n\nimport { BaseManager } from \"../BaseManager\";\nimport { CustomTypeFormat } from \"./types\";\nimport { existsSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { randomUUID } from \"node:crypto\";\nimport { join as joinPath } from \"node:path\";\nimport { mkdtemp, rename, rm, writeFile, readFile } from \"node:fs/promises\";\nimport { query as queryClaude } from \"@anthropic-ai/claude-agent-sdk\";\n\ntype SliceMachineManagerReadCustomTypeLibraryReturnType = {\n\tids: string[];\n\terrors: (DecodeError | HookError)[];\n};\n\ntype CustomTypesManagerReadAllCustomTypesArgs = {\n\tformat: CustomTypeFormat;\n};\n\ntype SliceMachineManagerReadAllCustomTypeReturnType = {\n\tmodels: { model: CustomType }[];\n\terrors: (DecodeError | HookError)[];\n};\n\ntype SliceMachineManagerReadCustomTypeReturnType = {\n\tmodel: CustomType | undefined;\n\terrors: (DecodeError | HookError)[];\n};\n\ntype SliceMachineManagerPushCustomTypeArgs = {\n\tid: string;\n\tuserAgent?: string;\n};\n\ntype SliceMachineManagerReadCustomTypeMocksConfigArgs = {\n\tcustomTypeID: string;\n};\n\ntype SliceMachineManagerReadCustomTypeMocksConfigArgsReturnType = {\n\t// TODO\n\tmocksConfig?: Record<string, unknown>;\n\terrors: HookError[];\n};\n\ntype SliceMachineManagerUpdateCustomTypeMocksConfigArgs = {\n\tcustomTypeID: string;\n\t// TODO\n\tmocksConfig: Record<string, unknown>;\n};\n\n/** `[field]` or `[group, field]` – path **inside** the Custom Type */\ntype PathWithoutCustomType = [string] | [string, string];\n\ntype SliceMachineManagerUpdateCustomTypeFieldIdChanged = {\n\t/**\n\t * Previous path of the changed field, excluding the custom type id. Can be\n\t * used to identify the field that had an API ID rename (e.g. [\"fieldA\"] or\n\t * [\"groupA\", \"fieldA\"])\n\t */\n\tpreviousPath: PathWithoutCustomType;\n\t/**\n\t * New path of the changed field, excluding the custom type id. Can be used to\n\t * identify the field that had an API ID rename (e.g. [\"fieldB\"] or [\"groupA\",\n\t * \"fieldB\"])\n\t */\n\tnewPath: PathWithoutCustomType;\n};\n\ntype SliceMachineManagerUpdateCustomTypeArgs = CustomTypeUpdateHookData & {\n\tupdateMeta?: {\n\t\tfieldIdChanged?: SliceMachineManagerUpdateCustomTypeFieldIdChanged;\n\t};\n};\n\ntype SliceMachineManagerUpdateCustomTypeMocksConfigArgsReturnType = {\n\terrors: HookError[];\n};\n\ntype CustomTypesMachineManagerDeleteCustomTypeArgs = {\n\tid: string;\n};\n\ntype CustomTypesMachineManagerDeleteCustomTypeReturnType = {\n\terrors: (DecodeError | HookError)[];\n};\n\ntype CustomTypesMachineManagerUpdateCustomTypeReturnType = {\n\terrors: (DecodeError | HookError)[];\n};\n\n/** `[ct, field]` or `[ct, group, field]` – path **with** Custom Type ID */\ntype PathWithCustomType = [string, string] | [string, string, string];\n\ntype CustomTypeFieldIdChangedMeta = {\n\tpreviousPath: PathWithCustomType;\n\tnewPath: PathWithCustomType;\n};\n\ntype LinkCustomType = NonNullable<LinkConfig[\"customtypes\"]>[number];\n\nexport class CustomTypesManager extends BaseManager {\n\tasync readCustomTypeLibrary(): Promise<SliceMachineManagerReadCustomTypeLibraryReturnType> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"custom-type-library:read\",\n\t\t\tundefined,\n\t\t);\n\t\tconst { data, errors } = decodeHookResult(\n\t\t\tt.type({\n\t\t\t\tids: t.array(t.string),\n\t\t\t}),\n\t\t\thookResult,\n\t\t);\n\n\t\treturn {\n\t\t\tids: data[0]?.ids || [],\n\t\t\terrors,\n\t\t};\n\t}\n\n\tasync readAllCustomTypes(\n\t\targs?: CustomTypesManagerReadAllCustomTypesArgs,\n\t): Promise<SliceMachineManagerReadAllCustomTypeReturnType> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst res: SliceMachineManagerReadAllCustomTypeReturnType = {\n\t\t\tmodels: [],\n\t\t\terrors: [],\n\t\t};\n\n\t\tconst { ids, errors } = await this.readCustomTypeLibrary();\n\t\tres.errors = [...res.errors, ...errors];\n\n\t\tif (ids) {\n\t\t\tfor (const id of ids) {\n\t\t\t\tconst { model, errors } = await this.readCustomType({ id });\n\t\t\t\tres.errors = [...res.errors, ...errors];\n\n\t\t\t\tif (model && (!args || args.format === model.format)) {\n\t\t\t\t\tres.models.push({ model });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn res;\n\t}\n\n\tasync createCustomType(\n\t\targs: CustomTypeCreateHookData,\n\t): Promise<OnlyHookErrors<CallHookReturnType<CustomTypeCreateHook>>> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"custom-type:create\",\n\t\t\targs,\n\t\t);\n\n\t\treturn {\n\t\t\terrors: hookResult.errors,\n\t\t};\n\t}\n\n\tasync readCustomType(\n\t\targs: CustomTypeReadHookData,\n\t): Promise<SliceMachineManagerReadCustomTypeReturnType> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"custom-type:read\",\n\t\t\targs,\n\t\t);\n\t\tconst { data, errors } = decodeHookResult(\n\t\t\tt.type({\n\t\t\t\tmodel: CustomType,\n\t\t\t}),\n\t\t\thookResult,\n\t\t);\n\n\t\treturn {\n\t\t\tmodel: data[0]?.model,\n\t\t\terrors,\n\t\t};\n\t}\n\n\t/**\n\t * Update the Content Relationship API IDs for all existing custom types and\n\t * slices. The change is determined by properties inside the `updateMeta`\n\t * property.\n\t */\n\tprivate async updateContentRelationships(\n\t\targs: {\n\t\t\tmodel: CustomType;\n\t\t} & SliceMachineManagerUpdateCustomTypeFieldIdChanged,\n\t): Promise<\n\t\tOnlyHookErrors<CallHookReturnType<CustomTypeUpdateHook>> & {\n\t\t\trollback?: () => Promise<void>;\n\t\t}\n\t> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst {\n\t\t\tmodel,\n\t\t\tpreviousPath: previousFieldPath,\n\t\t\tnewPath: newFieldPath,\n\t\t} = args;\n\n\t\tif (previousFieldPath.join(\".\") !== newFieldPath.join(\".\")) {\n\t\t\tconst { id: ctId } = model;\n\t\t\tconst previousPath: PathWithCustomType = [ctId, ...previousFieldPath];\n\t\t\tconst newPath: PathWithCustomType = [ctId, ...newFieldPath];\n\n\t\t\tconst crUpdates: {\n\t\t\t\tupdatePromise: Promise<{ errors: HookError[] }>;\n\t\t\t\trollback: () => void;\n\t\t\t}[] = [];\n\n\t\t\t// Find existing content relationships that link to the renamed field id in\n\t\t\t// any custom type and update them to use the new one.\n\t\t\tconst customTypes = await this.readAllCustomTypes();\n\n\t\t\tupdateCustomTypeContentRelationships({\n\t\t\t\tmodels: customTypes.models,\n\t\t\t\tonUpdate: ({ previousModel, model: updatedModel }) => {\n\t\t\t\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\t\t\t\tcrUpdates.push({\n\t\t\t\t\t\tupdatePromise: this.sliceMachinePluginRunner?.callHook(\n\t\t\t\t\t\t\t\"custom-type:update\",\n\t\t\t\t\t\t\t{ model: updatedModel },\n\t\t\t\t\t\t),\n\t\t\t\t\t\trollback: () => {\n\t\t\t\t\t\t\tthis.sliceMachinePluginRunner?.callHook(\"custom-type:update\", {\n\t\t\t\t\t\t\t\tmodel: previousModel,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\tpreviousPath,\n\t\t\t\tnewPath,\n\t\t\t});\n\n\t\t\t// Find existing slice with content relationships that link to the renamed\n\t\t\t// field id in all libraries and update them to use the new one.\n\t\t\tconst { libraries } = await this.slices.readAllSliceLibraries();\n\n\t\t\tfor (const library of libraries) {\n\t\t\t\tconst slices = await this.slices.readAllSlicesForLibrary({\n\t\t\t\t\tlibraryID: library.libraryID,\n\t\t\t\t});\n\n\t\t\t\tupdateSharedSliceContentRelationships({\n\t\t\t\t\tmodels: slices.models,\n\t\t\t\t\tonUpdate: ({ previousModel, model: updatedModel }) => {\n\t\t\t\t\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\t\t\t\t\tcrUpdates.push({\n\t\t\t\t\t\t\tupdatePromise: this.sliceMachinePluginRunner?.callHook(\n\t\t\t\t\t\t\t\t\"slice:update\",\n\t\t\t\t\t\t\t\t{ libraryID: library.libraryID, model: updatedModel },\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\trollback: () => {\n\t\t\t\t\t\t\t\tthis.sliceMachinePluginRunner?.callHook(\"slice:update\", {\n\t\t\t\t\t\t\t\t\tlibraryID: library.libraryID,\n\t\t\t\t\t\t\t\t\tmodel: previousModel,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\t\t\t\t\t},\n\t\t\t\t\tpreviousPath,\n\t\t\t\t\tnewPath,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Process all the Content Relationship updates at once.\n\t\t\tconst crUpdatesResult = await Promise.all(\n\t\t\t\tcrUpdates.map((update) => update.updatePromise),\n\t\t\t);\n\n\t\t\tif (crUpdatesResult.some((result) => result.errors.length > 0)) {\n\t\t\t\treturn {\n\t\t\t\t\terrors: crUpdatesResult.flatMap((result) => result.errors),\n\t\t\t\t\trollback: async () => {\n\t\t\t\t\t\tawait Promise.all(crUpdates.map((update) => update.rollback()));\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\treturn { errors: [] };\n\t}\n\n\tasync updateCustomType(\n\t\targs: SliceMachineManagerUpdateCustomTypeArgs,\n\t): Promise<CustomTypesMachineManagerUpdateCustomTypeReturnType> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\t\tconst { model } = args;\n\t\tconst { fieldIdChanged } = args.updateMeta ?? {};\n\n\t\tlet previousCustomType: CustomType | undefined;\n\n\t\tif (fieldIdChanged) {\n\t\t\tconst customTypeRead = await this.readCustomType({ id: model.id });\n\n\t\t\tif (customTypeRead.errors.length > 0) {\n\t\t\t\treturn { errors: customTypeRead.errors };\n\t\t\t}\n\t\t\tif (!customTypeRead.model) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`readCustomType succeeded reading custom type ${model.id} but model is undefined.`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tpreviousCustomType = customTypeRead.model;\n\t\t}\n\n\t\tconst customTypeUpdateResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"custom-type:update\",\n\t\t\t{ model },\n\t\t);\n\n\t\tif (customTypeUpdateResult.errors.length > 0) {\n\t\t\treturn { errors: customTypeUpdateResult.errors };\n\t\t}\n\n\t\tif (previousCustomType && fieldIdChanged) {\n\t\t\tconst crUpdateResult = await this.updateContentRelationships({\n\t\t\t\t...fieldIdChanged,\n\t\t\t\tmodel: previousCustomType,\n\t\t\t});\n\n\t\t\tif (crUpdateResult.errors.length > 0) {\n\t\t\t\t// put the previous custom type back\n\t\t\t\tawait this.sliceMachinePluginRunner?.callHook(\"custom-type:update\", {\n\t\t\t\t\tmodel: previousCustomType,\n\t\t\t\t});\n\t\t\t\t// revert the content relationships updates\n\t\t\t\tawait crUpdateResult.rollback?.();\n\n\t\t\t\treturn { errors: crUpdateResult.errors };\n\t\t\t}\n\t\t}\n\n\t\treturn { errors: [] };\n\t}\n\n\tasync renameCustomType(\n\t\targs: CustomTypeRenameHookData,\n\t): Promise<OnlyHookErrors<CallHookReturnType<CustomTypeRenameHook>>> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"custom-type:rename\",\n\t\t\targs,\n\t\t);\n\n\t\treturn {\n\t\t\terrors: hookResult.errors,\n\t\t};\n\t}\n\n\tasync deleteCustomType(\n\t\targs: CustomTypesMachineManagerDeleteCustomTypeArgs,\n\t): Promise<CustomTypesMachineManagerDeleteCustomTypeReturnType> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst { model, errors: readCustomTypeErrors } = await this.readCustomType({\n\t\t\tid: args.id,\n\t\t});\n\n\t\tif (model) {\n\t\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\t\"custom-type:delete\",\n\t\t\t\t{ model },\n\t\t\t);\n\n\t\t\treturn {\n\t\t\t\terrors: hookResult.errors,\n\t\t\t};\n\t\t} else {\n\t\t\treturn {\n\t\t\t\terrors: readCustomTypeErrors,\n\t\t\t};\n\t\t}\n\t}\n\n\tasync pushCustomType(\n\t\targs: SliceMachineManagerPushCustomTypeArgs,\n\t): Promise<void> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst authenticationToken = await this.user.getAuthenticationToken();\n\t\tconst repositoryName = await this.project.getResolvedRepositoryName();\n\n\t\t// TODO: Handle errors\n\t\tconst { model } = await this.readCustomType({ id: args.id });\n\n\t\tif (model) {\n\t\t\t// TODO: Create a single shared client.\n\t\t\tconst client = prismicCustomTypesClient.createClient({\n\t\t\t\tendpoint: API_ENDPOINTS.PrismicModels,\n\t\t\t\trepositoryName,\n\t\t\t\ttoken: authenticationToken,\n\t\t\t\tfetch,\n\t\t\t\tfetchOptions: {\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t\"User-Agent\": args.userAgent || SLICE_MACHINE_USER_AGENT,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t});\n\n\t\t\ttry {\n\t\t\t\t// Check if Custom Type already exists on the repository.\n\t\t\t\tawait client.getCustomTypeByID(args.id);\n\n\t\t\t\t// If it exists on the repository, update it.\n\t\t\t\tawait client.updateCustomType(model);\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof prismicCustomTypesClient.NotFoundError) {\n\t\t\t\t\t// If it doesn't exist on the repository, insert it.\n\t\t\t\t\tawait client.insertCustomType(model);\n\t\t\t\t} else if (error instanceof prismicCustomTypesClient.ForbiddenError) {\n\t\t\t\t\tthrow new UnauthorizedError(\n\t\t\t\t\t\t\"You do not have access to push types to this Prismic repository.\",\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcause: error,\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// TODO: Remove\n\tasync readCustomTypeMocksConfig(\n\t\targs: SliceMachineManagerReadCustomTypeMocksConfigArgs,\n\t): Promise<SliceMachineManagerReadCustomTypeMocksConfigArgsReturnType> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"custom-type:asset:read\",\n\t\t\t{\n\t\t\t\tcustomTypeID: args.customTypeID,\n\t\t\t\tassetID: \"mocks.config.json\",\n\t\t\t},\n\t\t);\n\t\tconst data = hookResult.data[0]?.data;\n\n\t\t// TODO: Validate the returned data.\n\n\t\tif (data) {\n\t\t\treturn {\n\t\t\t\tmocksConfig: JSON.parse(data.toString()),\n\t\t\t\terrors: hookResult.errors,\n\t\t\t};\n\t\t} else {\n\t\t\treturn {\n\t\t\t\tmocksConfig: undefined,\n\t\t\t\terrors: hookResult.errors,\n\t\t\t};\n\t\t}\n\t}\n\n\t// TODO: Remove\n\tasync updateCustomTypeMocksConfig(\n\t\targs: SliceMachineManagerUpdateCustomTypeMocksConfigArgs,\n\t): Promise<SliceMachineManagerUpdateCustomTypeMocksConfigArgsReturnType> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"custom-type:asset:update\",\n\t\t\t{\n\t\t\t\tcustomTypeID: args.customTypeID,\n\t\t\t\tasset: {\n\t\t\t\t\tid: \"mocks.config.json\",\n\t\t\t\t\tdata: Buffer.from(JSON.stringify(args.mocksConfig, null, \"\\t\")),\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\n\t\treturn {\n\t\t\terrors: hookResult.errors,\n\t\t};\n\t}\n\n\tasync fetchRemoteCustomTypes(): Promise<CustomType[]> {\n\t\tconst authenticationToken = await this.user.getAuthenticationToken();\n\t\tconst repositoryName = await this.project.getResolvedRepositoryName();\n\n\t\tconst client = prismicCustomTypesClient.createClient({\n\t\t\tendpoint: API_ENDPOINTS.PrismicModels,\n\t\t\trepositoryName,\n\t\t\ttoken: authenticationToken,\n\t\t\tfetch,\n\t\t\tfetchOptions: {\n\t\t\t\theaders: {\n\t\t\t\t\t\"User-Agent\": SLICE_MACHINE_USER_AGENT,\n\t\t\t\t},\n\t\t\t},\n\t\t});\n\n\t\treturn await client.getAllCustomTypes();\n\t}\n\n\tasync inferSlice(\n\t\targs: { imageUrl: string } & (\n\t\t\t| { source: \"upload\" }\n\t\t\t| { source: \"figma\"; libraryID: string }\n\t\t),\n\t): Promise<InferSliceResponse> {\n\t\tconst { source, imageUrl } = args;\n\n\t\tconst authToken = await this.user.getAuthenticationToken();\n\t\tconst repository = await this.project.getResolvedRepositoryName();\n\n\t\tconsole.info(`inferSlice (${source}) started`);\n\t\tconst startTime = Date.now();\n\n\t\ttry {\n\t\t\tif (source === \"figma\") {\n\t\t\t\tconst { libraryID } = args;\n\n\t\t\t\tconst exp =\n\t\t\t\t\tawait this.telemetry.getExperimentVariant(\"llm-proxy-access\");\n\t\t\t\tif (exp?.value !== \"on\") {\n\t\t\t\t\tthrow new Error(\"User does not have access to the LLM proxy.\");\n\t\t\t\t}\n\n\t\t\t\tconst { llmProxyUrl } = z\n\t\t\t\t\t.object({ llmProxyUrl: z.string().url() })\n\t\t\t\t\t.parse(exp.payload);\n\n\t\t\t\tlet tmpDir: string | undefined;\n\t\t\t\ttry {\n\t\t\t\t\tconst config = await this.project.getSliceMachineConfig();\n\n\t\t\t\t\tlet framework:\n\t\t\t\t\t\t| { type: \"nextjs\" | \"nuxt\" | \"sveltekit\"; label: string }\n\t\t\t\t\t\t| undefined;\n\t\t\t\t\tif (config.adapter === \"@slicemachine/adapter-next\") {\n\t\t\t\t\t\tframework = { type: \"nextjs\", label: \"Next.js (React)\" };\n\t\t\t\t\t} else if (\n\t\t\t\t\t\tconfig.adapter === \"@slicemachine/adapter-nuxt\" ||\n\t\t\t\t\t\tconfig.adapter === \"@slicemachine/adapter-nuxt2\"\n\t\t\t\t\t) {\n\t\t\t\t\t\tframework = { type: \"nuxt\", label: \"Nuxt (Vue)\" };\n\t\t\t\t\t} else if (config.adapter === \"@slicemachine/adapter-sveltekit\") {\n\t\t\t\t\t\tframework = { type: \"sveltekit\", label: \"SvelteKit (Svelte)\" };\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!framework) {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\"Could not determine framework from Slice Machine config.\",\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tlet frameworkFileExtension: string | undefined;\n\t\t\t\t\tif (framework.type === \"nextjs\") {\n\t\t\t\t\t\tframeworkFileExtension = \"tsx\";\n\t\t\t\t\t} else if (framework.type === \"nuxt\") {\n\t\t\t\t\t\tframeworkFileExtension = \"vue\";\n\t\t\t\t\t} else if (framework.type === \"sveltekit\") {\n\t\t\t\t\t\tframeworkFileExtension = \"svelte\";\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!frameworkFileExtension) {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\"Could not determine framework from Slice Machine config.\",\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst projectRoot = await this.project.getRoot();\n\t\t\t\t\tconst libraryAbsPath = joinPath(projectRoot, libraryID);\n\n\t\t\t\t\ttmpDir = await mkdtemp(\n\t\t\t\t\t\tjoinPath(tmpdir(), \"slice-machine-infer-slice-tmp-\"),\n\t\t\t\t\t);\n\t\t\t\t\tconst tmpImagePath = joinPath(tmpDir, `${randomUUID()}.png`);\n\t\t\t\t\tconst response = await fetch(imageUrl);\n\t\t\t\t\tif (!response.ok) {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t`Failed to download image: ${response.status} ${response.statusText}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tawait writeFile(\n\t\t\t\t\t\ttmpImagePath,\n\t\t\t\t\t\tBuffer.from(await response.arrayBuffer()),\n\t\t\t\t\t);\n\n\t\t\t\t\tconst queries = queryClaude({\n\t\t\t\t\t\tprompt: `CRITICAL INSTRUCTIONS - READ FIRST:\n\t- You MUST start immediately with Step 1.1. DO NOT read, analyze, or explore any project files first.\n\t- Work step-by-step through the numbered tasks below.\n\t- DO NOT present any summary, explanation, or completion message after finishing.\n\t- DO NOT create TODO lists while performing tasks.\n\t- Keep responses minimal - only show necessary tool calls and brief progress notes.\n\t\n\t# CONTEXT \n\t\n\tThe user wants to build a new Prismic Slice based on a design image they provided.\n\tYour goal is to analyze the design image and generate the JSON model data and boilerplate code for the slice following Prismic requirements.\n\t\n\tYou will work under the slice library at <slice_library_path>, where all the slices are stored.\n\t\n\t# AVAILABLE RESOURCES\n\t\n\t<design_image_path>\n\t${tmpImagePath}\n\t</design_image_path>\n\t\n\t<slice_library_path>\n\t${libraryAbsPath}\n\t</slice_library_path>\n\t\n\t<framework>\n\t${framework.label}\n\t</framework>\n\t\n\t# AVAILABLE TOOLS\n\t\n\tYou have access to specialized Prismic MCP tools for this task:\n\t\n\t<tool name=\"mcp__prismic__how_to_model_slice\">\n\t<description>\n\tProvides detailed guidance on creating Prismic slice models, including field types, naming conventions, and best practices.\n\t</description>\n\t<when_to_use>\n\tCall this tool in Step 2.1 to learn how to structure the slice model data for the design you analysed.\n\t</when_to_use>\n\t</tool>\n\t\n\t<tool name=\"mcp__prismic__how_to_code_slice\">\n\t<description>\n\tProvides guidance on implementing Prismic slice components, including how to use Prismic field components, props structure, and best practices.\n\t</description>\n\t<when_to_use>\n\tCall this tool in Step 2.1 to learn how to properly structure the slice component with Prismic fields.\n\t</when_to_use>\n\t</tool>\n\t\n\t<tool name=\"mcp__prismic__save_slice_data\">\n\t<description>\n\tValidates and saves the slice model data to model.json. This is the ONLY way to create the model file.\n\t</description>\n\t<when_to_use>\n\tCall this tool in Step 2.3 after you have built the complete slice model structure in memory.\n\t</when_to_use>\n\t</tool>\n\t\n\t# TASK REQUIREMENTS\n\t\n\t## Step 1: Gather information from the design image\n\t1.1. Analyse the design image at <design_image_path>.\n\t1.2. Identify all elements in the image that should be dynamically editable (e.g., headings, paragraphs, images, links, buttons, etc.).\n\t1.3. List the slice directories under <slice_library_path>.\n\t1.4. Come up with a unique name for the new slice based on the content of the image and the slice directories.\n\t\n\t## Step 2: Model the Prismic slice\n\t2.1. Call mcp__prismic__how_to_model_slice to learn how to structure the model for this design.\n\t- Make sure the name you use for the new slice does not yet exist in the slice library at <slice_library_path>. If it does, use a different name.\n\t2.2. Build the complete slice JSON model data in memory based on the guidance received and the information extracted from the image.\n\t2.3. Call mcp__prismic__save_slice_data to save the model (DO NOT manually write model.json) in the slice library at <slice_library_path>.\n\t\n\t## Step 3: Code a boilerplate slice component based on the model\n\t3.1. Call mcp__prismic__how_to_code_slice to learn how to properly structure the slice component with Prismic fields.\n\t3.2. Update the slice component code at <slice_library_path>/index.${frameworkFileExtension}, replacing the placeholder code with boilerplate code with the following requirements:\n\t- Must NOT be based on existing slices or components from the codebase.\n\t- Must render all the Prismic components to display the fields of the slice model created at <slice_model_path>.\n\t- Must be a valid ${framework.label} component.\n\t- Must NOT have any styling/CSS. No inlines styles or classNames. Just the skeleton component structure.\n\t- Must NOT use any other custom component or functions from the user's codebase.\n\t- Avoid creating unnecessary wrapper elements, like if they only wrap a single component (e.g., <div><PrismicRichText /></div>).\n\t\n\t## Step 4: Present the newly created slice path\n\t4.1. Present the path to the newly created slice in the following format: <new_slice_path>${libraryAbsPath}/MyNewSlice</new_slice_path>.\n\t- \"MyNewSlice\" must be the name of the directory of the newly created slice.\n\t\n\t# EXAMPLE OF CORRECT EXECUTION\n\t\n\t<example>\n\tAssistant: Step 1.1: Analysing design image...\n\t[reads <design_image_path>]\n\t\n\tStep 1.2: Identifying editable content elements...\n\t[identifies: title field, description field, buttonText field, buttonLink field, backgroundImage field]\n\t\n\tStep 1.3: Listing slice directories under <slice_library_path>...\n\t[lists slice directories: Hero, Hero2, Hero3]\n\t\n\tStep 1.4: Coming up with a unique name for the new slice...\n\t[comes up with a unique name for the new slice: Hero4]\n\t\n\tStep 2.1: Getting Prismic modeling guidance...\n\t[calls mcp__prismic__how_to_model_slice]\n\t\n\tStep 2.2: Building slice model based on guidance and the information extracted...\n\t[creates model with title field, description field, buttonText field, buttonLink field, backgroundImage field]\n\t\n\tStep 2.3: Saving slice model...\n\t[calls mcp__prismic__save_slice_data]\n\t\n\tStep 3.1: Learning Prismic slice coding requirements...\n\t[calls mcp__prismic__how_to_code_slice]\n\t\n\tStep 3.2: Coding boilerplate slice component based on the model...\n\t[updates component with Prismic field components, no styling, no other components]\n\t\n\tStep 4.1: Presenting the path to the newly created slice...\n\t[presents <new_slice_path>${joinPath(\n\t\tlibraryAbsPath,\n\t\t\"MyNewSlice\",\n\t)}</new_slice_path>]\n\t\n\t# DELIVERABLES\n\t- Slice model saved to <slice_library_path>/model.json using mcp__prismic__save_slice_data\n\t- Slice component at <slice_library_path>/index.${frameworkFileExtension} updated with boilerplate code\n\t- New slice path presented in the format mentioned in Step 3.1\n\t\n\tYOU ARE NOT FINISHED UNTIL YOU HAVE THESE DELIVERABLES.\n\t\n\t---\n\t\n\tFINAL REMINDERS:\n\t- You MUST use mcp__prismic__save_slice_data to save the model\n\t- You MUST call mcp__prismic__how_to_code_slice in Step 3.1\n\t- DO NOT ATTEMPT TO BUILD THE APPLICATION\n\t- START IMMEDIATELY WITH STEP 1.1 - NO PRELIMINARY ANALYSIS;`,\n\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\tcwd: libraryAbsPath,\n\t\t\t\t\t\t\tstderr: (data) => console.error(\"inferSlice error:\" + data),\n\t\t\t\t\t\t\tmodel: \"claude-haiku-4-5\",\n\t\t\t\t\t\t\tpermissionMode: \"bypassPermissions\",\n\t\t\t\t\t\t\tallowedTools: [\n\t\t\t\t\t\t\t\t\"Bash\",\n\t\t\t\t\t\t\t\t\"Read\",\n\t\t\t\t\t\t\t\t\"FileSearch\",\n\t\t\t\t\t\t\t\t\"Grep\",\n\t\t\t\t\t\t\t\t\"Glob\",\n\t\t\t\t\t\t\t\t\"Task\",\n\t\t\t\t\t\t\t\t\"Edit\",\n\t\t\t\t\t\t\t\t\"Write\",\n\t\t\t\t\t\t\t\t\"MultiEdit\",\n\t\t\t\t\t\t\t\t\"mcp__prismic__how_to_model_slice\",\n\t\t\t\t\t\t\t\t\"mcp__prismic__how_to_code_slice\",\n\t\t\t\t\t\t\t\t\"mcp__prismic__save_slice_data\",\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\tdisallowedTools: [\n\t\t\t\t\t\t\t\t`Edit(**/model.json)`,\n\t\t\t\t\t\t\t\t`Write(**/model.json)`,\n\t\t\t\t\t\t\t\t\"Edit(**/mocks.json)\",\n\t\t\t\t\t\t\t\t\"Write(**/mocks.json)\",\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\tenv: {\n\t\t\t\t\t\t\t\t...process.env,\n\t\t\t\t\t\t\t\tANTHROPIC_BASE_URL: llmProxyUrl,\n\t\t\t\t\t\t\t\tANTHROPIC_CUSTOM_HEADERS:\n\t\t\t\t\t\t\t\t\t`x-prismic-token: ${authToken}\\n` +\n\t\t\t\t\t\t\t\t\t`x-prismic-repository: ${repository}\\n`,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tmcpServers: {\n\t\t\t\t\t\t\t\tprismic: {\n\t\t\t\t\t\t\t\t\ttype: \"stdio\",\n\t\t\t\t\t\t\t\t\tcommand: \"npx\",\n\t\t\t\t\t\t\t\t\targs: [\"-y\", \"@prismicio/mcp-server@0.0.20-alpha.6\"],\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\n\t\t\t\t\tlet newSliceAbsPath: string | undefined;\n\n\t\t\t\t\tfor await (const query of queries) {\n\t\t\t\t\t\tswitch (query.type) {\n\t\t\t\t\t\t\tcase \"result\":\n\t\t\t\t\t\t\t\tif (query.subtype === \"success\") {\n\t\t\t\t\t\t\t\t\tnewSliceAbsPath = query.result.match(\n\t\t\t\t\t\t\t\t\t\t/<new_slice_path>(.*)<\\/new_slice_path>/s,\n\t\t\t\t\t\t\t\t\t)?.[1];\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!newSliceAbsPath) {\n\t\t\t\t\t\tthrow new Error(\"Could not find path for the newly created slice.\");\n\t\t\t\t\t}\n\n\t\t\t\t\tconst model = await readFile(\n\t\t\t\t\t\tjoinPath(newSliceAbsPath, \"model.json\"),\n\t\t\t\t\t\t\"utf8\",\n\t\t\t\t\t);\n\n\t\t\t\t\tif (!model) {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\"Could not find model for the newly created slice.\",\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\t// move the screenshot image to the new slice directory\n\t\t\t\t\tawait rename(\n\t\t\t\t\t\ttmpImagePath,\n\t\t\t\t\t\tjoinPath(newSliceAbsPath, \"screenshot-default.png\"),\n\t\t\t\t\t);\n\n\t\t\t\t\treturn InferSliceResponse.parse({ slice: JSON.parse(model) });\n\t\t\t\t} finally {\n\t\t\t\t\tif (tmpDir && existsSync(tmpDir)) {\n\t\t\t\t\t\tawait rm(tmpDir, { recursive: true });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst searchParams = new URLSearchParams({ repository });\n\t\t\t\tconst url = new URL(\"./slices/infer\", API_ENDPOINTS.CustomTypeService);\n\t\t\t\turl.search = searchParams.toString();\n\n\t\t\t\tconst response = await fetch(url.toString(), {\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\theaders: { Authorization: `Bearer ${authToken}` },\n\t\t\t\t\tbody: JSON.stringify({ imageUrl }),\n\t\t\t\t});\n\n\t\t\t\tif (!response.ok) {\n\t\t\t\t\tthrow new Error(`Failed to infer slice: ${response.statusText}`);\n\t\t\t\t}\n\n\t\t\t\tconst json = await response.json();\n\n\t\t\t\treturn InferSliceResponse.parse(json);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsole.error(`inferSlice (${source}) failed`, error);\n\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\tconst elapsedTimeSeconds = (Date.now() - startTime) / 1000;\n\t\t\tconsole.info(`inferSlice (${source}) took ${elapsedTimeSeconds}s`);\n\t\t}\n\t}\n}\n\ntype InferSliceResponse = z.infer<typeof InferSliceResponse>;\n\nconst InferSliceResponse = z.object({\n\tslice: z.custom().transform((value, ctx) => {\n\t\tconst result = SharedSlice.decode(value);\n\t\tif (result._tag === \"Right\") {\n\t\t\treturn result.right;\n\t\t}\n\t\tctx.addIssue({\n\t\t\tcode: z.ZodIssueCode.custom,\n\t\t\tmessage: `Invalid shared slice: ${JSON.stringify(value, null, 2)}`,\n\t\t});\n\n\t\treturn z.NEVER;\n\t}),\n\tlangSmithUrl: z.string().url().optional(),\n});\n\nfunction updateCRCustomType(\n\targs: { customType: LinkCustomType } & CustomTypeFieldIdChangedMeta,\n): LinkCustomType {\n\tconst previousPath = getPathIds(args.previousPath);\n\tconst newPath = getPathIds(args.newPath);\n\n\tif (!previousPath.customTypeId || !newPath.customTypeId) {\n\t\tthrow new Error(\n\t\t\t`Could not find a customtype id in previousPath (${args.previousPath.join(\n\t\t\t\t\".\",\n\t\t\t)}) and/or newPath (${args.newPath.join(\n\t\t\t\t\".\",\n\t\t\t)}), which should not be possible.`,\n\t\t);\n\t}\n\n\tif (!previousPath.fieldId || !newPath.fieldId) {\n\t\tthrow new Error(\n\t\t\t`Could not find a field id in previousPath (${args.previousPath.join(\n\t\t\t\t\".\",\n\t\t\t)}) and/or newPath (${args.newPath.join(\n\t\t\t\t\".\",\n\t\t\t)}), which should not be possible.`,\n\t\t);\n\t}\n\n\tconst customType = shallowCloneIfObject(args.customType);\n\n\tif (typeof customType === \"string\") {\n\t\t// Legacy format support, we don't have anything to update here.\n\t\treturn customType;\n\t}\n\n\tconst matchedCustomTypeId = customType.id === previousPath.customTypeId;\n\n\treturn {\n\t\t...customType,\n\t\tfields: customType.fields.map((fieldArg) => {\n\t\t\tconst customTypeField = shallowCloneIfObject(fieldArg);\n\n\t\t\t// Regular field\n\t\t\tif (typeof customTypeField === \"string\") {\n\t\t\t\tif (\n\t\t\t\t\tmatchedCustomTypeId &&\n\t\t\t\t\tcustomTypeField === previousPath.fieldId &&\n\t\t\t\t\tcustomTypeField !== newPath.fieldId\n\t\t\t\t) {\n\t\t\t\t\t// The id of the field has changed.\n\t\t\t\t\treturn newPath.fieldId;\n\t\t\t\t}\n\n\t\t\t\treturn customTypeField;\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\tmatchedCustomTypeId &&\n\t\t\t\tcustomTypeField.id === previousPath.fieldId &&\n\t\t\t\tcustomTypeField.id !== newPath.fieldId\n\t\t\t) {\n\t\t\t\t// The id of the field has changed. We don't exit return because there\n\t\t\t\t// might be other fields further down in nested custom types or groups\n\t\t\t\t// that need to be updated.\n\t\t\t\tcustomTypeField.id = newPath.fieldId;\n\t\t\t}\n\n\t\t\t// Group field\n\t\t\tif (\"fields\" in customTypeField) {\n\t\t\t\tif (\n\t\t\t\t\t!previousPath.groupId &&\n\t\t\t\t\t!newPath.groupId &&\n\t\t\t\t\tcustomTypeField.id === previousPath.fieldId &&\n\t\t\t\t\tcustomTypeField.id !== newPath.fieldId\n\t\t\t\t) {\n\t\t\t\t\t// Only the id of the group has changed. Group id is not defined, so\n\t\t\t\t\t// we can return early.\n\t\t\t\t\treturn newPath.fieldId;\n\t\t\t\t}\n\n\t\t\t\tconst matchedGroupId = customTypeField.id === previousPath.groupId;\n\n\t\t\t\tif (\n\t\t\t\t\tpreviousPath.groupId &&\n\t\t\t\t\tnewPath.groupId &&\n\t\t\t\t\tmatchedGroupId &&\n\t\t\t\t\tcustomTypeField.id !== newPath.groupId\n\t\t\t\t) {\n\t\t\t\t\t// The id of the group field has changed, so we update it. We don't\n\t\t\t\t\t// return because there are group fields that may need to be updated.\n\t\t\t\t\tcustomTypeField.id = newPath.groupId;\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\t...customTypeField,\n\t\t\t\t\tfields: customTypeField.fields.map((groupFieldArg) => {\n\t\t\t\t\t\tconst groupField = shallowCloneIfObject(groupFieldArg);\n\n\t\t\t\t\t\t// Regular field inside a group field\n\t\t\t\t\t\tif (typeof groupField === \"string\") {\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tmatchedGroupId &&\n\t\t\t\t\t\t\t\tgroupField === previousPath.fieldId &&\n\t\t\t\t\t\t\t\tgroupField !== newPath.fieldId\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t// The id of the field inside the group has changed.\n\t\t\t\t\t\t\t\treturn newPath.fieldId;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\treturn groupField;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Content relationship field inside a group field\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t...groupField,\n\t\t\t\t\t\t\tfields: updateContentRelationshipFields({\n\t\t\t\t\t\t\t\tcustomtypes: groupField.customtypes,\n\t\t\t\t\t\t\t\tpreviousPath,\n\t\t\t\t\t\t\t\tnewPath,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t};\n\t\t\t\t\t}),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Content relationship field\n\t\t\treturn {\n\t\t\t\t...customTypeField,\n\t\t\t\tcustomtypes: updateContentRelationshipFields({\n\t\t\t\t\tcustomtypes: customTypeField.customtypes,\n\t\t\t\t\tpreviousPath,\n\t\t\t\t\tnewPath,\n\t\t\t\t}),\n\t\t\t};\n\t\t}),\n\t};\n}\n\nfunction updateContentRelationshipFields(args: {\n\tcustomtypes: readonly (\n\t\t| string\n\t\t| {\n\t\t\t\tid: string;\n\t\t\t\tfields: readonly (string | { id: string; fields: readonly string[] })[];\n\t\t }\n\t)[];\n\tpreviousPath: CrUpdatePathIds;\n\tnewPath: CrUpdatePathIds;\n}) {\n\tconst { customtypes, previousPath, newPath } = args;\n\n\treturn customtypes.map((nestedCtArg) => {\n\t\tconst nestedCt = shallowCloneIfObject(nestedCtArg);\n\n\t\tif (\n\t\t\ttypeof nestedCt === \"string\" ||\n\t\t\t// Since we are entering a new custom type, if the previous id\n\t\t\t// doesn't match, we can return early, because it's not the\n\t\t\t// custom type we are looking for.\n\t\t\tnestedCt.id !== previousPath.customTypeId\n\t\t) {\n\t\t\treturn nestedCt;\n\t\t}\n\n\t\treturn {\n\t\t\t...nestedCt,\n\t\t\tfields: nestedCt.fields.map((nestedCtFieldArg) => {\n\t\t\t\tconst nestedCtField = shallowCloneIfObject(nestedCtFieldArg);\n\n\t\t\t\t// Regular field\n\t\t\t\tif (typeof nestedCtField === \"string\") {\n\t\t\t\t\tif (\n\t\t\t\t\t\tnestedCtField === previousPath.fieldId &&\n\t\t\t\t\t\tnestedCtField !== newPath.fieldId\n\t\t\t\t\t) {\n\t\t\t\t\t\t// The id of the field has changed.\n\t\t\t\t\t\treturn newPath.fieldId;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn nestedCtField;\n\t\t\t\t}\n\n\t\t\t\t// Group field\n\n\t\t\t\tif (\n\t\t\t\t\tnestedCtField.id === previousPath.fieldId &&\n\t\t\t\t\tnestedCtField.id !== newPath.fieldId\n\t\t\t\t) {\n\t\t\t\t\t// The id of the field has changed.\n\t\t\t\t\tnestedCtField.id = newPath.fieldId;\n\t\t\t\t}\n\n\t\t\t\t// Further down the path, the field can only be a group field. So if we have\n\t\t\t\t// no group id defined, no need to continue.\n\t\t\t\tif (\n\t\t\t\t\t!previousPath.groupId ||\n\t\t\t\t\t!newPath.groupId ||\n\t\t\t\t\tnestedCtField.id !== previousPath.groupId\n\t\t\t\t) {\n\t\t\t\t\treturn nestedCtField;\n\t\t\t\t}\n\n\t\t\t\tif (nestedCtField.id !== newPath.groupId) {\n\t\t\t\t\t// The id of the group has changed.\n\t\t\t\t\tnestedCtField.id = newPath.groupId;\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\t...nestedCtField,\n\t\t\t\t\tfields: nestedCtField.fields.map((nestedCtGroupFieldId) => {\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tnestedCtGroupFieldId === previousPath.fieldId &&\n\t\t\t\t\t\t\tnestedCtGroupFieldId !== newPath.fieldId\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t// The id of the field inside the group has changed.\n\t\t\t\t\t\t\treturn newPath.fieldId;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn nestedCtGroupFieldId;\n\t\t\t\t\t}),\n\t\t\t\t};\n\t\t\t}),\n\t\t};\n\t});\n}\n\n/**\n * Update the Content Relationship API IDs of a single field. The change is\n * determined by the `previousPath` and `newPath` properties.\n */\nfunction updateFieldContentRelationships<\n\tT extends UID | NestableWidget | Group | NestedGroup,\n>(args: { field: T } & CustomTypeFieldIdChangedMeta): T {\n\tconst { field, ...updateMeta } = args;\n\tif (\n\t\tfield.type !== \"Link\" ||\n\t\tfield.config?.select !== \"document\" ||\n\t\t!field.config?.customtypes\n\t) {\n\t\t// not a content relationship field\n\t\treturn field;\n\t}\n\n\tconst newCustomTypes = field.config.customtypes.map((customType) => {\n\t\treturn updateCRCustomType({ ...updateMeta, customType });\n\t});\n\n\treturn {\n\t\t...field,\n\t\tconfig: { ...field.config, customtypes: newCustomTypes },\n\t};\n}\n\nexport function updateCustomTypeContentRelationships(\n\targs: {\n\t\tmodels: { model: CustomType }[];\n\t\tonUpdate: (model: { previousModel: CustomType; model: CustomType }) => void;\n\t} & CustomTypeFieldIdChangedMeta,\n): void {\n\tconst { models, previousPath, newPath, onUpdate } = args;\n\n\tfor (const { model: customType } of models) {\n\t\tconst updatedCustomType = traverseCustomType({\n\t\t\tcustomType,\n\t\t\tonField: ({ field }) => {\n\t\t\t\treturn updateFieldContentRelationships({\n\t\t\t\t\tfield,\n\t\t\t\t\tpreviousPath,\n\t\t\t\t\tnewPath,\n\t\t\t\t});\n\t\t\t},\n\t\t});\n\n\t\tif (!isEqualModel(customType, updatedCustomType)) {\n\t\t\tonUpdate({ model: updatedCustomType, previousModel: customType });\n\t\t}\n\t}\n}\n\nexport function updateSharedSliceContentRelationships(\n\targs: {\n\t\tmodels: { model: SharedSlice }[];\n\t\tonUpdate: (model: {\n\t\t\tpreviousModel: SharedSlice;\n\t\t\tmodel: SharedSlice;\n\t\t}) => void;\n\t} & CustomTypeFieldIdChangedMeta,\n): void {\n\tconst { models, previousPath, newPath, onUpdate } = args;\n\n\tfor (const { model: slice } of models) {\n\t\tconst updateSlice = traverseSharedSlice({\n\t\t\tpath: [],\n\t\t\tslice,\n\t\t\tonField: ({ field }) => {\n\t\t\t\treturn updateFieldContentRelationships({\n\t\t\t\t\tfield,\n\t\t\t\t\tpreviousPath,\n\t\t\t\t\tnewPath,\n\t\t\t\t});\n\t\t\t},\n\t\t});\n\n\t\tif (!isEqualModel(slice, updateSlice)) {\n\t\t\tonUpdate({ model: updateSlice, previousModel: slice });\n\t\t}\n\t}\n}\n\ninterface CrUpdatePathIds {\n\tcustomTypeId: string;\n\tgroupId: string | undefined;\n\tfieldId: string;\n}\n\nfunction getPathIds(path: PathWithCustomType): CrUpdatePathIds {\n\tif (path.length < 2) {\n\t\tthrow new Error(\n\t\t\t`Unexpected path length ${\n\t\t\t\tpath.length\n\t\t\t}. Expected at least 2 segments (got: ${path.join(\".\")}).`,\n\t\t);\n\t}\n\n\tconst [customTypeId, groupOrFieldId, fieldId] = path;\n\n\treturn {\n\t\tcustomTypeId,\n\t\t/**\n\t\t * Id of a changed group. If it's defined, it means that a group or a field\n\t\t * inside a group had its API ID renamed. It's defined when the path has a\n\t\t * third element (e.g. `[\"customtypeA\", \"groupA\", \"fieldA\"]`).\n\t\t */\n\t\tgroupId: fieldId ? groupOrFieldId : undefined,\n\t\tfieldId: fieldId || groupOrFieldId,\n\t};\n}\n\nfunction isEqualModel<T extends CustomType | SharedSlice>(\n\tmodelA: T,\n\tmodelB: T,\n): boolean {\n\treturn JSON.stringify(modelA) === JSON.stringify(modelB);\n}\n\nfunction shallowCloneIfObject<T>(value: T): T {\n\tif (typeof value === \"object\") {\n\t\treturn { ...value };\n\t}\n\n\treturn value;\n}\n"],"names":["errors","_a","joinPath","queryClaude","query"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@slicemachine/manager",
3
- "version": "0.25.7-alpha.jp-figma-to-prismic.8",
3
+ "version": "0.25.7-alpha.jp-figma-to-slice-1.2",
4
4
  "description": "Manage all aspects of a Slice Machine project.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -71,7 +71,7 @@
71
71
  "@prismicio/mocks": "2.14.0",
72
72
  "@prismicio/types-internal": "3.11.2",
73
73
  "@segment/analytics-node": "^2.1.2",
74
- "@slicemachine/plugin-kit": "0.4.85-alpha.jp-figma-to-prismic.8",
74
+ "@slicemachine/plugin-kit": "0.4.85-alpha.jp-figma-to-slice-1.2",
75
75
  "cookie": "^1.0.1",
76
76
  "cors": "^2.8.5",
77
77
  "execa": "^7.1.1",
@@ -23,7 +23,6 @@ import {
23
23
  HookError,
24
24
  } from "@slicemachine/plugin-kit";
25
25
  import { z } from "zod";
26
- import { query as queryClaude } from "@anthropic-ai/claude-agent-sdk";
27
26
 
28
27
  import { DecodeError } from "../../lib/DecodeError";
29
28
  import { assertPluginsInitialized } from "../../lib/assertPluginsInitialized";
@@ -34,14 +33,15 @@ import { OnlyHookErrors } from "../../types";
34
33
  import { API_ENDPOINTS } from "../../constants/API_ENDPOINTS";
35
34
  import { SLICE_MACHINE_USER_AGENT } from "../../constants/SLICE_MACHINE_USER_AGENT";
36
35
  import { UnauthorizedError } from "../../errors";
37
- import { mkdtemp, readFile, rename, rm, writeFile } from "fs/promises";
38
- import { tmpdir } from "os";
39
- import path from "path";
40
- import { randomUUID } from "crypto";
41
- import { existsSync } from "fs";
42
36
 
43
37
  import { BaseManager } from "../BaseManager";
44
38
  import { CustomTypeFormat } from "./types";
39
+ import { existsSync } from "node:fs";
40
+ import { tmpdir } from "node:os";
41
+ import { randomUUID } from "node:crypto";
42
+ import { join as joinPath } from "node:path";
43
+ import { mkdtemp, rename, rm, writeFile, readFile } from "node:fs/promises";
44
+ import { query as queryClaude } from "@anthropic-ai/claude-agent-sdk";
45
45
 
46
46
  type SliceMachineManagerReadCustomTypeLibraryReturnType = {
47
47
  ids: string[];
@@ -134,8 +134,6 @@ type CustomTypeFieldIdChangedMeta = {
134
134
  type LinkCustomType = NonNullable<LinkConfig["customtypes"]>[number];
135
135
 
136
136
  export class CustomTypesManager extends BaseManager {
137
- private inferSliceAbortControllers = new Map<string, AbortController>();
138
-
139
137
  async readCustomTypeLibrary(): Promise<SliceMachineManagerReadCustomTypeLibraryReturnType> {
140
138
  assertPluginsInitialized(this.sliceMachinePluginRunner);
141
139
 
@@ -542,30 +540,17 @@ export class CustomTypesManager extends BaseManager {
542
540
  }
543
541
 
544
542
  async inferSlice(
545
- args: { imageUrl: string; requestId?: string } & (
543
+ args: { imageUrl: string } & (
546
544
  | { source: "upload" }
547
545
  | { source: "figma"; libraryID: string }
548
546
  ),
549
547
  ): Promise<InferSliceResponse> {
550
- const { source, imageUrl, requestId } = args;
548
+ const { source, imageUrl } = args;
551
549
 
552
550
  const authToken = await this.user.getAuthenticationToken();
553
551
  const repository = await this.project.getResolvedRepositoryName();
554
552
 
555
- let abortController: AbortController | undefined;
556
- if (requestId) {
557
- abortController = new AbortController();
558
- abortController.signal.addEventListener("abort", () => {
559
- console.warn(`inferSlice (${source}) request ${requestId} was aborted`);
560
- });
561
- this.inferSliceAbortControllers.set(requestId, abortController);
562
- }
563
-
564
- console.info(
565
- `inferSlice (${source}) started${
566
- requestId ? ` for request ${requestId}` : ""
567
- }`,
568
- );
553
+ console.info(`inferSlice (${source}) started`);
569
554
  const startTime = Date.now();
570
555
 
571
556
  try {
@@ -622,12 +607,12 @@ export class CustomTypesManager extends BaseManager {
622
607
  }
623
608
 
624
609
  const projectRoot = await this.project.getRoot();
625
- const libraryAbsPath = path.join(projectRoot, libraryID);
610
+ const libraryAbsPath = joinPath(projectRoot, libraryID);
626
611
 
627
612
  tmpDir = await mkdtemp(
628
- path.join(tmpdir(), "slice-machine-infer-slice-tmp-"),
613
+ joinPath(tmpdir(), "slice-machine-infer-slice-tmp-"),
629
614
  );
630
- const tmpImagePath = path.join(tmpDir, `${randomUUID()}.png`);
615
+ const tmpImagePath = joinPath(tmpDir, `${randomUUID()}.png`);
631
616
  const response = await fetch(imageUrl);
632
617
  if (!response.ok) {
633
618
  throw new Error(
@@ -758,7 +743,7 @@ export class CustomTypesManager extends BaseManager {
758
743
  [updates component with Prismic field components, no styling, no other components]
759
744
 
760
745
  Step 4.1: Presenting the path to the newly created slice...
761
- [presents <new_slice_path>${path.join(
746
+ [presents <new_slice_path>${joinPath(
762
747
  libraryAbsPath,
763
748
  "MyNewSlice",
764
749
  )}</new_slice_path>]
@@ -816,7 +801,6 @@ export class CustomTypesManager extends BaseManager {
816
801
  args: ["-y", "@prismicio/mcp-server@0.0.20-alpha.6"],
817
802
  },
818
803
  },
819
- ...(abortController && { abortController }),
820
804
  },
821
805
  });
822
806
 
@@ -839,7 +823,7 @@ export class CustomTypesManager extends BaseManager {
839
823
  }
840
824
 
841
825
  const model = await readFile(
842
- path.join(newSliceAbsPath, "model.json"),
826
+ joinPath(newSliceAbsPath, "model.json"),
843
827
  "utf8",
844
828
  );
845
829
 
@@ -852,7 +836,7 @@ export class CustomTypesManager extends BaseManager {
852
836
  // move the screenshot image to the new slice directory
853
837
  await rename(
854
838
  tmpImagePath,
855
- path.join(newSliceAbsPath, "screenshot-default.png"),
839
+ joinPath(newSliceAbsPath, "screenshot-default.png"),
856
840
  );
857
841
 
858
842
  return InferSliceResponse.parse({ slice: JSON.parse(model) });
@@ -870,7 +854,6 @@ export class CustomTypesManager extends BaseManager {
870
854
  method: "POST",
871
855
  headers: { Authorization: `Bearer ${authToken}` },
872
856
  body: JSON.stringify({ imageUrl }),
873
- ...(abortController && { signal: abortController.signal }),
874
857
  });
875
858
 
876
859
  if (!response.ok) {
@@ -882,42 +865,13 @@ export class CustomTypesManager extends BaseManager {
882
865
  return InferSliceResponse.parse(json);
883
866
  }
884
867
  } catch (error) {
885
- console.error(
886
- `inferSlice (${source}) failed${
887
- requestId ? ` for request ${requestId}` : ""
888
- }`,
889
- error,
890
- );
868
+ console.error(`inferSlice (${source}) failed`, error);
891
869
 
892
870
  throw error;
893
871
  } finally {
894
- if (requestId) {
895
- this.inferSliceAbortControllers.delete(requestId);
896
- }
897
-
898
872
  const elapsedTimeSeconds = (Date.now() - startTime) / 1000;
899
- console.info(
900
- `inferSlice took ${elapsedTimeSeconds}s${
901
- requestId ? ` for request ${requestId}` : ""
902
- }`,
903
- );
904
- }
905
- }
906
-
907
- async cancelInferSlice(args: {
908
- requestId: string;
909
- }): Promise<{ cancelled: boolean }> {
910
- const { requestId } = args;
911
- const abortController = this.inferSliceAbortControllers.get(requestId);
912
-
913
- if (abortController) {
914
- abortController.abort();
915
- this.inferSliceAbortControllers.delete(requestId);
916
-
917
- return { cancelled: true };
873
+ console.info(`inferSlice (${source}) took ${elapsedTimeSeconds}s`);
918
874
  }
919
-
920
- return { cancelled: false };
921
875
  }
922
876
  }
923
877