sunpeak 0.16.29 → 0.17.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (140) hide show
  1. package/bin/commands/dev.mjs +169 -342
  2. package/bin/commands/inspect.mjs +763 -0
  3. package/bin/commands/new.mjs +2 -2
  4. package/bin/lib/inspect/inspect-config.d.mts +20 -0
  5. package/bin/lib/inspect/inspect-config.mjs +76 -0
  6. package/bin/lib/live/global-setup.mjs +6 -1
  7. package/bin/sunpeak.js +11 -1
  8. package/dist/chatgpt/globals.css +8 -0
  9. package/dist/chatgpt/index.cjs +3 -11
  10. package/dist/chatgpt/index.cjs.map +1 -1
  11. package/dist/chatgpt/index.d.ts +2 -2
  12. package/dist/chatgpt/index.js +4 -8
  13. package/dist/chatgpt/index.js.map +1 -1
  14. package/dist/claude/index.cjs +1 -1
  15. package/dist/claude/index.js +1 -1
  16. package/dist/discovery-Cgoegt62.js +114 -0
  17. package/dist/discovery-Cgoegt62.js.map +1 -0
  18. package/dist/discovery-Clu4uHp1.cjs +161 -0
  19. package/dist/discovery-Clu4uHp1.cjs.map +1 -0
  20. package/dist/index.cjs +1 -4
  21. package/dist/index.cjs.map +1 -1
  22. package/dist/index.js +2 -3
  23. package/dist/index.js.map +1 -1
  24. package/dist/lib/discovery-cli.cjs +1 -1
  25. package/dist/lib/discovery-cli.js +1 -1
  26. package/dist/lib/discovery.d.ts +7 -67
  27. package/dist/lib/index.d.ts +0 -1
  28. package/dist/mcp/index.cjs +34 -23
  29. package/dist/mcp/index.cjs.map +1 -1
  30. package/dist/mcp/index.js +34 -23
  31. package/dist/mcp/index.js.map +1 -1
  32. package/dist/mcp/types.d.ts +5 -0
  33. package/dist/simulator/index.cjs +5 -11
  34. package/dist/simulator/index.cjs.map +1 -1
  35. package/dist/simulator/index.d.ts +4 -2
  36. package/dist/simulator/index.js +5 -8
  37. package/dist/simulator/index.js.map +1 -1
  38. package/dist/simulator/simple-sidebar.d.ts +7 -4
  39. package/dist/simulator/simulator-url.d.ts +8 -0
  40. package/dist/simulator/simulator.d.ts +15 -2
  41. package/dist/simulator/use-mcp-connection.d.ts +19 -0
  42. package/dist/{simulator-DIVvI69i.cjs → simulator-CH9hs0N6.cjs} +129 -21
  43. package/dist/simulator-CH9hs0N6.cjs.map +1 -0
  44. package/dist/{simulator-C7mkK7Sz.js → simulator-Dl8B-Ljb.js} +124 -22
  45. package/dist/simulator-Dl8B-Ljb.js.map +1 -0
  46. package/dist/{simulator-url-BDGD4vZD.cjs → simulator-url-CozKF1jf.cjs} +3 -1
  47. package/dist/simulator-url-CozKF1jf.cjs.map +1 -0
  48. package/dist/{simulator-url-Bkxj43yT.js → simulator-url-KoS_ToP6.js} +3 -1
  49. package/dist/simulator-url-KoS_ToP6.js.map +1 -0
  50. package/dist/style.css +8 -0
  51. package/package.json +11 -3
  52. package/template/dist/albums/albums.html +105 -0
  53. package/template/dist/albums/albums.json +16 -0
  54. package/template/dist/carousel/carousel.html +105 -0
  55. package/template/dist/carousel/carousel.json +16 -0
  56. package/template/dist/map/map.html +3060 -0
  57. package/template/dist/map/map.json +22 -0
  58. package/template/dist/review/review.html +105 -0
  59. package/template/dist/review/review.json +16 -0
  60. package/template/dist/server.js +15 -0
  61. package/template/dist/tools/review-diff.js +50 -0
  62. package/template/dist/tools/review-post.js +50 -0
  63. package/template/dist/tools/review-purchase.js +61 -0
  64. package/template/dist/tools/review.js +31 -0
  65. package/template/dist/tools/show-albums.js +56 -0
  66. package/template/dist/tools/show-carousel.js +41 -0
  67. package/template/dist/tools/show-map.js +47 -0
  68. package/template/node_modules/.vite/deps/_metadata.json +8 -0
  69. package/template/node_modules/.vite/deps/package.json +3 -0
  70. package/template/node_modules/.vite-mcp/deps/@modelcontextprotocol_ext-apps.js +500 -0
  71. package/template/node_modules/.vite-mcp/deps/@modelcontextprotocol_ext-apps.js.map +1 -0
  72. package/template/node_modules/.vite-mcp/deps/@modelcontextprotocol_ext-apps_app-bridge.js +563 -0
  73. package/template/node_modules/.vite-mcp/deps/@modelcontextprotocol_ext-apps_app-bridge.js.map +1 -0
  74. package/template/node_modules/.vite-mcp/deps/@modelcontextprotocol_ext-apps_react.js +575 -0
  75. package/template/node_modules/.vite-mcp/deps/@modelcontextprotocol_ext-apps_react.js.map +1 -0
  76. package/template/node_modules/.vite-mcp/deps/@testing-library_react.js +11363 -0
  77. package/template/node_modules/.vite-mcp/deps/@testing-library_react.js.map +1 -0
  78. package/template/node_modules/.vite-mcp/deps/_metadata.json +130 -0
  79. package/template/node_modules/.vite-mcp/deps/chunk-BoAXSpZd.js +33 -0
  80. package/template/node_modules/.vite-mcp/deps/client-CU1wWud4.js +14385 -0
  81. package/template/node_modules/.vite-mcp/deps/client-CU1wWud4.js.map +1 -0
  82. package/template/node_modules/.vite-mcp/deps/clsx.js +18 -0
  83. package/template/node_modules/.vite-mcp/deps/clsx.js.map +1 -0
  84. package/template/node_modules/.vite-mcp/deps/dist-uWX8WbjY.js +505 -0
  85. package/template/node_modules/.vite-mcp/deps/dist-uWX8WbjY.js.map +1 -0
  86. package/template/node_modules/.vite-mcp/deps/embla-carousel-react.js +1461 -0
  87. package/template/node_modules/.vite-mcp/deps/embla-carousel-react.js.map +1 -0
  88. package/template/node_modules/.vite-mcp/deps/embla-carousel-wheel-gestures.js +536 -0
  89. package/template/node_modules/.vite-mcp/deps/embla-carousel-wheel-gestures.js.map +1 -0
  90. package/template/node_modules/.vite-mcp/deps/magic-string.es-Cklsmr-5.js +1013 -0
  91. package/template/node_modules/.vite-mcp/deps/magic-string.es-Cklsmr-5.js.map +1 -0
  92. package/template/node_modules/.vite-mcp/deps/mapbox-gl.js +46311 -0
  93. package/template/node_modules/.vite-mcp/deps/mapbox-gl.js.map +1 -0
  94. package/template/node_modules/.vite-mcp/deps/package.json +3 -0
  95. package/template/node_modules/.vite-mcp/deps/protocol-CTflwIfG.js +2090 -0
  96. package/template/node_modules/.vite-mcp/deps/protocol-CTflwIfG.js.map +1 -0
  97. package/template/node_modules/.vite-mcp/deps/react-dom.js +186 -0
  98. package/template/node_modules/.vite-mcp/deps/react-dom.js.map +1 -0
  99. package/template/node_modules/.vite-mcp/deps/react-dom_client.js +2 -0
  100. package/template/node_modules/.vite-mcp/deps/react.js +769 -0
  101. package/template/node_modules/.vite-mcp/deps/react.js.map +1 -0
  102. package/template/node_modules/.vite-mcp/deps/react_jsx-dev-runtime.js +205 -0
  103. package/template/node_modules/.vite-mcp/deps/react_jsx-dev-runtime.js.map +1 -0
  104. package/template/node_modules/.vite-mcp/deps/react_jsx-runtime.js +209 -0
  105. package/template/node_modules/.vite-mcp/deps/react_jsx-runtime.js.map +1 -0
  106. package/template/node_modules/.vite-mcp/deps/schemas-NsgmY9QV.js +12157 -0
  107. package/template/node_modules/.vite-mcp/deps/schemas-NsgmY9QV.js.map +1 -0
  108. package/template/node_modules/.vite-mcp/deps/tailwind-merge.js +2025 -0
  109. package/template/node_modules/.vite-mcp/deps/tailwind-merge.js.map +1 -0
  110. package/template/node_modules/.vite-mcp/deps/vitest.js +14021 -0
  111. package/template/node_modules/.vite-mcp/deps/vitest.js.map +1 -0
  112. package/template/node_modules/.vite-mcp/deps/zod.js +624 -0
  113. package/template/node_modules/.vite-mcp/deps/zod.js.map +1 -0
  114. package/template/src/tools/review-diff.test.ts +5 -1
  115. package/template/src/tools/review-diff.ts +1 -1
  116. package/template/src/tools/review-post.test.ts +5 -1
  117. package/template/src/tools/review-post.ts +1 -1
  118. package/template/src/tools/review-purchase.test.ts +5 -1
  119. package/template/src/tools/review-purchase.ts +1 -1
  120. package/template/src/tools/review.test.ts +5 -1
  121. package/template/src/tools/review.ts +1 -1
  122. package/template/src/tools/show-albums.test.ts +5 -1
  123. package/template/src/tools/show-albums.ts +1 -1
  124. package/template/src/tools/show-carousel.test.ts +5 -1
  125. package/template/src/tools/show-carousel.ts +1 -1
  126. package/template/src/tools/show-map.test.ts +5 -1
  127. package/template/src/tools/show-map.ts +1 -1
  128. package/dist/discovery-BxKCIgG5.cjs +0 -332
  129. package/dist/discovery-BxKCIgG5.cjs.map +0 -1
  130. package/dist/discovery-Du4LHrih.js +0 -261
  131. package/dist/discovery-Du4LHrih.js.map +0 -1
  132. package/dist/simulator-C7mkK7Sz.js.map +0 -1
  133. package/dist/simulator-DIVvI69i.cjs.map +0 -1
  134. package/dist/simulator-url-BDGD4vZD.cjs.map +0 -1
  135. package/dist/simulator-url-Bkxj43yT.js.map +0 -1
  136. package/template/.sunpeak/dev.tsx +0 -79
  137. package/template/.sunpeak/resource-loader.html +0 -20
  138. package/template/.sunpeak/resource-loader.tsx +0 -57
  139. package/template/index.html +0 -14
  140. package/template/src/resources/index.ts +0 -17
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zod.js","names":["core.config","_schemas","_checks","_iso","string","core._coercedString","schemas.ZodString","number","core._coercedNumber","schemas.ZodNumber","boolean","core._coercedBoolean","schemas.ZodBoolean","bigint","core._coercedBigint","schemas.ZodBigInt","date","core._coercedDate","schemas.ZodDate","en","z"],"sources":["../../../../../../node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/classic/compat.js","../../../../../../node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/classic/from-json-schema.js","../../../../../../node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/classic/coerce.js","../../../../../../node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/classic/external.js","../../../../../../node_modules/.pnpm/zod@4.3.6/node_modules/zod/index.js"],"sourcesContent":["// Zod 3 compat layer\nimport * as core from \"../core/index.js\";\n/** @deprecated Use the raw string literal codes instead, e.g. \"invalid_type\". */\nexport const ZodIssueCode = {\n invalid_type: \"invalid_type\",\n too_big: \"too_big\",\n too_small: \"too_small\",\n invalid_format: \"invalid_format\",\n not_multiple_of: \"not_multiple_of\",\n unrecognized_keys: \"unrecognized_keys\",\n invalid_union: \"invalid_union\",\n invalid_key: \"invalid_key\",\n invalid_element: \"invalid_element\",\n invalid_value: \"invalid_value\",\n custom: \"custom\",\n};\nexport { $brand, config } from \"../core/index.js\";\n/** @deprecated Use `z.config(params)` instead. */\nexport function setErrorMap(map) {\n core.config({\n customError: map,\n });\n}\n/** @deprecated Use `z.config()` instead. */\nexport function getErrorMap() {\n return core.config().customError;\n}\n/** @deprecated Do not use. Stub definition, only included for zod-to-json-schema compatibility. */\nexport var ZodFirstPartyTypeKind;\n(function (ZodFirstPartyTypeKind) {\n})(ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {}));\n","import { globalRegistry } from \"../core/registries.js\";\nimport * as _checks from \"./checks.js\";\nimport * as _iso from \"./iso.js\";\nimport * as _schemas from \"./schemas.js\";\n// Local z object to avoid circular dependency with ../index.js\nconst z = {\n ..._schemas,\n ..._checks,\n iso: _iso,\n};\n// Keys that are recognized and handled by the conversion logic\nconst RECOGNIZED_KEYS = new Set([\n // Schema identification\n \"$schema\",\n \"$ref\",\n \"$defs\",\n \"definitions\",\n // Core schema keywords\n \"$id\",\n \"id\",\n \"$comment\",\n \"$anchor\",\n \"$vocabulary\",\n \"$dynamicRef\",\n \"$dynamicAnchor\",\n // Type\n \"type\",\n \"enum\",\n \"const\",\n // Composition\n \"anyOf\",\n \"oneOf\",\n \"allOf\",\n \"not\",\n // Object\n \"properties\",\n \"required\",\n \"additionalProperties\",\n \"patternProperties\",\n \"propertyNames\",\n \"minProperties\",\n \"maxProperties\",\n // Array\n \"items\",\n \"prefixItems\",\n \"additionalItems\",\n \"minItems\",\n \"maxItems\",\n \"uniqueItems\",\n \"contains\",\n \"minContains\",\n \"maxContains\",\n // String\n \"minLength\",\n \"maxLength\",\n \"pattern\",\n \"format\",\n // Number\n \"minimum\",\n \"maximum\",\n \"exclusiveMinimum\",\n \"exclusiveMaximum\",\n \"multipleOf\",\n // Already handled metadata\n \"description\",\n \"default\",\n // Content\n \"contentEncoding\",\n \"contentMediaType\",\n \"contentSchema\",\n // Unsupported (error-throwing)\n \"unevaluatedItems\",\n \"unevaluatedProperties\",\n \"if\",\n \"then\",\n \"else\",\n \"dependentSchemas\",\n \"dependentRequired\",\n // OpenAPI\n \"nullable\",\n \"readOnly\",\n]);\nfunction detectVersion(schema, defaultTarget) {\n const $schema = schema.$schema;\n if ($schema === \"https://json-schema.org/draft/2020-12/schema\") {\n return \"draft-2020-12\";\n }\n if ($schema === \"http://json-schema.org/draft-07/schema#\") {\n return \"draft-7\";\n }\n if ($schema === \"http://json-schema.org/draft-04/schema#\") {\n return \"draft-4\";\n }\n // Use defaultTarget if provided, otherwise default to draft-2020-12\n return defaultTarget ?? \"draft-2020-12\";\n}\nfunction resolveRef(ref, ctx) {\n if (!ref.startsWith(\"#\")) {\n throw new Error(\"External $ref is not supported, only local refs (#/...) are allowed\");\n }\n const path = ref.slice(1).split(\"/\").filter(Boolean);\n // Handle root reference \"#\"\n if (path.length === 0) {\n return ctx.rootSchema;\n }\n const defsKey = ctx.version === \"draft-2020-12\" ? \"$defs\" : \"definitions\";\n if (path[0] === defsKey) {\n const key = path[1];\n if (!key || !ctx.defs[key]) {\n throw new Error(`Reference not found: ${ref}`);\n }\n return ctx.defs[key];\n }\n throw new Error(`Reference not found: ${ref}`);\n}\nfunction convertBaseSchema(schema, ctx) {\n // Handle unsupported features\n if (schema.not !== undefined) {\n // Special case: { not: {} } represents never\n if (typeof schema.not === \"object\" && Object.keys(schema.not).length === 0) {\n return z.never();\n }\n throw new Error(\"not is not supported in Zod (except { not: {} } for never)\");\n }\n if (schema.unevaluatedItems !== undefined) {\n throw new Error(\"unevaluatedItems is not supported\");\n }\n if (schema.unevaluatedProperties !== undefined) {\n throw new Error(\"unevaluatedProperties is not supported\");\n }\n if (schema.if !== undefined || schema.then !== undefined || schema.else !== undefined) {\n throw new Error(\"Conditional schemas (if/then/else) are not supported\");\n }\n if (schema.dependentSchemas !== undefined || schema.dependentRequired !== undefined) {\n throw new Error(\"dependentSchemas and dependentRequired are not supported\");\n }\n // Handle $ref\n if (schema.$ref) {\n const refPath = schema.$ref;\n if (ctx.refs.has(refPath)) {\n return ctx.refs.get(refPath);\n }\n if (ctx.processing.has(refPath)) {\n // Circular reference - use lazy\n return z.lazy(() => {\n if (!ctx.refs.has(refPath)) {\n throw new Error(`Circular reference not resolved: ${refPath}`);\n }\n return ctx.refs.get(refPath);\n });\n }\n ctx.processing.add(refPath);\n const resolved = resolveRef(refPath, ctx);\n const zodSchema = convertSchema(resolved, ctx);\n ctx.refs.set(refPath, zodSchema);\n ctx.processing.delete(refPath);\n return zodSchema;\n }\n // Handle enum\n if (schema.enum !== undefined) {\n const enumValues = schema.enum;\n // Special case: OpenAPI 3.0 null representation { type: \"string\", nullable: true, enum: [null] }\n if (ctx.version === \"openapi-3.0\" &&\n schema.nullable === true &&\n enumValues.length === 1 &&\n enumValues[0] === null) {\n return z.null();\n }\n if (enumValues.length === 0) {\n return z.never();\n }\n if (enumValues.length === 1) {\n return z.literal(enumValues[0]);\n }\n // Check if all values are strings\n if (enumValues.every((v) => typeof v === \"string\")) {\n return z.enum(enumValues);\n }\n // Mixed types - use union of literals\n const literalSchemas = enumValues.map((v) => z.literal(v));\n if (literalSchemas.length < 2) {\n return literalSchemas[0];\n }\n return z.union([literalSchemas[0], literalSchemas[1], ...literalSchemas.slice(2)]);\n }\n // Handle const\n if (schema.const !== undefined) {\n return z.literal(schema.const);\n }\n // Handle type\n const type = schema.type;\n if (Array.isArray(type)) {\n // Expand type array into anyOf union\n const typeSchemas = type.map((t) => {\n const typeSchema = { ...schema, type: t };\n return convertBaseSchema(typeSchema, ctx);\n });\n if (typeSchemas.length === 0) {\n return z.never();\n }\n if (typeSchemas.length === 1) {\n return typeSchemas[0];\n }\n return z.union(typeSchemas);\n }\n if (!type) {\n // No type specified - empty schema (any)\n return z.any();\n }\n let zodSchema;\n switch (type) {\n case \"string\": {\n let stringSchema = z.string();\n // Apply format using .check() with Zod format functions\n if (schema.format) {\n const format = schema.format;\n // Map common formats to Zod check functions\n if (format === \"email\") {\n stringSchema = stringSchema.check(z.email());\n }\n else if (format === \"uri\" || format === \"uri-reference\") {\n stringSchema = stringSchema.check(z.url());\n }\n else if (format === \"uuid\" || format === \"guid\") {\n stringSchema = stringSchema.check(z.uuid());\n }\n else if (format === \"date-time\") {\n stringSchema = stringSchema.check(z.iso.datetime());\n }\n else if (format === \"date\") {\n stringSchema = stringSchema.check(z.iso.date());\n }\n else if (format === \"time\") {\n stringSchema = stringSchema.check(z.iso.time());\n }\n else if (format === \"duration\") {\n stringSchema = stringSchema.check(z.iso.duration());\n }\n else if (format === \"ipv4\") {\n stringSchema = stringSchema.check(z.ipv4());\n }\n else if (format === \"ipv6\") {\n stringSchema = stringSchema.check(z.ipv6());\n }\n else if (format === \"mac\") {\n stringSchema = stringSchema.check(z.mac());\n }\n else if (format === \"cidr\") {\n stringSchema = stringSchema.check(z.cidrv4());\n }\n else if (format === \"cidr-v6\") {\n stringSchema = stringSchema.check(z.cidrv6());\n }\n else if (format === \"base64\") {\n stringSchema = stringSchema.check(z.base64());\n }\n else if (format === \"base64url\") {\n stringSchema = stringSchema.check(z.base64url());\n }\n else if (format === \"e164\") {\n stringSchema = stringSchema.check(z.e164());\n }\n else if (format === \"jwt\") {\n stringSchema = stringSchema.check(z.jwt());\n }\n else if (format === \"emoji\") {\n stringSchema = stringSchema.check(z.emoji());\n }\n else if (format === \"nanoid\") {\n stringSchema = stringSchema.check(z.nanoid());\n }\n else if (format === \"cuid\") {\n stringSchema = stringSchema.check(z.cuid());\n }\n else if (format === \"cuid2\") {\n stringSchema = stringSchema.check(z.cuid2());\n }\n else if (format === \"ulid\") {\n stringSchema = stringSchema.check(z.ulid());\n }\n else if (format === \"xid\") {\n stringSchema = stringSchema.check(z.xid());\n }\n else if (format === \"ksuid\") {\n stringSchema = stringSchema.check(z.ksuid());\n }\n // Note: json-string format is not currently supported by Zod\n // Custom formats are ignored - keep as plain string\n }\n // Apply constraints\n if (typeof schema.minLength === \"number\") {\n stringSchema = stringSchema.min(schema.minLength);\n }\n if (typeof schema.maxLength === \"number\") {\n stringSchema = stringSchema.max(schema.maxLength);\n }\n if (schema.pattern) {\n // JSON Schema patterns are not implicitly anchored (match anywhere in string)\n stringSchema = stringSchema.regex(new RegExp(schema.pattern));\n }\n zodSchema = stringSchema;\n break;\n }\n case \"number\":\n case \"integer\": {\n let numberSchema = type === \"integer\" ? z.number().int() : z.number();\n // Apply constraints\n if (typeof schema.minimum === \"number\") {\n numberSchema = numberSchema.min(schema.minimum);\n }\n if (typeof schema.maximum === \"number\") {\n numberSchema = numberSchema.max(schema.maximum);\n }\n if (typeof schema.exclusiveMinimum === \"number\") {\n numberSchema = numberSchema.gt(schema.exclusiveMinimum);\n }\n else if (schema.exclusiveMinimum === true && typeof schema.minimum === \"number\") {\n numberSchema = numberSchema.gt(schema.minimum);\n }\n if (typeof schema.exclusiveMaximum === \"number\") {\n numberSchema = numberSchema.lt(schema.exclusiveMaximum);\n }\n else if (schema.exclusiveMaximum === true && typeof schema.maximum === \"number\") {\n numberSchema = numberSchema.lt(schema.maximum);\n }\n if (typeof schema.multipleOf === \"number\") {\n numberSchema = numberSchema.multipleOf(schema.multipleOf);\n }\n zodSchema = numberSchema;\n break;\n }\n case \"boolean\": {\n zodSchema = z.boolean();\n break;\n }\n case \"null\": {\n zodSchema = z.null();\n break;\n }\n case \"object\": {\n const shape = {};\n const properties = schema.properties || {};\n const requiredSet = new Set(schema.required || []);\n // Convert properties - mark optional ones\n for (const [key, propSchema] of Object.entries(properties)) {\n const propZodSchema = convertSchema(propSchema, ctx);\n // If not in required array, make it optional\n shape[key] = requiredSet.has(key) ? propZodSchema : propZodSchema.optional();\n }\n // Handle propertyNames\n if (schema.propertyNames) {\n const keySchema = convertSchema(schema.propertyNames, ctx);\n const valueSchema = schema.additionalProperties && typeof schema.additionalProperties === \"object\"\n ? convertSchema(schema.additionalProperties, ctx)\n : z.any();\n // Case A: No properties (pure record)\n if (Object.keys(shape).length === 0) {\n zodSchema = z.record(keySchema, valueSchema);\n break;\n }\n // Case B: With properties (intersection of object and looseRecord)\n const objectSchema = z.object(shape).passthrough();\n const recordSchema = z.looseRecord(keySchema, valueSchema);\n zodSchema = z.intersection(objectSchema, recordSchema);\n break;\n }\n // Handle patternProperties\n if (schema.patternProperties) {\n // patternProperties: keys matching pattern must satisfy corresponding schema\n // Use loose records so non-matching keys pass through\n const patternProps = schema.patternProperties;\n const patternKeys = Object.keys(patternProps);\n const looseRecords = [];\n for (const pattern of patternKeys) {\n const patternValue = convertSchema(patternProps[pattern], ctx);\n const keySchema = z.string().regex(new RegExp(pattern));\n looseRecords.push(z.looseRecord(keySchema, patternValue));\n }\n // Build intersection: object schema + all pattern property records\n const schemasToIntersect = [];\n if (Object.keys(shape).length > 0) {\n // Use passthrough so patternProperties can validate additional keys\n schemasToIntersect.push(z.object(shape).passthrough());\n }\n schemasToIntersect.push(...looseRecords);\n if (schemasToIntersect.length === 0) {\n zodSchema = z.object({}).passthrough();\n }\n else if (schemasToIntersect.length === 1) {\n zodSchema = schemasToIntersect[0];\n }\n else {\n // Chain intersections: (A & B) & C & D ...\n let result = z.intersection(schemasToIntersect[0], schemasToIntersect[1]);\n for (let i = 2; i < schemasToIntersect.length; i++) {\n result = z.intersection(result, schemasToIntersect[i]);\n }\n zodSchema = result;\n }\n break;\n }\n // Handle additionalProperties\n // In JSON Schema, additionalProperties defaults to true (allow any extra properties)\n // In Zod, objects strip unknown keys by default, so we need to handle this explicitly\n const objectSchema = z.object(shape);\n if (schema.additionalProperties === false) {\n // Strict mode - no extra properties allowed\n zodSchema = objectSchema.strict();\n }\n else if (typeof schema.additionalProperties === \"object\") {\n // Extra properties must match the specified schema\n zodSchema = objectSchema.catchall(convertSchema(schema.additionalProperties, ctx));\n }\n else {\n // additionalProperties is true or undefined - allow any extra properties (passthrough)\n zodSchema = objectSchema.passthrough();\n }\n break;\n }\n case \"array\": {\n // TODO: uniqueItems is not supported\n // TODO: contains/minContains/maxContains are not supported\n // Check if this is a tuple (prefixItems or items as array)\n const prefixItems = schema.prefixItems;\n const items = schema.items;\n if (prefixItems && Array.isArray(prefixItems)) {\n // Tuple with prefixItems (draft-2020-12)\n const tupleItems = prefixItems.map((item) => convertSchema(item, ctx));\n const rest = items && typeof items === \"object\" && !Array.isArray(items)\n ? convertSchema(items, ctx)\n : undefined;\n if (rest) {\n zodSchema = z.tuple(tupleItems).rest(rest);\n }\n else {\n zodSchema = z.tuple(tupleItems);\n }\n // Apply minItems/maxItems constraints to tuples\n if (typeof schema.minItems === \"number\") {\n zodSchema = zodSchema.check(z.minLength(schema.minItems));\n }\n if (typeof schema.maxItems === \"number\") {\n zodSchema = zodSchema.check(z.maxLength(schema.maxItems));\n }\n }\n else if (Array.isArray(items)) {\n // Tuple with items array (draft-7)\n const tupleItems = items.map((item) => convertSchema(item, ctx));\n const rest = schema.additionalItems && typeof schema.additionalItems === \"object\"\n ? convertSchema(schema.additionalItems, ctx)\n : undefined; // additionalItems: false means no rest, handled by default tuple behavior\n if (rest) {\n zodSchema = z.tuple(tupleItems).rest(rest);\n }\n else {\n zodSchema = z.tuple(tupleItems);\n }\n // Apply minItems/maxItems constraints to tuples\n if (typeof schema.minItems === \"number\") {\n zodSchema = zodSchema.check(z.minLength(schema.minItems));\n }\n if (typeof schema.maxItems === \"number\") {\n zodSchema = zodSchema.check(z.maxLength(schema.maxItems));\n }\n }\n else if (items !== undefined) {\n // Regular array\n const element = convertSchema(items, ctx);\n let arraySchema = z.array(element);\n // Apply constraints\n if (typeof schema.minItems === \"number\") {\n arraySchema = arraySchema.min(schema.minItems);\n }\n if (typeof schema.maxItems === \"number\") {\n arraySchema = arraySchema.max(schema.maxItems);\n }\n zodSchema = arraySchema;\n }\n else {\n // No items specified - array of any\n zodSchema = z.array(z.any());\n }\n break;\n }\n default:\n throw new Error(`Unsupported type: ${type}`);\n }\n // Apply metadata\n if (schema.description) {\n zodSchema = zodSchema.describe(schema.description);\n }\n if (schema.default !== undefined) {\n zodSchema = zodSchema.default(schema.default);\n }\n return zodSchema;\n}\nfunction convertSchema(schema, ctx) {\n if (typeof schema === \"boolean\") {\n return schema ? z.any() : z.never();\n }\n // Convert base schema first (ignoring composition keywords)\n let baseSchema = convertBaseSchema(schema, ctx);\n const hasExplicitType = schema.type || schema.enum !== undefined || schema.const !== undefined;\n // Process composition keywords LAST (they can appear together)\n // Handle anyOf - wrap base schema with union\n if (schema.anyOf && Array.isArray(schema.anyOf)) {\n const options = schema.anyOf.map((s) => convertSchema(s, ctx));\n const anyOfUnion = z.union(options);\n baseSchema = hasExplicitType ? z.intersection(baseSchema, anyOfUnion) : anyOfUnion;\n }\n // Handle oneOf - exclusive union (exactly one must match)\n if (schema.oneOf && Array.isArray(schema.oneOf)) {\n const options = schema.oneOf.map((s) => convertSchema(s, ctx));\n const oneOfUnion = z.xor(options);\n baseSchema = hasExplicitType ? z.intersection(baseSchema, oneOfUnion) : oneOfUnion;\n }\n // Handle allOf - wrap base schema with intersection\n if (schema.allOf && Array.isArray(schema.allOf)) {\n if (schema.allOf.length === 0) {\n baseSchema = hasExplicitType ? baseSchema : z.any();\n }\n else {\n let result = hasExplicitType ? baseSchema : convertSchema(schema.allOf[0], ctx);\n const startIdx = hasExplicitType ? 0 : 1;\n for (let i = startIdx; i < schema.allOf.length; i++) {\n result = z.intersection(result, convertSchema(schema.allOf[i], ctx));\n }\n baseSchema = result;\n }\n }\n // Handle nullable (OpenAPI 3.0)\n if (schema.nullable === true && ctx.version === \"openapi-3.0\") {\n baseSchema = z.nullable(baseSchema);\n }\n // Handle readOnly\n if (schema.readOnly === true) {\n baseSchema = z.readonly(baseSchema);\n }\n // Collect metadata: core schema keywords and unrecognized keys\n const extraMeta = {};\n // Core schema keywords that should be captured as metadata\n const coreMetadataKeys = [\"$id\", \"id\", \"$comment\", \"$anchor\", \"$vocabulary\", \"$dynamicRef\", \"$dynamicAnchor\"];\n for (const key of coreMetadataKeys) {\n if (key in schema) {\n extraMeta[key] = schema[key];\n }\n }\n // Content keywords - store as metadata\n const contentMetadataKeys = [\"contentEncoding\", \"contentMediaType\", \"contentSchema\"];\n for (const key of contentMetadataKeys) {\n if (key in schema) {\n extraMeta[key] = schema[key];\n }\n }\n // Unrecognized keys (custom metadata)\n for (const key of Object.keys(schema)) {\n if (!RECOGNIZED_KEYS.has(key)) {\n extraMeta[key] = schema[key];\n }\n }\n if (Object.keys(extraMeta).length > 0) {\n ctx.registry.add(baseSchema, extraMeta);\n }\n return baseSchema;\n}\n/**\n * Converts a JSON Schema to a Zod schema. This function should be considered semi-experimental. It's behavior is liable to change. */\nexport function fromJSONSchema(schema, params) {\n // Handle boolean schemas\n if (typeof schema === \"boolean\") {\n return schema ? z.any() : z.never();\n }\n const version = detectVersion(schema, params?.defaultTarget);\n const defs = (schema.$defs || schema.definitions || {});\n const ctx = {\n version,\n defs,\n refs: new Map(),\n processing: new Set(),\n rootSchema: schema,\n registry: params?.registry ?? globalRegistry,\n };\n return convertSchema(schema, ctx);\n}\n","import * as core from \"../core/index.js\";\nimport * as schemas from \"./schemas.js\";\nexport function string(params) {\n return core._coercedString(schemas.ZodString, params);\n}\nexport function number(params) {\n return core._coercedNumber(schemas.ZodNumber, params);\n}\nexport function boolean(params) {\n return core._coercedBoolean(schemas.ZodBoolean, params);\n}\nexport function bigint(params) {\n return core._coercedBigint(schemas.ZodBigInt, params);\n}\nexport function date(params) {\n return core._coercedDate(schemas.ZodDate, params);\n}\n","export * as core from \"../core/index.js\";\nexport * from \"./schemas.js\";\nexport * from \"./checks.js\";\nexport * from \"./errors.js\";\nexport * from \"./parse.js\";\nexport * from \"./compat.js\";\n// zod-specified\nimport { config } from \"../core/index.js\";\nimport en from \"../locales/en.js\";\nconfig(en());\nexport { globalRegistry, registry, config, $output, $input, $brand, clone, regexes, treeifyError, prettifyError, formatError, flattenError, TimePrecision, util, NEVER, } from \"../core/index.js\";\nexport { toJSONSchema } from \"../core/json-schema-processors.js\";\nexport { fromJSONSchema } from \"./from-json-schema.js\";\nexport * as locales from \"../locales/index.js\";\n// iso\n// must be exported from top-level\n// https://github.com/colinhacks/zod/issues/4491\nexport { ZodISODateTime, ZodISODate, ZodISOTime, ZodISODuration } from \"./iso.js\";\nexport * as iso from \"./iso.js\";\nexport * as coerce from \"./coerce.js\";\n","import * as z from \"./v4/classic/external.js\";\nexport * from \"./v4/classic/external.js\";\nexport { z };\nexport default z;\n"],"x_google_ignoreList":[0,1,2,3,4],"mappings":"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"}
@@ -7,7 +7,11 @@ describe('review-diff tool', () => {
7
7
  it('exports correct tool config', () => {
8
8
  expect(tool.resource).toBe('review');
9
9
  expect(tool.title).toBe('Diff Review');
10
- expect(tool.annotations?.readOnlyHint).toBe(false);
10
+ expect(tool.annotations).toEqual({
11
+ readOnlyHint: true,
12
+ destructiveHint: false,
13
+ openWorldHint: false,
14
+ });
11
15
  });
12
16
 
13
17
  it('has expected schema fields', () => {
@@ -5,7 +5,7 @@ export const tool: AppToolConfig = {
5
5
  resource: 'review',
6
6
  title: 'Diff Review',
7
7
  description: 'Show a review dialog for a proposed code diff',
8
- annotations: { readOnlyHint: false },
8
+ annotations: { readOnlyHint: true, destructiveHint: false, openWorldHint: false },
9
9
  _meta: {
10
10
  ui: { visibility: ['model', 'app'] },
11
11
  },
@@ -7,7 +7,11 @@ describe('review-post tool', () => {
7
7
  it('exports correct tool config', () => {
8
8
  expect(tool.resource).toBe('review');
9
9
  expect(tool.title).toBe('Review Post');
10
- expect(tool.annotations?.readOnlyHint).toBe(false);
10
+ expect(tool.annotations).toEqual({
11
+ readOnlyHint: true,
12
+ destructiveHint: false,
13
+ openWorldHint: false,
14
+ });
11
15
  });
12
16
 
13
17
  it('has expected schema fields', () => {
@@ -5,7 +5,7 @@ export const tool: AppToolConfig = {
5
5
  resource: 'review',
6
6
  title: 'Review Post',
7
7
  description: 'Review a social media post before publishing',
8
- annotations: { readOnlyHint: false },
8
+ annotations: { readOnlyHint: true, destructiveHint: false, openWorldHint: false },
9
9
  _meta: {
10
10
  ui: { visibility: ['model', 'app'] },
11
11
  },
@@ -7,7 +7,11 @@ describe('review-purchase tool', () => {
7
7
  it('exports correct tool config', () => {
8
8
  expect(tool.resource).toBe('review');
9
9
  expect(tool.title).toBe('Review Purchase');
10
- expect(tool.annotations?.readOnlyHint).toBe(false);
10
+ expect(tool.annotations).toEqual({
11
+ readOnlyHint: true,
12
+ destructiveHint: false,
13
+ openWorldHint: false,
14
+ });
11
15
  });
12
16
 
13
17
  it('has expected schema fields', () => {
@@ -5,7 +5,7 @@ export const tool: AppToolConfig = {
5
5
  resource: 'review',
6
6
  title: 'Review Purchase',
7
7
  description: 'Review a purchase before completing the transaction',
8
- annotations: { readOnlyHint: false },
8
+ annotations: { readOnlyHint: true, destructiveHint: false, openWorldHint: false },
9
9
  _meta: {
10
10
  ui: { visibility: ['model', 'app'] },
11
11
  },
@@ -6,7 +6,11 @@ const extra = {} as Parameters<typeof handler>[1];
6
6
  describe('review (confirm) tool', () => {
7
7
  it('exports correct tool config', () => {
8
8
  expect(tool.title).toBe('Confirm Review');
9
- expect(tool.annotations?.readOnlyHint).toBe(false);
9
+ expect(tool.annotations).toEqual({
10
+ readOnlyHint: false,
11
+ destructiveHint: true,
12
+ openWorldHint: false,
13
+ });
10
14
  // No resource — this is a server-side-only tool
11
15
  expect((tool as { resource?: string }).resource).toBeUndefined();
12
16
  });
@@ -4,7 +4,7 @@ import type { AppToolConfig, ToolHandlerExtra } from 'sunpeak/mcp';
4
4
  export const tool: AppToolConfig = {
5
5
  title: 'Confirm Review',
6
6
  description: 'Execute or cancel a reviewed action after user approval in the review UI',
7
- annotations: { readOnlyHint: false },
7
+ annotations: { readOnlyHint: false, destructiveHint: true, openWorldHint: false },
8
8
  _meta: { ui: { visibility: ['model', 'app'] } },
9
9
  };
10
10
 
@@ -7,7 +7,11 @@ describe('show-albums tool', () => {
7
7
  it('exports correct tool config', () => {
8
8
  expect(tool.resource).toBe('albums');
9
9
  expect(tool.title).toBe('Show Albums');
10
- expect(tool.annotations?.readOnlyHint).toBe(true);
10
+ expect(tool.annotations).toEqual({
11
+ readOnlyHint: true,
12
+ destructiveHint: false,
13
+ openWorldHint: false,
14
+ });
11
15
  });
12
16
 
13
17
  it('has expected schema fields', () => {
@@ -5,7 +5,7 @@ export const tool: AppToolConfig = {
5
5
  resource: 'albums',
6
6
  title: 'Show Albums',
7
7
  description: 'Show photo albums',
8
- annotations: { readOnlyHint: true },
8
+ annotations: { readOnlyHint: true, destructiveHint: false, openWorldHint: false },
9
9
  _meta: {
10
10
  ui: { visibility: ['model', 'app'] },
11
11
  },
@@ -7,7 +7,11 @@ describe('show-carousel tool', () => {
7
7
  it('exports correct tool config', () => {
8
8
  expect(tool.resource).toBe('carousel');
9
9
  expect(tool.title).toBe('Show Carousel');
10
- expect(tool.annotations?.readOnlyHint).toBe(true);
10
+ expect(tool.annotations).toEqual({
11
+ readOnlyHint: true,
12
+ destructiveHint: false,
13
+ openWorldHint: false,
14
+ });
11
15
  });
12
16
 
13
17
  it('has expected schema fields', () => {
@@ -5,7 +5,7 @@ export const tool: AppToolConfig = {
5
5
  resource: 'carousel',
6
6
  title: 'Show Carousel',
7
7
  description: 'Show popular places to visit',
8
- annotations: { readOnlyHint: true },
8
+ annotations: { readOnlyHint: true, destructiveHint: false, openWorldHint: false },
9
9
  _meta: {
10
10
  ui: { visibility: ['model', 'app'] },
11
11
  },
@@ -7,7 +7,11 @@ describe('show-map tool', () => {
7
7
  it('exports correct tool config', () => {
8
8
  expect(tool.resource).toBe('map');
9
9
  expect(tool.title).toBe('Show Map');
10
- expect(tool.annotations?.readOnlyHint).toBe(true);
10
+ expect(tool.annotations).toEqual({
11
+ readOnlyHint: true,
12
+ destructiveHint: false,
13
+ openWorldHint: false,
14
+ });
11
15
  });
12
16
 
13
17
  it('has expected schema fields', () => {
@@ -5,7 +5,7 @@ export const tool: AppToolConfig = {
5
5
  resource: 'map',
6
6
  title: 'Show Map',
7
7
  description: 'Show the map',
8
- annotations: { readOnlyHint: true },
8
+ annotations: { readOnlyHint: true, destructiveHint: false, openWorldHint: false },
9
9
  _meta: {
10
10
  ui: { visibility: ['model', 'app'] },
11
11
  },
@@ -1,332 +0,0 @@
1
- //#region src/lib/discovery.ts
2
- /**
3
- * Convert a kebab-case string to PascalCase
4
- * @example toPascalCase('review') // 'Review'
5
- * @example toPascalCase('album-art') // 'AlbumArt'
6
- */
7
- function toPascalCase(str) {
8
- return str.split("-").map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("");
9
- }
10
- /**
11
- * Extract the resource key from a resource file path.
12
- * Matches {name}.tsx (e.g., './albums/albums.tsx' → 'albums')
13
- */
14
- function extractResourceKey(path) {
15
- const match = path.match(/([^/]+)\.tsx$/);
16
- return match ? match[1] : void 0;
17
- }
18
- /**
19
- * Extract the simulation key from a simulation file path.
20
- * Matches any *.json file (e.g., './show-albums.json' → 'show-albums')
21
- */
22
- function extractSimulationKey(path) {
23
- const match = path.match(/([^/]+)\.json$/);
24
- return match ? match[1] : void 0;
25
- }
26
- /**
27
- * Find the best matching resource key for a simulation key.
28
- * Matches the longest resource name that is a prefix of the simulation key.
29
- * @example findResourceKey('review-diff', ['review', 'carousel']) // 'review'
30
- * @example findResourceKey('albums', ['albums', 'review']) // 'albums'
31
- */
32
- function findResourceKey(simulationKey, resourceKeys) {
33
- const sorted = [...resourceKeys].sort((a, b) => b.length - a.length);
34
- for (const resourceKey of sorted) if (simulationKey === resourceKey || simulationKey.startsWith(resourceKey + "-")) return resourceKey;
35
- }
36
- /**
37
- * Get the expected component export name for a resource
38
- * @example getComponentName('review') // 'ReviewResource'
39
- * @example getComponentName('album-art') // 'AlbumArtResource'
40
- */
41
- function getComponentName(resourceKey) {
42
- return `${toPascalCase(resourceKey)}Resource`;
43
- }
44
- /**
45
- * Process resource component modules from import.meta.glob() result.
46
- * Extracts components and exports them with PascalCase names.
47
- *
48
- * @example
49
- * const modules = import.meta.glob('./*\/*.tsx', { eager: true });
50
- * export default createResourceExports(modules);
51
- */
52
- function createResourceExports(modules) {
53
- const resources = {};
54
- for (const [path, module] of Object.entries(modules)) {
55
- const key = extractResourceKey(path);
56
- if (!key) continue;
57
- const exportName = getComponentName(key);
58
- const mod = module;
59
- const component = mod.default ?? mod[exportName];
60
- if (component && (typeof component === "function" || typeof component === "object")) resources[exportName] = component;
61
- }
62
- return resources;
63
- }
64
- /**
65
- * Build a resource metadata map from import.meta.glob() result.
66
- * Used for connecting simulations to their resource definitions.
67
- *
68
- * @example
69
- * const modules = import.meta.glob('../src/resources/*\/*.tsx', { eager: true });
70
- * const resourcesMap = buildResourceMap(modules);
71
- */
72
- function buildResourceMap(modules) {
73
- const map = /* @__PURE__ */ new Map();
74
- for (const [path, module] of Object.entries(modules)) {
75
- const key = extractResourceKey(path);
76
- if (key) map.set(key, module.resource);
77
- }
78
- return map;
79
- }
80
- /**
81
- * Build simulations by connecting simulation data with resources and components.
82
- * This is the main orchestration function for dev server bootstrap.
83
- */
84
- function buildSimulations(options) {
85
- const { simulationModules, resourcesMap, resourceComponents, createSimulation, onMissingResource = (key, prefix) => console.warn(`No matching resource found for simulation "${key}". Expected a resource file like src/resources/${prefix}/${prefix}.tsx`) } = options;
86
- const resourceKeys = Array.from(resourcesMap.keys());
87
- const simulations = {};
88
- for (const [path, module] of Object.entries(simulationModules)) {
89
- const simulationKey = extractSimulationKey(path);
90
- if (!simulationKey) continue;
91
- const simulationData = module.default;
92
- const resourceKey = findResourceKey(simulationKey, resourceKeys);
93
- if (!resourceKey) {
94
- onMissingResource(simulationKey, simulationKey.split("-")[0]);
95
- continue;
96
- }
97
- const resource = resourcesMap.get(resourceKey);
98
- const componentName = getComponentName(resourceKey);
99
- const resourceComponent = resourceComponents[componentName];
100
- if (!resourceComponent) {
101
- console.warn(`Resource component "${componentName}" not found for resource "${resourceKey}". Make sure src/resources/${resourceKey}/${resourceKey}.tsx exists with a default export.`);
102
- continue;
103
- }
104
- simulations[simulationKey] = createSimulation(simulationKey, simulationData, resource, resourceComponent);
105
- }
106
- return simulations;
107
- }
108
- /**
109
- * Build simulations for the dev server from glob results.
110
- * Simulation JSON has `"tool": "tool-name"` string referencing a tool file.
111
- * Tool files have `resource: 'name'` linking to a resource discovered from resourceModules.
112
- */
113
- function buildDevSimulations(options) {
114
- const { simulationModules, resourceComponents, toolModules, resourceModules } = options;
115
- const resourceMetaByName = /* @__PURE__ */ new Map();
116
- const resourceKeyByName = /* @__PURE__ */ new Map();
117
- for (const [path, module] of Object.entries(resourceModules)) {
118
- const key = extractResourceKey(path);
119
- if (!key) continue;
120
- const mod = module;
121
- if (mod.resource) {
122
- const name = mod.resource.name ?? key;
123
- resourceMetaByName.set(name, {
124
- ...mod.resource,
125
- name
126
- });
127
- resourceKeyByName.set(name, key);
128
- }
129
- }
130
- const toolsMap = /* @__PURE__ */ new Map();
131
- if (toolModules) for (const [path, module] of Object.entries(toolModules)) {
132
- const nameMatch = path.match(/([^/]+)\.ts$/);
133
- if (!nameMatch) continue;
134
- const mod = module;
135
- if (mod.tool) {
136
- const resourceName = mod.tool.resource;
137
- toolsMap.set(nameMatch[1], {
138
- tool: mod.tool,
139
- resourceName
140
- });
141
- }
142
- }
143
- const simulations = {};
144
- for (const [path, module] of Object.entries(simulationModules)) {
145
- const simKey = extractSimulationKey(path);
146
- if (!simKey) continue;
147
- const simulationData = module.default;
148
- const toolName = typeof simulationData.tool === "string" ? simulationData.tool : simKey;
149
- const toolInfo = toolsMap.get(toolName);
150
- if (!toolInfo) {
151
- console.warn(`Tool "${toolName}" not found for simulation "${simKey}". Make sure src/tools/${toolName}.ts exists.`);
152
- continue;
153
- }
154
- const resourceMeta = toolInfo.resourceName ? resourceMetaByName.get(toolInfo.resourceName) : void 0;
155
- const resourceKey = toolInfo.resourceName ? resourceKeyByName.get(toolInfo.resourceName) : void 0;
156
- if (toolInfo.resourceName && (!resourceMeta || !resourceKey)) {
157
- console.warn(`Resource "${toolInfo.resourceName}" not found for tool "${toolName}". Make sure a resource with name "${toolInfo.resourceName}" exists in src/resources/.`);
158
- continue;
159
- }
160
- let resourceBlock = {};
161
- if (resourceKey && resourceMeta) {
162
- const componentName = getComponentName(resourceKey);
163
- if (!resourceComponents[componentName]) {
164
- console.warn(`Resource component "${componentName}" not found for tool "${toolName}".`);
165
- continue;
166
- }
167
- resourceBlock = {
168
- resource: {
169
- uri: `ui://${resourceKey}`,
170
- name: resourceKey,
171
- ...resourceMeta.title != null ? { title: resourceMeta.title } : {},
172
- ...resourceMeta.description != null ? { description: resourceMeta.description } : {},
173
- ...resourceMeta.mimeType != null ? { mimeType: resourceMeta.mimeType } : {},
174
- ...resourceMeta._meta != null ? { _meta: resourceMeta._meta } : {}
175
- },
176
- resourceUrl: `/.sunpeak/resource-loader.html?component=${componentName}`
177
- };
178
- }
179
- simulations[simKey] = {
180
- name: simKey,
181
- userMessage: simulationData.userMessage,
182
- tool: {
183
- name: toolName,
184
- description: toolInfo.tool.description ?? "",
185
- inputSchema: { type: "object" },
186
- ...toolInfo.tool.title != null ? { title: toolInfo.tool.title } : {},
187
- ...toolInfo.tool.annotations != null ? { annotations: toolInfo.tool.annotations } : {},
188
- ...toolInfo.tool._meta != null ? { _meta: toolInfo.tool._meta } : {}
189
- },
190
- ...resourceBlock,
191
- toolInput: simulationData.toolInput,
192
- toolResult: simulationData.toolResult,
193
- serverTools: simulationData.serverTools
194
- };
195
- }
196
- return simulations;
197
- }
198
- /**
199
- * Find all resource directories in a base directory.
200
- * Each valid resource directory contains a file matching the expected pattern.
201
- *
202
- * @param baseDir - Base directory to scan (e.g., 'src/resources' or 'dist')
203
- * @param filePattern - Function to generate expected filename from resource key
204
- * @param fs - File system operations (for testing)
205
- *
206
- * @example
207
- * // Find source resources (tsx files)
208
- * const resources = findResourceDirs('src/resources', key => `${key}.tsx`);
209
- *
210
- * @example
211
- * // Find built resources (js files)
212
- * const resources = findResourceDirs('dist', key => `${key}.js`);
213
- */
214
- function findResourceDirs(baseDir, filePattern, fs) {
215
- if (!fs.existsSync(baseDir)) return [];
216
- return fs.readdirSync(baseDir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => {
217
- const key = entry.name;
218
- const dir = `${baseDir}/${key}`;
219
- const resourcePath = `${dir}/${filePattern(key)}`;
220
- if (!fs.existsSync(resourcePath)) return null;
221
- return {
222
- key,
223
- dir,
224
- resourcePath
225
- };
226
- }).filter((info) => info !== null);
227
- }
228
- /**
229
- * Find all tool files in a tools directory.
230
- * Matches *.ts files directly in the directory (not recursive).
231
- *
232
- * @example
233
- * findToolFiles('src/tools', fs)
234
- * // [{ name: 'show-albums', path: 'src/tools/show-albums.ts' }]
235
- */
236
- function findToolFiles(toolsDir, fs) {
237
- if (!fs.existsSync(toolsDir)) return [];
238
- return fs.readdirSync(toolsDir, { withFileTypes: true }).filter((entry) => !entry.isDirectory() && entry.name.endsWith(".ts") && !entry.name.endsWith(".test.ts")).map((entry) => ({
239
- name: entry.name.replace(/\.ts$/, ""),
240
- path: `${toolsDir}/${entry.name}`
241
- }));
242
- }
243
- /**
244
- * Find all simulation JSON files in a flat simulations directory.
245
- * Matches any *.json file directly in the directory.
246
- *
247
- * @example
248
- * findSimulationFilesFlat('tests/simulations', fs)
249
- * // [{ name: 'show-albums', path: 'tests/simulations/show-albums.json' }]
250
- */
251
- function findSimulationFilesFlat(simulationsDir, fs) {
252
- if (!fs.existsSync(simulationsDir)) return [];
253
- return fs.readdirSync(simulationsDir, { withFileTypes: true }).filter((entry) => !entry.isDirectory() && entry.name.endsWith(".json")).map((entry) => ({
254
- name: entry.name.replace(/\.json$/, ""),
255
- path: `${simulationsDir}/${entry.name}`
256
- }));
257
- }
258
- //#endregion
259
- Object.defineProperty(exports, "buildDevSimulations", {
260
- enumerable: true,
261
- get: function() {
262
- return buildDevSimulations;
263
- }
264
- });
265
- Object.defineProperty(exports, "buildResourceMap", {
266
- enumerable: true,
267
- get: function() {
268
- return buildResourceMap;
269
- }
270
- });
271
- Object.defineProperty(exports, "buildSimulations", {
272
- enumerable: true,
273
- get: function() {
274
- return buildSimulations;
275
- }
276
- });
277
- Object.defineProperty(exports, "createResourceExports", {
278
- enumerable: true,
279
- get: function() {
280
- return createResourceExports;
281
- }
282
- });
283
- Object.defineProperty(exports, "extractResourceKey", {
284
- enumerable: true,
285
- get: function() {
286
- return extractResourceKey;
287
- }
288
- });
289
- Object.defineProperty(exports, "extractSimulationKey", {
290
- enumerable: true,
291
- get: function() {
292
- return extractSimulationKey;
293
- }
294
- });
295
- Object.defineProperty(exports, "findResourceDirs", {
296
- enumerable: true,
297
- get: function() {
298
- return findResourceDirs;
299
- }
300
- });
301
- Object.defineProperty(exports, "findResourceKey", {
302
- enumerable: true,
303
- get: function() {
304
- return findResourceKey;
305
- }
306
- });
307
- Object.defineProperty(exports, "findSimulationFilesFlat", {
308
- enumerable: true,
309
- get: function() {
310
- return findSimulationFilesFlat;
311
- }
312
- });
313
- Object.defineProperty(exports, "findToolFiles", {
314
- enumerable: true,
315
- get: function() {
316
- return findToolFiles;
317
- }
318
- });
319
- Object.defineProperty(exports, "getComponentName", {
320
- enumerable: true,
321
- get: function() {
322
- return getComponentName;
323
- }
324
- });
325
- Object.defineProperty(exports, "toPascalCase", {
326
- enumerable: true,
327
- get: function() {
328
- return toPascalCase;
329
- }
330
- });
331
-
332
- //# sourceMappingURL=discovery-BxKCIgG5.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"discovery-BxKCIgG5.cjs","names":[],"sources":["../src/lib/discovery.ts"],"sourcesContent":["/**\n * Discovery utilities for auto-discovering resources and simulations\n *\n * These helpers process the results of import.meta.glob() calls to extract\n * keys, build component maps, and connect simulations to resources.\n *\n * The glob calls themselves must remain in the template (Vite compile-time),\n * but all the processing logic lives here for easy updates across templates.\n *\n * Node.js utilities (findResourceDirs, findToolFiles, etc.) can be used\n * by CLI commands for build-time and runtime discovery.\n */\n\nimport type { Simulation } from '../types/simulation.js';\n\n/**\n * Convert a kebab-case string to PascalCase\n * @example toPascalCase('review') // 'Review'\n * @example toPascalCase('album-art') // 'AlbumArt'\n */\nexport function toPascalCase(str: string): string {\n return str\n .split('-')\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n .join('');\n}\n\n/**\n * Extract the resource key from a resource file path.\n * Matches {name}.tsx (e.g., './albums/albums.tsx' → 'albums')\n */\nexport function extractResourceKey(path: string): string | undefined {\n const match = path.match(/([^/]+)\\.tsx$/);\n return match ? match[1] : undefined;\n}\n\n/**\n * Extract the simulation key from a simulation file path.\n * Matches any *.json file (e.g., './show-albums.json' → 'show-albums')\n */\nexport function extractSimulationKey(path: string): string | undefined {\n const match = path.match(/([^/]+)\\.json$/);\n return match ? match[1] : undefined;\n}\n\n/**\n * Find the best matching resource key for a simulation key.\n * Matches the longest resource name that is a prefix of the simulation key.\n * @example findResourceKey('review-diff', ['review', 'carousel']) // 'review'\n * @example findResourceKey('albums', ['albums', 'review']) // 'albums'\n */\nexport function findResourceKey(simulationKey: string, resourceKeys: string[]): string | undefined {\n // Sort by length descending to find longest match first\n const sorted = [...resourceKeys].sort((a, b) => b.length - a.length);\n for (const resourceKey of sorted) {\n if (simulationKey === resourceKey || simulationKey.startsWith(resourceKey + '-')) {\n return resourceKey;\n }\n }\n return undefined;\n}\n\n/**\n * Get the expected component export name for a resource\n * @example getComponentName('review') // 'ReviewResource'\n * @example getComponentName('album-art') // 'AlbumArtResource'\n */\nexport function getComponentName(resourceKey: string): string {\n return `${toPascalCase(resourceKey)}Resource`;\n}\n\n// --- Glob processing helpers ---\n\ntype GlobModules = Record<string, unknown>;\n\n/**\n * Process resource component modules from import.meta.glob() result.\n * Extracts components and exports them with PascalCase names.\n *\n * @example\n * const modules = import.meta.glob('./*\\/*.tsx', { eager: true });\n * export default createResourceExports(modules);\n */\nexport function createResourceExports(modules: GlobModules): Record<string, React.ComponentType> {\n const resources: Record<string, React.ComponentType> = {};\n\n for (const [path, module] of Object.entries(modules)) {\n const key = extractResourceKey(path);\n if (!key) continue;\n\n const exportName = getComponentName(key);\n const mod = module as Record<string, unknown>;\n\n // Try default export first, then named export matching the expected name\n const component = mod.default ?? mod[exportName];\n\n // Accept functions (regular components) or objects (forwardRef/memo components)\n if (component && (typeof component === 'function' || typeof component === 'object')) {\n resources[exportName] = component as React.ComponentType;\n }\n }\n\n return resources;\n}\n\n/**\n * Build a resource metadata map from import.meta.glob() result.\n * Used for connecting simulations to their resource definitions.\n *\n * @example\n * const modules = import.meta.glob('../src/resources/*\\/*.tsx', { eager: true });\n * const resourcesMap = buildResourceMap(modules);\n */\nexport function buildResourceMap<T>(modules: GlobModules): Map<string, T> {\n const map = new Map<string, T>();\n\n for (const [path, module] of Object.entries(modules)) {\n const key = extractResourceKey(path);\n if (key) {\n map.set(key, (module as { resource: T }).resource);\n }\n }\n\n return map;\n}\n\n/**\n * Options for building simulations from discovered modules\n */\nexport interface BuildSimulationsOptions<TResource, TSimulation> {\n /** Glob result of simulation JSON files */\n simulationModules: GlobModules;\n /** Map of resource key -> resource metadata */\n resourcesMap: Map<string, TResource>;\n /** Map of component name -> React component */\n resourceComponents: Record<string, React.ComponentType>;\n /** Create the final simulation object */\n createSimulation: (\n simulationKey: string,\n simulationData: unknown,\n resource: TResource,\n resourceComponent: React.ComponentType\n ) => TSimulation;\n /** Optional warning handler for missing resources */\n onMissingResource?: (simulationKey: string, expectedPrefix: string) => void;\n}\n\n/**\n * Build simulations by connecting simulation data with resources and components.\n * This is the main orchestration function for dev server bootstrap.\n */\nexport function buildSimulations<TResource, TSimulation>(\n options: BuildSimulationsOptions<TResource, TSimulation>\n): Record<string, TSimulation> {\n const {\n simulationModules,\n resourcesMap,\n resourceComponents,\n createSimulation,\n onMissingResource = (key, prefix) =>\n console.warn(\n `No matching resource found for simulation \"${key}\". ` +\n `Expected a resource file like src/resources/${prefix}/${prefix}.tsx`\n ),\n } = options;\n\n const resourceKeys = Array.from(resourcesMap.keys());\n const simulations: Record<string, TSimulation> = {};\n\n for (const [path, module] of Object.entries(simulationModules)) {\n const simulationKey = extractSimulationKey(path);\n if (!simulationKey) continue;\n\n const simulationData = (module as { default: unknown }).default;\n\n // Find matching resource\n const resourceKey = findResourceKey(simulationKey, resourceKeys);\n if (!resourceKey) {\n onMissingResource(simulationKey, simulationKey.split('-')[0]);\n continue;\n }\n\n const resource = resourcesMap.get(resourceKey)!;\n\n // Get component\n const componentName = getComponentName(resourceKey);\n const resourceComponent = resourceComponents[componentName];\n\n if (!resourceComponent) {\n console.warn(\n `Resource component \"${componentName}\" not found for resource \"${resourceKey}\". ` +\n `Make sure src/resources/${resourceKey}/${resourceKey}.tsx exists with a default export.`\n );\n continue;\n }\n\n simulations[simulationKey] = createSimulation(\n simulationKey,\n simulationData,\n resource,\n resourceComponent\n );\n }\n\n return simulations;\n}\n\n// --- Dev server helpers ---\n\n/**\n * Resource metadata from resource .tsx files\n */\nexport interface ResourceMetadata {\n name: string;\n [key: string]: unknown;\n}\n\n/**\n * Options for building dev simulations\n */\nexport interface BuildDevSimulationsOptions {\n /** Glob result of simulation JSON files */\n simulationModules: GlobModules;\n /** Resource components map from src/resources/index.ts */\n resourceComponents: Record<string, React.ComponentType>;\n /** Glob result of tool files: import.meta.glob('src/tools/*.ts', { eager: true }) */\n toolModules: GlobModules;\n /** Glob result of resource .tsx files from src/resources/ */\n resourceModules: GlobModules;\n}\n\n/**\n * Tool metadata extracted from a tool module's `tool` export\n */\ninterface ToolModuleInfo {\n tool: Record<string, unknown>;\n /** Resource name string from tool.resource (undefined for tools without UI) */\n resourceName?: string;\n}\n\n/**\n * Build simulations for the dev server from glob results.\n * Simulation JSON has `\"tool\": \"tool-name\"` string referencing a tool file.\n * Tool files have `resource: 'name'` linking to a resource discovered from resourceModules.\n */\nexport function buildDevSimulations(\n options: BuildDevSimulationsOptions\n): Record<string, Simulation> {\n const { simulationModules, resourceComponents, toolModules, resourceModules } = options;\n\n // Build resource metadata map from resource modules (keyed by resource name)\n const resourceMetaByName = new Map<string, ResourceMetadata>();\n const resourceKeyByName = new Map<string, string>();\n for (const [path, module] of Object.entries(resourceModules)) {\n const key = extractResourceKey(path);\n if (!key) continue;\n const mod = module as { resource?: ResourceMetadata };\n if (mod.resource) {\n // Use explicit name if provided, otherwise derive from directory key\n const name = mod.resource.name ?? key;\n resourceMetaByName.set(name, { ...mod.resource, name });\n resourceKeyByName.set(name, key);\n }\n }\n\n // Build tool map from tool modules\n const toolsMap = new Map<string, ToolModuleInfo>();\n if (toolModules) {\n for (const [path, module] of Object.entries(toolModules)) {\n const nameMatch = path.match(/([^/]+)\\.ts$/);\n if (!nameMatch) continue;\n const mod = module as { tool?: Record<string, unknown> };\n if (mod.tool) {\n const resourceName = mod.tool.resource as string | undefined;\n toolsMap.set(nameMatch[1], { tool: mod.tool, resourceName });\n }\n }\n }\n\n const simulations: Record<string, Simulation> = {};\n\n for (const [path, module] of Object.entries(simulationModules)) {\n const simKey = extractSimulationKey(path);\n if (!simKey) continue;\n\n const simulationData = (module as { default: Record<string, unknown> }).default;\n\n const toolName =\n typeof simulationData.tool === 'string' ? (simulationData.tool as string) : simKey;\n const toolInfo = toolsMap.get(toolName);\n if (!toolInfo) {\n console.warn(\n `Tool \"${toolName}\" not found for simulation \"${simKey}\". ` +\n `Make sure src/tools/${toolName}.ts exists.`\n );\n continue;\n }\n\n // Look up resource metadata by name (if tool has a UI)\n const resourceMeta = toolInfo.resourceName\n ? resourceMetaByName.get(toolInfo.resourceName)\n : undefined;\n const resourceKey = toolInfo.resourceName\n ? resourceKeyByName.get(toolInfo.resourceName)\n : undefined;\n\n if (toolInfo.resourceName && (!resourceMeta || !resourceKey)) {\n console.warn(\n `Resource \"${toolInfo.resourceName}\" not found for tool \"${toolName}\". ` +\n `Make sure a resource with name \"${toolInfo.resourceName}\" exists in src/resources/.`\n );\n continue;\n }\n\n // Build resource block only for UI tools\n let resourceBlock: Pick<Simulation, 'resource' | 'resourceUrl'> = {};\n if (resourceKey && resourceMeta) {\n const componentName = getComponentName(resourceKey);\n const resourceComponent = resourceComponents[componentName];\n\n if (!resourceComponent) {\n console.warn(`Resource component \"${componentName}\" not found for tool \"${toolName}\".`);\n continue;\n }\n\n resourceBlock = {\n resource: {\n uri: `ui://${resourceKey}`,\n name: resourceKey,\n ...(resourceMeta.title != null ? { title: resourceMeta.title as string } : {}),\n ...(resourceMeta.description != null\n ? { description: resourceMeta.description as string }\n : {}),\n ...(resourceMeta.mimeType != null ? { mimeType: resourceMeta.mimeType as string } : {}),\n ...(resourceMeta._meta != null\n ? { _meta: resourceMeta._meta as Record<string, unknown> }\n : {}),\n },\n resourceUrl: `/.sunpeak/resource-loader.html?component=${componentName}`,\n };\n }\n\n simulations[simKey] = {\n name: simKey,\n userMessage: simulationData.userMessage as string | undefined,\n tool: {\n name: toolName,\n description: (toolInfo.tool.description as string) ?? '',\n inputSchema: { type: 'object' as const },\n ...(toolInfo.tool.title != null ? { title: toolInfo.tool.title as string } : {}),\n ...(toolInfo.tool.annotations != null\n ? { annotations: toolInfo.tool.annotations as Record<string, unknown> }\n : {}),\n ...(toolInfo.tool._meta != null\n ? { _meta: toolInfo.tool._meta as Record<string, unknown> }\n : {}),\n },\n ...resourceBlock,\n toolInput: simulationData.toolInput as Record<string, unknown> | undefined,\n toolResult: simulationData.toolResult as Simulation['toolResult'],\n serverTools: simulationData.serverTools as Simulation['serverTools'],\n };\n }\n\n return simulations;\n}\n\n// --- Node.js utilities for CLI commands ---\n// These utilities use standard Node.js APIs and can be imported by build/push/mcp commands.\n\n/**\n * Information about a discovered resource directory\n */\nexport interface ResourceDirInfo {\n /** Resource key (directory name), e.g., 'albums', 'carousel' */\n key: string;\n /** Full path to the resource directory */\n dir: string;\n /** Full path to the main resource file (tsx or json depending on context) */\n resourcePath: string;\n}\n\n/**\n * File system operations interface for dependency injection in tests\n */\nexport interface FsOps {\n readdirSync: (\n path: string,\n options: { withFileTypes: true }\n ) => Array<{ name: string; isDirectory: () => boolean }>;\n existsSync: (path: string) => boolean;\n}\n\n/**\n * Find all resource directories in a base directory.\n * Each valid resource directory contains a file matching the expected pattern.\n *\n * @param baseDir - Base directory to scan (e.g., 'src/resources' or 'dist')\n * @param filePattern - Function to generate expected filename from resource key\n * @param fs - File system operations (for testing)\n *\n * @example\n * // Find source resources (tsx files)\n * const resources = findResourceDirs('src/resources', key => `${key}.tsx`);\n *\n * @example\n * // Find built resources (js files)\n * const resources = findResourceDirs('dist', key => `${key}.js`);\n */\nexport function findResourceDirs(\n baseDir: string,\n filePattern: (key: string) => string,\n fs: FsOps\n): ResourceDirInfo[] {\n if (!fs.existsSync(baseDir)) {\n return [];\n }\n\n const entries = fs.readdirSync(baseDir, { withFileTypes: true });\n\n return entries\n .filter((entry) => entry.isDirectory())\n .map((entry) => {\n const key = entry.name;\n const dir = `${baseDir}/${key}`;\n const resourcePath = `${dir}/${filePattern(key)}`;\n\n if (!fs.existsSync(resourcePath)) {\n return null;\n }\n\n return { key, dir, resourcePath };\n })\n .filter((info): info is ResourceDirInfo => info !== null);\n}\n\n// --- Tool files + flat simulations discovery ---\n\n/**\n * Information about a discovered tool file\n */\nexport interface ToolFileInfo {\n /** Tool name derived from filename (e.g., 'show-albums') */\n name: string;\n /** Full path to the tool file */\n path: string;\n}\n\n/**\n * Find all tool files in a tools directory.\n * Matches *.ts files directly in the directory (not recursive).\n *\n * @example\n * findToolFiles('src/tools', fs)\n * // [{ name: 'show-albums', path: 'src/tools/show-albums.ts' }]\n */\nexport function findToolFiles(\n toolsDir: string,\n fs: Pick<FsOps, 'readdirSync' | 'existsSync'>\n): ToolFileInfo[] {\n if (!fs.existsSync(toolsDir)) {\n return [];\n }\n\n const entries = fs.readdirSync(toolsDir, { withFileTypes: true });\n\n return entries\n .filter(\n (entry) =>\n !entry.isDirectory() && entry.name.endsWith('.ts') && !entry.name.endsWith('.test.ts')\n )\n .map((entry) => ({\n name: entry.name.replace(/\\.ts$/, ''),\n path: `${toolsDir}/${entry.name}`,\n }));\n}\n\n/**\n * Information about a discovered simulation file (flat convention)\n */\nexport interface SimulationFileInfo {\n /** Filename without extension (e.g., 'show-albums') */\n name: string;\n /** Full path to the simulation file */\n path: string;\n}\n\n/**\n * Find all simulation JSON files in a flat simulations directory.\n * Matches any *.json file directly in the directory.\n *\n * @example\n * findSimulationFilesFlat('tests/simulations', fs)\n * // [{ name: 'show-albums', path: 'tests/simulations/show-albums.json' }]\n */\nexport function findSimulationFilesFlat(\n simulationsDir: string,\n fs: Pick<FsOps, 'readdirSync' | 'existsSync'>\n): SimulationFileInfo[] {\n if (!fs.existsSync(simulationsDir)) {\n return [];\n }\n\n const entries = fs.readdirSync(simulationsDir, { withFileTypes: true });\n\n return entries\n .filter((entry) => !entry.isDirectory() && entry.name.endsWith('.json'))\n .map((entry) => ({\n name: entry.name.replace(/\\.json$/, ''),\n path: `${simulationsDir}/${entry.name}`,\n }));\n}\n"],"mappings":";;;;;;AAoBA,SAAgB,aAAa,KAAqB;AAChD,QAAO,IACJ,MAAM,IAAI,CACV,KAAK,SAAS,KAAK,OAAO,EAAE,CAAC,aAAa,GAAG,KAAK,MAAM,EAAE,CAAC,CAC3D,KAAK,GAAG;;;;;;AAOb,SAAgB,mBAAmB,MAAkC;CACnE,MAAM,QAAQ,KAAK,MAAM,gBAAgB;AACzC,QAAO,QAAQ,MAAM,KAAK,KAAA;;;;;;AAO5B,SAAgB,qBAAqB,MAAkC;CACrE,MAAM,QAAQ,KAAK,MAAM,iBAAiB;AAC1C,QAAO,QAAQ,MAAM,KAAK,KAAA;;;;;;;;AAS5B,SAAgB,gBAAgB,eAAuB,cAA4C;CAEjG,MAAM,SAAS,CAAC,GAAG,aAAa,CAAC,MAAM,GAAG,MAAM,EAAE,SAAS,EAAE,OAAO;AACpE,MAAK,MAAM,eAAe,OACxB,KAAI,kBAAkB,eAAe,cAAc,WAAW,cAAc,IAAI,CAC9E,QAAO;;;;;;;AAWb,SAAgB,iBAAiB,aAA6B;AAC5D,QAAO,GAAG,aAAa,YAAY,CAAC;;;;;;;;;;AAetC,SAAgB,sBAAsB,SAA2D;CAC/F,MAAM,YAAiD,EAAE;AAEzD,MAAK,MAAM,CAAC,MAAM,WAAW,OAAO,QAAQ,QAAQ,EAAE;EACpD,MAAM,MAAM,mBAAmB,KAAK;AACpC,MAAI,CAAC,IAAK;EAEV,MAAM,aAAa,iBAAiB,IAAI;EACxC,MAAM,MAAM;EAGZ,MAAM,YAAY,IAAI,WAAW,IAAI;AAGrC,MAAI,cAAc,OAAO,cAAc,cAAc,OAAO,cAAc,UACxE,WAAU,cAAc;;AAI5B,QAAO;;;;;;;;;;AAWT,SAAgB,iBAAoB,SAAsC;CACxE,MAAM,sBAAM,IAAI,KAAgB;AAEhC,MAAK,MAAM,CAAC,MAAM,WAAW,OAAO,QAAQ,QAAQ,EAAE;EACpD,MAAM,MAAM,mBAAmB,KAAK;AACpC,MAAI,IACF,KAAI,IAAI,KAAM,OAA2B,SAAS;;AAItD,QAAO;;;;;;AA4BT,SAAgB,iBACd,SAC6B;CAC7B,MAAM,EACJ,mBACA,cACA,oBACA,kBACA,qBAAqB,KAAK,WACxB,QAAQ,KACN,8CAA8C,IAAI,iDACD,OAAO,GAAG,OAAO,MACnE,KACD;CAEJ,MAAM,eAAe,MAAM,KAAK,aAAa,MAAM,CAAC;CACpD,MAAM,cAA2C,EAAE;AAEnD,MAAK,MAAM,CAAC,MAAM,WAAW,OAAO,QAAQ,kBAAkB,EAAE;EAC9D,MAAM,gBAAgB,qBAAqB,KAAK;AAChD,MAAI,CAAC,cAAe;EAEpB,MAAM,iBAAkB,OAAgC;EAGxD,MAAM,cAAc,gBAAgB,eAAe,aAAa;AAChE,MAAI,CAAC,aAAa;AAChB,qBAAkB,eAAe,cAAc,MAAM,IAAI,CAAC,GAAG;AAC7D;;EAGF,MAAM,WAAW,aAAa,IAAI,YAAY;EAG9C,MAAM,gBAAgB,iBAAiB,YAAY;EACnD,MAAM,oBAAoB,mBAAmB;AAE7C,MAAI,CAAC,mBAAmB;AACtB,WAAQ,KACN,uBAAuB,cAAc,4BAA4B,YAAY,6BAChD,YAAY,GAAG,YAAY,oCACzD;AACD;;AAGF,cAAY,iBAAiB,iBAC3B,eACA,gBACA,UACA,kBACD;;AAGH,QAAO;;;;;;;AAyCT,SAAgB,oBACd,SAC4B;CAC5B,MAAM,EAAE,mBAAmB,oBAAoB,aAAa,oBAAoB;CAGhF,MAAM,qCAAqB,IAAI,KAA+B;CAC9D,MAAM,oCAAoB,IAAI,KAAqB;AACnD,MAAK,MAAM,CAAC,MAAM,WAAW,OAAO,QAAQ,gBAAgB,EAAE;EAC5D,MAAM,MAAM,mBAAmB,KAAK;AACpC,MAAI,CAAC,IAAK;EACV,MAAM,MAAM;AACZ,MAAI,IAAI,UAAU;GAEhB,MAAM,OAAO,IAAI,SAAS,QAAQ;AAClC,sBAAmB,IAAI,MAAM;IAAE,GAAG,IAAI;IAAU;IAAM,CAAC;AACvD,qBAAkB,IAAI,MAAM,IAAI;;;CAKpC,MAAM,2BAAW,IAAI,KAA6B;AAClD,KAAI,YACF,MAAK,MAAM,CAAC,MAAM,WAAW,OAAO,QAAQ,YAAY,EAAE;EACxD,MAAM,YAAY,KAAK,MAAM,eAAe;AAC5C,MAAI,CAAC,UAAW;EAChB,MAAM,MAAM;AACZ,MAAI,IAAI,MAAM;GACZ,MAAM,eAAe,IAAI,KAAK;AAC9B,YAAS,IAAI,UAAU,IAAI;IAAE,MAAM,IAAI;IAAM;IAAc,CAAC;;;CAKlE,MAAM,cAA0C,EAAE;AAElD,MAAK,MAAM,CAAC,MAAM,WAAW,OAAO,QAAQ,kBAAkB,EAAE;EAC9D,MAAM,SAAS,qBAAqB,KAAK;AACzC,MAAI,CAAC,OAAQ;EAEb,MAAM,iBAAkB,OAAgD;EAExE,MAAM,WACJ,OAAO,eAAe,SAAS,WAAY,eAAe,OAAkB;EAC9E,MAAM,WAAW,SAAS,IAAI,SAAS;AACvC,MAAI,CAAC,UAAU;AACb,WAAQ,KACN,SAAS,SAAS,8BAA8B,OAAO,yBAC9B,SAAS,aACnC;AACD;;EAIF,MAAM,eAAe,SAAS,eAC1B,mBAAmB,IAAI,SAAS,aAAa,GAC7C,KAAA;EACJ,MAAM,cAAc,SAAS,eACzB,kBAAkB,IAAI,SAAS,aAAa,GAC5C,KAAA;AAEJ,MAAI,SAAS,iBAAiB,CAAC,gBAAgB,CAAC,cAAc;AAC5D,WAAQ,KACN,aAAa,SAAS,aAAa,wBAAwB,SAAS,qCAC/B,SAAS,aAAa,6BAC5D;AACD;;EAIF,IAAI,gBAA8D,EAAE;AACpE,MAAI,eAAe,cAAc;GAC/B,MAAM,gBAAgB,iBAAiB,YAAY;AAGnD,OAAI,CAFsB,mBAAmB,gBAErB;AACtB,YAAQ,KAAK,uBAAuB,cAAc,wBAAwB,SAAS,IAAI;AACvF;;AAGF,mBAAgB;IACd,UAAU;KACR,KAAK,QAAQ;KACb,MAAM;KACN,GAAI,aAAa,SAAS,OAAO,EAAE,OAAO,aAAa,OAAiB,GAAG,EAAE;KAC7E,GAAI,aAAa,eAAe,OAC5B,EAAE,aAAa,aAAa,aAAuB,GACnD,EAAE;KACN,GAAI,aAAa,YAAY,OAAO,EAAE,UAAU,aAAa,UAAoB,GAAG,EAAE;KACtF,GAAI,aAAa,SAAS,OACtB,EAAE,OAAO,aAAa,OAAkC,GACxD,EAAE;KACP;IACD,aAAa,4CAA4C;IAC1D;;AAGH,cAAY,UAAU;GACpB,MAAM;GACN,aAAa,eAAe;GAC5B,MAAM;IACJ,MAAM;IACN,aAAc,SAAS,KAAK,eAA0B;IACtD,aAAa,EAAE,MAAM,UAAmB;IACxC,GAAI,SAAS,KAAK,SAAS,OAAO,EAAE,OAAO,SAAS,KAAK,OAAiB,GAAG,EAAE;IAC/E,GAAI,SAAS,KAAK,eAAe,OAC7B,EAAE,aAAa,SAAS,KAAK,aAAwC,GACrE,EAAE;IACN,GAAI,SAAS,KAAK,SAAS,OACvB,EAAE,OAAO,SAAS,KAAK,OAAkC,GACzD,EAAE;IACP;GACD,GAAG;GACH,WAAW,eAAe;GAC1B,YAAY,eAAe;GAC3B,aAAa,eAAe;GAC7B;;AAGH,QAAO;;;;;;;;;;;;;;;;;;AA6CT,SAAgB,iBACd,SACA,aACA,IACmB;AACnB,KAAI,CAAC,GAAG,WAAW,QAAQ,CACzB,QAAO,EAAE;AAKX,QAFgB,GAAG,YAAY,SAAS,EAAE,eAAe,MAAM,CAAC,CAG7D,QAAQ,UAAU,MAAM,aAAa,CAAC,CACtC,KAAK,UAAU;EACd,MAAM,MAAM,MAAM;EAClB,MAAM,MAAM,GAAG,QAAQ,GAAG;EAC1B,MAAM,eAAe,GAAG,IAAI,GAAG,YAAY,IAAI;AAE/C,MAAI,CAAC,GAAG,WAAW,aAAa,CAC9B,QAAO;AAGT,SAAO;GAAE;GAAK;GAAK;GAAc;GACjC,CACD,QAAQ,SAAkC,SAAS,KAAK;;;;;;;;;;AAuB7D,SAAgB,cACd,UACA,IACgB;AAChB,KAAI,CAAC,GAAG,WAAW,SAAS,CAC1B,QAAO,EAAE;AAKX,QAFgB,GAAG,YAAY,UAAU,EAAE,eAAe,MAAM,CAAC,CAG9D,QACE,UACC,CAAC,MAAM,aAAa,IAAI,MAAM,KAAK,SAAS,MAAM,IAAI,CAAC,MAAM,KAAK,SAAS,WAAW,CACzF,CACA,KAAK,WAAW;EACf,MAAM,MAAM,KAAK,QAAQ,SAAS,GAAG;EACrC,MAAM,GAAG,SAAS,GAAG,MAAM;EAC5B,EAAE;;;;;;;;;;AAqBP,SAAgB,wBACd,gBACA,IACsB;AACtB,KAAI,CAAC,GAAG,WAAW,eAAe,CAChC,QAAO,EAAE;AAKX,QAFgB,GAAG,YAAY,gBAAgB,EAAE,eAAe,MAAM,CAAC,CAGpE,QAAQ,UAAU,CAAC,MAAM,aAAa,IAAI,MAAM,KAAK,SAAS,QAAQ,CAAC,CACvE,KAAK,WAAW;EACf,MAAM,MAAM,KAAK,QAAQ,WAAW,GAAG;EACvC,MAAM,GAAG,eAAe,GAAG,MAAM;EAClC,EAAE"}