@sarjallab09/figma-intelligence 1.0.0

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 (286) hide show
  1. package/LICENSE +26 -0
  2. package/README.md +327 -0
  3. package/bin/cli.js +859 -0
  4. package/design-bridge/.env.example +5 -0
  5. package/design-bridge/bridge.js +196 -0
  6. package/design-bridge/lib/assets.js +367 -0
  7. package/design-bridge/lib/prompt.js +85 -0
  8. package/design-bridge/lib/server.js +66 -0
  9. package/design-bridge/lib/stitch.js +37 -0
  10. package/design-bridge/lib/tokens.js +82 -0
  11. package/design-bridge/package-lock.json +579 -0
  12. package/design-bridge/package.json +19 -0
  13. package/figma-bridge-plugin/README.md +97 -0
  14. package/figma-bridge-plugin/anthropic-chat-runner.js +192 -0
  15. package/figma-bridge-plugin/bridge-relay.js +2363 -0
  16. package/figma-bridge-plugin/chat-runner.js +459 -0
  17. package/figma-bridge-plugin/code.js +1528 -0
  18. package/figma-bridge-plugin/codex-runner.js +505 -0
  19. package/figma-bridge-plugin/component-schemas.js +110 -0
  20. package/figma-bridge-plugin/content-context.js +869 -0
  21. package/figma-bridge-plugin/create-button.js +216 -0
  22. package/figma-bridge-plugin/gemini-cli-runner.js +291 -0
  23. package/figma-bridge-plugin/gemini-runner.js +187 -0
  24. package/figma-bridge-plugin/html-to-figma.js +927 -0
  25. package/figma-bridge-plugin/knowledge-hub/.gitkeep +0 -0
  26. package/figma-bridge-plugin/knowledge-hub/uspec-references/anatomy-spec.md +159 -0
  27. package/figma-bridge-plugin/knowledge-hub/uspec-references/api-spec.md +162 -0
  28. package/figma-bridge-plugin/knowledge-hub/uspec-references/color-spec.md +148 -0
  29. package/figma-bridge-plugin/knowledge-hub/uspec-references/full-spec-template.md +314 -0
  30. package/figma-bridge-plugin/knowledge-hub/uspec-references/property-spec.md +175 -0
  31. package/figma-bridge-plugin/knowledge-hub/uspec-references/screen-reader-spec.md +180 -0
  32. package/figma-bridge-plugin/knowledge-hub/uspec-references/structure-spec.md +165 -0
  33. package/figma-bridge-plugin/manifest.json +21 -0
  34. package/figma-bridge-plugin/package-lock.json +1936 -0
  35. package/figma-bridge-plugin/package.json +20 -0
  36. package/figma-bridge-plugin/perplexity-runner.js +188 -0
  37. package/figma-bridge-plugin/references/SKILL.md +178 -0
  38. package/figma-bridge-plugin/references/anatomy-spec.md +159 -0
  39. package/figma-bridge-plugin/references/api-spec.md +162 -0
  40. package/figma-bridge-plugin/references/color-spec.md +148 -0
  41. package/figma-bridge-plugin/references/full-spec-template.md +314 -0
  42. package/figma-bridge-plugin/references/property-spec.md +175 -0
  43. package/figma-bridge-plugin/references/screen-reader-spec.md +180 -0
  44. package/figma-bridge-plugin/references/structure-spec.md +165 -0
  45. package/figma-bridge-plugin/shared-prompt-config.js +604 -0
  46. package/figma-bridge-plugin/spec-helpers/build-table.js +269 -0
  47. package/figma-bridge-plugin/spec-helpers/classify-elements.js +189 -0
  48. package/figma-bridge-plugin/spec-helpers/index.js +35 -0
  49. package/figma-bridge-plugin/spec-helpers/parse-figma-link.js +49 -0
  50. package/figma-bridge-plugin/spec-helpers/position-markers.js +158 -0
  51. package/figma-bridge-plugin/stitch-auth.js +322 -0
  52. package/figma-bridge-plugin/stitch-runner.js +1427 -0
  53. package/figma-bridge-plugin/token-resolver.js +107 -0
  54. package/figma-bridge-plugin/ui.html +4467 -0
  55. package/figma-intelligence-layer/.env.example +39 -0
  56. package/figma-intelligence-layer/docs/local-image-generation.md +60 -0
  57. package/figma-intelligence-layer/examples/comfyui-workflow-template.example.json +101 -0
  58. package/figma-intelligence-layer/jest.config.js +14 -0
  59. package/figma-intelligence-layer/mcp-config.json +19 -0
  60. package/figma-intelligence-layer/package-lock.json +5892 -0
  61. package/figma-intelligence-layer/package.json +48 -0
  62. package/figma-intelligence-layer/scripts/setup-comfyui-local.sh +67 -0
  63. package/figma-intelligence-layer/scripts/start-comfyui.sh +33 -0
  64. package/figma-intelligence-layer/src/index.ts +2233 -0
  65. package/figma-intelligence-layer/src/shared/auto-layout-validator.ts +404 -0
  66. package/figma-intelligence-layer/src/shared/cache.ts +187 -0
  67. package/figma-intelligence-layer/src/shared/color-operations.ts +533 -0
  68. package/figma-intelligence-layer/src/shared/color-utils.ts +138 -0
  69. package/figma-intelligence-layer/src/shared/component-script-builder.ts +413 -0
  70. package/figma-intelligence-layer/src/shared/component-templates.ts +2767 -0
  71. package/figma-intelligence-layer/src/shared/concept-taxonomy.ts +694 -0
  72. package/figma-intelligence-layer/src/shared/decision-log.ts +128 -0
  73. package/figma-intelligence-layer/src/shared/design-system-context.ts +568 -0
  74. package/figma-intelligence-layer/src/shared/design-system-intelligence.ts +131 -0
  75. package/figma-intelligence-layer/src/shared/design-system-matcher.ts +184 -0
  76. package/figma-intelligence-layer/src/shared/design-system-normalizers.ts +196 -0
  77. package/figma-intelligence-layer/src/shared/design-system-tokens.ts +295 -0
  78. package/figma-intelligence-layer/src/shared/dtcg-validator.ts +530 -0
  79. package/figma-intelligence-layer/src/shared/enrichment-pipeline.ts +671 -0
  80. package/figma-intelligence-layer/src/shared/figma-bridge.ts +1408 -0
  81. package/figma-intelligence-layer/src/shared/font-config.ts +126 -0
  82. package/figma-intelligence-layer/src/shared/icon-catalog.ts +360 -0
  83. package/figma-intelligence-layer/src/shared/icon-fetch.ts +80 -0
  84. package/figma-intelligence-layer/src/shared/prototype-script-builder.ts +162 -0
  85. package/figma-intelligence-layer/src/shared/response-compression.ts +440 -0
  86. package/figma-intelligence-layer/src/shared/semantic-token-catalog.ts +324 -0
  87. package/figma-intelligence-layer/src/shared/token-binder.ts +505 -0
  88. package/figma-intelligence-layer/src/shared/token-math.ts +427 -0
  89. package/figma-intelligence-layer/src/shared/token-naming.ts +468 -0
  90. package/figma-intelligence-layer/src/shared/token-utils.ts +420 -0
  91. package/figma-intelligence-layer/src/shared/types.ts +346 -0
  92. package/figma-intelligence-layer/src/shared/typography-presets.ts +94 -0
  93. package/figma-intelligence-layer/src/shared/unsplash.ts +165 -0
  94. package/figma-intelligence-layer/src/shared/vision-client.ts +607 -0
  95. package/figma-intelligence-layer/src/shared/vision-provider-anthropic.ts +334 -0
  96. package/figma-intelligence-layer/src/shared/vision-provider-openai.ts +446 -0
  97. package/figma-intelligence-layer/src/tools/phase1-vision/a11y-audit/a11y-annotate-handler.ts +782 -0
  98. package/figma-intelligence-layer/src/tools/phase1-vision/a11y-audit/a11y-annotate-renderer.ts +496 -0
  99. package/figma-intelligence-layer/src/tools/phase1-vision/a11y-audit/a11y-annotation-kit.ts +230 -0
  100. package/figma-intelligence-layer/src/tools/phase1-vision/a11y-audit/colorblind-sim.ts +66 -0
  101. package/figma-intelligence-layer/src/tools/phase1-vision/a11y-audit/index.ts +810 -0
  102. package/figma-intelligence-layer/src/tools/phase1-vision/a11y-audit/keyboard-sr-order-analyzer.ts +1191 -0
  103. package/figma-intelligence-layer/src/tools/phase1-vision/a11y-audit/keyboard-sr-order-figma-page.ts +1346 -0
  104. package/figma-intelligence-layer/src/tools/phase1-vision/a11y-audit/keyboard-sr-order-handler.ts +148 -0
  105. package/figma-intelligence-layer/src/tools/phase1-vision/a11y-audit/vpat-figma-page.ts +499 -0
  106. package/figma-intelligence-layer/src/tools/phase1-vision/a11y-audit/vpat-report.ts +910 -0
  107. package/figma-intelligence-layer/src/tools/phase1-vision/a11y-audit/wcag-checker.ts +989 -0
  108. package/figma-intelligence-layer/src/tools/phase1-vision/a11y-audit/wcag-criteria.ts +1160 -0
  109. package/figma-intelligence-layer/src/tools/phase1-vision/design-from-ref/index.ts +424 -0
  110. package/figma-intelligence-layer/src/tools/phase1-vision/screen-cloner/component-recognizer.ts +38 -0
  111. package/figma-intelligence-layer/src/tools/phase1-vision/screen-cloner/ds-matcher.ts +111 -0
  112. package/figma-intelligence-layer/src/tools/phase1-vision/screen-cloner/font-matcher.ts +114 -0
  113. package/figma-intelligence-layer/src/tools/phase1-vision/screen-cloner/icon-resolver.ts +103 -0
  114. package/figma-intelligence-layer/src/tools/phase1-vision/screen-cloner/index.ts +1060 -0
  115. package/figma-intelligence-layer/src/tools/phase1-vision/screen-cloner/layout-segmenter.ts +18 -0
  116. package/figma-intelligence-layer/src/tools/phase1-vision/screen-cloner/token-inferencer.ts +39 -0
  117. package/figma-intelligence-layer/src/tools/phase1-vision/screen-cloner/vision-pipeline.ts +58 -0
  118. package/figma-intelligence-layer/src/tools/phase1-vision/sketch-to-design/index.ts +298 -0
  119. package/figma-intelligence-layer/src/tools/phase1-vision/visual-audit/index.ts +197 -0
  120. package/figma-intelligence-layer/src/tools/phase2-accuracy/component-audit/index.ts +494 -0
  121. package/figma-intelligence-layer/src/tools/phase2-accuracy/intent-translator/index.ts +356 -0
  122. package/figma-intelligence-layer/src/tools/phase2-accuracy/layout-intelligence/container-patterns.ts +123 -0
  123. package/figma-intelligence-layer/src/tools/phase2-accuracy/layout-intelligence/index.ts +663 -0
  124. package/figma-intelligence-layer/src/tools/phase2-accuracy/lint-rules/built-in-rules.yaml +56 -0
  125. package/figma-intelligence-layer/src/tools/phase2-accuracy/lint-rules/index.ts +614 -0
  126. package/figma-intelligence-layer/src/tools/phase2-accuracy/lint-rules/rule-engine.ts +113 -0
  127. package/figma-intelligence-layer/src/tools/phase2-accuracy/theme-generator/color-theory.ts +178 -0
  128. package/figma-intelligence-layer/src/tools/phase2-accuracy/theme-generator/index.ts +470 -0
  129. package/figma-intelligence-layer/src/tools/phase2-accuracy/variant-expander/index.ts +429 -0
  130. package/figma-intelligence-layer/src/tools/phase2-accuracy/variant-expander/token-override-maps.ts +226 -0
  131. package/figma-intelligence-layer/src/tools/phase3-generation/ai-image-insert/index.ts +535 -0
  132. package/figma-intelligence-layer/src/tools/phase3-generation/component-archaeologist/index.ts +660 -0
  133. package/figma-intelligence-layer/src/tools/phase3-generation/component-archaeologist/pattern-fingerprints.ts +209 -0
  134. package/figma-intelligence-layer/src/tools/phase3-generation/composition-builder/index.ts +540 -0
  135. package/figma-intelligence-layer/src/tools/phase3-generation/figma-animated-build.ts +391 -0
  136. package/figma-intelligence-layer/src/tools/phase3-generation/page-architect/index.ts +2019 -0
  137. package/figma-intelligence-layer/src/tools/phase3-generation/page-architect/screen-templates.ts +131 -0
  138. package/figma-intelligence-layer/src/tools/phase3-generation/prototype-map/index.ts +381 -0
  139. package/figma-intelligence-layer/src/tools/phase3-generation/prototype-wire/index.ts +565 -0
  140. package/figma-intelligence-layer/src/tools/phase3-generation/swarm-build/index.ts +764 -0
  141. package/figma-intelligence-layer/src/tools/phase3-generation/system-drift/index.ts +535 -0
  142. package/figma-intelligence-layer/src/tools/phase3-generation/unsplash-search/index.ts +84 -0
  143. package/figma-intelligence-layer/src/tools/phase3-generation/url-to-frame/index.ts +401 -0
  144. package/figma-intelligence-layer/src/tools/phase4-sync/animation-specifier/code-generators/css-animations.ts +68 -0
  145. package/figma-intelligence-layer/src/tools/phase4-sync/animation-specifier/code-generators/framer-motion.ts +78 -0
  146. package/figma-intelligence-layer/src/tools/phase4-sync/animation-specifier/code-generators/swift-animations.ts +93 -0
  147. package/figma-intelligence-layer/src/tools/phase4-sync/animation-specifier/index.ts +596 -0
  148. package/figma-intelligence-layer/src/tools/phase4-sync/ci-check/index.ts +462 -0
  149. package/figma-intelligence-layer/src/tools/phase4-sync/export-tokens/index.ts +1470 -0
  150. package/figma-intelligence-layer/src/tools/phase4-sync/generate-component-code/index.ts +829 -0
  151. package/figma-intelligence-layer/src/tools/phase4-sync/handoff-spec/index.ts +702 -0
  152. package/figma-intelligence-layer/src/tools/phase4-sync/icon-library-sync/index.ts +483 -0
  153. package/figma-intelligence-layer/src/tools/phase4-sync/sync-from-code/index.ts +501 -0
  154. package/figma-intelligence-layer/src/tools/phase4-sync/sync-from-code/storybook-parser.ts +106 -0
  155. package/figma-intelligence-layer/src/tools/phase4-sync/watch-docs/index.ts +676 -0
  156. package/figma-intelligence-layer/src/tools/phase4-sync/webhook-listener/index.ts +560 -0
  157. package/figma-intelligence-layer/src/tools/phase5-governance/apg-doc/index.ts +1043 -0
  158. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/component-detection.ts +620 -0
  159. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/extractors/anatomy.ts +331 -0
  160. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/extractors/color-tokens.ts +77 -0
  161. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/extractors/properties.ts +54 -0
  162. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/extractors/snapshot.ts +287 -0
  163. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/extractors/spacing.ts +71 -0
  164. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/extractors/states.ts +43 -0
  165. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/extractors/typography.ts +71 -0
  166. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/index.ts +221 -0
  167. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/_default.ts +166 -0
  168. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/accordion.ts +232 -0
  169. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/alert.ts +234 -0
  170. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/avatar-group.ts +270 -0
  171. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/avatar.ts +249 -0
  172. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/badge.ts +231 -0
  173. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/banner.ts +293 -0
  174. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/breadcrumb.ts +240 -0
  175. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/button.ts +243 -0
  176. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/calendar.ts +307 -0
  177. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/card.ts +143 -0
  178. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/checkbox.ts +227 -0
  179. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/chip.ts +233 -0
  180. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/combobox.ts +282 -0
  181. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/datepicker.ts +276 -0
  182. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/divider.ts +223 -0
  183. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/drawer.ts +255 -0
  184. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/dropdown-menu.ts +289 -0
  185. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/empty-state.ts +261 -0
  186. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/file-uploader.ts +290 -0
  187. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/form.ts +265 -0
  188. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/grid.ts +238 -0
  189. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/icon.ts +255 -0
  190. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/index.ts +128 -0
  191. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/inline-edit.ts +286 -0
  192. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/inline-message.ts +255 -0
  193. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/input.ts +330 -0
  194. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/link.ts +247 -0
  195. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/list.ts +250 -0
  196. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/menu.ts +247 -0
  197. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/modal.ts +144 -0
  198. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/navbar.ts +264 -0
  199. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/navigation.ts +251 -0
  200. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/number-input.ts +261 -0
  201. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/pagination.ts +248 -0
  202. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/popover.ts +270 -0
  203. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/progress.ts +251 -0
  204. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/radio.ts +142 -0
  205. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/range-slider.ts +282 -0
  206. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/rating.ts +250 -0
  207. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/search.ts +258 -0
  208. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/segmented-control.ts +265 -0
  209. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/select.ts +319 -0
  210. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/skeleton.ts +256 -0
  211. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/slider.ts +232 -0
  212. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/spinner.ts +239 -0
  213. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/status-dot.ts +252 -0
  214. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/stepper.ts +270 -0
  215. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/table.ts +244 -0
  216. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/tabs.ts +143 -0
  217. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/tag.ts +243 -0
  218. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/textarea.ts +259 -0
  219. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/time-picker.ts +293 -0
  220. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/toast.ts +144 -0
  221. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/toggle.ts +289 -0
  222. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/toolbar.ts +267 -0
  223. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/tooltip.ts +232 -0
  224. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/treeview.ts +257 -0
  225. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/typography.ts +319 -0
  226. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/legacy-compat.ts +121 -0
  227. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/renderers/anatomy-diagram.ts +430 -0
  228. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/renderers/figma-page.ts +312 -0
  229. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/renderers/json.ts +129 -0
  230. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/renderers/markdown.ts +78 -0
  231. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/renderers/visual-doc.ts +2333 -0
  232. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/accessibility.ts +100 -0
  233. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/anatomy.ts +32 -0
  234. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/color-tokens.ts +59 -0
  235. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/content-guidance.ts +18 -0
  236. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/design-tokens.ts +53 -0
  237. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/interaction-rules.ts +19 -0
  238. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/overview.ts +91 -0
  239. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/properties-api.ts +71 -0
  240. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/qa-criteria.ts +19 -0
  241. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/related-components.ts +110 -0
  242. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/responsive.ts +19 -0
  243. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/size-specs.ts +67 -0
  244. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/spacing-structure.ts +58 -0
  245. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/state-specs.ts +79 -0
  246. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/states.ts +50 -0
  247. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/type-hierarchy.ts +33 -0
  248. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/typography.ts +55 -0
  249. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/usage-guidelines.ts +73 -0
  250. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/variants.ts +81 -0
  251. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/types.ts +409 -0
  252. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec-sheet/index.ts +198 -0
  253. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec-sheet/renderer.ts +701 -0
  254. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec-sheet/types.ts +88 -0
  255. package/figma-intelligence-layer/src/tools/phase5-governance/decision-log/index.ts +135 -0
  256. package/figma-intelligence-layer/src/tools/phase5-governance/design-decision-log/index.ts +491 -0
  257. package/figma-intelligence-layer/src/tools/phase5-governance/ds-primitives/index.ts +416 -0
  258. package/figma-intelligence-layer/src/tools/phase5-governance/ds-scaffolder/index.ts +722 -0
  259. package/figma-intelligence-layer/src/tools/phase5-governance/ds-variables/index.ts +449 -0
  260. package/figma-intelligence-layer/src/tools/phase5-governance/health-report/index.ts +393 -0
  261. package/figma-intelligence-layer/src/tools/phase5-governance/taxonomy-docs/index.ts +406 -0
  262. package/figma-intelligence-layer/src/tools/phase5-governance/taxonomy-docs/renderers/figma-page.ts +292 -0
  263. package/figma-intelligence-layer/src/tools/phase5-governance/taxonomy-docs/renderers/json.ts +24 -0
  264. package/figma-intelligence-layer/src/tools/phase5-governance/taxonomy-docs/renderers/markdown.ts +172 -0
  265. package/figma-intelligence-layer/src/tools/phase5-governance/taxonomy-docs/renderers/naming-guide.ts +409 -0
  266. package/figma-intelligence-layer/src/tools/phase5-governance/token-analytics/index.ts +594 -0
  267. package/figma-intelligence-layer/src/tools/phase5-governance/token-docs/index.ts +710 -0
  268. package/figma-intelligence-layer/src/tools/phase5-governance/token-migrate/index.ts +458 -0
  269. package/figma-intelligence-layer/src/tools/phase5-governance/token-naming/index.ts +134 -0
  270. package/figma-intelligence-layer/tests/apg-doc.test.ts +101 -0
  271. package/figma-intelligence-layer/tests/design-system-context.test.ts +152 -0
  272. package/figma-intelligence-layer/tests/design-system-matcher.test.ts +144 -0
  273. package/figma-intelligence-layer/tests/figma-bridge.test.ts +83 -0
  274. package/figma-intelligence-layer/tests/generate-image-and-insert.test.ts +56 -0
  275. package/figma-intelligence-layer/tests/screen-cloner-regression.test.ts +69 -0
  276. package/figma-intelligence-layer/tests/smoke.test.ts +174 -0
  277. package/figma-intelligence-layer/tests/spec-generator.test.ts +127 -0
  278. package/figma-intelligence-layer/tests/token-migrate.test.ts +21 -0
  279. package/figma-intelligence-layer/tests/token-naming.test.ts +30 -0
  280. package/figma-intelligence-layer/tsconfig.json +19 -0
  281. package/package.json +35 -0
  282. package/scripts/clean-existing-chunks.js +179 -0
  283. package/scripts/connect-ai-tool.js +490 -0
  284. package/scripts/convert-hub-pdfs.js +425 -0
  285. package/scripts/figma-mcp-status.js +349 -0
  286. package/scripts/register-codex-mcp.js +96 -0
@@ -0,0 +1,607 @@
1
+ import {
2
+ VisionResult,
3
+ LayoutZone,
4
+ LayoutNode,
5
+ LayoutNodeAlignment,
6
+ LayoutNodeType,
7
+ ComponentManifest,
8
+ } from "./types.js";
9
+ import { OpenAIVisionProvider } from "./vision-provider-openai.js";
10
+ import { AnthropicVisionProvider } from "./vision-provider-anthropic.js";
11
+
12
+ const DEFAULT_MANIFEST: ComponentManifest = {
13
+ componentType: "Unknown",
14
+ variants: {},
15
+ iconPresent: false,
16
+ iconKind: "unknown",
17
+ preferredIconLibrary: "material-symbols",
18
+ interactiveElement: false,
19
+ estimatedSpacing: 8,
20
+ confidence: 0.3,
21
+ };
22
+
23
+ function clampConfidence(value: unknown, fallback = 0.5): number {
24
+ if (typeof value !== "number" || !Number.isFinite(value)) return fallback;
25
+ return Math.min(1, Math.max(0, value));
26
+ }
27
+
28
+ function coerceOptionalConfidence(value: unknown): number | undefined {
29
+ if (typeof value !== "number" || !Number.isFinite(value)) return undefined;
30
+ return Math.min(1, Math.max(0, value));
31
+ }
32
+
33
+ function coerceOptionalString(value: unknown): string | undefined {
34
+ return typeof value === "string" && value.trim() ? value.trim() : undefined;
35
+ }
36
+
37
+ function coerceOptionalNumber(value: unknown): number | undefined {
38
+ return typeof value === "number" && Number.isFinite(value) ? value : undefined;
39
+ }
40
+
41
+ function coerceStringArray(value: unknown): string[] | undefined {
42
+ if (!Array.isArray(value)) return undefined;
43
+ const strings = value.filter((item): item is string => typeof item === "string" && item.trim().length > 0);
44
+ return strings.length > 0 ? strings : undefined;
45
+ }
46
+
47
+ function normalizeLayoutType(value: unknown): LayoutNodeType {
48
+ switch (value) {
49
+ case "page":
50
+ case "sidebar":
51
+ case "header":
52
+ case "toolbar":
53
+ case "content":
54
+ case "footer":
55
+ case "drawer":
56
+ case "modal":
57
+ case "card":
58
+ case "form":
59
+ case "form-row":
60
+ case "nav":
61
+ case "button-group":
62
+ case "tab-bar":
63
+ case "table":
64
+ case "table-row":
65
+ case "list":
66
+ case "list-item":
67
+ case "section":
68
+ case "overlay":
69
+ return value;
70
+ default:
71
+ return "content";
72
+ }
73
+ }
74
+
75
+ function normalizeLayoutAlignment(raw: unknown): LayoutNodeAlignment | undefined {
76
+ if (!raw || typeof raw !== "object") return undefined;
77
+ const candidate = raw as Record<string, unknown>;
78
+ const padding =
79
+ candidate.padding && typeof candidate.padding === "object"
80
+ ? (candidate.padding as Record<string, unknown>)
81
+ : null;
82
+
83
+ const direction =
84
+ candidate.direction === "horizontal" ||
85
+ candidate.direction === "vertical" ||
86
+ candidate.direction === "none"
87
+ ? candidate.direction
88
+ : undefined;
89
+
90
+ const distribution =
91
+ candidate.distribution === "start" ||
92
+ candidate.distribution === "center" ||
93
+ candidate.distribution === "end" ||
94
+ candidate.distribution === "space-between"
95
+ ? candidate.distribution
96
+ : undefined;
97
+
98
+ const crossAlignment =
99
+ candidate.crossAlignment === "start" ||
100
+ candidate.crossAlignment === "center" ||
101
+ candidate.crossAlignment === "end" ||
102
+ candidate.crossAlignment === "stretch"
103
+ ? candidate.crossAlignment
104
+ : undefined;
105
+
106
+ const stackingOrder =
107
+ candidate.stackingOrder === "normal" ||
108
+ candidate.stackingOrder === "reverse" ||
109
+ candidate.stackingOrder === "overlay"
110
+ ? candidate.stackingOrder
111
+ : undefined;
112
+
113
+ const normalizedPadding =
114
+ padding &&
115
+ [padding.top, padding.right, padding.bottom, padding.left].some((value) => coerceOptionalNumber(value) != null)
116
+ ? {
117
+ top: coerceOptionalNumber(padding.top),
118
+ right: coerceOptionalNumber(padding.right),
119
+ bottom: coerceOptionalNumber(padding.bottom),
120
+ left: coerceOptionalNumber(padding.left),
121
+ }
122
+ : undefined;
123
+
124
+ if (
125
+ direction == null &&
126
+ distribution == null &&
127
+ crossAlignment == null &&
128
+ coerceOptionalNumber(candidate.gap) == null &&
129
+ normalizedPadding == null &&
130
+ coerceOptionalNumber(candidate.columns) == null &&
131
+ stackingOrder == null
132
+ ) {
133
+ return undefined;
134
+ }
135
+
136
+ return {
137
+ direction,
138
+ distribution,
139
+ crossAlignment,
140
+ gap: coerceOptionalNumber(candidate.gap),
141
+ padding: normalizedPadding,
142
+ columns: coerceOptionalNumber(candidate.columns),
143
+ stackingOrder,
144
+ };
145
+ }
146
+
147
+ function normalizeLayoutNode(
148
+ raw: unknown,
149
+ path: string,
150
+ fallbackType: LayoutNodeType = "content"
151
+ ): LayoutNode | null {
152
+ if (!raw || typeof raw !== "object") return null;
153
+ const candidate = raw as Record<string, unknown>;
154
+ const boundingBox =
155
+ candidate.boundingBox && typeof candidate.boundingBox === "object"
156
+ ? (candidate.boundingBox as Record<string, unknown>)
157
+ : null;
158
+
159
+ if (!boundingBox) return null;
160
+
161
+ const x = coerceOptionalNumber(boundingBox.x);
162
+ const y = coerceOptionalNumber(boundingBox.y);
163
+ const width = coerceOptionalNumber(boundingBox.width);
164
+ const height = coerceOptionalNumber(boundingBox.height);
165
+
166
+ if ([x, y, width, height].some((value) => value == null)) return null;
167
+
168
+ const children = Array.isArray(candidate.children)
169
+ ? candidate.children
170
+ .map((child, index) => normalizeLayoutNode(child, `${path}.${index}`))
171
+ .filter((child): child is LayoutNode => child !== null)
172
+ : undefined;
173
+
174
+ const normalizedChildCount = Math.max(
175
+ 0,
176
+ Math.round(
177
+ coerceOptionalNumber(candidate.childCount) ??
178
+ children?.length ??
179
+ 0
180
+ )
181
+ );
182
+
183
+ const alignedLeftWith = coerceStringArray((candidate.siblingHints as Record<string, unknown> | undefined)?.alignedLeftWith);
184
+ const equalSpacingWith = coerceStringArray((candidate.siblingHints as Record<string, unknown> | undefined)?.equalSpacingWith);
185
+ const repeatedChildren = coerceStringArray((candidate.siblingHints as Record<string, unknown> | undefined)?.repeatedChildren);
186
+ const anchored =
187
+ (candidate.siblingHints as Record<string, unknown> | undefined)?.anchored === "left" ||
188
+ (candidate.siblingHints as Record<string, unknown> | undefined)?.anchored === "right" ||
189
+ (candidate.siblingHints as Record<string, unknown> | undefined)?.anchored === "top" ||
190
+ (candidate.siblingHints as Record<string, unknown> | undefined)?.anchored === "bottom" ||
191
+ (candidate.siblingHints as Record<string, unknown> | undefined)?.anchored === "center"
192
+ ? ((candidate.siblingHints as Record<string, unknown>).anchored as "left" | "right" | "top" | "bottom" | "center")
193
+ : undefined;
194
+
195
+ const repetitionCandidate =
196
+ candidate.repetition && typeof candidate.repetition === "object"
197
+ ? (candidate.repetition as Record<string, unknown>)
198
+ : null;
199
+
200
+ return {
201
+ id: coerceOptionalString(candidate.id) ?? path,
202
+ label: coerceOptionalString(candidate.label) ?? "Zone",
203
+ boundingBox: { x: x!, y: y!, width: width!, height: height! },
204
+ layoutType: normalizeLayoutType(candidate.layoutType ?? fallbackType),
205
+ childCount: normalizedChildCount,
206
+ children: children && children.length > 0 ? children : undefined,
207
+ layout: normalizeLayoutAlignment(candidate.layout),
208
+ siblingHints:
209
+ alignedLeftWith || equalSpacingWith || repeatedChildren || anchored || candidate.overlay === true
210
+ ? {
211
+ alignedLeftWith,
212
+ equalSpacingWith,
213
+ repeatedChildren,
214
+ anchored,
215
+ overlay: candidate.overlay === true || (candidate.siblingHints as Record<string, unknown> | undefined)?.overlay === true,
216
+ }
217
+ : undefined,
218
+ repetition:
219
+ repetitionCandidate && repetitionCandidate.isRepeated === true
220
+ ? {
221
+ isRepeated: true,
222
+ pattern:
223
+ repetitionCandidate.pattern === "row" ||
224
+ repetitionCandidate.pattern === "column" ||
225
+ repetitionCandidate.pattern === "grid" ||
226
+ repetitionCandidate.pattern === "tabs" ||
227
+ repetitionCandidate.pattern === "menu" ||
228
+ repetitionCandidate.pattern === "list"
229
+ ? repetitionCandidate.pattern
230
+ : undefined,
231
+ itemCount: coerceOptionalNumber(repetitionCandidate.itemCount),
232
+ canonicalChildId: coerceOptionalString(repetitionCandidate.canonicalChildId),
233
+ repeatedChildIds: coerceStringArray(repetitionCandidate.repeatedChildIds),
234
+ repeatAxis:
235
+ repetitionCandidate.repeatAxis === "horizontal" || repetitionCandidate.repeatAxis === "vertical"
236
+ ? repetitionCandidate.repeatAxis
237
+ : undefined,
238
+ }
239
+ : undefined,
240
+ zoneImage: coerceOptionalString(candidate.zoneImage),
241
+ };
242
+ }
243
+
244
+ function inferDirectionFromChildren(children: LayoutNode[]): "horizontal" | "vertical" | "none" {
245
+ if (children.length < 2) return "none";
246
+
247
+ const xSpread =
248
+ Math.max(...children.map((child) => child.boundingBox.x + child.boundingBox.width / 2)) -
249
+ Math.min(...children.map((child) => child.boundingBox.x + child.boundingBox.width / 2));
250
+ const ySpread =
251
+ Math.max(...children.map((child) => child.boundingBox.y + child.boundingBox.height / 2)) -
252
+ Math.min(...children.map((child) => child.boundingBox.y + child.boundingBox.height / 2));
253
+
254
+ return xSpread > ySpread ? "horizontal" : "vertical";
255
+ }
256
+
257
+ function enrichRepeatedPatterns(nodes: LayoutNode[]): LayoutNode[] {
258
+ return nodes.map((node) => {
259
+ const children = node.children ? enrichRepeatedPatterns(node.children) : undefined;
260
+ const nextNode: LayoutNode = { ...node, children };
261
+
262
+ if (!children || children.length < 2 || nextNode.repetition?.isRepeated) {
263
+ return nextNode;
264
+ }
265
+
266
+ const repeated = children.filter((child) => child.layoutType === children[0].layoutType);
267
+ const aligned =
268
+ repeated.length >= 2 &&
269
+ repeated.every((child) => {
270
+ const widthDelta = Math.abs(child.boundingBox.width - repeated[0].boundingBox.width);
271
+ const heightDelta = Math.abs(child.boundingBox.height - repeated[0].boundingBox.height);
272
+ return widthDelta <= 6 || heightDelta <= 6;
273
+ });
274
+
275
+ if (!aligned) return nextNode;
276
+
277
+ const repeatAxis =
278
+ nextNode.layout?.direction && nextNode.layout.direction !== "none"
279
+ ? nextNode.layout.direction
280
+ : inferDirectionFromChildren(children);
281
+
282
+ const pattern =
283
+ repeated[0].layoutType === "table-row"
284
+ ? "row"
285
+ : repeated[0].layoutType === "tab-bar"
286
+ ? "tabs"
287
+ : repeated[0].layoutType === "list-item"
288
+ ? "list"
289
+ : repeatAxis === "horizontal"
290
+ ? "row"
291
+ : "list";
292
+
293
+ nextNode.repetition = {
294
+ isRepeated: true,
295
+ pattern,
296
+ itemCount: repeated.length,
297
+ canonicalChildId: repeated[0].id,
298
+ repeatedChildIds: repeated.map((child) => child.id),
299
+ repeatAxis: repeatAxis === "none" ? "vertical" : repeatAxis,
300
+ };
301
+
302
+ return nextNode;
303
+ });
304
+ }
305
+
306
+ function normalizeManifest(raw: unknown): ComponentManifest {
307
+ if (!raw || typeof raw !== "object") return { ...DEFAULT_MANIFEST };
308
+
309
+ const candidate = raw as Record<string, unknown>;
310
+ const iconPresent = Boolean(candidate.iconPresent ?? candidate.iconName);
311
+ const normalized: ComponentManifest = {
312
+ componentType: coerceOptionalString(candidate.componentType) ?? DEFAULT_MANIFEST.componentType,
313
+ variants:
314
+ candidate.variants && typeof candidate.variants === "object"
315
+ ? Object.fromEntries(
316
+ Object.entries(candidate.variants as Record<string, unknown>).filter(
317
+ (entry): entry is [string, string] => typeof entry[1] === "string"
318
+ )
319
+ )
320
+ : {},
321
+ textContent: coerceOptionalString(candidate.textContent),
322
+ textContentConfidence: coerceOptionalConfidence(candidate.textContentConfidence),
323
+ iconPresent,
324
+ iconName: coerceOptionalString(candidate.iconName),
325
+ iconNameConfidence: coerceOptionalConfidence(candidate.iconNameConfidence),
326
+ iconKind:
327
+ candidate.iconKind === "system" ||
328
+ candidate.iconKind === "brand" ||
329
+ candidate.iconKind === "illustration" ||
330
+ candidate.iconKind === "unknown"
331
+ ? candidate.iconKind
332
+ : "unknown",
333
+ preferredIconLibrary: coerceOptionalString(candidate.preferredIconLibrary),
334
+ openSourceIconName: coerceOptionalString(candidate.openSourceIconName),
335
+ interactiveElement: Boolean(candidate.interactiveElement),
336
+ estimatedSpacing: coerceOptionalNumber(candidate.estimatedSpacing) ?? DEFAULT_MANIFEST.estimatedSpacing,
337
+ estimatedSpacingConfidence: coerceOptionalConfidence(candidate.estimatedSpacingConfidence),
338
+ estimatedRadius: coerceOptionalNumber(candidate.estimatedRadius),
339
+ estimatedRadiusConfidence: coerceOptionalConfidence(candidate.estimatedRadiusConfidence),
340
+ estimatedFontSize: coerceOptionalNumber(candidate.estimatedFontSize),
341
+ estimatedFontSizeConfidence: coerceOptionalConfidence(candidate.estimatedFontSizeConfidence),
342
+ fontFamilyGuess: coerceOptionalString(candidate.fontFamilyGuess),
343
+ fontFamilyGuessConfidence: coerceOptionalConfidence(candidate.fontFamilyGuessConfidence),
344
+ fontStyleGuess: coerceOptionalString(candidate.fontStyleGuess),
345
+ fontStyleGuessConfidence: coerceOptionalConfidence(candidate.fontStyleGuessConfidence),
346
+ fontWeightGuess: coerceOptionalNumber(candidate.fontWeightGuess),
347
+ fontWeightGuessConfidence: coerceOptionalConfidence(candidate.fontWeightGuessConfidence),
348
+ confidence: clampConfidence(candidate.confidence, DEFAULT_MANIFEST.confidence),
349
+ dsBestMatch: coerceOptionalString(candidate.dsBestMatch),
350
+ dsNodeId: coerceOptionalString(candidate.dsNodeId),
351
+ };
352
+
353
+ if (!normalized.iconPresent) {
354
+ normalized.iconName = undefined;
355
+ normalized.iconNameConfidence = undefined;
356
+ }
357
+
358
+ return normalized;
359
+ }
360
+
361
+ function normalizeZones(raw: unknown): LayoutZone[] | undefined {
362
+ if (!Array.isArray(raw)) return undefined;
363
+
364
+ const zones = raw
365
+ .map((zone, index) => normalizeLayoutNode(zone, `zone-${index}`))
366
+ .filter((zone): zone is LayoutZone => zone !== null);
367
+
368
+ return zones.length > 0 ? enrichRepeatedPatterns(zones) : undefined;
369
+ }
370
+
371
+ function normalizeVisionResult(raw: unknown): VisionResult {
372
+ const candidate = raw && typeof raw === "object" ? (raw as Record<string, unknown>) : {};
373
+ const layoutTree = normalizeZones(candidate.layoutTree ?? candidate.zones);
374
+ return {
375
+ rawAnalysis:
376
+ typeof candidate.rawAnalysis === "string" && candidate.rawAnalysis.trim()
377
+ ? candidate.rawAnalysis
378
+ : "[Vision analysis unavailable]",
379
+ confidence: clampConfidence(candidate.confidence, 0.5),
380
+ layoutTree,
381
+ zones: layoutTree,
382
+ manifest: candidate.manifest ? normalizeManifest(candidate.manifest) : undefined,
383
+ };
384
+ }
385
+
386
+ /**
387
+ * VisionClient — local heuristic image analysis utility.
388
+ *
389
+ * No external API key required. Returns reasonable defaults.
390
+ * The MCP client AI provides actual vision intelligence by
391
+ * seeing images returned in tool responses.
392
+ */
393
+ export class VisionClient {
394
+ private readonly providerName: string;
395
+ private readonly openaiProvider: OpenAIVisionProvider;
396
+ private readonly anthropicProvider: AnthropicVisionProvider;
397
+
398
+ constructor() {
399
+ const explicit = (process.env.VISION_PROVIDER || "").toLowerCase();
400
+ // Auto-detect a real vision provider when none is explicitly configured.
401
+ // Priority: explicit env → anthropic (if API key present) → openai (if API key present) → offline
402
+ if (explicit) {
403
+ this.providerName = explicit;
404
+ } else if (process.env.ANTHROPIC_API_KEY) {
405
+ this.providerName = "anthropic";
406
+ } else if (process.env.OPENAI_API_KEY) {
407
+ this.providerName = "openai";
408
+ } else {
409
+ this.providerName = "offline";
410
+ }
411
+ this.openaiProvider = new OpenAIVisionProvider();
412
+ this.anthropicProvider = new AnthropicVisionProvider();
413
+ }
414
+
415
+ private isOfflineProvider(): boolean {
416
+ return (
417
+ this.providerName === "offline" ||
418
+ this.providerName === "local" ||
419
+ this.providerName === "heuristic" ||
420
+ this.providerName === "none"
421
+ );
422
+ }
423
+
424
+ async analyze(image: string, prompt: string): Promise<VisionResult> {
425
+ if (this.providerName === "openai") {
426
+ const result = await this.openaiProvider.analyze(image, prompt);
427
+ return normalizeVisionResult(result);
428
+ }
429
+
430
+ if (this.providerName === "anthropic") {
431
+ const result = await this.anthropicProvider.analyze(image, prompt);
432
+ return normalizeVisionResult(result);
433
+ }
434
+
435
+ if (this.isOfflineProvider()) {
436
+ return {
437
+ rawAnalysis:
438
+ "[Offline heuristic analysis] Remote vision is disabled, so the cloner is using a local fallback summary.",
439
+ confidence: 0.25,
440
+ };
441
+ }
442
+
443
+ return {
444
+ rawAnalysis: `[Vision provider "${this.providerName}" is not supported]`,
445
+ confidence: 0,
446
+ };
447
+ }
448
+
449
+ async segment(_image: string): Promise<LayoutNode[]> {
450
+ const prompt = `Identify the UI layout as a nested hierarchy, not a flat zone list. Return strict JSON with:
451
+ - rawAnalysis: short machine-readable summary string
452
+ - confidence: overall confidence from 0 to 1
453
+ - layoutTree: array of root layout nodes
454
+ - each layout node must include:
455
+ - id: stable node id string
456
+ - label: descriptive name of the region
457
+ - boundingBox: {x, y, width, height} as percentages (0-100) of total image size
458
+ - layoutType: one of "page"|"sidebar"|"header"|"toolbar"|"content"|"footer"|"drawer"|"modal"|"card"|"form"|"form-row"|"nav"|"button-group"|"tab-bar"|"table"|"table-row"|"list"|"list-item"|"section"|"overlay"
459
+ - childCount: estimated number of direct child elements
460
+ - children: nested layout nodes
461
+ - layout: { direction, distribution, crossAlignment, gap, padding, columns, stackingOrder }
462
+ - siblingHints: { alignedLeftWith, equalSpacingWith, repeatedChildren, anchored, overlay }
463
+ - repetition: { isRepeated, pattern, itemCount, canonicalChildId, repeatedChildIds, repeatAxis } when a repeated row/list/tab/menu structure exists
464
+
465
+ Prefer a single "page" root when the whole screen is one page. Include repeated row/list hints whenever items visually repeat. Only use overlays for floating drawers, modals, popovers, badges, or absolute-positioned elements.
466
+
467
+ Return ONLY valid JSON.`;
468
+
469
+ if (this.providerName === "openai") {
470
+ const result = await this.openaiProvider.segment(_image, prompt);
471
+ return normalizeVisionResult(result).layoutTree ?? [];
472
+ }
473
+
474
+ if (this.providerName === "anthropic") {
475
+ const result = await this.anthropicProvider.segment(_image, prompt);
476
+ return normalizeVisionResult(result).layoutTree ?? [];
477
+ }
478
+
479
+ if (this.isOfflineProvider()) {
480
+ return [
481
+ {
482
+ id: "page-root",
483
+ label: "Page",
484
+ boundingBox: { x: 0, y: 0, width: 100, height: 100 },
485
+ layoutType: "page",
486
+ childCount: 0,
487
+ layout: {
488
+ direction: "vertical",
489
+ distribution: "start",
490
+ crossAlignment: "stretch",
491
+ gap: 0,
492
+ padding: { top: 0, right: 0, bottom: 0, left: 0 },
493
+ stackingOrder: "normal",
494
+ },
495
+ },
496
+ ];
497
+ }
498
+
499
+ return [];
500
+ }
501
+
502
+ async identify(zoneImage: string): Promise<ComponentManifest> {
503
+ const prompt = `Analyze this UI region and identify the component. Return JSON with:
504
+ - componentType: specific UI component name (e.g. "PrimaryButton", "TextInput", "NavigationBar")
505
+ - variants: object of detected variants {size, state, theme, type}
506
+ - textContent: visible text content (null if none)
507
+ - iconPresent: boolean
508
+ - iconName: best guess for the icon or logo name (null if none)
509
+ - iconKind: "system" | "brand" | "illustration" | "unknown"
510
+ - preferredIconLibrary: best open-source icon family for this region, prefer "material-symbols" for common UI icons and "simple-icons" for brands
511
+ - openSourceIconName: exact open-source icon slug if recognizable (examples: "menu", "search", "close", "shopping_cart")
512
+ - interactiveElement: boolean (is this clickable/focusable?)
513
+ - estimatedSpacing: measured padding/gap in pixels, prefer exact visual estimate over assumptions
514
+ - estimatedRadius: border radius in pixels if visible
515
+ - estimatedFontSize: visible text size in pixels if text is present
516
+ - fontFamilyGuess: closest visible font family name if text is present
517
+ - fontStyleGuess: closest visible font style name if text is present
518
+ - fontWeightGuess: closest visible font weight number if text is present
519
+ - confidence: 0-1 how confident you are in this identification
520
+
521
+ Return ONLY valid JSON.`;
522
+
523
+ if (this.providerName === "openai") {
524
+ const result = await this.openaiProvider.identify(zoneImage, prompt);
525
+ return normalizeVisionResult(result).manifest ?? { ...DEFAULT_MANIFEST };
526
+ }
527
+
528
+ if (this.providerName === "anthropic") {
529
+ const result = await this.anthropicProvider.identify(zoneImage, prompt);
530
+ return normalizeVisionResult(result).manifest ?? { ...DEFAULT_MANIFEST };
531
+ }
532
+
533
+ if (this.isOfflineProvider()) {
534
+ return {
535
+ ...DEFAULT_MANIFEST,
536
+ componentType: "ScreenshotRegion",
537
+ interactiveElement: false,
538
+ estimatedSpacing: 0,
539
+ confidence: 0.2,
540
+ };
541
+ }
542
+
543
+ return { ...DEFAULT_MANIFEST };
544
+ }
545
+
546
+ async describeComponent(image: string): Promise<string> {
547
+ const prompt = `Describe this UI component in one concise sentence focusing on its purpose, visual style, and key properties. Be specific about size, color, state, and interactive behavior.`;
548
+ const result = await this.analyze(image, prompt);
549
+ return result.rawAnalysis;
550
+ }
551
+
552
+ async auditVisualQuality(
553
+ image: string,
554
+ areas: string[]
555
+ ): Promise<Record<string, unknown>> {
556
+ const prompt = `Perform a professional UX quality audit of this UI screenshot. Analyze: ${areas.join(", ")}.
557
+
558
+ Return JSON with:
559
+ {
560
+ "hierarchyScore": 0-100,
561
+ "cognitiveLoadRating": "low"|"medium"|"high",
562
+ "brandAlignmentNotes": "...",
563
+ "consistencyIssues": ["..."],
564
+ "overallScore": 0-100,
565
+ "topIssues": [{"severity":"error"|"warning"|"suggestion","description":"...","area":"..."}],
566
+ "estimatedFixTimeMinutes": N
567
+ }
568
+
569
+ Return ONLY valid JSON.`;
570
+
571
+ const result = await this.analyze(image, prompt);
572
+ try {
573
+ const jsonMatch = result.rawAnalysis.match(/```json\n?([\s\S]*?)\n?```/);
574
+ if (jsonMatch) return JSON.parse(jsonMatch[1]);
575
+ return JSON.parse(result.rawAnalysis);
576
+ } catch {
577
+ return { rawAnalysis: result.rawAnalysis };
578
+ }
579
+ }
580
+
581
+ async interpretSketch(
582
+ _image: string,
583
+ _productContext: string
584
+ ): Promise<LayoutZone[]> {
585
+ return [
586
+ { id: "sketch-header", label: "Top Section", boundingBox: { x: 0, y: 0, width: 100, height: 20 }, layoutType: "header", childCount: 2 },
587
+ { id: "sketch-content", label: "Content Area", boundingBox: { x: 0, y: 20, width: 100, height: 60 }, layoutType: "content", childCount: 4 },
588
+ { id: "sketch-footer", label: "Action Area", boundingBox: { x: 0, y: 80, width: 100, height: 20 }, layoutType: "footer", childCount: 2 },
589
+ ];
590
+ }
591
+
592
+ async extractDesignLanguage(
593
+ _references: string[],
594
+ _extractTypes: string[]
595
+ ): Promise<Record<string, unknown>> {
596
+ return {
597
+ layout: { gridStructure: "12-column", zoneProportions: "balanced", hierarchy: "standard" },
598
+ spacing: { density: "comfortable", paddingPattern: "16px", dominantGap: 16 },
599
+ colorPalette: [
600
+ { role: "primary", hex: "#2563EB", frequency: "dominant" },
601
+ { role: "surface", hex: "#FFFFFF", frequency: "dominant" },
602
+ { role: "text", hex: "#1E293B", frequency: "dominant" },
603
+ ],
604
+ typography: { scalePattern: "modular", dominantWeights: [400, 600], hierarchyLevels: 3 },
605
+ };
606
+ }
607
+ }