diff --git a/.github/workflows/autogenerate-docs.yml b/.github/workflows/autogenerate-docs.yml index 18875141a4..23afc9d889 100644 --- a/.github/workflows/autogenerate-docs.yml +++ b/.github/workflows/autogenerate-docs.yml @@ -47,7 +47,7 @@ jobs: id: commit_docs uses: EndBug/add-and-commit@v9 with: - add: '["packages/visual-editor/src/docs/components.md", "packages/visual-editor/src/docs/ai/components.d.ts"]' + add: '["packages/visual-editor/src/docs/components.md"]' message: "docs: auto-generate component documentation" push: true default_author: github_actions diff --git a/packages/puck-ai-backend/.gitignore b/packages/puck-ai-backend/.gitignore new file mode 100644 index 0000000000..393de5fcd0 --- /dev/null +++ b/packages/puck-ai-backend/.gitignore @@ -0,0 +1,12 @@ +# wrangler project + +.dev.vars* +!.dev.vars.example +.env* +!.env.example +.wrangler/ + +worker-configuration.d.ts + +# IDE +.vscode/** \ No newline at end of file diff --git a/packages/puck-ai-backend/package.json b/packages/puck-ai-backend/package.json new file mode 100644 index 0000000000..c9be173b52 --- /dev/null +++ b/packages/puck-ai-backend/package.json @@ -0,0 +1,22 @@ +{ + "name": "puck-ai-backend", + "version": "0.0.0", + "author": "sumo@yext.com", + "private": true, + "packageManager": "pnpm@9.12.3", + "scripts": { + "deploy": "wrangler deploy", + "dev": "wrangler dev", + "start": "wrangler dev", + "cf-typegen": "wrangler types" + }, + "devDependencies": { + "@types/node": "^25.2.1", + "typescript": "^5.5.2", + "wrangler": "^4.63.0" + }, + "dependencies": { + "@puckeditor/cloud-client": "0.6.0", + "hono": "^4.6.12" + } +} diff --git a/packages/puck-ai-backend/src/cors.ts b/packages/puck-ai-backend/src/cors.ts new file mode 100644 index 0000000000..1f69e5ec3b --- /dev/null +++ b/packages/puck-ai-backend/src/cors.ts @@ -0,0 +1,53 @@ +import type { MiddlewareHandler } from "hono"; + +const isLocalHost = (host: string) => + host === "localhost" || host === "127.0.0.1" || host === "0.0.0.0"; + +const isAllowedOrigin = (origin: string, isLocalServer: boolean) => { + try { + const url = new URL(origin); + const host = url.hostname.toLowerCase(); + if (host.endsWith(".preview.pagescdn.com")) { + return true; + } + if (isLocalServer && isLocalHost(host)) { + return true; + } + return false; + } catch { + return false; + } +}; + +export const corsForPuck: MiddlewareHandler = async (c, next) => { + const origin = c.req.header("Origin"); + const hostHeader = c.req.header("Host") ?? ""; + const requestHost = hostHeader.split(":")[0].toLowerCase(); + const isLocalServer = isLocalHost(requestHost); + const allowed = origin ? isAllowedOrigin(origin, isLocalServer) : false; + + if (c.req.method === "OPTIONS") { + if (allowed && origin) { + c.header("Access-Control-Allow-Origin", origin); + c.header("Vary", "Origin"); + c.header("Access-Control-Allow-Methods", "POST, OPTIONS"); + const requestedHeaders = c.req.header("Access-Control-Request-Headers"); + if (requestedHeaders) { + c.header("Access-Control-Allow-Headers", requestedHeaders); + } + } + return c.body(null, 204); + } + + await next(); + + if (allowed && origin) { + c.res.headers.set("Access-Control-Allow-Origin", origin); + c.res.headers.set("Vary", "Origin"); + c.res.headers.set("Access-Control-Allow-Methods", "POST, OPTIONS"); + const requestedHeaders = c.req.header("Access-Control-Request-Headers"); + if (requestedHeaders) { + c.res.headers.set("Access-Control-Allow-Headers", requestedHeaders); + } + } +}; diff --git a/packages/puck-ai-backend/src/index.ts b/packages/puck-ai-backend/src/index.ts new file mode 100644 index 0000000000..c85388ca36 --- /dev/null +++ b/packages/puck-ai-backend/src/index.ts @@ -0,0 +1,12 @@ +import { Hono } from "hono"; +import { corsForPuck } from "./cors"; +import { puckRouter } from "./puckRouter"; + +const app = new Hono(); + +app.get("/", (c) => c.text("Yext Pages Puck AI Backend is running.")); + +app.use("/api/puck/*", corsForPuck); +app.post("/api/puck/:route", puckRouter); + +export default app; diff --git a/packages/puck-ai-backend/src/puckRouter.ts b/packages/puck-ai-backend/src/puckRouter.ts new file mode 100644 index 0000000000..ccc1d4df8b --- /dev/null +++ b/packages/puck-ai-backend/src/puckRouter.ts @@ -0,0 +1,87 @@ +import { puckHandler, ChatParams } from "@puckeditor/cloud-client"; +import type { Context } from "hono"; + +type CustomChatParams = ChatParams & { systemPrompt: string }; + +const parseBody = async (c: Context): Promise => { + const contentType = c.req.header("content-type") ?? ""; + if (contentType.includes("application/json")) { + try { + return await c.req.json(); + } catch { + return; + } + } + if ( + contentType.includes("application/x-www-form-urlencoded") || + contentType.includes("multipart/form-data") + ) { + try { + const parsedBody = await c.req.parseBody(); + if (typeof parsedBody === "object" && "chatId" in parsedBody) { + return parsedBody as unknown as CustomChatParams; + } + return; + } catch { + return; + } + } + return; +}; + +/** Accept the request from the editor, forward it to Puck, and stream the response. */ +export const puckRouter = async (c: Context) => { + try { + const puckApiKey = c.env.PUCK_API_KEY; + if (!puckApiKey) { + return c.json({ success: false, error: "Missing PUCK_API_KEY" }, 500); + } + + const origin = c.req.header("Origin"); + if (!origin) { + return c.json({ success: false, error: "Missing Origin header" }, 400); + } + const pathname = `/api/puck/${c.req.param("route") ?? ""}`.replace( + /\/+$/, + "", + ); + const url = new URL(pathname, origin); + + const body = await parseBody(c); + + if (!body) { + return c.json({ success: false, error: "Invalid request body" }, 400); + } + + const puckRequest = new Request(url, { + method: "POST", + body: JSON.stringify(body), + headers: { "content-type": "application/json" }, + }); + + const puckResponse = await puckHandler(puckRequest, { + ai: { context: body.systemPrompt }, + apiKey: puckApiKey, + }); + + const isServerSideEvents = ( + puckResponse.headers.get("content-type") ?? "" + ).includes("text/event-stream"); + if (!isServerSideEvents) { + return puckResponse; + } + + const headers = new Headers(puckResponse.headers); + headers.set("Cache-Control", "no-cache"); + headers.set("Connection", "keep-alive"); + + return new Response(puckResponse.body, { + status: puckResponse.status, + statusText: puckResponse.statusText, + headers, + }); + } catch (error) { + console.error(error); + return c.json({ success: false, error: "Failed to process request" }, 500); + } +}; diff --git a/packages/puck-ai-backend/tsconfig.json b/packages/puck-ai-backend/tsconfig.json new file mode 100644 index 0000000000..af48afe768 --- /dev/null +++ b/packages/puck-ai-backend/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "target": "es2024", + "lib": ["es2024"], + "jsx": "react-jsx", + "module": "es2022", + "moduleResolution": "Bundler", + "resolveJsonModule": true, + "allowJs": true, + "checkJs": false, + "noEmit": true, + "isolatedModules": true, + "allowSyntheticDefaultImports": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true, + "types": ["./worker-configuration.d.ts", "node"] + }, + "include": ["worker-configuration.d.ts", "src/**/*.ts"] +} diff --git a/packages/puck-ai-backend/wrangler.jsonc b/packages/puck-ai-backend/wrangler.jsonc new file mode 100644 index 0000000000..456537bff4 --- /dev/null +++ b/packages/puck-ai-backend/wrangler.jsonc @@ -0,0 +1,14 @@ +/** + * For more details on how to configure Wrangler, refer to: + * https://developers.cloudflare.com/workers/wrangler/configuration/ + */ +{ + "$schema": "node_modules/wrangler/config-schema.json", + "name": "puck-ai-backend", + "main": "src/index.ts", + "compatibility_date": "2025-09-27", + "observability": { + "enabled": true, + }, + "compatibility_flags": ["nodejs_compat"], +} diff --git a/packages/visual-editor/THIRD-PARTY-NOTICES b/packages/visual-editor/THIRD-PARTY-NOTICES index ea5262cca2..519f6e7248 100644 --- a/packages/visual-editor/THIRD-PARTY-NOTICES +++ b/packages/visual-editor/THIRD-PARTY-NOTICES @@ -1161,12 +1161,11 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ----------- -The following npm packages may be included in this product: +The following npm package may be included in this product: - - @puckeditor/core@0.21.1 - next-themes@0.3.0 -These packages each contain the following license: +This package contains the following license: MIT diff --git a/packages/visual-editor/package.json b/packages/visual-editor/package.json index fca19cb6b5..5d3fdbae25 100644 --- a/packages/visual-editor/package.json +++ b/packages/visual-editor/package.json @@ -21,6 +21,11 @@ "import": "./dist/visual-editor.js", "default": "./dist/visual-editor.js" }, + "./tailwind": { + "types": "./dist/tailwind.d.ts", + "import": "./dist/tailwind.js", + "default": "./dist/tailwind.js" + }, "./plugin": { "import": "./dist/plugin/plugin.js", "default": "./dist/plugin/plugin.js" @@ -42,7 +47,7 @@ "autofix": "pnpm run lint && pnpm run prettier", "prepare": "pnpm build", "generate-notices": "generate-license-file --input package.json --output ./THIRD-PARTY-NOTICES --overwrite", - "generate-component-docs": "api-extractor run --local ; node generate-docs.mjs ; tsx scripts/generateComponentTypeDefinitions.ts", + "generate-component-docs": "api-extractor run --local ; node generate-docs.mjs", "docs:dev": "vitepress dev .", "docs:build": "vitepress build .", "docs:preview": "vitepress preview .", @@ -62,7 +67,6 @@ "@microsoft/api-documenter": "^7.26.29", "@microsoft/api-extractor": "^7.52.8", "@microsoft/api-extractor-model": "^7.30.6", - "@puckeditor/core": "0.21.1", "@radix-ui/react-accordion": "^1.2.3", "@radix-ui/react-alert-dialog": "^1.1.1", "@radix-ui/react-dialog": "^1.1.13", @@ -163,6 +167,8 @@ "@yext/search-ui-react": "^2.0.2", "mapbox-gl": "^2.9.2", "react": "^17.0.2 || ^18.2.0", - "react-dom": "^17.0.2 || ^18.2.0" + "react-dom": "^17.0.2 || ^18.2.0", + "@puckeditor/core": "0.21.1", + "@puckeditor/plugin-ai": "0.6.0" } } diff --git a/packages/visual-editor/scripts/generateComponentTypeDefinitions.ts b/packages/visual-editor/scripts/generateComponentTypeDefinitions.ts deleted file mode 100644 index cbf084a16a..0000000000 --- a/packages/visual-editor/scripts/generateComponentTypeDefinitions.ts +++ /dev/null @@ -1,221 +0,0 @@ -/** - * @fileoverview - * This script generates a trimmed .d.ts file containing only the types - * that are used by the specified entry points. It uses the TypeScript Compiler API - * to parse the bundled .d.ts file, extract the type definitions for the entry points, - * and recursively find all referenced types. The resulting types are written to - * a new .d.ts file, preserving import statements as needed. - */ - -import { writeFileSync, readFileSync } from "node:fs"; -import path from "node:path"; -import ts from "typescript"; - -const inputFilepath = path.resolve("dist/index.d.ts"); -const outputFilepath = path.resolve("src/docs/ai/components.d.ts"); -const entryPoints = new Set([ - "PageSectionCategoryProps", - "ExpandedHeaderProps", - "ExpandedFooterProps", -]); - -/** - * Parses file content using the TypeScript Compiler API to extract all - * type, interface, and class definitions. - * @param content The string content of a .d.ts file. - * @returns An object mapping type names to their full definition and a Set of all type names. - */ -const parseTypes = ( - content: string -): { - definitions: Map; - allTypeNames: Set; -} => { - const definitions = new Map(); - const allTypeNames = new Set(); - - const sourceFile = ts.createSourceFile( - "temp.d.ts", - content, - ts.ScriptTarget.ES2020, - true - ); - - ts.forEachChild(sourceFile, (node) => { - if ( - ts.isTypeAliasDeclaration(node) || - ts.isInterfaceDeclaration(node) || - ts.isClassDeclaration(node) - ) { - const typeName = node.name?.getText(sourceFile); - if (!typeName) { - return; - } - - const fullDefinition = node.getFullText(sourceFile); - definitions.set(typeName, fullDefinition); - allTypeNames.add(typeName); - } - }); - - return { definitions, allTypeNames }; -}; - -/** - * Finds all referenced type names within a given definition by walking its AST node. - * @param node The AST node of the definition. - * @param sourceFile The SourceFile object for the file. - * @param allTypeNames A Set of all known type names in the file. - * @param importedTypes A map of all imported type names. - * @returns An array of referenced type names. - */ -const findReferencedTypes = ( - node: ts.Node, - sourceFile: ts.SourceFile, - allTypeNames: Set, - importedTypes: Set -): string[] => { - const referenced = new Set(); - - const checkNode = (child: ts.Node) => { - // Check for a TypeReference, which indicates a reference to another type. - if (ts.isTypeReferenceNode(child)) { - const typeName = child.typeName.getText(sourceFile); - if (allTypeNames.has(typeName) || importedTypes.has(typeName)) { - referenced.add(typeName); - } - } - // Also check for a simple Identifier, as some types are just a single name. - if ( - ts.isIdentifier(child) && - (allTypeNames.has(child.getText(sourceFile)) || - importedTypes.has(child.getText(sourceFile))) - ) { - referenced.add(child.getText(sourceFile)); - } - - ts.forEachChild(child, checkNode); - }; - - ts.forEachChild(node, checkNode); - - return Array.from(referenced); -}; - -/** - * Parses the file content for import statements and maps imported type names to the - * full import string. - * @param content The string content of a .d.ts file. - * @returns A map from imported type name to its full import string. - */ -const parseImports = (content: string): Map => { - const importedTypes = new Map(); - const sourceFile = ts.createSourceFile( - "temp.d.ts", - content, - ts.ScriptTarget.ES2020, - true - ); - - ts.forEachChild(sourceFile, (node) => { - if (ts.isImportDeclaration(node)) { - if ( - node.importClause && - node.importClause.namedBindings && - ts.isNamedImports(node.importClause.namedBindings) - ) { - const importString = node.getText(sourceFile); - for (const element of node.importClause.namedBindings.elements) { - const typeName = element.name.getText(sourceFile); - importedTypes.set(typeName, importString); - } - } - } - }); - - return importedTypes; -}; - -const main = () => { - console.log("Generating ", outputFilepath); - try { - const fileContent = readFileSync(inputFilepath, "utf8"); - const sourceFile = ts.createSourceFile( - "temp.d.ts", - fileContent, - ts.ScriptTarget.ES2020, - true - ); - - const { definitions, allTypeNames } = parseTypes(fileContent); - const importedTypesMap = parseImports(fileContent); - const importedTypesSet = new Set(importedTypesMap.keys()); - - const typesToKeep = new Set(entryPoints); - const importsToKeep = new Set(); - let newTypesFound = true; - - // Iteratively find and add referenced types until no new ones are found. - while (newTypesFound) { - newTypesFound = false; - const typesToAdd = new Set(); - - for (const typeName of typesToKeep) { - const node = sourceFile.statements.find((stmt) => { - return ( - (ts.isTypeAliasDeclaration(stmt) || - ts.isInterfaceDeclaration(stmt) || - ts.isClassDeclaration(stmt)) && - stmt?.name?.getText(sourceFile) === typeName - ); - }); - - if (node) { - const referencedTypes = findReferencedTypes( - node, - sourceFile, - allTypeNames, - importedTypesSet - ); - - for (const referencedType of referencedTypes) { - if (importedTypesSet.has(referencedType)) { - const importStatement = importedTypesMap.get(referencedType); - if (importStatement && !importsToKeep.has(importStatement)) { - importsToKeep.add(importStatement); - } - } else if (!typesToKeep.has(referencedType)) { - typesToAdd.add(referencedType); - newTypesFound = true; - } - } - } - } - - for (const type of typesToAdd) { - typesToKeep.add(type); - } - } - - // Construct the final output - const output: string[] = []; - for (const importString of importsToKeep) { - output.push(importString); - } - - for (const typeName of typesToKeep) { - const definition = definitions.get(typeName); - if (definition) { - output.push(definition); - } - } - - writeFileSync(outputFilepath, output.join("\n"), "utf8"); - console.log(outputFilepath, "generated successfully."); - } catch (error) { - console.error(`An error occurred:`, error); - } -}; - -// Execute the main function -main(); diff --git a/packages/visual-editor/src/components/testing/screenshots/StaticMapSection/[desktop] default props with coordinate - with api key.png b/packages/visual-editor/src/components/testing/screenshots/StaticMapSection/[desktop] default props with coordinate - with api key.png index e3e4dfc03e..fbd0337508 100644 Binary files a/packages/visual-editor/src/components/testing/screenshots/StaticMapSection/[desktop] default props with coordinate - with api key.png and b/packages/visual-editor/src/components/testing/screenshots/StaticMapSection/[desktop] default props with coordinate - with api key.png differ diff --git a/packages/visual-editor/src/components/testing/screenshots/StaticMapSection/[mobile] default props with coordinate - with api key.png b/packages/visual-editor/src/components/testing/screenshots/StaticMapSection/[mobile] default props with coordinate - with api key.png index 0dfdf9f9f0..e87657fb68 100644 Binary files a/packages/visual-editor/src/components/testing/screenshots/StaticMapSection/[mobile] default props with coordinate - with api key.png and b/packages/visual-editor/src/components/testing/screenshots/StaticMapSection/[mobile] default props with coordinate - with api key.png differ diff --git a/packages/visual-editor/src/docs/ai/components.d.ts b/packages/visual-editor/src/docs/ai/components.d.ts deleted file mode 100644 index 5cca63f146..0000000000 --- a/packages/visual-editor/src/docs/ai/components.d.ts +++ /dev/null @@ -1,1151 +0,0 @@ -import { - Config, - Data, - DefaultComponentProps, - DefaultRootProps, - Field, - ComponentConfig, - CustomField, - ArrayField, - BaseField, - ObjectField, - NumberField, - Fields, - ComponentData, - Slot, -} from "@puckeditor/core"; -import { - ImageType, - CTA as CTA$1, - LinkType, - HoursTableProps as HoursTableProps$1, - ComplexImageType, - HoursType, - AddressType, - DayOfWeekNames, - Coordinate, - ListingType, -} from "@yext/pages-components"; -import { VariantProps } from "class-variance-authority"; - -interface PageSectionCategoryProps { - AboutSection: AboutSectionProps; - BannerSection: BannerSectionProps; - BreadcrumbsSection: BreadcrumbsSectionProps; - CoreInfoSection: CoreInfoSectionProps; - EventSection: EventSectionProps; - FAQSection: FAQSectionProps; - HeroSection: HeroSectionProps; - InsightSection: InsightSectionProps; - NearbyLocationsSection: NearbyLocationsSectionProps; - PhotoGallerySection: PhotoGallerySectionProps; - ProductSection: ProductSectionProps; - ProfessionalHeroSection: ProfessionalHeroSectionProps; - PromoSection: PromoSectionProps; - ReviewsSection: ReviewsSectionProps; - StaticMapSection: StaticMapSectionProps; - TeamSection: TeamSectionProps; - TestimonialSection: TestimonialSectionProps; - VideoSection: VideoSectionProps; -} - -interface ExpandedHeaderProps { - /** - * This object contains properties for customizing the appearance of both header tiers. - * @propCategory Style Props - */ - styles: ExpandedHeaderStyles; - /** @internal */ - slots: { - PrimaryHeaderSlot: Slot; - SecondaryHeaderSlot: Slot; - }; - /** @internal */ - analytics: { - scope?: string; - }; - /** - * Indicates which props should not be checked for missing translations. - * @internal - */ - ignoreLocaleWarning?: string[]; -} - -interface ExpandedFooterProps { - /** - * This object contains all the content for both footer tiers. - * @propCategory Data Props - */ - data: ExpandedFooterData; - /** - * This object contains properties for customizing the appearance of both footer tiers. - * @propCategory Style Props - */ - styles: ExpandedFooterStyles; - /** @internal */ - slots: { - LogoSlot: Slot; - SocialLinksSlot: Slot; - UtilityImagesSlot: Slot; - PrimaryLinksWrapperSlot: Slot; - ExpandedLinksWrapperSlot: Slot; - SecondaryFooterSlot: Slot; - }; - /** @internal */ - analytics: { - scope?: string; - }; - /** - * Indicates which props should not be checked for missing translations. - * @internal */ - ignoreLocaleWarning?: string[]; -} - -type AboutSectionProps = { - /** - * This object contains properties for customizing the component's data. - * @propCategory Data Props - */ - data: { - showDetailsColumn: boolean; - }; - /** - * This object contains properties for customizing the component's appearance. - * @propCategory Style Props - */ - styles: { - /** - * The background color of the section. - * @defaultValue Background Color 2 - */ - backgroundColor?: BackgroundStyle; - }; - /** @internal */ - slots: { - SectionHeadingSlot: Slot; - DescriptionSlot: Slot; - SidebarSlot: Slot; - }; - /** - * If 'true', the component is visible on the live page; if 'false', it's hidden. - * @defaultValue true - */ - liveVisibility: boolean; -}; - -interface BannerSectionProps { - /** - * This object contains the content to be displayed by the component. - * @propCategory Data Props - */ - data: BannerData; - /** - * This object contains properties for customizing the component's appearance. - * @propCategory Style Props - */ - styles: BannerStyles; - /** - * If 'true', the component is visible on the live page; if 'false', it's hidden. - * @defaultValue true - */ - liveVisibility: boolean; - /** - * Indicates which props should not be checked for missing translations. - * @internal - */ - ignoreLocaleWarning?: string[]; -} - -/** - * @public Defines the complete set of properties for the BreadcrumbsSection component. - */ -interface BreadcrumbsSectionProps { - /** - * This object contains the content used by the component. - * @propCategory Data Props - */ - data: BreadcrumbsData; - /** - * This object contains properties for customizing the component's appearance. - * @propCategory Style Props - */ - styles: BreadcrumbsStyles; - /** - * @internal - */ - analytics: { - scope?: string; - }; - /** - * If 'true', the component is visible on the live page; if 'false', it's hidden. - * @defaultValue true - */ - liveVisibility: boolean; -} - -interface CoreInfoSectionProps { - /** - * This object contains properties for customizing the component's appearance. - * @propCategory Style Props - */ - styles: CoreInfoStyles; - slots: { - CoreInfoHeadingSlot: Slot; - CoreInfoAddressSlot: Slot; - CoreInfoPhoneNumbersSlot: Slot; - CoreInfoEmailsSlot: Slot; - HoursHeadingSlot: Slot; - HoursTableSlot: Slot; - ServicesHeadingSlot: Slot; - TextListSlot: Slot; - }; - /** @internal */ - conditionalRender?: { - coreInfoCol?: boolean; - hoursCol?: boolean; - servicesCol?: boolean; - }; - /** @internal */ - analytics: { - scope?: string; - }; - /** - * If 'true', the component is visible on the live page; if 'false', it's hidden. - * @defaultValue true - */ - liveVisibility: boolean; -} - -interface EventSectionProps { - /** - * This object contains properties for customizing the component's appearance. - * @propCategory Style Props - */ - styles: { - /** - * The background color of the section. - * @defaultValue Background Color 3 - */ - backgroundColor?: BackgroundStyle; - }; - /** @internal */ - slots: { - SectionHeadingSlot: Slot; - CardsWrapperSlot: Slot; - }; - /** @internal */ - analytics: { - scope?: string; - }; - /** - * If 'true', the component is visible on the live page; if 'false', it's hidden. - * @defaultValue true - */ - liveVisibility: boolean; -} - -interface FAQSectionProps { - data: Omit, "constantValue"> & { - constantValue: { - id?: string; - }[]; - }; - /** - * This object contains properties for customizing the component's appearance. - * @propCategory Style Props - */ - styles: FAQStyles; - slots: { - HeadingSlot: Slot; - CardSlot: Slot; - }; - /** @internal */ - analytics: { - scope?: string; - }; - /** - * If 'true', the component is visible on the live page; if 'false', it's hidden. - * @defaultValue true - */ - liveVisibility: boolean; -} - -interface HeroSectionProps { - /** - * This object contains the content to be displayed by the component. - * @propCategory Data Props - */ - data: HeroData; - /** - * This object contains properties for customizing the component's appearance. - * @propCategory Style Props - */ - styles: HeroStyles; - slots: { - BusinessNameSlot: Slot; - GeomodifierSlot: Slot; - HoursStatusSlot: Slot; - ImageSlot: Slot; - PrimaryCTASlot: Slot; - SecondaryCTASlot: Slot; - }; - /** @internal */ - conditionalRender?: { - hours: boolean; - }; - /** @internal */ - analytics: { - scope?: string; - }; - /** - * If 'true', the component is visible on the live page; if 'false', it's hidden. - * @defaultValue true - */ - liveVisibility?: boolean; -} - -interface InsightSectionProps { - /** - * This object contains properties for customizing the component's appearance. - * @propCategory Style Props - */ - styles: { - /** - * The background color for the entire section. - * @defaultValue Background Color 2 - */ - backgroundColor?: BackgroundStyle; - }; - slots: { - SectionHeadingSlot: Slot; - CardsWrapperSlot: Slot; - }; - /** @internal */ - analytics: { - scope?: string; - }; - /** - * If 'true', the component is visible on the live page; if 'false', it's hidden. - * @defaultValue true - */ - liveVisibility: boolean; -} - -interface NearbyLocationsSectionProps { - /** - * This object contains extensive properties for customizing the component's appearance. - * @propCategory Style Props - */ - styles: { - /** - * The background color for the entire section. - * @defaultValue Background Color 1 - */ - backgroundColor?: BackgroundStyle; - }; - /** @internal */ - analytics: { - scope?: string; - }; - /** @internal */ - slots: { - SectionHeadingSlot: Slot; - CardsWrapperSlot: Slot; - }; - /** - * If 'true', the component is visible on the live page; if 'false', it's hidden. - * @defaultValue true - */ - liveVisibility: boolean; -} - -interface PhotoGallerySectionProps { - /** - * This object contains properties for customizing the component's appearance. - * @propCategory Style Props - */ - styles: PhotoGalleryStyles; - /** @internal */ - slots: { - HeadingSlot: Slot; - PhotoGalleryWrapper: Slot; - }; - /** - * If 'true', the component is visible on the live page; if 'false', it's hidden. - * @defaultValue true - */ - liveVisibility: boolean; -} - -interface ProductSectionProps { - /** - * This object contains properties for customizing the component's appearance. - * @propCategory Style Props - */ - styles: { - /** - * The background color for the entire section. - * @defaultValue Background Color 2 - */ - backgroundColor?: BackgroundStyle; - /** - * The variant of the product cards. - * @defaultValue Immersive - */ - cardVariant?: ProductSectionVariant; - /** - * Whether to show the product image. - * @defaultValue true - */ - showImage?: boolean; - /** - * Whether to show the product brow text. - * @defaultValue true - */ - showBrow?: boolean; - /** - * Whether to show the product title. - * @defaultValue true - */ - showTitle?: boolean; - /** - * Whether to show the product price. - * @defaultValue true - */ - showPrice?: boolean; - /** - * Whether to show the product description. - * @defaultValue true - */ - showDescription?: boolean; - /** - * Whether to show the product CTA. - * @defaultValue true - */ - showCTA?: boolean; - }; - slots: { - SectionHeadingSlot: Slot; - CardsWrapperSlot: Slot; - }; - /** @internal */ - analytics: { - scope?: string; - }; - /** - * If 'true', the component is visible on the live page; if 'false', it's hidden. - * @defaultValue true - */ - liveVisibility: boolean; -} - -interface ProfessionalHeroSectionProps { - /** - * This object contains properties for customizing the component's appearance. - * @propCategory Style Props - */ - styles: ProfessionalHeroStyles; - /** @internal */ - slots: { - ImageSlot: Slot; - BusinessNameSlot: Slot; - CredentialsSlot: Slot; - ProfessionalNameSlot: Slot; - ProfessionalTitleSlot: Slot; - SubtitleSlot: Slot; - AddressSlot: Slot; - PrimaryCTASlot: Slot; - SecondaryCTASlot: Slot; - PhoneSlot: Slot; - EmailSlot: Slot; - }; - /** - * If 'true', the component is visible on the live page; if 'false', it's hidden. - * @defaultValue true - */ - liveVisibility?: boolean; - /** @internal */ - conditionalRender?: { - isRightColumnVisible?: boolean; - }; - /** @internal */ - analytics: { - scope?: string; - }; -} - -interface PromoSectionProps { - /** - * This object contains the content to be displayed by the component. - * @propCategory Data Props - */ - data: PromoData; - /** - * This object contains properties for customizing the component's appearance. - * @propCategory Style Props - */ - styles: PromoStyles; - /** @internal */ - slots: { - HeadingSlot: Slot; - DescriptionSlot: Slot; - VideoSlot: Slot; - ImageSlot: Slot; - CTASlot: Slot; - }; - /** @internal */ - analytics: { - scope?: string; - }; - /** - * If 'true', the component is visible on the live page; if 'false', it's hidden. - * @defaultValue true - */ - liveVisibility?: boolean; -} - -interface ReviewsSectionProps { - /** - * This object contains properties for customizing the component's appearance. - * @propCategory Style Props - */ - styles: { - /** - * The background color of the section. - * @defaultValue Background Color 1 - */ - backgroundColor?: BackgroundStyle; - }; - /** @internal */ - slots: { - SectionHeadingSlot: Slot; - }; - /** @internal */ - analytics: { - scope?: string; - }; - /** - * If 'true', the component is visible on the live page; if 'false', it's hidden. - * @defaultValue true - */ - liveVisibility: boolean; -} - -interface StaticMapSectionProps { - /** - * This object contains the configuration needed to generate the map. - * @propCategory Data Props - */ - data: StaticMapData; - /** - * If 'true', the component is visible on the live page; if 'false', it's hidden. - * @defaultValue true - */ - liveVisibility: boolean; - /** - * This object contains properties for customizing the component's appearance. - * @propCategory Styles Props - */ - styles: StaticMapStyles; -} - -interface TeamSectionProps { - /** - * This object contains properties for customizing the component's appearance. - * @propCategory Style Props - */ - styles: { - /** - * The background color of the section. - * @defaultValue Background Color 3 - */ - backgroundColor?: BackgroundStyle; - }; - /** @internal */ - slots: { - SectionHeadingSlot: Slot; - CardsWrapperSlot: Slot; - }; - /** @internal */ - analytics: { - scope?: string; - }; - /** - * If 'true', the component is visible on the live page; if 'false', it's hidden. - * @defaultValue true - */ - liveVisibility: boolean; -} - -interface TestimonialSectionProps { - /** - * This object contains properties for customizing the component's appearance. - * @propCategory Style Props - */ - styles: { - /** - * The background color of the section. - * @defaultValue Background Color 2 - */ - backgroundColor?: BackgroundStyle; - }; - /** @internal */ - slots: { - SectionHeadingSlot: Slot; - CardsWrapperSlot: Slot; - }; - /** @internal */ - analytics: { - scope?: string; - }; - /** - * If 'true', the component is visible on the live page; if 'false', it's hidden. - * @defaultValue true - */ - liveVisibility: boolean; -} - -interface VideoSectionProps { - /** - * This object contains properties for customizing the component's appearance. - * @propCategory Style Props - */ - styles: { - /** - * The background color for the entire section, selected from the theme. - * @defaultValue Background Color 1 - */ - backgroundColor?: BackgroundStyle; - }; - slots: { - SectionHeadingSlot: Slot; - VideoSlot: Slot; - }; - /** - * If 'true', the component is visible on the live page; if 'false', it's hidden. - * @defaultValue true - */ - liveVisibility: boolean; -} - -interface ExpandedHeaderStyles { - /** The maximum width of the header */ - maxWidth: PageSectionProps["maxWidth"]; - /** Whether the header is fixed to the top of the page or not */ - headerPosition: "fixed" | "scrollsWithPage"; -} - -interface ExpandedFooterData { - /** Content for the primary footer bar. */ - primaryFooter: { - /** - * Whether to expand the footer to show additional link categories. - * expandedFooter: false uses a single row of footerLinks. - * expandedFooter: true uses multiple columns of expandedFooterLinks. - */ - expandedFooter: boolean; - }; -} - -interface ExpandedFooterStyles { - /** Styling for the primary footer bar. */ - primaryFooter: { - backgroundColor?: BackgroundStyle; - linksPosition: "left" | "right"; - }; - /** The maximum width of the footer. */ - maxWidth: PageSectionProps["maxWidth"]; -} - -/** - * Applies a theme color as the background of a page section - * @ai This value MUST be one of the following - * { bgColor: "bg-white", textColor: "text-black" } - * { bgColor: "bg-palette-primary-light", textColor: "text-black", isDarkBackground: false } - * { bgColor: "bg-palette-secondary-light", textColor: "text-black", isDarkBackground: false } - * { bgColor: "bg-palette-tertiary-light", textColor: "text-black", isDarkBackground: false } - * { bgColor: "bg-palette-quaternary-light", textColor: "text-black", isDarkBackground: false } - * { bgColor: "bg-palette-primary-dark", textColor: "text-white", isDarkBackground: true } - * { bgColor: "bg-palette-secondary-dark", textColor: "text-white", isDarkBackground: true } - */ -type BackgroundStyle = { - /** The tailwind background color class */ - bgColor: string; - /** The tailwind text color class */ - textColor: string; - /** Whether the background color is dark (for adjusting other styles based on background) */ - isDarkBackground?: boolean; -}; - -interface BannerData { - /** - * The rich text to display. It can be linked to a Yext entity field or set as a constant value. - * @defaultValue "Banner Text" (constant) - */ - text: YextEntityField; -} - -interface BannerStyles { - /** - * The background color of the section. - * @defaultValue Background Color 6 - */ - backgroundColor?: BackgroundStyle; - /** - * The horizontal alignment of the text. - * @defaultValue center - */ - textAlignment: "left" | "right" | "center"; -} - -interface BreadcrumbsData { - /** - * The display label for the first link in the breadcrumb trail (the top-level directory page). - * @defaultValue "Directory Root" - */ - directoryRoot: TranslatableString; -} - -interface BreadcrumbsStyles { - /** - * The background color of the section. - * @defaultValue Background Color 1 - */ - backgroundColor?: BackgroundStyle; -} - -interface CoreInfoStyles { - /** - * The background color of the section. - * @defaultValue `Background Color 1` - */ - backgroundColor?: BackgroundStyle; -} - -/** Represents data that can either be from the Yext Knowledge Graph or statically defined */ -type YextEntityField = { - /** The api name of the Yext field */ - field: string; - /** The static value of the field */ - constantValue: T; - /** Whether to use the Yext field or the constant value */ - constantValueEnabled?: boolean; - /** - * Whether the field can be translated or not. - * @ai always omit this property - */ - disallowTranslation?: boolean; - /** - * Filter the embedded field input to this type. - * @ai always omit this property - */ - selectedType?: string; -}; - -/** Data for the FAQSection */ -type FAQSectionType = { - faqs: Array; -}; - -interface FAQStyles { - /** - * The background color of the section. - * @defaultValue Background Color 3 - */ - backgroundColor?: BackgroundStyle; -} - -interface HeroData { - backgroundImage: YextEntityField< - ImageType | AssetImageType | TranslatableAssetImage - >; -} - -interface HeroStyles { - /** - * The visual variant for the hero section. - * @defaultValue classic - */ - variant: "classic" | "immersive" | "spotlight" | "compact"; - /** - * The background color for the entire section (classic and compact variants). - * The background color for the featured content (spotlight variant). - * @defaultValue Background Color 1 - */ - backgroundColor?: BackgroundStyle; - /** - * If 'true', displays the entity's average review rating. - * @defaultValue true - */ - showAverageReview: boolean; - /** - * Whether to show the hero image (classic and compact variant). - * @defaultValue true - */ - showImage: boolean; - /** - * Image Height for the hero image with Immersive or Spotlight variant - * Minimum height: content height + Page Section Top/Bottom Padding - * @default 500px - */ - imageHeight?: number; - /** - * Container position on desktop (spotlight and immersive variants). - * @defaultValue left - */ - desktopContainerPosition?: "left" | "center"; - /** - * Content alignment for mobile viewports. - * @defaultValue left - */ - mobileContentAlignment?: "left" | "center"; - /** - * Positions the image to the left or right of the hero content on desktop (classic and compact variants). - * @defaultValue right - */ - desktopImagePosition: "left" | "right"; - /** - * Positions the image to the top or bottom of the hero content on mobile (classic and compact variants). - * @defaultValue top - */ - mobileImagePosition: "bottom" | "top"; -} - -interface PhotoGalleryStyles { - /** - * The background color for the entire section, selected from the theme. - * @defaultValue Background Color 1 - */ - backgroundColor?: BackgroundStyle; - /** - * The layout style for displaying images in the gallery. - * @defaultValue "gallery" - */ - variant: "gallery" | "carousel"; -} - -type ProductSectionVariant = "immersive" | "classic" | "minimal"; - -interface ProfessionalHeroStyles { - /** - * The background color for the section. - * @defaultValue Background Color 1 - */ - backgroundColor?: BackgroundStyle; - /** - * If 'true', displays the entity's average review rating. - * @defaultValue true - */ - showAverageReview: boolean; - /** - * Whether to show the hero image. - * @defaultValue true - */ - showImage: boolean; - /** - * Positions the image to the left or right of the hero content on desktop. - * @defaultValue left - */ - desktopImagePosition: "left" | "right"; - /** - * Positions the image to the top or bottom of the hero content on mobile. - * @defaultValue top - */ - mobileImagePosition: "bottom" | "top"; - /** - * Whether to show the credentials slot. - * @defaultValue true - */ - showCredentials?: boolean; - /** - * Whether to show the subtitle slot. - * @defaultValue true - */ - showSubtitle?: boolean; - /** - * Whether to show the business name slot. - * @defaultValue true - */ - showBusinessName?: boolean; - /** - * Whether to show the professional title slot. - * @defaultValue true - */ - showProfessionalTitle?: boolean; - /** - * Whether to show the address slot. - * @defaultValue true - */ - showAddress?: boolean; - /** - * Whether to show the primary CTA slot. - * @defaultValue true - */ - showPrimaryCTA?: boolean; - /** - * Whether to show the secondary CTA slot. - * @defaultValue true - */ - showSecondaryCTA?: boolean; - /** - * Whether to show the phone slot. - * @defaultValue true - */ - showPhone?: boolean; - /** - * Whether to show the email slot. - * @defaultValue true - */ - showEmail?: boolean; -} - -interface PromoData { - /** - * The source for the promotional content, including an image, title, description, and a call-to-action. - * @defaultValue Placeholder content for a featured promotion. - */ - promo: YextEntityField; - /** - * Determines whether to display an image or video in the media section. - * @defaultValue 'image' - */ - media: "image" | "video"; - /** - * The background image used by the immersive and spotlight variants. - * @defaultValue Placeholder image. - */ - backgroundImage: YextEntityField< - ImageType | AssetImageType | TranslatableAssetImage - >; -} - -interface PromoStyles { - /** - * The visual variant for the promo section. - * @defaultValue classic - */ - variant: "classic" | "immersive" | "spotlight" | "compact"; - /** - * The background color for the entire section. - * @defaultValue Background Color 1 - */ - backgroundColor?: BackgroundStyle; - /** - * Positions the media to the left or right of the promo content on desktop (classic and compact variants). - * @defaultValue right - */ - desktopImagePosition: "left" | "right"; - /** - * Positions the media to the top or bottom of the promo content on mobile (classic and compact variants). - * @defaultValue top - */ - mobileImagePosition: "top" | "bottom"; - /** - * Text content position and alignment. - * @defaultValue left - */ - containerAlignment: "left" | "center" | "right"; - /** - * Image Height for the promo image with Immersive or Spotlight variant - * Minimum height: content height + Page Section Top/Bottom Padding - * @default 500px - */ - imageHeight: number; -} - -interface StaticMapData { - /** - * The API key used to generate the map image. - * @defaultValue "" - */ - apiKey: string; -} - -interface StaticMapStyles { - /** - * The background color of the section. - * @defaultValue Background Color 1 - */ - backgroundColor?: BackgroundStyle; - /** - * The style of the map to be displayed. - * @defaultValue Default (streets-v12) - */ - mapStyle: string; -} - -interface PageSectionProps - extends VariantProps, - React.HTMLAttributes { - background?: BackgroundStyle; - verticalPadding?: VariantProps["verticalPadding"]; - as?: "div" | "section" | "nav" | "header" | "footer" | "main" | "aside"; - outerClassName?: string; - outerStyle?: React.CSSProperties; -} - -/** - * Rich text that can be translated for different locales. - * @ai This should always be Record - */ -type TranslatableRichText = - | (string | RichText) - | Record; - -/** - * A string that can be translated for different locales. - * @ai This should always be the LocalizedValues type - */ -type TranslatableString = string | LocalizedValues; - -/** An individual FAQ */ -type FAQStruct = { - /** The question (always visible on the page) */ - question: TranslatableString | TranslatableRichText; - /** The answer (visible when the question is clicked) */ - answer: TranslatableRichText; -}; - -type AssetImageType = Omit & { - alternateText?: TranslatableString; - assetImage?: ImageContentData; -}; - -type TranslatableAssetImage = AssetImageType | LocalizedAssetImage; - -/** Data for the PromoSection */ -type PromoSectionType = { - /** - * The image or video to show in the promo - * @ai Always use ImageType - */ - image?: ImageType | AssetImageType | AssetVideo; - /** The main text to display in the promo */ - title?: TranslatableString; - /** The sub text to display in the promo */ - description?: TranslatableRichText; - /** The CTA button for the promo */ - cta: EnhancedTranslatableCTA; -}; - -/** - * A rich text object with HTML and JSON (LexicalRichText) representations. - * The HTML representation is used on the live page. - * The JSON representation is used in the editor for rich text editing. - */ -type RichText = { - html?: string; - json?: string; -}; - -/** Represents a translatable string. The key is the locale (en, es, fr), and the value is the localized string. */ -type LocalizedValues = { - hasLocalizedValue: "true"; -} & Record; - -/** Describes the data corresponding to a piece of image content. */ -type ImageContentData = { - name?: string; - transformedImage?: ImageData; - originalImage?: ImageData; - childImages?: ImageData[]; - transformations?: ImageTransformations; - sourceUrl?: string; - altText?: string; -}; - -type LocalizedAssetImage = { - hasLocalizedValue: "true"; -} & { - [key: string]: AssetImageType | undefined; -}; - -type AssetVideo = { - video: Video$1; - /** Asset video description field */ - videoDescription?: string; - /** Asset name (unique) */ - name: string; - /** Asset internal id */ - id: string; -}; - -/** Enhanced CTA options */ -type EnhancedTranslatableCTA = TranslatableCTA & { - /** - * The type of CTA button to display. - * textAndLink is a standard button - * getDirections is a button that opens a map based on the coordinate field - * presetImage uses a preset image such as app store or food delivery logos for the button - * @defaultValue "textAndLink" - */ - ctaType?: "textAndLink" | "getDirections" | "presetImage"; -}; - -/** Describes the data corresponding to a single image. */ -type ImageData = { - url: string; - dimension?: ImageDimension; - exifMetadata?: { - rotate: number; - }; -}; - -type ImageTransformations = Partial>; - -type Video$1 = { - /** The YouTube video URL */ - url: string; - /** The YouTube video ID */ - id: string; - /** The YouTube video title */ - title: string; - /** The YouTube video thumbnail URL */ - thumbnail: string; - /** The YouTube video duration */ - duration: string; - /** The embedded YouTube video URL (https://youtube.com/embed/) */ - embeddedUrl: string; -}; - -/** - * A pages-components CTA with a translatable label and link - */ -type TranslatableCTA = Omit & { - /** The text to display in the CTA */ - label: TranslatableString; - /** The link the for the CTA */ - link: TranslatableString; - openInNewTab?: boolean; -}; - -/** Describes the dimensions of an image. */ -type ImageDimension = { - width: number; - height: number; -}; - -type TransformKind = "CROP" | "ROTATION"; - -/** Outlines the possible image transformations. */ -type ImageTransformation = ImageRotation | ImageCrop; - -/** Describes the data corresponding to an image rotation. */ -type ImageRotation = { - degree: number; -}; - -/** Describes the crop boundary box data */ -type ImageCrop = { - left: number; - top: number; - height: number; - width: number; - aspectRatio?: ImageAspectRatio; -}; - -/** Describes an image's aspect ratio. */ -type ImageAspectRatio = { - horizontalFactor: number; - verticalFactor: number; -}; diff --git a/packages/visual-editor/src/docs/hybrid-development.md b/packages/visual-editor/src/docs/hybrid-development.md index 9432ccdbd7..8cfda56238 100644 --- a/packages/visual-editor/src/docs/hybrid-development.md +++ b/packages/visual-editor/src/docs/hybrid-development.md @@ -290,7 +290,7 @@ import { defaultThemeTailwindExtensions, defaultThemeConfig, VisualEditorComponentsContentPath, -} from "@yext/visual-editor"; +} from "@yext/visual-editor/tailwind"; import { ComponentsContentPath as SearchUiComponentsContentPath } from "@yext/search-ui-react"; export default { diff --git a/packages/visual-editor/src/editor/YextEntityFieldSelector.tsx b/packages/visual-editor/src/editor/YextEntityFieldSelector.tsx index 0bac7d921b..1b9a0f49b6 100644 --- a/packages/visual-editor/src/editor/YextEntityFieldSelector.tsx +++ b/packages/visual-editor/src/editor/YextEntityFieldSelector.tsx @@ -189,6 +189,36 @@ export const YextEntityFieldSelector = , U>( ): Field> => { return { type: "custom", + // TEMP: basic setup for string fields so that the Puck API doesn't return an error + ai: + props.filter.types?.[0] === "type.string" && + !props.filter.includeListsOnly + ? { + schema: { + type: "object", + properties: { + constantValueEnabled: { + type: "boolean", + }, + field: { + type: "string", + }, + constantValue: { + type: "object", + properties: { + hasLocalizedValue: { + type: "string", + enum: ["true"], + }, + en: { + type: "string", + }, + }, + }, + }, + }, + } + : undefined, render: ({ value, onChange }: RenderProps) => { const toggleConstantValueEnabled = (constantValueEnabled: boolean) => { onChange({ diff --git a/packages/visual-editor/src/editor/index.css b/packages/visual-editor/src/editor/index.css index 88a36d64df..412486221e 100644 --- a/packages/visual-editor/src/editor/index.css +++ b/packages/visual-editor/src/editor/index.css @@ -1,4 +1,7 @@ @import "@puckeditor/core/no-external.css"; +@import "@puckeditor/plugin-ai/styles.css"; +@import "react-international-phone/style.css"; +@import "../internal/puck/ui/puck.css"; @tailwind base; @tailwind components; @tailwind utilities; diff --git a/packages/visual-editor/src/editor/yextEntityFieldUtils.ts b/packages/visual-editor/src/editor/yextEntityFieldUtils.ts index 1dda8437ef..ec3c003ba5 100644 --- a/packages/visual-editor/src/editor/yextEntityFieldUtils.ts +++ b/packages/visual-editor/src/editor/yextEntityFieldUtils.ts @@ -14,12 +14,10 @@ export type YextEntityField = { constantValueEnabled?: boolean; /** * Whether the field can be translated or not. - * @ai always omit this property */ disallowTranslation?: boolean; /** * Filter the embedded field input to this type. - * @ai always omit this property */ selectedType?: string; }; diff --git a/packages/visual-editor/src/internal/components/AdvancedSettings.tsx b/packages/visual-editor/src/internal/components/AdvancedSettings.tsx index a019a1087d..370721abb6 100644 --- a/packages/visual-editor/src/internal/components/AdvancedSettings.tsx +++ b/packages/visual-editor/src/internal/components/AdvancedSettings.tsx @@ -117,6 +117,9 @@ const advancedSettingsFields: Fields = { objectFields: { schemaMarkup: SCHEMA_MARKUP_FIELD, }, + ai: { + exclude: true, + }, }, }; diff --git a/packages/visual-editor/src/internal/components/InternalLayoutEditor.tsx b/packages/visual-editor/src/internal/components/InternalLayoutEditor.tsx index de41f01c85..85c9706430 100644 --- a/packages/visual-editor/src/internal/components/InternalLayoutEditor.tsx +++ b/packages/visual-editor/src/internal/components/InternalLayoutEditor.tsx @@ -15,8 +15,7 @@ import { blocksPlugin, outlinePlugin, } from "@puckeditor/core"; -import React from "react"; -import { useState, useRef, useCallback } from "react"; +import React, { useState, useRef, useCallback, useMemo } from "react"; import { TemplateMetadata } from "../types/templateMetadata.ts"; import { EntityTooltipsProvider } from "../../editor/EntityField.tsx"; import { LayoutSaveState } from "../types/saveState.ts"; @@ -36,6 +35,8 @@ import { useDocument } from "../../hooks/useDocument.tsx"; import { fieldsOverride } from "../puck/components/FieldsOverride.tsx"; import { isDeepEqual } from "../../utils/deepEqual.ts"; import { useErrorContext } from "../../contexts/ErrorContext.tsx"; +import { createAiPlugin } from "@puckeditor/plugin-ai"; +import { preparePuckAiRequest } from "../../utils/ai/prepareRequest.ts"; const devLogger = new DevLogger(); const usePuck = createUsePuck(); @@ -45,6 +46,9 @@ const outline = outlinePlugin(); // Advanced Settings link configuration const createAdvancedSettingsLink = () => ({ type: "custom" as const, + ai: { + exclude: true, + }, render: () => { const getPuck = useGetPuck(); @@ -112,6 +116,23 @@ export const InternalLayoutEditor = ({ const { i18n } = usePlatformTranslation(); const streamDocument = useDocument(); const { errorCount } = useErrorContext(); + const aiPlugin = useMemo( + () => + templateMetadata.aiPageGeneration + ? createAiPlugin( + localDev + ? { + host: "http://127.0.0.1:8787/api/puck/chat", + prepareRequest: preparePuckAiRequest, + } + : { + host: "https://puck-ai-backend.sitescdn-cdntest.workers.dev/api/puck/chat", + prepareRequest: preparePuckAiRequest, + } + ) + : undefined, + [templateMetadata.aiPageGeneration, localDev] + ); /** * When the Puck history changes save it to localStorage and send a message @@ -398,7 +419,11 @@ export const InternalLayoutEditor = ({ data={{}} // we use puckInitialHistory instead initialHistory={puckInitialHistory} onChange={change} - plugins={[{ ...blocks, label: pt("sections", "Sections") }, outline]} + plugins={[ + { ...blocks, label: pt("sections", "Sections") }, + outline, + ...(aiPlugin ? [aiPlugin] : []), + ]} overrides={{ fields: fieldsOverride, header: () => ( diff --git a/packages/visual-editor/src/internal/puck/components/theme-editor-sidebars/ThemeEditorRightSidebar.tsx b/packages/visual-editor/src/internal/puck/components/theme-editor-sidebars/ThemeEditorRightSidebar.tsx index 46161b37af..cef48c47d8 100644 --- a/packages/visual-editor/src/internal/puck/components/theme-editor-sidebars/ThemeEditorRightSidebar.tsx +++ b/packages/visual-editor/src/internal/puck/components/theme-editor-sidebars/ThemeEditorRightSidebar.tsx @@ -2,7 +2,6 @@ import React from "react"; import { Alert, AlertDescription } from "../../ui/atoms/Alert.tsx"; import { ThemeConfig } from "../../../../utils/themeResolver.ts"; import { OnThemeChangeFunc, ThemeHistories } from "../../../types/themeData.ts"; -import "@puckeditor/core/dist/index.css"; import { ThemeFieldsSidebar } from "./ThemeFieldsSidebar.tsx"; import { pt } from "../../../../utils/i18n/platform.ts"; diff --git a/packages/visual-editor/src/internal/puck/constant-value-fields/Phone.tsx b/packages/visual-editor/src/internal/puck/constant-value-fields/Phone.tsx index 37a492ba92..c38f80cb6f 100644 --- a/packages/visual-editor/src/internal/puck/constant-value-fields/Phone.tsx +++ b/packages/visual-editor/src/internal/puck/constant-value-fields/Phone.tsx @@ -1,6 +1,5 @@ import { CustomField, FieldLabel } from "@puckeditor/core"; import { PhoneInput } from "react-international-phone"; -import "react-international-phone/style.css"; import "../ui/puck.css"; import { pt } from "../../../utils/i18n/platform.ts"; import React from "react"; diff --git a/packages/visual-editor/src/internal/types/templateMetadata.ts b/packages/visual-editor/src/internal/types/templateMetadata.ts index fbef522034..b4dcc7cf2d 100644 --- a/packages/visual-editor/src/internal/types/templateMetadata.ts +++ b/packages/visual-editor/src/internal/types/templateMetadata.ts @@ -20,6 +20,7 @@ export type TemplateMetadata = { layoutTaskApprovals: boolean; locatorDisplayFields?: Record; customFonts?: FontRegistry; + aiPageGeneration?: boolean; }; export type FieldTypeData = { @@ -63,6 +64,7 @@ export function generateTemplateMetadata(): TemplateMetadata { field_type_id: "type.phone", }, }, + aiPageGeneration: !!import.meta.env.VITE_ENABLE_AI_PAGE_GENERATION, }; } diff --git a/packages/visual-editor/src/tailwind.ts b/packages/visual-editor/src/tailwind.ts new file mode 100644 index 0000000000..8f24410417 --- /dev/null +++ b/packages/visual-editor/src/tailwind.ts @@ -0,0 +1,6 @@ +export { defaultThemeConfig } from "./components/DefaultThemeConfig.ts"; +export { + defaultThemeTailwindExtensions, + VisualEditorComponentsContentPath, +} from "./utils/themeConfigOptions.ts"; +export { themeResolver } from "./utils/themeResolver.ts"; diff --git a/packages/visual-editor/src/utils/ai/enabledComponents.ts b/packages/visual-editor/src/utils/ai/enabledComponents.ts new file mode 100644 index 0000000000..7433b482f5 --- /dev/null +++ b/packages/visual-editor/src/utils/ai/enabledComponents.ts @@ -0,0 +1,45 @@ +import { PageSectionCategoryProps } from "../../components/categories/PageSectionCategory.tsx"; +import { DirectoryCategoryProps } from "../../components/categories/DirectoryCategory.tsx"; +import { LocatorCategoryProps } from "../../components/categories/LocatorCategory.tsx"; +import { SlotsCategoryProps } from "../../components/categories/SlotsCategory.tsx"; +import { AdvancedCoreInfoCategoryProps } from "../../components/categories/AdvancedCoreInfoCategory.tsx"; +import { OtherCategoryProps } from "../../components/categories/OtherCategory.tsx"; + +/** The config passed to Puck will be filtered to the components listed here */ +export const enabledAiComponents: ( + | keyof PageSectionCategoryProps + | keyof DirectoryCategoryProps + | keyof LocatorCategoryProps + | keyof SlotsCategoryProps + | keyof AdvancedCoreInfoCategoryProps + | keyof OtherCategoryProps +)[] = [ + "AddressSlot", + "BannerSection", + "BodyTextSlot", + "CopyrightMessageSlot", + "CoreInfoSection", + "CTASlot", + "EmailsSlot", + "ExpandedFooter", + "ExpandedHeader", + "FooterExpandedLinksWrapper", + "FooterLinksSlot", + "FooterLogoSlot", + "FooterSocialLinksSlot", + "FooterUtilityImagesSlot", + "HeaderLinks", + "HeadingTextSlot", + "HeroImageSlot", + "HeroSection", + "HoursStatusSlot", + "HoursTableSlot", + "ImageSlot", + "PhoneNumbersSlot", + "PrimaryHeaderSlot", + "PromoSection", + "SecondaryHeaderSlot", + "SecondaryFooterSlot", + "TextListSlot", + "VideoSlot", +]; diff --git a/packages/visual-editor/src/utils/ai/prepareRequest.ts b/packages/visual-editor/src/utils/ai/prepareRequest.ts new file mode 100644 index 0000000000..ca9c99b32f --- /dev/null +++ b/packages/visual-editor/src/utils/ai/prepareRequest.ts @@ -0,0 +1,31 @@ +import { createAiPlugin } from "@puckeditor/plugin-ai"; +import { enabledAiComponents } from "./enabledComponents.ts"; +import { puckAiSystemContext } from "./systemPrompt.ts"; + +type PrepareRequestFn = Exclude< + Parameters[0], + undefined +>["prepareRequest"]; + +/** Transform the Chat request before sending it to the backend */ +export const preparePuckAiRequest: PrepareRequestFn = (opts) => { + let updatedOpts = { ...opts }; + + if (!updatedOpts.body) { + updatedOpts.body = {}; + } + + updatedOpts.body.systemPrompt = puckAiSystemContext; + + if (!updatedOpts.body?.config?.components) { + return updatedOpts; + } + + updatedOpts.body.config.components = Object.fromEntries( + Object.entries(updatedOpts.body.config.components).filter(([component]) => + (enabledAiComponents as string[]).includes(component) + ) + ); + + return updatedOpts; +}; diff --git a/packages/visual-editor/src/utils/ai/systemPrompt.ts b/packages/visual-editor/src/utils/ai/systemPrompt.ts new file mode 100644 index 0000000000..72d1de5987 --- /dev/null +++ b/packages/visual-editor/src/utils/ai/systemPrompt.ts @@ -0,0 +1,19 @@ +/**This prompt is used as the system context for all chat requests */ +export const puckAiSystemContext = ` +You are an AI assistant for Yext Pages, a platform for creating and + managing web pages for brick-and-mortar business locations. + + Each page will be powered by an 'entity' which contains data fields relevant to a specific business location. + The layout we are building will apply to all entities. + + Many fields have the 'field' and 'constantValueEnabled' property. If 'constantValueEnabled' is false, + the rendered value will be the value of the 'field' property on the entity. + If 'constantValueEnabled' is true, the rendered value will be the 'constantValue' property, which will be the same for all entities. + You can also use [[fieldName]] to reference the value of a field on the entity, even if 'constantValueEnabled' is false. + + All pages should have a BannerSection, HeroSection, PromoSection, and CoreInfoSection unless the user explicitly says not to include one of those sections. + + All 'slot' fields must contain a component; they should never be left empty. +` + .replaceAll(/\s+/g, " ") + .trim(); diff --git a/packages/visual-editor/src/utils/themeConfigOptions.ts b/packages/visual-editor/src/utils/themeConfigOptions.ts index a64b24a7eb..f18b808476 100644 --- a/packages/visual-editor/src/utils/themeConfigOptions.ts +++ b/packages/visual-editor/src/utils/themeConfigOptions.ts @@ -69,14 +69,6 @@ const getSpacingOptions = () => { /** * Applies a theme color as the background of a page section - * @ai This value MUST be one of the following - * { bgColor: "bg-white", textColor: "text-black" } - * { bgColor: "bg-palette-primary-light", textColor: "text-black", isDarkBackground: false } - * { bgColor: "bg-palette-secondary-light", textColor: "text-black", isDarkBackground: false } - * { bgColor: "bg-palette-tertiary-light", textColor: "text-black", isDarkBackground: false } - * { bgColor: "bg-palette-quaternary-light", textColor: "text-black", isDarkBackground: false } - * { bgColor: "bg-palette-primary-dark", textColor: "text-white", isDarkBackground: true } - * { bgColor: "bg-palette-secondary-dark", textColor: "text-white", isDarkBackground: true } */ export type BackgroundStyle = { /** The tailwind background color class */ diff --git a/packages/visual-editor/src/vite-plugin/templates/edit.tsx b/packages/visual-editor/src/vite-plugin/templates/edit.tsx index 95a3dcbdda..5e849d8396 100644 --- a/packages/visual-editor/src/vite-plugin/templates/edit.tsx +++ b/packages/visual-editor/src/vite-plugin/templates/edit.tsx @@ -1,5 +1,6 @@ /** THIS FILE IS AUTOGENERATED AND SHOULD NOT BE EDITED */ import "@yext/visual-editor/editor.css"; +import "@yext/visual-editor/style.css"; import "../index.css"; import { applyTheme, diff --git a/packages/visual-editor/vite.config.ts b/packages/visual-editor/vite.config.ts index 0495f4ccdc..ce984d72a2 100644 --- a/packages/visual-editor/vite.config.ts +++ b/packages/visual-editor/vite.config.ts @@ -18,7 +18,10 @@ export default defineConfig(() => ({ build: { cssCodeSplit: true, lib: { - entry: path.resolve(__dirname, "src/index.ts"), + entry: { + "visual-editor": path.resolve(__dirname, "src/index.ts"), + tailwind: path.resolve(__dirname, "src/tailwind.ts"), + }, name: "visual-editor", formats: ["es"] as LibraryFormats[], // typescript is unhappy without this forced type definition }, @@ -27,6 +30,7 @@ export default defineConfig(() => ({ "react", "react-dom", "@puckeditor/core", + "@puckeditor/plugin-ai", "uuid", "@yext/pages-components", "mapbox-gl", @@ -40,7 +44,9 @@ export default defineConfig(() => ({ }, }, input: { - editor: path.resolve(__dirname, "src/index.ts"), + "visual-editor": path.resolve(__dirname, "src/index.ts"), + tailwind: path.resolve(__dirname, "src/tailwind.ts"), + editor: path.resolve(__dirname, "src/editor/index.css"), style: path.resolve(__dirname, "src/components/styles.css"), }, }, @@ -80,7 +86,7 @@ const dts = (): Plugin => ({ return; } - exec("tsup src/index.ts --format esm --dts-only", (err) => { + exec("tsup src/index.ts src/tailwind.ts --format esm --dts-only", (err) => { if (err) { throw new Error("Failed to generate declaration files"); } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4d8e8826a2..f2763a40fb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -80,6 +80,25 @@ importers: specifier: ^2.3.4 version: 2.8.1 + packages/puck-ai-backend: + dependencies: + "@puckeditor/cloud-client": + specifier: 0.6.0 + version: 0.6.0 + hono: + specifier: ^4.6.12 + version: 4.11.7 + devDependencies: + "@types/node": + specifier: ^25.2.1 + version: 25.2.1 + typescript: + specifier: ^5.5.2 + version: 5.9.2 + wrangler: + specifier: ^4.63.0 + version: 4.63.0 + packages/visual-editor: dependencies: "@microsoft/api-documenter": @@ -94,6 +113,9 @@ importers: "@puckeditor/core": specifier: 0.21.1 version: 0.21.1(@floating-ui/dom@1.7.4)(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(immer@9.0.21)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(use-sync-external-store@1.5.0(react@18.3.1)) + "@puckeditor/plugin-ai": + specifier: 0.6.0 + version: 0.6.0(@puckeditor/core@0.21.1(@floating-ui/dom@1.7.4)(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(immer@9.0.21)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(use-sync-external-store@1.5.0(react@18.3.1)))(@types/react@18.3.24)(react@18.3.1)(zod@3.25.76) "@radix-ui/react-accordion": specifier: ^1.2.3 version: 1.2.12(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -380,6 +402,9 @@ importers: "@puckeditor/core": specifier: 0.21.1 version: 0.21.1(@floating-ui/dom@1.7.4)(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(immer@9.0.21)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(use-sync-external-store@1.5.0(react@18.3.1)) + "@puckeditor/plugin-ai": + specifier: 0.6.0 + version: 0.6.0(@puckeditor/core@0.21.1(@floating-ui/dom@1.7.4)(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(immer@9.0.21)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(use-sync-external-store@1.5.0(react@18.3.1)))(@types/react@18.3.24)(react@18.3.1)(zod@3.25.76) "@radix-ui/react-accordion": specifier: ^1.2.0 version: 1.2.12(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -410,6 +435,9 @@ importers: "@types/node": specifier: ^20.12.3 version: 20.19.11 + "@yext/pages": + specifier: 1.2.9 + version: 1.2.9(@algolia/client-search@5.35.0)(@types/node@20.19.11)(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)(typescript@5.9.2)(vite@5.4.19(@types/node@20.19.11)) "@yext/search-headless-react": specifier: ^2.5.3 version: 2.6.0(encoding@0.1.13)(react@18.3.1) @@ -471,9 +499,6 @@ importers: "@vitejs/plugin-react": specifier: ^4.2.1 version: 4.7.0(vite@5.4.19(@types/node@20.19.11)) - "@yext/pages": - specifier: 1.2.9 - version: 1.2.9(@algolia/client-search@5.35.0)(@types/node@20.19.11)(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)(typescript@5.9.2)(vite@5.4.19(@types/node@20.19.11)) "@yext/pages-components": specifier: ^2.0.0 version: 2.0.0(lexical@0.38.2)(mapbox-gl@2.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -500,6 +525,31 @@ importers: version: 5.4.19(@types/node@20.19.11) packages: + "@ai-sdk/gateway@3.0.39": + resolution: + { + integrity: sha512-SeCZBAdDNbWpVUXiYgOAqis22p5MEYfrjRw0hiBa5hM+7sDGYQpMinUjkM8kbPXMkY+AhKLrHleBl+SuqpzlgA==, + } + engines: { node: ">=18" } + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + + "@ai-sdk/provider-utils@4.0.14": + resolution: + { + integrity: sha512-7bzKd9lgiDeXM7O4U4nQ8iTxguAOkg8LZGD9AfDVZYjO5cKYRwBPwVjboFcVrxncRHu0tYxZtXZtiLKpG4pEng==, + } + engines: { node: ">=18" } + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + + "@ai-sdk/provider@3.0.8": + resolution: + { + integrity: sha512-oGMAgGoQdBXbZqNG0Ze56CHjDZ1IDYOwGYxYjO5KLSlz5HiNQ9udIXsPZ61VWaHGZ5XW/jyjmr6t2xz2jGVwbQ==, + } + engines: { node: ">=18" } + "@algolia/abtesting@1.1.0": resolution: { @@ -848,6 +898,70 @@ packages: integrity: sha512-5uL1EIhAlfg0dvWsR1DGfqIsyiPBUsD/qlra15B82Ik28BcH7ScYEHLA4F34fZA0KamlpYcappvt2n1pTuDUfw==, } + "@cloudflare/kv-asset-handler@0.4.2": + resolution: + { + integrity: sha512-SIOD2DxrRRwQ+jgzlXCqoEFiKOFqaPjhnNTGKXSRLvp1HiOvapLaFG2kEr9dYQTYe8rKrd9uvDUzmAITeNyaHQ==, + } + engines: { node: ">=18.0.0" } + + "@cloudflare/unenv-preset@2.12.0": + resolution: + { + integrity: sha512-NK4vN+2Z/GbfGS4BamtbbVk1rcu5RmqaYGiyHJQrA09AoxdZPHDF3W/EhgI0YSK8p3vRo/VNCtbSJFPON7FWMQ==, + } + peerDependencies: + unenv: 2.0.0-rc.24 + workerd: ^1.20260115.0 + peerDependenciesMeta: + workerd: + optional: true + + "@cloudflare/workerd-darwin-64@1.20260205.0": + resolution: + { + integrity: sha512-ToOItqcirmWPwR+PtT+Q4bdjTn/63ZxhJKEfW4FNn7FxMTS1Tw5dml0T0mieOZbCpcvY8BdvPKFCSlJuI8IVHQ==, + } + engines: { node: ">=16" } + cpu: [x64] + os: [darwin] + + "@cloudflare/workerd-darwin-arm64@1.20260205.0": + resolution: + { + integrity: sha512-402ZqLz+LrG0NDXp7Hn7IZbI0DyhjNfjAlVenb0K3yod9KCuux0u3NksNBvqJx0mIGHvVR4K05h+jfT5BTHqGA==, + } + engines: { node: ">=16" } + cpu: [arm64] + os: [darwin] + + "@cloudflare/workerd-linux-64@1.20260205.0": + resolution: + { + integrity: sha512-rz9jBzazIA18RHY+osa19hvsPfr0LZI1AJzIjC6UqkKKphcTpHBEQ25Xt8cIA34ivMIqeENpYnnmpDFesLkfcQ==, + } + engines: { node: ">=16" } + cpu: [x64] + os: [linux] + + "@cloudflare/workerd-linux-arm64@1.20260205.0": + resolution: + { + integrity: sha512-jr6cKpMM/DBEbL+ATJ9rYue758CKp0SfA/nXt5vR32iINVJrb396ye9iat2y9Moa/PgPKnTrFgmT6urUmG3IUg==, + } + engines: { node: ">=16" } + cpu: [arm64] + os: [linux] + + "@cloudflare/workerd-windows-64@1.20260205.0": + resolution: + { + integrity: sha512-SMPW5jCZYOG7XFIglSlsgN8ivcl0pCrSAYxCwxtWvZ88whhcDB/aISNtiQiDZujPH8tIo2hE5dEkxW7tGEwc3A==, + } + engines: { node: ">=16" } + cpu: [x64] + os: [win32] + "@commander-js/extra-typings@13.1.0": resolution: { @@ -1015,6 +1129,12 @@ packages: search-insights: optional: true + "@emnapi/runtime@1.8.1": + resolution: + { + integrity: sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==, + } + "@esbuild/aix-ppc64@0.21.5": resolution: { @@ -1042,6 +1162,15 @@ packages: cpu: [ppc64] os: [aix] + "@esbuild/aix-ppc64@0.27.0": + resolution: + { + integrity: sha512-KuZrd2hRjz01y5JK9mEBSD3Vj3mbCvemhT466rSuJYeE/hjuBrHfjjcjMdTm/sz7au+++sdbJZJmuBwQLuw68A==, + } + engines: { node: ">=18" } + cpu: [ppc64] + os: [aix] + "@esbuild/android-arm64@0.21.5": resolution: { @@ -1069,6 +1198,15 @@ packages: cpu: [arm64] os: [android] + "@esbuild/android-arm64@0.27.0": + resolution: + { + integrity: sha512-CC3vt4+1xZrs97/PKDkl0yN7w8edvU2vZvAFGD16n9F0Cvniy5qvzRXjfO1l94efczkkQE6g1x0i73Qf5uthOQ==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [android] + "@esbuild/android-arm@0.21.5": resolution: { @@ -1096,6 +1234,15 @@ packages: cpu: [arm] os: [android] + "@esbuild/android-arm@0.27.0": + resolution: + { + integrity: sha512-j67aezrPNYWJEOHUNLPj9maeJte7uSMM6gMoxfPC9hOg8N02JuQi/T7ewumf4tNvJadFkvLZMlAq73b9uwdMyQ==, + } + engines: { node: ">=18" } + cpu: [arm] + os: [android] + "@esbuild/android-x64@0.21.5": resolution: { @@ -1123,6 +1270,15 @@ packages: cpu: [x64] os: [android] + "@esbuild/android-x64@0.27.0": + resolution: + { + integrity: sha512-wurMkF1nmQajBO1+0CJmcN17U4BP6GqNSROP8t0X/Jiw2ltYGLHpEksp9MpoBqkrFR3kv2/te6Sha26k3+yZ9Q==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [android] + "@esbuild/darwin-arm64@0.21.5": resolution: { @@ -1150,6 +1306,15 @@ packages: cpu: [arm64] os: [darwin] + "@esbuild/darwin-arm64@0.27.0": + resolution: + { + integrity: sha512-uJOQKYCcHhg07DL7i8MzjvS2LaP7W7Pn/7uA0B5S1EnqAirJtbyw4yC5jQ5qcFjHK9l6o/MX9QisBg12kNkdHg==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [darwin] + "@esbuild/darwin-x64@0.21.5": resolution: { @@ -1177,6 +1342,15 @@ packages: cpu: [x64] os: [darwin] + "@esbuild/darwin-x64@0.27.0": + resolution: + { + integrity: sha512-8mG6arH3yB/4ZXiEnXof5MK72dE6zM9cDvUcPtxhUZsDjESl9JipZYW60C3JGreKCEP+p8P/72r69m4AZGJd5g==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [darwin] + "@esbuild/freebsd-arm64@0.21.5": resolution: { @@ -1204,6 +1378,15 @@ packages: cpu: [arm64] os: [freebsd] + "@esbuild/freebsd-arm64@0.27.0": + resolution: + { + integrity: sha512-9FHtyO988CwNMMOE3YIeci+UV+x5Zy8fI2qHNpsEtSF83YPBmE8UWmfYAQg6Ux7Gsmd4FejZqnEUZCMGaNQHQw==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [freebsd] + "@esbuild/freebsd-x64@0.21.5": resolution: { @@ -1231,6 +1414,15 @@ packages: cpu: [x64] os: [freebsd] + "@esbuild/freebsd-x64@0.27.0": + resolution: + { + integrity: sha512-zCMeMXI4HS/tXvJz8vWGexpZj2YVtRAihHLk1imZj4efx1BQzN76YFeKqlDr3bUWI26wHwLWPd3rwh6pe4EV7g==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [freebsd] + "@esbuild/linux-arm64@0.21.5": resolution: { @@ -1258,6 +1450,15 @@ packages: cpu: [arm64] os: [linux] + "@esbuild/linux-arm64@0.27.0": + resolution: + { + integrity: sha512-AS18v0V+vZiLJyi/4LphvBE+OIX682Pu7ZYNsdUHyUKSoRwdnOsMf6FDekwoAFKej14WAkOef3zAORJgAtXnlQ==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [linux] + "@esbuild/linux-arm@0.21.5": resolution: { @@ -1285,6 +1486,15 @@ packages: cpu: [arm] os: [linux] + "@esbuild/linux-arm@0.27.0": + resolution: + { + integrity: sha512-t76XLQDpxgmq2cNXKTVEB7O7YMb42atj2Re2Haf45HkaUpjM2J0UuJZDuaGbPbamzZ7bawyGFUkodL+zcE+jvQ==, + } + engines: { node: ">=18" } + cpu: [arm] + os: [linux] + "@esbuild/linux-ia32@0.21.5": resolution: { @@ -1312,6 +1522,15 @@ packages: cpu: [ia32] os: [linux] + "@esbuild/linux-ia32@0.27.0": + resolution: + { + integrity: sha512-Mz1jxqm/kfgKkc/KLHC5qIujMvnnarD9ra1cEcrs7qshTUSksPihGrWHVG5+osAIQ68577Zpww7SGapmzSt4Nw==, + } + engines: { node: ">=18" } + cpu: [ia32] + os: [linux] + "@esbuild/linux-loong64@0.21.5": resolution: { @@ -1339,6 +1558,15 @@ packages: cpu: [loong64] os: [linux] + "@esbuild/linux-loong64@0.27.0": + resolution: + { + integrity: sha512-QbEREjdJeIreIAbdG2hLU1yXm1uu+LTdzoq1KCo4G4pFOLlvIspBm36QrQOar9LFduavoWX2msNFAAAY9j4BDg==, + } + engines: { node: ">=18" } + cpu: [loong64] + os: [linux] + "@esbuild/linux-mips64el@0.21.5": resolution: { @@ -1366,6 +1594,15 @@ packages: cpu: [mips64el] os: [linux] + "@esbuild/linux-mips64el@0.27.0": + resolution: + { + integrity: sha512-sJz3zRNe4tO2wxvDpH/HYJilb6+2YJxo/ZNbVdtFiKDufzWq4JmKAiHy9iGoLjAV7r/W32VgaHGkk35cUXlNOg==, + } + engines: { node: ">=18" } + cpu: [mips64el] + os: [linux] + "@esbuild/linux-ppc64@0.21.5": resolution: { @@ -1393,6 +1630,15 @@ packages: cpu: [ppc64] os: [linux] + "@esbuild/linux-ppc64@0.27.0": + resolution: + { + integrity: sha512-z9N10FBD0DCS2dmSABDBb5TLAyF1/ydVb+N4pi88T45efQ/w4ohr/F/QYCkxDPnkhkp6AIpIcQKQ8F0ANoA2JA==, + } + engines: { node: ">=18" } + cpu: [ppc64] + os: [linux] + "@esbuild/linux-riscv64@0.21.5": resolution: { @@ -1420,6 +1666,15 @@ packages: cpu: [riscv64] os: [linux] + "@esbuild/linux-riscv64@0.27.0": + resolution: + { + integrity: sha512-pQdyAIZ0BWIC5GyvVFn5awDiO14TkT/19FTmFcPdDec94KJ1uZcmFs21Fo8auMXzD4Tt+diXu1LW1gHus9fhFQ==, + } + engines: { node: ">=18" } + cpu: [riscv64] + os: [linux] + "@esbuild/linux-s390x@0.21.5": resolution: { @@ -1447,6 +1702,15 @@ packages: cpu: [s390x] os: [linux] + "@esbuild/linux-s390x@0.27.0": + resolution: + { + integrity: sha512-hPlRWR4eIDDEci953RI1BLZitgi5uqcsjKMxwYfmi4LcwyWo2IcRP+lThVnKjNtk90pLS8nKdroXYOqW+QQH+w==, + } + engines: { node: ">=18" } + cpu: [s390x] + os: [linux] + "@esbuild/linux-x64@0.21.5": resolution: { @@ -1474,6 +1738,15 @@ packages: cpu: [x64] os: [linux] + "@esbuild/linux-x64@0.27.0": + resolution: + { + integrity: sha512-1hBWx4OUJE2cab++aVZ7pObD6s+DK4mPGpemtnAORBvb5l/g5xFGk0vc0PjSkrDs0XaXj9yyob3d14XqvnQ4gw==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [linux] + "@esbuild/netbsd-arm64@0.24.2": resolution: { @@ -1492,6 +1765,15 @@ packages: cpu: [arm64] os: [netbsd] + "@esbuild/netbsd-arm64@0.27.0": + resolution: + { + integrity: sha512-6m0sfQfxfQfy1qRuecMkJlf1cIzTOgyaeXaiVaaki8/v+WB+U4hc6ik15ZW6TAllRlg/WuQXxWj1jx6C+dfy3w==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [netbsd] + "@esbuild/netbsd-x64@0.21.5": resolution: { @@ -1519,6 +1801,15 @@ packages: cpu: [x64] os: [netbsd] + "@esbuild/netbsd-x64@0.27.0": + resolution: + { + integrity: sha512-xbbOdfn06FtcJ9d0ShxxvSn2iUsGd/lgPIO2V3VZIPDbEaIj1/3nBBe1AwuEZKXVXkMmpr6LUAgMkLD/4D2PPA==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [netbsd] + "@esbuild/openbsd-arm64@0.24.2": resolution: { @@ -1537,6 +1828,15 @@ packages: cpu: [arm64] os: [openbsd] + "@esbuild/openbsd-arm64@0.27.0": + resolution: + { + integrity: sha512-fWgqR8uNbCQ/GGv0yhzttj6sU/9Z5/Sv/VGU3F5OuXK6J6SlriONKrQ7tNlwBrJZXRYk5jUhuWvF7GYzGguBZQ==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [openbsd] + "@esbuild/openbsd-x64@0.21.5": resolution: { @@ -1564,6 +1864,15 @@ packages: cpu: [x64] os: [openbsd] + "@esbuild/openbsd-x64@0.27.0": + resolution: + { + integrity: sha512-aCwlRdSNMNxkGGqQajMUza6uXzR/U0dIl1QmLjPtRbLOx3Gy3otfFu/VjATy4yQzo9yFDGTxYDo1FfAD9oRD2A==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [openbsd] + "@esbuild/openharmony-arm64@0.25.9": resolution: { @@ -1573,6 +1882,15 @@ packages: cpu: [arm64] os: [openharmony] + "@esbuild/openharmony-arm64@0.27.0": + resolution: + { + integrity: sha512-nyvsBccxNAsNYz2jVFYwEGuRRomqZ149A39SHWk4hV0jWxKM0hjBPm3AmdxcbHiFLbBSwG6SbpIcUbXjgyECfA==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [openharmony] + "@esbuild/sunos-x64@0.21.5": resolution: { @@ -1600,6 +1918,15 @@ packages: cpu: [x64] os: [sunos] + "@esbuild/sunos-x64@0.27.0": + resolution: + { + integrity: sha512-Q1KY1iJafM+UX6CFEL+F4HRTgygmEW568YMqDA5UV97AuZSm21b7SXIrRJDwXWPzr8MGr75fUZPV67FdtMHlHA==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [sunos] + "@esbuild/win32-arm64@0.21.5": resolution: { @@ -1627,6 +1954,15 @@ packages: cpu: [arm64] os: [win32] + "@esbuild/win32-arm64@0.27.0": + resolution: + { + integrity: sha512-W1eyGNi6d+8kOmZIwi/EDjrL9nxQIQ0MiGqe/AWc6+IaHloxHSGoeRgDRKHFISThLmsewZ5nHFvGFWdBYlgKPg==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [win32] + "@esbuild/win32-ia32@0.21.5": resolution: { @@ -1654,6 +1990,15 @@ packages: cpu: [ia32] os: [win32] + "@esbuild/win32-ia32@0.27.0": + resolution: + { + integrity: sha512-30z1aKL9h22kQhilnYkORFYt+3wp7yZsHWus+wSKAJR8JtdfI76LJ4SBdMsCopTR3z/ORqVu5L1vtnHZWVj4cQ==, + } + engines: { node: ">=18" } + cpu: [ia32] + os: [win32] + "@esbuild/win32-x64@0.21.5": resolution: { @@ -1681,6 +2026,15 @@ packages: cpu: [x64] os: [win32] + "@esbuild/win32-x64@0.27.0": + resolution: + { + integrity: sha512-aIitBcjQeyOhMTImhLZmtxfdOcuNRpwlPNmlFKPcHQYPhEssw75Cl1TSXJXpMkzaua9FUetx/4OQKq7eJul5Cg==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [win32] + "@floating-ui/core@1.7.3": resolution: { @@ -1792,6 +2146,218 @@ packages: peerDependencies: react: "*" + "@img/colour@1.0.0": + resolution: + { + integrity: sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==, + } + engines: { node: ">=18" } + + "@img/sharp-darwin-arm64@0.34.5": + resolution: + { + integrity: sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==, + } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } + cpu: [arm64] + os: [darwin] + + "@img/sharp-darwin-x64@0.34.5": + resolution: + { + integrity: sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==, + } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } + cpu: [x64] + os: [darwin] + + "@img/sharp-libvips-darwin-arm64@1.2.4": + resolution: + { + integrity: sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==, + } + cpu: [arm64] + os: [darwin] + + "@img/sharp-libvips-darwin-x64@1.2.4": + resolution: + { + integrity: sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==, + } + cpu: [x64] + os: [darwin] + + "@img/sharp-libvips-linux-arm64@1.2.4": + resolution: + { + integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==, + } + cpu: [arm64] + os: [linux] + + "@img/sharp-libvips-linux-arm@1.2.4": + resolution: + { + integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==, + } + cpu: [arm] + os: [linux] + + "@img/sharp-libvips-linux-ppc64@1.2.4": + resolution: + { + integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==, + } + cpu: [ppc64] + os: [linux] + + "@img/sharp-libvips-linux-riscv64@1.2.4": + resolution: + { + integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==, + } + cpu: [riscv64] + os: [linux] + + "@img/sharp-libvips-linux-s390x@1.2.4": + resolution: + { + integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==, + } + cpu: [s390x] + os: [linux] + + "@img/sharp-libvips-linux-x64@1.2.4": + resolution: + { + integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==, + } + cpu: [x64] + os: [linux] + + "@img/sharp-libvips-linuxmusl-arm64@1.2.4": + resolution: + { + integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==, + } + cpu: [arm64] + os: [linux] + + "@img/sharp-libvips-linuxmusl-x64@1.2.4": + resolution: + { + integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==, + } + cpu: [x64] + os: [linux] + + "@img/sharp-linux-arm64@0.34.5": + resolution: + { + integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==, + } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } + cpu: [arm64] + os: [linux] + + "@img/sharp-linux-arm@0.34.5": + resolution: + { + integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==, + } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } + cpu: [arm] + os: [linux] + + "@img/sharp-linux-ppc64@0.34.5": + resolution: + { + integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==, + } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } + cpu: [ppc64] + os: [linux] + + "@img/sharp-linux-riscv64@0.34.5": + resolution: + { + integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==, + } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } + cpu: [riscv64] + os: [linux] + + "@img/sharp-linux-s390x@0.34.5": + resolution: + { + integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==, + } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } + cpu: [s390x] + os: [linux] + + "@img/sharp-linux-x64@0.34.5": + resolution: + { + integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==, + } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } + cpu: [x64] + os: [linux] + + "@img/sharp-linuxmusl-arm64@0.34.5": + resolution: + { + integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==, + } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } + cpu: [arm64] + os: [linux] + + "@img/sharp-linuxmusl-x64@0.34.5": + resolution: + { + integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==, + } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } + cpu: [x64] + os: [linux] + + "@img/sharp-wasm32@0.34.5": + resolution: + { + integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==, + } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } + cpu: [wasm32] + + "@img/sharp-win32-arm64@0.34.5": + resolution: + { + integrity: sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==, + } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } + cpu: [arm64] + os: [win32] + + "@img/sharp-win32-ia32@0.34.5": + resolution: + { + integrity: sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==, + } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } + cpu: [ia32] + os: [win32] + + "@img/sharp-win32-x64@0.34.5": + resolution: + { + integrity: sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==, + } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } + cpu: [x64] + os: [win32] + "@internationalized/date@3.8.2": resolution: { @@ -2257,6 +2823,13 @@ packages: integrity: sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA==, } + "@opentelemetry/api@1.9.0": + resolution: + { + integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==, + } + engines: { node: ">=8.0.0" } + "@oxlint/darwin-arm64@1.2.0": resolution: { @@ -2361,12 +2934,36 @@ packages: integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==, } + "@poppinss/colors@4.1.6": + resolution: + { + integrity: sha512-H9xkIdFswbS8n1d6vmRd8+c10t2Qe+rZITbbDHHkQixH5+2x1FDGmi/0K+WgWiqQFKPSlIYB7jlH6Kpfn6Fleg==, + } + + "@poppinss/dumper@0.6.5": + resolution: + { + integrity: sha512-NBdYIb90J7LfOI32dOewKI1r7wnkiH6m920puQ3qHUeZkxNkQiFnXVWoE6YtFSv6QOiPPf7ys6i+HWWecDz7sw==, + } + + "@poppinss/exception@1.2.3": + resolution: + { + integrity: sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw==, + } + "@preact/signals-core@1.12.0": resolution: { integrity: sha512-etWpENXm469RHMWIZGblgWrapbIGcRcbccEGGaLkFez3PjlI3XkBrUtSiNFsIfV/DN16PxMOxbWAZUIaLFyJDg==, } + "@puckeditor/cloud-client@0.6.0": + resolution: + { + integrity: sha512-xzTVIhfPFo2Naad+yjIn4mRzhAgyNLzxu33zRiSH0xV5KDLwxR3VnU+4PS6xasj4NW7WN8qr/dgi1SeofeMwpQ==, + } + "@puckeditor/core@0.21.1": resolution: { @@ -2375,6 +2972,15 @@ packages: peerDependencies: react: ^18.0.0 || ^19.0.0 + "@puckeditor/plugin-ai@0.6.0": + resolution: + { + integrity: sha512-VW1mSMBQR2vs3yD+77N0Ll2bt3E8tu42ujHKzy0p7OuJfr5jWG78FG5Pw+VS0Wtij2xhJgUsPhSqU+CvUI5QTw==, + } + peerDependencies: + "@puckeditor/core": ^0.21.0 || 0.21.0-canary.de0baf39 + react: ^18.0.0 || ^19.0.0 + "@radix-ui/primitive@1.1.3": resolution: { @@ -4270,6 +4876,25 @@ packages: integrity: sha512-gwBNIP8ZAYev/ORDWW0QvxdwPXwxBtLsdsJgSc7eDIRt8ubP+rxUBzPsrwnu16fgEF8Bx4lh/+mvQvJzcTM6Kw==, } + "@sindresorhus/is@7.2.0": + resolution: + { + integrity: sha512-P1Cz1dWaFfR4IR+U13mqqiGsLFf1KbayybWwdd2vfctdV6hDpUkgCY0nKOLLTMSoRd/jJNjtbqzf13K8DCCXQw==, + } + engines: { node: ">=18" } + + "@speed-highlight/core@1.2.14": + resolution: + { + integrity: sha512-G4ewlBNhUtlLvrJTb88d2mdy2KRijzs4UhnlrOSRT4bmjh/IqNElZa3zkrZ+TC47TwtlDWzVLFADljF1Ijp5hA==, + } + + "@standard-schema/spec@1.1.0": + resolution: + { + integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==, + } + "@swc/helpers@0.5.17": resolution: { @@ -4655,6 +5280,12 @@ packages: integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==, } + "@types/estree-jsx@1.0.5": + resolution: + { + integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==, + } + "@types/estree@1.0.8": resolution: { @@ -4781,6 +5412,12 @@ packages: integrity: sha512-uug3FEEGv0r+jrecvUUpbY8lLisvIjg6AAic6a2bSP5OEOLeJsDSnvhCDov7ipFFMXS3orMpzlmi0ZcuGkBbow==, } + "@types/node@25.2.1": + resolution: + { + integrity: sha512-CPrnr8voK8vC6eEtyRzvMpgp3VyVRhgclonE7qYi6P9sXwYb59ucfrnmFBTaP0yUi8Gk4yZg/LlTJULGxvTNsg==, + } + "@types/parse5@5.0.3": resolution: { @@ -4931,6 +5568,13 @@ packages: integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==, } + "@vercel/oidc@3.1.0": + resolution: + { + integrity: sha512-Fw28YZpRnA3cAHHDlkt7xQHiJ0fcL+NRcIqsocZQUSmbzeIKRpwttJjik5ZGanXP+vlA4SbTg+AbA3bP363l+w==, + } + engines: { node: ">= 20" } + "@vitejs/plugin-react@4.7.0": resolution: { @@ -5387,6 +6031,15 @@ packages: } engines: { node: ">= 14" } + ai@6.0.78: + resolution: + { + integrity: sha512-eriIX/NLWfWNDeE/OJy8wmIp9fyaH7gnxTOCPT5bp0MNkvORstp1TwRUql9au8XjXzH7o2WApqbwgxJDDV0Rbw==, + } + engines: { node: ">=18" } + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + ajv-draft-04@1.0.0: resolution: { @@ -5623,6 +6276,12 @@ packages: integrity: sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==, } + bail@2.0.2: + resolution: + { + integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==, + } + balanced-match@1.0.2: resolution: { @@ -5635,6 +6294,13 @@ packages: integrity: sha512-AuTJkq9XmE6Vk0FJVNq5QxETrSA/vKHarWVBG5l/JbdCL1prJemiyJqUS0jrlXO0MftuPq4m3YVYhoNc5+aE/g==, } + base64-arraybuffer@1.0.2: + resolution: + { + integrity: sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==, + } + engines: { node: ">= 0.6.0" } + base64-js@1.5.1: resolution: { @@ -5679,6 +6345,12 @@ packages: integrity: sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==, } + blake3-wasm@2.1.5: + resolution: + { + integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==, + } + bluebird@3.7.2: resolution: { @@ -5946,10 +6618,16 @@ packages: integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==, } - character-entities@1.2.4: + character-entities@1.2.4: + resolution: + { + integrity: sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==, + } + + character-entities@2.0.2: resolution: { - integrity: sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==, + integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==, } character-reference-invalid@1.1.4: @@ -5958,6 +6636,12 @@ packages: integrity: sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==, } + character-reference-invalid@2.0.1: + resolution: + { + integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==, + } + check-error@2.1.1: resolution: { @@ -6245,6 +6929,13 @@ packages: } engines: { node: ">= 0.6" } + cookie@1.1.1: + resolution: + { + integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==, + } + engines: { node: ">=18" } + copy-anything@3.0.5: resolution: { @@ -6332,6 +7023,12 @@ packages: } engines: { node: ">= 0.10" } + css-line-break@2.1.0: + resolution: + { + integrity: sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==, + } + csscolorparser@1.0.3: resolution: { @@ -6395,6 +7092,12 @@ packages: integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==, } + decode-named-character-reference@1.3.0: + resolution: + { + integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==, + } + decode-uri-component@0.4.1: resolution: { @@ -6524,6 +7227,13 @@ packages: } engines: { node: ">= 0.8", npm: 1.2.8000 || >= 1.4.16 } + detect-libc@2.1.2: + resolution: + { + integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==, + } + engines: { node: ">=8" } + detect-node-es@1.1.0: resolution: { @@ -6745,6 +7455,12 @@ packages: integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==, } + error-stack-parser-es@1.0.5: + resolution: + { + integrity: sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==, + } + es-define-property@1.0.1: resolution: { @@ -6803,6 +7519,14 @@ packages: engines: { node: ">=18" } hasBin: true + esbuild@0.27.0: + resolution: + { + integrity: sha512-jd0f4NHbD6cALCyGElNpGAOtWxSq46l9X/sWB0Nzd5er4Kz2YTm+Vl0qKFT9KUJvD8+fiO8AvoHhFvEatfVixA==, + } + engines: { node: ">=18" } + hasBin: true + escalade@3.2.0: resolution: { @@ -6846,6 +7570,12 @@ packages: engines: { node: ">=4" } hasBin: true + estree-util-is-identifier-name@3.0.0: + resolution: + { + integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==, + } + estree-walker@2.0.2: resolution: { @@ -6865,6 +7595,12 @@ packages: } engines: { node: ">= 0.6" } + eventemitter3@4.0.7: + resolution: + { + integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==, + } + eventemitter3@5.0.1: resolution: { @@ -6878,6 +7614,13 @@ packages: } engines: { node: ">=0.8.x" } + eventsource-parser@3.0.6: + resolution: + { + integrity: sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==, + } + engines: { node: ">=18.0.0" } + evp_bytestokey@1.0.3: resolution: { @@ -7385,6 +8128,12 @@ packages: integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==, } + hast-util-to-jsx-runtime@2.3.6: + resolution: + { + integrity: sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==, + } + hast-util-to-parse5@6.0.0: resolution: { @@ -7409,6 +8158,13 @@ packages: integrity: sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==, } + hono@4.11.7: + resolution: + { + integrity: sha512-l7qMiNee7t82bH3SeyUCt9UF15EVmaBvsppY2zQtrbIhl/yzBTny+YUxsVjSjQ6gaqaeVtZmGocom8TzBlA4Yw==, + } + engines: { node: ">=16.9.0" } + hookable@5.5.3: resolution: { @@ -7435,6 +8191,12 @@ packages: integrity: sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==, } + html-url-attributes@3.0.1: + resolution: + { + integrity: sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==, + } + html-void-elements@1.0.5: resolution: { @@ -7447,6 +8209,13 @@ packages: integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==, } + html2canvas-pro@1.6.6: + resolution: + { + integrity: sha512-5mRhTXZhv4B0kIcsn3bFBjol2o8vzP35mhtxdXBGPA3V3gZd6Sa2PIIFbT//DiqAX8UuywlcJit5jRKej4nV4Q==, + } + engines: { node: ">=16.0.0" } + http-cache-semantics@4.2.0: resolution: { @@ -7608,6 +8377,12 @@ packages: integrity: sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==, } + inline-style-parser@0.2.7: + resolution: + { + integrity: sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==, + } + intl-messageformat@10.7.16: resolution: { @@ -7634,12 +8409,24 @@ packages: integrity: sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==, } + is-alphabetical@2.0.1: + resolution: + { + integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==, + } + is-alphanumerical@1.0.4: resolution: { integrity: sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==, } + is-alphanumerical@2.0.1: + resolution: + { + integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==, + } + is-arguments@1.2.0: resolution: { @@ -7687,6 +8474,12 @@ packages: integrity: sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==, } + is-decimal@2.0.1: + resolution: + { + integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==, + } + is-docker@3.0.0: resolution: { @@ -7750,6 +8543,12 @@ packages: integrity: sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==, } + is-hexadecimal@2.0.1: + resolution: + { + integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==, + } + is-inside-container@1.0.0: resolution: { @@ -7800,6 +8599,13 @@ packages: } engines: { node: ">=8" } + is-plain-obj@4.1.0: + resolution: + { + integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==, + } + engines: { node: ">=12" } + is-plain-object@2.0.4: resolution: { @@ -8103,6 +8909,12 @@ packages: integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==, } + json-schema@0.4.0: + resolution: + { + integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==, + } + json-stringify-nice@1.1.4: resolution: { @@ -8162,6 +8974,13 @@ packages: } engines: { node: ">=6" } + kleur@4.1.5: + resolution: + { + integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==, + } + engines: { node: ">=6" } + ky@1.9.0: resolution: { @@ -8312,6 +9131,12 @@ packages: integrity: sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==, } + longest-streak@3.1.0: + resolution: + { + integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==, + } + loose-envify@1.4.0: resolution: { @@ -8455,6 +9280,12 @@ packages: integrity: sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==, } + mdast-util-from-markdown@2.0.2: + resolution: + { + integrity: sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==, + } + mdast-util-gfm-autolink-literal@0.1.3: resolution: { @@ -8485,6 +9316,30 @@ packages: integrity: sha512-NNkhDx/qYcuOWB7xHUGWZYVXvjPFFd6afg6/e2g+SV4r9q5XUcCbV4Wfa3DLYIiD+xAEZc6K4MGaE/m0KDcPwQ==, } + mdast-util-mdx-expression@2.0.1: + resolution: + { + integrity: sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==, + } + + mdast-util-mdx-jsx@3.2.0: + resolution: + { + integrity: sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==, + } + + mdast-util-mdxjs-esm@2.0.1: + resolution: + { + integrity: sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==, + } + + mdast-util-phrasing@4.1.0: + resolution: + { + integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==, + } + mdast-util-to-hast@10.2.0: resolution: { @@ -8503,12 +9358,24 @@ packages: integrity: sha512-XeV9sDE7ZlOQvs45C9UKMtfTcctcaj/pGwH8YLbMHoMOXNNCn2LsqVQOqrF1+/NU8lKDAqozme9SCXWyo9oAcQ==, } + mdast-util-to-markdown@2.1.2: + resolution: + { + integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==, + } + mdast-util-to-string@2.0.0: resolution: { integrity: sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==, } + mdast-util-to-string@4.0.0: + resolution: + { + integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==, + } + mdurl@1.0.1: resolution: { @@ -8554,6 +9421,12 @@ packages: } engines: { node: ">= 0.6" } + micromark-core-commonmark@2.0.3: + resolution: + { + integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==, + } + micromark-extension-gfm-autolink-literal@0.5.7: resolution: { @@ -8590,24 +9463,108 @@ packages: integrity: sha512-oVN4zv5/tAIA+l3GbMi7lWeYpJ14oQyJ3uEim20ktYFAcfX1x3LNlFGGlmrZHt7u9YlKExmyJdDGaTt6cMSR/A==, } + micromark-factory-destination@2.0.1: + resolution: + { + integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==, + } + + micromark-factory-label@2.0.1: + resolution: + { + integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==, + } + + micromark-factory-space@2.0.1: + resolution: + { + integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==, + } + + micromark-factory-title@2.0.1: + resolution: + { + integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==, + } + + micromark-factory-whitespace@2.0.1: + resolution: + { + integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==, + } + micromark-util-character@2.1.1: resolution: { integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==, } + micromark-util-chunked@2.0.1: + resolution: + { + integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==, + } + + micromark-util-classify-character@2.0.1: + resolution: + { + integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==, + } + + micromark-util-combine-extensions@2.0.1: + resolution: + { + integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==, + } + + micromark-util-decode-numeric-character-reference@2.0.2: + resolution: + { + integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==, + } + + micromark-util-decode-string@2.0.1: + resolution: + { + integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==, + } + micromark-util-encode@2.0.1: resolution: { integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==, } + micromark-util-html-tag-name@2.0.1: + resolution: + { + integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==, + } + + micromark-util-normalize-identifier@2.0.1: + resolution: + { + integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==, + } + + micromark-util-resolve-all@2.0.1: + resolution: + { + integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==, + } + micromark-util-sanitize-uri@2.0.1: resolution: { integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==, } + micromark-util-subtokenize@2.1.0: + resolution: + { + integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==, + } + micromark-util-symbol@2.0.1: resolution: { @@ -8626,6 +9583,12 @@ packages: integrity: sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==, } + micromark@4.0.2: + resolution: + { + integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==, + } + micromatch@4.0.8: resolution: { @@ -8690,6 +9653,14 @@ packages: } hasBin: true + miniflare@4.20260205.0: + resolution: + { + integrity: sha512-jG1TknEDeFqcq/z5gsOm1rKeg4cNG7ruWxEuiPxl3pnQumavxo8kFpeQC6XKVpAhh2PI9ODGyIYlgd77sTHl5g==, + } + engines: { node: ">=18.0.0" } + hasBin: true + minimalistic-assert@1.0.1: resolution: { @@ -9147,6 +10118,13 @@ packages: engines: { node: ">=8.*" } hasBin: true + p-finally@1.0.0: + resolution: + { + integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==, + } + engines: { node: ">=4" } + p-limit@3.1.0: resolution: { @@ -9168,6 +10146,20 @@ packages: } engines: { node: ">=18" } + p-queue@6.6.2: + resolution: + { + integrity: sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==, + } + engines: { node: ">=8" } + + p-timeout@3.2.0: + resolution: + { + integrity: sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==, + } + engines: { node: ">=8" } + package-json-from-dist@1.0.1: resolution: { @@ -9230,6 +10222,12 @@ packages: integrity: sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==, } + parse-entities@4.0.2: + resolution: + { + integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==, + } + parse-json@5.2.0: resolution: { @@ -9309,6 +10307,12 @@ packages: integrity: sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==, } + path-to-regexp@6.3.0: + resolution: + { + integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==, + } + pathe@2.0.3: resolution: { @@ -9884,6 +10888,12 @@ packages: react: 15.x || 16.x || 17.x || 18.x react-dom: 15.x || 16.x || 17.x || 18.x + qler@0.6.2: + resolution: + { + integrity: sha512-W29Qj+cztc+zCwcTVAHrDLhzweRPScPrCJTn2OKmMFHly+44ipZt6AWNwajYIsAw3MVCtlxv//08esiLvmf1sw==, + } + qs@6.13.0: resolution: { @@ -10090,6 +11100,15 @@ packages: integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==, } + react-markdown@10.1.0: + resolution: + { + integrity: sha512-qKxVopLT/TyA6BX3Ue5NwabOsAzm0Q7kAPwq6L+wWDwisYs7R8vZ0nRXqq6rkueboxpkjvLGU9fWifiX/ZZFxQ==, + } + peerDependencies: + "@types/react": ">=18" + react: ">=18" + react-markdown@6.0.3: resolution: { @@ -10315,12 +11334,24 @@ packages: integrity: sha512-KfexHJCiqvrdBZVbQ6RopMZGwaXz6wFJEfByIuEwGf0arvITHjiKKZ1dpXujjH9KZdm1//XJQwgfnJ3lmXaDPA==, } + remark-parse@11.0.0: + resolution: + { + integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==, + } + remark-parse@9.0.0: resolution: { integrity: sha512-geKatMwSzEXKHuzBNU1z676sGcDcFoChMK38TgdHJNAYfFtsfHDQG7MoJAjs6sgYMqyLduCYWDIWZIxiPeafEw==, } + remark-rehype@11.1.2: + resolution: + { + integrity: sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==, + } + remark-rehype@8.1.0: resolution: { @@ -10572,6 +11603,14 @@ packages: engines: { node: ">=10" } hasBin: true + semver@7.7.4: + resolution: + { + integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==, + } + engines: { node: ">=10" } + hasBin: true + send@0.19.0: resolution: { @@ -10620,6 +11659,13 @@ packages: } engines: { node: ">=8" } + sharp@0.34.5: + resolution: + { + integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==, + } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } + shebang-command@2.0.0: resolution: { @@ -10999,12 +12045,18 @@ packages: { integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==, } - engines: { node: ">=8" } + engines: { node: ">=8" } + + strip-literal@3.0.0: + resolution: + { + integrity: sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==, + } - strip-literal@3.0.0: + style-to-js@1.1.21: resolution: { - integrity: sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==, + integrity: sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==, } style-to-object@0.3.0: @@ -11013,6 +12065,12 @@ packages: integrity: sha512-CzFnRRXhzWIdItT3OmF8SQfWyahHhjq3HwcMNCNLn+N7klOOqPjMeG/4JSu77D7ypZdGvSzvkrbyeTMizz2VrA==, } + style-to-object@1.0.14: + resolution: + { + integrity: sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==, + } + sucrase@3.35.0: resolution: { @@ -11034,6 +12092,13 @@ packages: } engines: { node: ">=16" } + supports-color@10.2.2: + resolution: + { + integrity: sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==, + } + engines: { node: ">=18" } + supports-color@7.2.0: resolution: { @@ -11113,6 +12178,12 @@ packages: integrity: sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==, } + text-segmentation@1.0.3: + resolution: + { + integrity: sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==, + } + thenify-all@1.6.0: resolution: { @@ -11290,6 +12361,12 @@ packages: integrity: sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==, } + trough@2.2.0: + resolution: + { + integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==, + } + ts-interface-checker@0.1.13: resolution: { @@ -11438,6 +12515,13 @@ packages: engines: { node: ">=0.8.0" } hasBin: true + ulid@3.0.2: + resolution: + { + integrity: sha512-yu26mwteFYzBAot7KVMqFGCVpsF6g8wXfJzQUHvu1no3+rRRSFcSV2nKeYvNPLD2J4b08jYBDhHUjeH0ygIl9w==, + } + hasBin: true + ulidx@2.4.1: resolution: { @@ -11459,6 +12543,12 @@ packages: integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==, } + undici-types@7.16.0: + resolution: + { + integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==, + } + undici@6.21.3: resolution: { @@ -11466,6 +12556,25 @@ packages: } engines: { node: ">=18.17" } + undici@7.18.2: + resolution: + { + integrity: sha512-y+8YjDFzWdQlSE9N5nzKMT3g4a5UBX1HKowfdXh0uvAnTaqqwqB92Jt4UXBAeKekDs5IaDKyJFR4X1gYVCgXcw==, + } + engines: { node: ">=20.18.1" } + + unenv@2.0.0-rc.24: + resolution: + { + integrity: sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw==, + } + + unified@11.0.5: + resolution: + { + integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==, + } + unified@9.2.2: resolution: { @@ -11691,6 +12800,14 @@ packages: "@types/react": optional: true + use-stick-to-bottom@1.1.2: + resolution: + { + integrity: sha512-ssUfMNvfH8a8hGLoAt5kcOsjbsVORknon2tbkECuf3EsVucFFBbyXl+Xnv3b58P8ZRuZelzO81fgb6M0eRo8cg==, + } + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + use-sync-external-store@1.5.0: resolution: { @@ -11718,6 +12835,12 @@ packages: } engines: { node: ">= 0.4.0" } + utrie@1.0.2: + resolution: + { + integrity: sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==, + } + uuid@11.0.3: resolution: { @@ -11725,6 +12848,14 @@ packages: } hasBin: true + uuid@3.4.0: + resolution: + { + integrity: sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==, + } + deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. + hasBin: true + uuid@9.0.1: resolution: { @@ -12118,6 +13249,27 @@ packages: integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==, } + workerd@1.20260205.0: + resolution: + { + integrity: sha512-CcMH5clHwrH8VlY7yWS9C/G/C8g9czIz1yU3akMSP9Z3CkEMFSoC3GGdj5G7Alw/PHEeez1+1IrlYger4pwu+w==, + } + engines: { node: ">=16" } + hasBin: true + + wrangler@4.63.0: + resolution: + { + integrity: sha512-+R04jF7Eb8K3KRMSgoXpcIdLb8GC62eoSGusYh1pyrSMm/10E0hbKkd7phMJO4HxXc6R7mOHC5SSoX9eof30Uw==, + } + engines: { node: ">=20.0.0" } + hasBin: true + peerDependencies: + "@cloudflare/workers-types": ^4.20260205.0 + peerDependenciesMeta: + "@cloudflare/workers-types": + optional: true + wrap-ansi@7.0.0: resolution: { @@ -12152,6 +13304,21 @@ packages: } engines: { node: ^18.17.0 || >=20.5.0 } + ws@8.18.0: + resolution: + { + integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==, + } + engines: { node: ">=10.0.0" } + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ">=5.0.2" + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + ws@8.18.3: resolution: { @@ -12235,6 +13402,18 @@ packages: } engines: { node: ">=10" } + youch-core@0.3.3: + resolution: + { + integrity: sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA==, + } + + youch@4.1.0-beta.10: + resolution: + { + integrity: sha512-rLfVLB4FgQneDr0dv1oddCVZmKjcJ6yX6mS4pU82Mq/Dt9a3cLZQ62pDBL4AUO+uVrCvtWz3ZFUL2HFAFJ/BXQ==, + } + zod-package-json@1.2.0: resolution: { @@ -12282,6 +13461,24 @@ packages: } snapshots: + "@ai-sdk/gateway@3.0.39(zod@3.25.76)": + dependencies: + "@ai-sdk/provider": 3.0.8 + "@ai-sdk/provider-utils": 4.0.14(zod@3.25.76) + "@vercel/oidc": 3.1.0 + zod: 3.25.76 + + "@ai-sdk/provider-utils@4.0.14(zod@3.25.76)": + dependencies: + "@ai-sdk/provider": 3.0.8 + "@standard-schema/spec": 1.1.0 + eventsource-parser: 3.0.6 + zod: 3.25.76 + + "@ai-sdk/provider@3.0.8": + dependencies: + json-schema: 0.4.0 + "@algolia/abtesting@1.1.0": dependencies: "@algolia/client-common": 5.35.0 @@ -12561,6 +13758,29 @@ snapshots: "@capsizecss/metrics@3.6.2": {} + "@cloudflare/kv-asset-handler@0.4.2": {} + + "@cloudflare/unenv-preset@2.12.0(unenv@2.0.0-rc.24)(workerd@1.20260205.0)": + dependencies: + unenv: 2.0.0-rc.24 + optionalDependencies: + workerd: 1.20260205.0 + + "@cloudflare/workerd-darwin-64@1.20260205.0": + optional: true + + "@cloudflare/workerd-darwin-arm64@1.20260205.0": + optional: true + + "@cloudflare/workerd-linux-64@1.20260205.0": + optional: true + + "@cloudflare/workerd-linux-arm64@1.20260205.0": + optional: true + + "@cloudflare/workerd-windows-64@1.20260205.0": + optional: true + "@commander-js/extra-typings@13.1.0(commander@13.1.0)": dependencies: commander: 13.1.0 @@ -12687,6 +13907,11 @@ snapshots: transitivePeerDependencies: - "@algolia/client-search" + "@emnapi/runtime@1.8.1": + dependencies: + tslib: 2.8.1 + optional: true + "@esbuild/aix-ppc64@0.21.5": optional: true @@ -12696,6 +13921,9 @@ snapshots: "@esbuild/aix-ppc64@0.25.9": optional: true + "@esbuild/aix-ppc64@0.27.0": + optional: true + "@esbuild/android-arm64@0.21.5": optional: true @@ -12705,6 +13933,9 @@ snapshots: "@esbuild/android-arm64@0.25.9": optional: true + "@esbuild/android-arm64@0.27.0": + optional: true + "@esbuild/android-arm@0.21.5": optional: true @@ -12714,6 +13945,9 @@ snapshots: "@esbuild/android-arm@0.25.9": optional: true + "@esbuild/android-arm@0.27.0": + optional: true + "@esbuild/android-x64@0.21.5": optional: true @@ -12723,6 +13957,9 @@ snapshots: "@esbuild/android-x64@0.25.9": optional: true + "@esbuild/android-x64@0.27.0": + optional: true + "@esbuild/darwin-arm64@0.21.5": optional: true @@ -12732,6 +13969,9 @@ snapshots: "@esbuild/darwin-arm64@0.25.9": optional: true + "@esbuild/darwin-arm64@0.27.0": + optional: true + "@esbuild/darwin-x64@0.21.5": optional: true @@ -12741,6 +13981,9 @@ snapshots: "@esbuild/darwin-x64@0.25.9": optional: true + "@esbuild/darwin-x64@0.27.0": + optional: true + "@esbuild/freebsd-arm64@0.21.5": optional: true @@ -12750,6 +13993,9 @@ snapshots: "@esbuild/freebsd-arm64@0.25.9": optional: true + "@esbuild/freebsd-arm64@0.27.0": + optional: true + "@esbuild/freebsd-x64@0.21.5": optional: true @@ -12759,6 +14005,9 @@ snapshots: "@esbuild/freebsd-x64@0.25.9": optional: true + "@esbuild/freebsd-x64@0.27.0": + optional: true + "@esbuild/linux-arm64@0.21.5": optional: true @@ -12768,6 +14017,9 @@ snapshots: "@esbuild/linux-arm64@0.25.9": optional: true + "@esbuild/linux-arm64@0.27.0": + optional: true + "@esbuild/linux-arm@0.21.5": optional: true @@ -12777,6 +14029,9 @@ snapshots: "@esbuild/linux-arm@0.25.9": optional: true + "@esbuild/linux-arm@0.27.0": + optional: true + "@esbuild/linux-ia32@0.21.5": optional: true @@ -12786,6 +14041,9 @@ snapshots: "@esbuild/linux-ia32@0.25.9": optional: true + "@esbuild/linux-ia32@0.27.0": + optional: true + "@esbuild/linux-loong64@0.21.5": optional: true @@ -12795,6 +14053,9 @@ snapshots: "@esbuild/linux-loong64@0.25.9": optional: true + "@esbuild/linux-loong64@0.27.0": + optional: true + "@esbuild/linux-mips64el@0.21.5": optional: true @@ -12804,6 +14065,9 @@ snapshots: "@esbuild/linux-mips64el@0.25.9": optional: true + "@esbuild/linux-mips64el@0.27.0": + optional: true + "@esbuild/linux-ppc64@0.21.5": optional: true @@ -12813,6 +14077,9 @@ snapshots: "@esbuild/linux-ppc64@0.25.9": optional: true + "@esbuild/linux-ppc64@0.27.0": + optional: true + "@esbuild/linux-riscv64@0.21.5": optional: true @@ -12822,6 +14089,9 @@ snapshots: "@esbuild/linux-riscv64@0.25.9": optional: true + "@esbuild/linux-riscv64@0.27.0": + optional: true + "@esbuild/linux-s390x@0.21.5": optional: true @@ -12831,6 +14101,9 @@ snapshots: "@esbuild/linux-s390x@0.25.9": optional: true + "@esbuild/linux-s390x@0.27.0": + optional: true + "@esbuild/linux-x64@0.21.5": optional: true @@ -12840,12 +14113,18 @@ snapshots: "@esbuild/linux-x64@0.25.9": optional: true + "@esbuild/linux-x64@0.27.0": + optional: true + "@esbuild/netbsd-arm64@0.24.2": optional: true "@esbuild/netbsd-arm64@0.25.9": optional: true + "@esbuild/netbsd-arm64@0.27.0": + optional: true + "@esbuild/netbsd-x64@0.21.5": optional: true @@ -12855,12 +14134,18 @@ snapshots: "@esbuild/netbsd-x64@0.25.9": optional: true + "@esbuild/netbsd-x64@0.27.0": + optional: true + "@esbuild/openbsd-arm64@0.24.2": optional: true "@esbuild/openbsd-arm64@0.25.9": optional: true + "@esbuild/openbsd-arm64@0.27.0": + optional: true + "@esbuild/openbsd-x64@0.21.5": optional: true @@ -12870,9 +14155,15 @@ snapshots: "@esbuild/openbsd-x64@0.25.9": optional: true + "@esbuild/openbsd-x64@0.27.0": + optional: true + "@esbuild/openharmony-arm64@0.25.9": optional: true + "@esbuild/openharmony-arm64@0.27.0": + optional: true + "@esbuild/sunos-x64@0.21.5": optional: true @@ -12882,6 +14173,9 @@ snapshots: "@esbuild/sunos-x64@0.25.9": optional: true + "@esbuild/sunos-x64@0.27.0": + optional: true + "@esbuild/win32-arm64@0.21.5": optional: true @@ -12891,6 +14185,9 @@ snapshots: "@esbuild/win32-arm64@0.25.9": optional: true + "@esbuild/win32-arm64@0.27.0": + optional: true + "@esbuild/win32-ia32@0.21.5": optional: true @@ -12900,6 +14197,9 @@ snapshots: "@esbuild/win32-ia32@0.25.9": optional: true + "@esbuild/win32-ia32@0.27.0": + optional: true + "@esbuild/win32-x64@0.21.5": optional: true @@ -12909,6 +14209,9 @@ snapshots: "@esbuild/win32-x64@0.25.9": optional: true + "@esbuild/win32-x64@0.27.0": + optional: true + "@floating-ui/core@1.7.3": dependencies: "@floating-ui/utils": 0.2.10 @@ -12985,6 +14288,102 @@ snapshots: dependencies: react: 18.3.1 + "@img/colour@1.0.0": {} + + "@img/sharp-darwin-arm64@0.34.5": + optionalDependencies: + "@img/sharp-libvips-darwin-arm64": 1.2.4 + optional: true + + "@img/sharp-darwin-x64@0.34.5": + optionalDependencies: + "@img/sharp-libvips-darwin-x64": 1.2.4 + optional: true + + "@img/sharp-libvips-darwin-arm64@1.2.4": + optional: true + + "@img/sharp-libvips-darwin-x64@1.2.4": + optional: true + + "@img/sharp-libvips-linux-arm64@1.2.4": + optional: true + + "@img/sharp-libvips-linux-arm@1.2.4": + optional: true + + "@img/sharp-libvips-linux-ppc64@1.2.4": + optional: true + + "@img/sharp-libvips-linux-riscv64@1.2.4": + optional: true + + "@img/sharp-libvips-linux-s390x@1.2.4": + optional: true + + "@img/sharp-libvips-linux-x64@1.2.4": + optional: true + + "@img/sharp-libvips-linuxmusl-arm64@1.2.4": + optional: true + + "@img/sharp-libvips-linuxmusl-x64@1.2.4": + optional: true + + "@img/sharp-linux-arm64@0.34.5": + optionalDependencies: + "@img/sharp-libvips-linux-arm64": 1.2.4 + optional: true + + "@img/sharp-linux-arm@0.34.5": + optionalDependencies: + "@img/sharp-libvips-linux-arm": 1.2.4 + optional: true + + "@img/sharp-linux-ppc64@0.34.5": + optionalDependencies: + "@img/sharp-libvips-linux-ppc64": 1.2.4 + optional: true + + "@img/sharp-linux-riscv64@0.34.5": + optionalDependencies: + "@img/sharp-libvips-linux-riscv64": 1.2.4 + optional: true + + "@img/sharp-linux-s390x@0.34.5": + optionalDependencies: + "@img/sharp-libvips-linux-s390x": 1.2.4 + optional: true + + "@img/sharp-linux-x64@0.34.5": + optionalDependencies: + "@img/sharp-libvips-linux-x64": 1.2.4 + optional: true + + "@img/sharp-linuxmusl-arm64@0.34.5": + optionalDependencies: + "@img/sharp-libvips-linuxmusl-arm64": 1.2.4 + optional: true + + "@img/sharp-linuxmusl-x64@0.34.5": + optionalDependencies: + "@img/sharp-libvips-linuxmusl-x64": 1.2.4 + optional: true + + "@img/sharp-wasm32@0.34.5": + dependencies: + "@emnapi/runtime": 1.8.1 + optional: true + + "@img/sharp-win32-arm64@0.34.5": + optional: true + + "@img/sharp-win32-ia32@0.34.5": + optional: true + + "@img/sharp-win32-x64@0.34.5": + optional: true + "@internationalized/date@3.8.2": dependencies: "@swc/helpers": 0.5.17 @@ -13372,6 +14771,8 @@ snapshots: dependencies: "@octokit/openapi-types": 24.2.0 + "@opentelemetry/api@1.9.0": {} + "@oxlint/darwin-arm64@1.2.0": optional: true @@ -13415,8 +14816,22 @@ snapshots: "@popperjs/core@2.11.8": {} + "@poppinss/colors@4.1.6": + dependencies: + kleur: 4.1.5 + + "@poppinss/dumper@0.6.5": + dependencies: + "@poppinss/colors": 4.1.6 + "@sindresorhus/is": 7.2.0 + supports-color: 10.2.2 + + "@poppinss/exception@1.2.3": {} + "@preact/signals-core@1.12.0": {} + "@puckeditor/cloud-client@0.6.0": {} + "@puckeditor/core@0.21.1(@floating-ui/dom@1.7.4)(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(immer@9.0.21)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(use-sync-external-store@1.5.0(react@18.3.1))": dependencies: "@dnd-kit/helpers": 0.1.18 @@ -13462,6 +14877,22 @@ snapshots: - use-sync-external-store - utf-8-validate + "@puckeditor/plugin-ai@0.6.0(@puckeditor/core@0.21.1(@floating-ui/dom@1.7.4)(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(immer@9.0.21)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(use-sync-external-store@1.5.0(react@18.3.1)))(@types/react@18.3.24)(react@18.3.1)(zod@3.25.76)": + dependencies: + "@puckeditor/core": 0.21.1(@floating-ui/dom@1.7.4)(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(immer@9.0.21)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(use-sync-external-store@1.5.0(react@18.3.1)) + ai: 6.0.78(zod@3.25.76) + html2canvas-pro: 1.6.6 + qler: 0.6.2 + react: 18.3.1 + react-markdown: 10.1.0(@types/react@18.3.24)(react@18.3.1) + react-textarea-autosize: 8.5.9(@types/react@18.3.24)(react@18.3.1) + ulid: 3.0.2 + use-stick-to-bottom: 1.1.2(react@18.3.1) + transitivePeerDependencies: + - "@types/react" + - supports-color + - zod + "@radix-ui/primitive@1.1.3": {} "@radix-ui/react-accordion@1.2.12(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)": @@ -15219,6 +16650,12 @@ snapshots: "@sinclair/typebox@0.34.40": {} + "@sindresorhus/is@7.2.0": {} + + "@speed-highlight/core@1.2.14": {} + + "@standard-schema/spec@1.1.0": {} + "@swc/helpers@0.5.17": dependencies: tslib: 2.8.1 @@ -15471,10 +16908,13 @@ snapshots: "@types/debug@4.1.12": dependencies: "@types/ms": 2.1.0 - optional: true "@types/deep-eql@4.0.2": {} + "@types/estree-jsx@1.0.5": + dependencies: + "@types/estree": 1.0.8 + "@types/estree@1.0.8": {} "@types/fs-extra@11.0.4": @@ -15541,12 +16981,15 @@ snapshots: "@types/minimist@1.2.5": {} - "@types/ms@2.1.0": - optional: true + "@types/ms@2.1.0": {} "@types/node@20.19.11": dependencies: - undici-types: 6.21.0 + undici-types: 6.21.0 + + "@types/node@25.2.1": + dependencies: + undici-types: 7.16.0 "@types/parse5@5.0.3": {} @@ -15618,6 +17061,8 @@ snapshots: "@ungap/structured-clone@1.3.0": {} + "@vercel/oidc@3.1.0": {} + "@vitejs/plugin-react@4.7.0(vite@5.4.19(@types/node@20.19.11))": dependencies: "@babel/core": 7.28.3 @@ -16059,6 +17504,14 @@ snapshots: agent-base@7.1.4: {} + ai@6.0.78(zod@3.25.76): + dependencies: + "@ai-sdk/gateway": 3.0.39(zod@3.25.76) + "@ai-sdk/provider": 3.0.8 + "@ai-sdk/provider-utils": 4.0.14(zod@3.25.76) + "@opentelemetry/api": 1.9.0 + zod: 3.25.76 + ajv-draft-04@1.0.0(ajv@8.13.0): optionalDependencies: ajv: 8.13.0 @@ -16191,11 +17644,15 @@ snapshots: bail@1.0.5: {} + bail@2.0.2: {} + balanced-match@1.0.2: {} bare-events@2.6.1: optional: true + base64-arraybuffer@1.0.2: {} + base64-js@1.5.1: {} before-after-hook@2.2.3: {} @@ -16224,6 +17681,8 @@ snapshots: inherits: 2.0.4 readable-stream: 3.6.2 + blake3-wasm@2.1.5: {} + bluebird@3.7.2: {} bn.js@4.12.2: {} @@ -16411,8 +17870,12 @@ snapshots: character-entities@1.2.4: {} + character-entities@2.0.2: {} + character-reference-invalid@1.1.4: {} + character-reference-invalid@2.0.1: {} + check-error@2.1.1: {} chokidar@3.6.0: @@ -16546,6 +18009,8 @@ snapshots: cookie@0.7.1: {} + cookie@1.1.1: {} + copy-anything@3.0.5: dependencies: is-what: 4.1.16 @@ -16623,6 +18088,10 @@ snapshots: randombytes: 2.1.0 randomfill: 1.0.4 + css-line-break@2.1.0: + dependencies: + utrie: 1.0.2 + csscolorparser@1.0.3: {} cssesc@3.0.0: {} @@ -16649,6 +18118,10 @@ snapshots: decimal.js@10.6.0: {} + decode-named-character-reference@1.3.0: + dependencies: + character-entities: 2.0.2 + decode-uri-component@0.4.1: {} deep-diff@1.0.2: {} @@ -16703,6 +18176,8 @@ snapshots: destroy@1.2.0: {} + detect-libc@2.1.2: {} + detect-node-es@1.1.0: {} devlop@1.1.0: @@ -16806,6 +18281,8 @@ snapshots: dependencies: is-arrayish: 0.2.1 + error-stack-parser-es@1.0.5: {} + es-define-property@1.0.1: {} es-errors@1.3.0: {} @@ -16906,6 +18383,35 @@ snapshots: "@esbuild/win32-ia32": 0.25.9 "@esbuild/win32-x64": 0.25.9 + esbuild@0.27.0: + optionalDependencies: + "@esbuild/aix-ppc64": 0.27.0 + "@esbuild/android-arm": 0.27.0 + "@esbuild/android-arm64": 0.27.0 + "@esbuild/android-x64": 0.27.0 + "@esbuild/darwin-arm64": 0.27.0 + "@esbuild/darwin-x64": 0.27.0 + "@esbuild/freebsd-arm64": 0.27.0 + "@esbuild/freebsd-x64": 0.27.0 + "@esbuild/linux-arm": 0.27.0 + "@esbuild/linux-arm64": 0.27.0 + "@esbuild/linux-ia32": 0.27.0 + "@esbuild/linux-loong64": 0.27.0 + "@esbuild/linux-mips64el": 0.27.0 + "@esbuild/linux-ppc64": 0.27.0 + "@esbuild/linux-riscv64": 0.27.0 + "@esbuild/linux-s390x": 0.27.0 + "@esbuild/linux-x64": 0.27.0 + "@esbuild/netbsd-arm64": 0.27.0 + "@esbuild/netbsd-x64": 0.27.0 + "@esbuild/openbsd-arm64": 0.27.0 + "@esbuild/openbsd-x64": 0.27.0 + "@esbuild/openharmony-arm64": 0.27.0 + "@esbuild/sunos-x64": 0.27.0 + "@esbuild/win32-arm64": 0.27.0 + "@esbuild/win32-ia32": 0.27.0 + "@esbuild/win32-x64": 0.27.0 + escalade@3.2.0: {} escape-html@1.0.3: {} @@ -16918,6 +18424,8 @@ snapshots: esprima@4.0.1: {} + estree-util-is-identifier-name@3.0.0: {} + estree-walker@2.0.2: {} estree-walker@3.0.3: @@ -16926,10 +18434,14 @@ snapshots: etag@1.8.1: {} + eventemitter3@4.0.7: {} + eventemitter3@5.0.1: {} events@3.3.0: {} + eventsource-parser@3.0.6: {} + evp_bytestokey@1.0.3: dependencies: md5.js: 1.3.5 @@ -17321,6 +18833,26 @@ snapshots: stringify-entities: 4.0.4 zwitch: 2.0.4 + hast-util-to-jsx-runtime@2.3.6: + dependencies: + "@types/estree": 1.0.8 + "@types/hast": 3.0.4 + "@types/unist": 3.0.3 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + hast-util-whitespace: 3.0.0 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + style-to-js: 1.1.21 + unist-util-position: 5.0.0 + vfile-message: 4.0.3 + transitivePeerDependencies: + - supports-color + hast-util-to-parse5@6.0.0: dependencies: hast-to-hyperscript: 9.0.1 @@ -17347,6 +18879,8 @@ snapshots: minimalistic-assert: 1.0.1 minimalistic-crypto-utils: 1.0.1 + hono@4.11.7: {} + hookable@5.5.3: {} hosted-git-info@8.1.0: @@ -17361,10 +18895,17 @@ snapshots: dependencies: void-elements: 3.1.0 + html-url-attributes@3.0.1: {} + html-void-elements@1.0.5: {} html-void-elements@3.0.0: {} + html2canvas-pro@1.6.6: + dependencies: + css-line-break: 2.1.0 + text-segmentation: 1.0.3 + http-cache-semantics@4.2.0: {} http-errors@2.0.0: @@ -17462,6 +19003,8 @@ snapshots: inline-style-parser@0.1.1: {} + inline-style-parser@0.2.7: {} + intl-messageformat@10.7.16: dependencies: "@formatjs/ecma402-abstract": 2.3.4 @@ -17475,11 +19018,18 @@ snapshots: is-alphabetical@1.0.4: {} + is-alphabetical@2.0.1: {} + is-alphanumerical@1.0.4: dependencies: is-alphabetical: 1.0.4 is-decimal: 1.0.4 + is-alphanumerical@2.0.1: + dependencies: + is-alphabetical: 2.0.1 + is-decimal: 2.0.1 + is-arguments@1.2.0: dependencies: call-bound: 1.0.4 @@ -17501,6 +19051,8 @@ snapshots: is-decimal@1.0.4: {} + is-decimal@2.0.1: {} + is-docker@3.0.0: {} is-extendable@0.1.1: {} @@ -17528,6 +19080,8 @@ snapshots: is-hexadecimal@1.0.4: {} + is-hexadecimal@2.0.1: {} + is-inside-container@1.0.0: dependencies: is-docker: 3.0.0 @@ -17547,6 +19101,8 @@ snapshots: is-plain-obj@2.1.0: {} + is-plain-obj@4.1.0: {} + is-plain-object@2.0.4: dependencies: isobject: 3.0.1 @@ -17730,6 +19286,8 @@ snapshots: json-schema-traverse@1.0.0: {} + json-schema@0.4.0: {} + json-stringify-nice@1.1.4: {} json5@2.2.3: {} @@ -17752,6 +19310,8 @@ snapshots: kleur@3.0.3: {} + kleur@4.1.5: {} + ky@1.9.0: {} latest-version@9.0.0: @@ -17836,6 +19396,8 @@ snapshots: longest-streak@2.0.4: {} + longest-streak@3.1.0: {} + loose-envify@1.4.0: dependencies: js-tokens: 4.0.0 @@ -17956,6 +19518,23 @@ snapshots: transitivePeerDependencies: - supports-color + mdast-util-from-markdown@2.0.2: + dependencies: + "@types/mdast": 4.0.4 + "@types/unist": 3.0.3 + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + mdast-util-to-string: 4.0.0 + micromark: 4.0.2 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-decode-string: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-stringify-position: 4.0.0 + transitivePeerDependencies: + - supports-color + mdast-util-gfm-autolink-literal@0.1.3: dependencies: ccount: 1.1.0 @@ -17987,6 +19566,50 @@ snapshots: transitivePeerDependencies: - supports-color + mdast-util-mdx-expression@2.0.1: + dependencies: + "@types/estree-jsx": 1.0.5 + "@types/hast": 3.0.4 + "@types/mdast": 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx-jsx@3.2.0: + dependencies: + "@types/estree-jsx": 1.0.5 + "@types/hast": 3.0.4 + "@types/mdast": 4.0.4 + "@types/unist": 3.0.3 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + parse-entities: 4.0.2 + stringify-entities: 4.0.4 + unist-util-stringify-position: 4.0.0 + vfile-message: 4.0.3 + transitivePeerDependencies: + - supports-color + + mdast-util-mdxjs-esm@2.0.1: + dependencies: + "@types/estree-jsx": 1.0.5 + "@types/hast": 3.0.4 + "@types/mdast": 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-phrasing@4.1.0: + dependencies: + "@types/mdast": 4.0.4 + unist-util-is: 6.0.0 + mdast-util-to-hast@10.2.0: dependencies: "@types/mdast": 3.0.15 @@ -18019,8 +19642,24 @@ snapshots: repeat-string: 1.6.1 zwitch: 1.0.5 + mdast-util-to-markdown@2.1.2: + dependencies: + "@types/mdast": 4.0.4 + "@types/unist": 3.0.3 + longest-streak: 3.1.0 + mdast-util-phrasing: 4.1.0 + mdast-util-to-string: 4.0.0 + micromark-util-classify-character: 2.0.1 + micromark-util-decode-string: 2.0.1 + unist-util-visit: 5.0.0 + zwitch: 2.0.4 + mdast-util-to-string@2.0.0: {} + mdast-util-to-string@4.0.0: + dependencies: + "@types/mdast": 4.0.4 + mdurl@1.0.1: {} mdurl@2.0.0: {} @@ -18035,6 +19674,25 @@ snapshots: methods@1.1.2: {} + micromark-core-commonmark@2.0.3: + dependencies: + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + micromark-factory-destination: 2.0.1 + micromark-factory-label: 2.0.1 + micromark-factory-space: 2.0.1 + micromark-factory-title: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-html-tag-name: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + micromark-extension-gfm-autolink-literal@0.5.7: dependencies: micromark: 2.11.4 @@ -18072,19 +19730,94 @@ snapshots: transitivePeerDependencies: - supports-color + micromark-factory-destination@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-label@2.0.1: + dependencies: + devlop: 1.1.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-space@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-types: 2.0.2 + + micromark-factory-title@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-whitespace@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + micromark-util-character@2.1.1: dependencies: micromark-util-symbol: 2.0.1 micromark-util-types: 2.0.2 + micromark-util-chunked@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-classify-character@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-combine-extensions@2.0.1: + dependencies: + micromark-util-chunked: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-decode-numeric-character-reference@2.0.2: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-decode-string@2.0.1: + dependencies: + decode-named-character-reference: 1.3.0 + micromark-util-character: 2.1.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-symbol: 2.0.1 + micromark-util-encode@2.0.1: {} + micromark-util-html-tag-name@2.0.1: {} + + micromark-util-normalize-identifier@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-resolve-all@2.0.1: + dependencies: + micromark-util-types: 2.0.2 + micromark-util-sanitize-uri@2.0.1: dependencies: micromark-util-character: 2.1.1 micromark-util-encode: 2.0.1 micromark-util-symbol: 2.0.1 + micromark-util-subtokenize@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + micromark-util-symbol@2.0.1: {} micromark-util-types@2.0.2: {} @@ -18096,6 +19829,28 @@ snapshots: transitivePeerDependencies: - supports-color + micromark@4.0.2: + dependencies: + "@types/debug": 4.1.12 + debug: 4.4.1 + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-combine-extensions: 2.0.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-encode: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + transitivePeerDependencies: + - supports-color + micromatch@4.0.8: dependencies: braces: 3.0.3 @@ -18122,6 +19877,18 @@ snapshots: mini-svg-data-uri@1.4.4: {} + miniflare@4.20260205.0: + dependencies: + "@cspotcode/source-map-support": 0.8.1 + sharp: 0.34.5 + undici: 7.18.2 + workerd: 1.20260205.0 + ws: 8.18.0 + youch: 4.1.0-beta.10 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + minimalistic-assert@1.0.1: {} minimalistic-crypto-utils@1.0.1: {} @@ -18431,6 +20198,8 @@ snapshots: "@oxlint/win32-arm64": 1.2.0 "@oxlint/win32-x64": 1.2.0 + p-finally@1.0.0: {} + p-limit@3.1.0: dependencies: yocto-queue: 0.1.0 @@ -18441,6 +20210,15 @@ snapshots: p-map@7.0.3: {} + p-queue@6.6.2: + dependencies: + eventemitter3: 4.0.7 + p-timeout: 3.2.0 + + p-timeout@3.2.0: + dependencies: + p-finally: 1.0.0 + package-json-from-dist@1.0.1: {} package-json@10.0.1: @@ -18524,6 +20302,16 @@ snapshots: is-decimal: 1.0.4 is-hexadecimal: 1.0.4 + parse-entities@4.0.2: + dependencies: + "@types/unist": 2.0.11 + character-entities-legacy: 3.0.0 + character-reference-invalid: 2.0.1 + decode-named-character-reference: 1.3.0 + is-alphanumerical: 2.0.1 + is-decimal: 2.0.1 + is-hexadecimal: 2.0.1 + parse-json@5.2.0: dependencies: "@babel/code-frame": 7.27.1 @@ -18558,6 +20346,8 @@ snapshots: path-to-regexp@0.1.12: {} + path-to-regexp@6.3.0: {} + pathe@2.0.3: {} pathval@2.0.1: {} @@ -18890,6 +20680,11 @@ snapshots: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) + qler@0.6.2: + dependencies: + p-queue: 6.6.2 + uuid: 3.4.0 + qs@6.13.0: dependencies: side-channel: 1.1.0 @@ -19085,6 +20880,24 @@ snapshots: react-is@18.3.1: {} + react-markdown@10.1.0(@types/react@18.3.24)(react@18.3.1): + dependencies: + "@types/hast": 3.0.4 + "@types/mdast": 4.0.4 + "@types/react": 18.3.24 + devlop: 1.1.0 + hast-util-to-jsx-runtime: 2.3.6 + html-url-attributes: 3.0.1 + mdast-util-to-hast: 13.2.0 + react: 18.3.1 + remark-parse: 11.0.0 + remark-rehype: 11.1.2 + unified: 11.0.5 + unist-util-visit: 5.0.0 + vfile: 6.0.3 + transitivePeerDependencies: + - supports-color + react-markdown@6.0.3(@types/react@18.3.24)(react@18.3.1): dependencies: "@types/hast": 2.3.10 @@ -19272,12 +21085,29 @@ snapshots: transitivePeerDependencies: - supports-color + remark-parse@11.0.0: + dependencies: + "@types/mdast": 4.0.4 + mdast-util-from-markdown: 2.0.2 + micromark-util-types: 2.0.2 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + remark-parse@9.0.0: dependencies: mdast-util-from-markdown: 0.8.5 transitivePeerDependencies: - supports-color + remark-rehype@11.1.2: + dependencies: + "@types/hast": 3.0.4 + "@types/mdast": 4.0.4 + mdast-util-to-hast: 13.2.0 + unified: 11.0.5 + vfile: 6.0.3 + remark-rehype@8.1.0: dependencies: mdast-util-to-hast: 10.2.0 @@ -19415,6 +21245,8 @@ snapshots: semver@7.7.2: {} + semver@7.7.4: {} + send@0.19.0: dependencies: debug: 2.6.9 @@ -19465,6 +21297,37 @@ snapshots: dependencies: kind-of: 6.0.3 + sharp@0.34.5: + dependencies: + "@img/colour": 1.0.0 + detect-libc: 2.1.2 + semver: 7.7.4 + optionalDependencies: + "@img/sharp-darwin-arm64": 0.34.5 + "@img/sharp-darwin-x64": 0.34.5 + "@img/sharp-libvips-darwin-arm64": 1.2.4 + "@img/sharp-libvips-darwin-x64": 1.2.4 + "@img/sharp-libvips-linux-arm": 1.2.4 + "@img/sharp-libvips-linux-arm64": 1.2.4 + "@img/sharp-libvips-linux-ppc64": 1.2.4 + "@img/sharp-libvips-linux-riscv64": 1.2.4 + "@img/sharp-libvips-linux-s390x": 1.2.4 + "@img/sharp-libvips-linux-x64": 1.2.4 + "@img/sharp-libvips-linuxmusl-arm64": 1.2.4 + "@img/sharp-libvips-linuxmusl-x64": 1.2.4 + "@img/sharp-linux-arm": 0.34.5 + "@img/sharp-linux-arm64": 0.34.5 + "@img/sharp-linux-ppc64": 0.34.5 + "@img/sharp-linux-riscv64": 0.34.5 + "@img/sharp-linux-s390x": 0.34.5 + "@img/sharp-linux-x64": 0.34.5 + "@img/sharp-linuxmusl-arm64": 0.34.5 + "@img/sharp-linuxmusl-x64": 0.34.5 + "@img/sharp-wasm32": 0.34.5 + "@img/sharp-win32-arm64": 0.34.5 + "@img/sharp-win32-ia32": 0.34.5 + "@img/sharp-win32-x64": 0.34.5 + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 @@ -19704,10 +21567,18 @@ snapshots: dependencies: js-tokens: 9.0.1 + style-to-js@1.1.21: + dependencies: + style-to-object: 1.0.14 + style-to-object@0.3.0: dependencies: inline-style-parser: 0.1.1 + style-to-object@1.0.14: + dependencies: + inline-style-parser: 0.2.7 + sucrase@3.35.0: dependencies: "@jridgewell/gen-mapping": 0.3.13 @@ -19726,6 +21597,8 @@ snapshots: dependencies: copy-anything: 3.0.5 + supports-color@10.2.2: {} + supports-color@7.2.0: dependencies: has-flag: 4.0.0 @@ -19797,6 +21670,10 @@ snapshots: dependencies: b4a: 1.6.7 + text-segmentation@1.0.3: + dependencies: + utrie: 1.0.2 + thenify-all@1.6.0: dependencies: thenify: 3.3.1 @@ -19882,6 +21759,8 @@ snapshots: trough@1.0.5: {} + trough@2.2.0: {} + ts-interface-checker@0.1.13: {} ts-morph@22.0.0: @@ -19985,6 +21864,8 @@ snapshots: uglify-js@3.19.3: optional: true + ulid@3.0.2: {} + ulidx@2.4.1: dependencies: layerr: 3.0.0 @@ -19995,8 +21876,26 @@ snapshots: undici-types@6.21.0: {} + undici-types@7.16.0: {} + undici@6.21.3: {} + undici@7.18.2: {} + + unenv@2.0.0-rc.24: + dependencies: + pathe: 2.0.3 + + unified@11.0.5: + dependencies: + "@types/unist": 3.0.3 + bail: 2.0.2 + devlop: 1.1.0 + extend: 3.0.2 + is-plain-obj: 4.1.0 + trough: 2.2.0 + vfile: 6.0.3 + unified@9.2.2: dependencies: "@types/unist": 2.0.11 @@ -20129,6 +22028,10 @@ snapshots: optionalDependencies: "@types/react": 18.3.24 + use-stick-to-bottom@1.1.2(react@18.3.1): + dependencies: + react: 18.3.1 + use-sync-external-store@1.5.0(react@18.3.1): dependencies: react: 18.3.1 @@ -20145,8 +22048,14 @@ snapshots: utils-merge@1.0.1: {} + utrie@1.0.2: + dependencies: + base64-arraybuffer: 1.0.2 + uuid@11.0.3: {} + uuid@3.4.0: {} + uuid@9.0.1: {} v8-compile-cache-lib@3.0.1: {} @@ -20501,6 +22410,30 @@ snapshots: wordwrap@1.0.0: {} + workerd@1.20260205.0: + optionalDependencies: + "@cloudflare/workerd-darwin-64": 1.20260205.0 + "@cloudflare/workerd-darwin-arm64": 1.20260205.0 + "@cloudflare/workerd-linux-64": 1.20260205.0 + "@cloudflare/workerd-linux-arm64": 1.20260205.0 + "@cloudflare/workerd-windows-64": 1.20260205.0 + + wrangler@4.63.0: + dependencies: + "@cloudflare/kv-asset-handler": 0.4.2 + "@cloudflare/unenv-preset": 2.12.0(unenv@2.0.0-rc.24)(workerd@1.20260205.0) + blake3-wasm: 2.1.5 + esbuild: 0.27.0 + miniflare: 4.20260205.0 + path-to-regexp: 6.3.0 + unenv: 2.0.0-rc.24 + workerd: 1.20260205.0 + optionalDependencies: + fsevents: 2.3.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + wrap-ansi@7.0.0: dependencies: ansi-styles: 4.3.0 @@ -20526,6 +22459,8 @@ snapshots: imurmurhash: 0.1.4 signal-exit: 4.1.0 + ws@8.18.0: {} + ws@8.18.3: {} wsl-utils@0.1.0: @@ -20550,6 +22485,19 @@ snapshots: yocto-queue@0.1.0: {} + youch-core@0.3.3: + dependencies: + "@poppinss/exception": 1.2.3 + error-stack-parser-es: 1.0.5 + + youch@4.1.0-beta.10: + dependencies: + "@poppinss/colors": 4.1.6 + "@poppinss/dumper": 0.6.5 + "@speed-highlight/core": 1.2.14 + cookie: 1.1.1 + youch-core: 0.3.3 + zod-package-json@1.2.0: dependencies: zod: 3.25.76 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 90cb82bf82..bcd7baec9f 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,3 +1,4 @@ packages: - "packages/visual-editor" + - "packages/puck-ai-backend" - "starter" diff --git a/starter/package.json b/starter/package.json index 4c817404b3..9717bb1404 100644 --- a/starter/package.json +++ b/starter/package.json @@ -7,6 +7,7 @@ "type": "module", "scripts": { "dev": "cd .. && pnpm build && cd ./starter && pages dev --local --no-prod-url --noInit", + "dev:ai": "VITE_ENABLE_AI_PAGE_GENERATION=true pnpm run dev", "dev:stackblitz": "pages dev --local --no-prod-url --noInit", "prod": "pages prod", "build": "pages build", @@ -21,6 +22,8 @@ "@mantine/core": "^7.10.1", "@mantine/hooks": "^7.10.1", "@puckeditor/core": "0.21.1", + "@puckeditor/plugin-ai": "0.6.0", + "@yext/pages": "1.2.9", "@radix-ui/react-accordion": "^1.2.0", "@radix-ui/react-alert-dialog": "^1.0.5", "@radix-ui/react-dropdown-menu": "^2.1.15", @@ -53,7 +56,6 @@ "@types/react": "^18.2.77", "@types/react-dom": "^18.2.25", "@vitejs/plugin-react": "^4.2.1", - "@yext/pages": "1.2.9", "@yext/pages-components": "^2.0.0", "@yext/visual-editor": "workspace:*", "autoprefixer": "^10.4.8", diff --git a/starter/src/templates/dev.tsx b/starter/src/templates/dev.tsx index 459795e7bd..0d05f60507 100644 --- a/starter/src/templates/dev.tsx +++ b/starter/src/templates/dev.tsx @@ -1,4 +1,5 @@ import "@yext/visual-editor/editor.css"; +import "@yext/visual-editor/style.css"; import { GetHeadConfig, GetPath, @@ -23,7 +24,7 @@ import { } from "@yext/visual-editor"; import tailwindConfig from "../../tailwind.config"; import { devTemplateStream } from "../dev.config"; -import React from "react"; +import * as React from "react"; import { SchemaWrapper } from "@yext/pages-components"; export const config = { diff --git a/starter/tailwind.config.ts b/starter/tailwind.config.ts index 8a76441691..05072d153d 100644 --- a/starter/tailwind.config.ts +++ b/starter/tailwind.config.ts @@ -4,7 +4,7 @@ import { defaultThemeTailwindExtensions, defaultThemeConfig, VisualEditorComponentsContentPath, -} from "@yext/visual-editor"; +} from "@yext/visual-editor/tailwind"; export default { content: [ diff --git a/starter/tsconfig.json b/starter/tsconfig.json new file mode 100644 index 0000000000..d0a7242f11 --- /dev/null +++ b/starter/tsconfig.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "target": "ESNext", + "module": "ESNext", + "jsx": "react-jsx", + "moduleResolution": "bundler", + "types": ["vite/client"], + "allowJs": true, + "checkJs": false, + "resolveJsonModule": true, + "skipLibCheck": true + }, + "include": ["src"] +}