@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,458 @@
1
+ import { getBridge } from "../../../shared/figma-bridge";
2
+ import { analyzeTokenName } from "../../../shared/token-naming";
3
+
4
+ export type TokenMigrationAction = "scan" | "preview" | "apply";
5
+ export type TokenMigrationScope = "variables" | "styles" | "all";
6
+ export type TokenMigrationSchema = "compact" | "expanded";
7
+
8
+ export interface TokenMigrateArgs {
9
+ action: TokenMigrationAction;
10
+ scope?: TokenMigrationScope;
11
+ collectionName?: string;
12
+ canonicalSchema?: TokenMigrationSchema;
13
+ renameInPlace?: boolean;
14
+ createAliases?: boolean;
15
+ dryRun?: boolean;
16
+ }
17
+
18
+ interface VariableCollectionSummary {
19
+ id: string;
20
+ name: string;
21
+ modes: Array<{ modeId: string; name: string }>;
22
+ variables: Array<{
23
+ id: string;
24
+ name: string;
25
+ type: "COLOR" | "FLOAT" | "STRING" | "BOOLEAN";
26
+ collectionId?: string;
27
+ }>;
28
+ }
29
+
30
+ interface PaintStyleSummary {
31
+ id: string;
32
+ name: string;
33
+ description?: string;
34
+ }
35
+
36
+ interface TextStyleSummary {
37
+ id: string;
38
+ name: string;
39
+ description?: string;
40
+ }
41
+
42
+ interface EffectStyleSummary {
43
+ id: string;
44
+ name: string;
45
+ description?: string;
46
+ }
47
+
48
+ interface StyleSummaryResult {
49
+ paint?: PaintStyleSummary[];
50
+ text?: TextStyleSummary[];
51
+ effect?: EffectStyleSummary[];
52
+ }
53
+
54
+ export interface TokenMigrationItem {
55
+ kind: "variable" | "style";
56
+ subtype?: "paint" | "text" | "effect";
57
+ id: string;
58
+ collectionId?: string;
59
+ collectionName?: string;
60
+ originalName: string;
61
+ normalizedName: string;
62
+ suggestedName: string | null;
63
+ confidence: number;
64
+ safeToApply: boolean;
65
+ reasons: string[];
66
+ willRename: boolean;
67
+ }
68
+
69
+ export interface TokenMigrateResult {
70
+ ok: boolean;
71
+ action: TokenMigrationAction;
72
+ scope: TokenMigrationScope;
73
+ canonicalSchema: TokenMigrationSchema;
74
+ scanned: {
75
+ variables: number;
76
+ styles: number;
77
+ };
78
+ summary: {
79
+ proposed: number;
80
+ safe: number;
81
+ ambiguous: number;
82
+ applied: number;
83
+ aliased: number;
84
+ skipped: number;
85
+ };
86
+ items: TokenMigrationItem[];
87
+ appliedChanges: Array<{
88
+ kind: "variable" | "style" | "variable-alias";
89
+ id: string;
90
+ from?: string;
91
+ to: string;
92
+ }>;
93
+ notes: string[];
94
+ }
95
+
96
+ export function translateCanonicalName(name: string, schema: TokenMigrationSchema): {
97
+ normalizedName: string;
98
+ suggestedName: string | null;
99
+ reasons: string[];
100
+ confidence: number;
101
+ } {
102
+ const analysis = analyzeTokenName(name);
103
+ const normalizedName = analysis.normalizedName;
104
+ let nextName = analysis.suggestedName ?? normalizedName;
105
+ const reasons = analysis.issues.map((issue) => issue.message);
106
+ let confidence = reasons.length > 0 ? 0.94 : 0.9;
107
+
108
+ const transforms: Array<{ test: RegExp; replace: string; reason: string; confidence?: number }> =
109
+ schema === "compact"
110
+ ? [
111
+ {
112
+ test: /^color\/primitive\//,
113
+ replace: "color/",
114
+ reason: "Collapse primitive color namespace to the compact palette format.",
115
+ },
116
+ {
117
+ test: /^semantic\/color\//,
118
+ replace: "color/semantic/",
119
+ reason: "Align semantic colors to the compact semantic color path.",
120
+ },
121
+ {
122
+ test: /^typography\/size\//,
123
+ replace: "typography/font-size/",
124
+ reason: "Use explicit typography/font-size naming in the compact schema.",
125
+ },
126
+ {
127
+ test: /^typography\/weight\//,
128
+ replace: "typography/font-weight/",
129
+ reason: "Use explicit typography/font-weight naming in the compact schema.",
130
+ },
131
+ {
132
+ test: /^primitive\/color\//,
133
+ replace: "color/",
134
+ reason: "Lift legacy primitive/color tokens into the compact color namespace.",
135
+ },
136
+ {
137
+ test: /^components\//,
138
+ replace: "component/",
139
+ reason: "Use a singular component prefix.",
140
+ },
141
+ ]
142
+ : [
143
+ {
144
+ test: /^color\/(?!primitive\/|semantic\/)([^/]+\/.+)$/,
145
+ replace: "color/primitive/$1",
146
+ reason: "Expand compact color tokens into the primitive color namespace.",
147
+ },
148
+ {
149
+ test: /^typography\/font-size\//,
150
+ replace: "typography/size/",
151
+ reason: "Use compact typography size slots in the expanded schema.",
152
+ },
153
+ {
154
+ test: /^typography\/font-weight\//,
155
+ replace: "typography/weight/",
156
+ reason: "Use compact typography weight slots in the expanded schema.",
157
+ },
158
+ {
159
+ test: /^primitive\/color\//,
160
+ replace: "color/primitive/",
161
+ reason: "Normalize legacy primitive/color tokens into expanded schema order.",
162
+ },
163
+ {
164
+ test: /^components\//,
165
+ replace: "component/",
166
+ reason: "Use a singular component prefix.",
167
+ },
168
+ ];
169
+
170
+ for (const transform of transforms) {
171
+ if (!transform.test.test(nextName)) continue;
172
+ const updated = nextName.replace(transform.test, transform.replace);
173
+ if (updated !== nextName) {
174
+ nextName = updated;
175
+ reasons.push(transform.reason);
176
+ confidence = Math.min(confidence, transform.confidence ?? 0.92);
177
+ }
178
+ }
179
+
180
+ if (nextName === normalizedName) {
181
+ return {
182
+ normalizedName,
183
+ suggestedName: null,
184
+ reasons,
185
+ confidence: Math.min(1, confidence),
186
+ };
187
+ }
188
+
189
+ return {
190
+ normalizedName,
191
+ suggestedName: nextName,
192
+ reasons,
193
+ confidence: Math.min(1, confidence),
194
+ };
195
+ }
196
+
197
+ function isAmbiguousName(name: string): string[] {
198
+ const reasons: string[] = [];
199
+ if (/^primitive\/color\/[^/]+\/0$/.test(name) || /^color\/[^/]+\/0$/.test(name)) {
200
+ reasons.push("Scale value '0' is ambiguous across token systems and should be reviewed manually.");
201
+ }
202
+ return reasons;
203
+ }
204
+
205
+ function buildVariableConflictMap(collections: VariableCollectionSummary[]): Map<string, string> {
206
+ const map = new Map<string, string>();
207
+ for (const collection of collections) {
208
+ for (const variable of collection.variables) {
209
+ map.set(`${collection.id}::${variable.name}`, variable.id);
210
+ }
211
+ }
212
+ return map;
213
+ }
214
+
215
+ function planVariableItems(
216
+ collections: VariableCollectionSummary[],
217
+ schema: TokenMigrationSchema
218
+ ): TokenMigrationItem[] {
219
+ const items: TokenMigrationItem[] = [];
220
+ const byName = buildVariableConflictMap(collections);
221
+
222
+ for (const collection of collections) {
223
+ for (const variable of collection.variables) {
224
+ const translated = translateCanonicalName(variable.name, schema);
225
+ if (!translated.suggestedName) continue;
226
+
227
+ const ambiguityReasons = isAmbiguousName(translated.normalizedName);
228
+ const conflictId = byName.get(`${collection.id}::${translated.suggestedName}`);
229
+ const conflictReasons =
230
+ conflictId && conflictId !== variable.id
231
+ ? [`Target name '${translated.suggestedName}' already exists in collection '${collection.name}'.`]
232
+ : [];
233
+
234
+ const reasons = [...translated.reasons, ...ambiguityReasons, ...conflictReasons];
235
+ items.push({
236
+ kind: "variable",
237
+ id: variable.id,
238
+ collectionId: collection.id,
239
+ collectionName: collection.name,
240
+ originalName: variable.name,
241
+ normalizedName: translated.normalizedName,
242
+ suggestedName: translated.suggestedName,
243
+ confidence: conflictReasons.length || ambiguityReasons.length ? 0.45 : translated.confidence,
244
+ safeToApply: conflictReasons.length === 0 && ambiguityReasons.length === 0,
245
+ reasons,
246
+ willRename: true,
247
+ });
248
+ }
249
+ }
250
+
251
+ return items;
252
+ }
253
+
254
+ function planStyleItems(styles: StyleSummaryResult, schema: TokenMigrationSchema): TokenMigrationItem[] {
255
+ const items: TokenMigrationItem[] = [];
256
+ const groups: Array<["paint" | "text" | "effect", Array<{ id: string; name: string }>]> = [
257
+ ["paint", styles.paint ?? []],
258
+ ["text", styles.text ?? []],
259
+ ["effect", styles.effect ?? []],
260
+ ];
261
+
262
+ for (const [subtype, list] of groups) {
263
+ for (const style of list) {
264
+ const translated = translateCanonicalName(style.name, schema);
265
+ if (!translated.suggestedName) continue;
266
+
267
+ const ambiguityReasons = isAmbiguousName(translated.normalizedName);
268
+ items.push({
269
+ kind: "style",
270
+ subtype,
271
+ id: style.id,
272
+ originalName: style.name,
273
+ normalizedName: translated.normalizedName,
274
+ suggestedName: translated.suggestedName,
275
+ confidence: ambiguityReasons.length ? 0.45 : translated.confidence,
276
+ safeToApply: ambiguityReasons.length === 0,
277
+ reasons: [...translated.reasons, ...ambiguityReasons],
278
+ willRename: true,
279
+ });
280
+ }
281
+ }
282
+
283
+ return items;
284
+ }
285
+
286
+ async function renameStyles(
287
+ styleItems: TokenMigrationItem[]
288
+ ): Promise<Array<{ kind: "style"; id: string; from: string; to: string }>> {
289
+ if (styleItems.length === 0) return [];
290
+
291
+ const bridge = await getBridge();
292
+ const payload = styleItems.map((item) => ({
293
+ id: item.id,
294
+ from: item.originalName,
295
+ to: item.suggestedName,
296
+ }));
297
+
298
+ const exec = await bridge.execute(`
299
+ const renames = ${JSON.stringify(payload)};
300
+ const allStyles = [
301
+ ...(await figma.getLocalPaintStylesAsync()),
302
+ ...(await figma.getLocalTextStylesAsync()),
303
+ ...(await figma.getLocalEffectStylesAsync()),
304
+ ];
305
+ const renamed = [];
306
+ const skipped = [];
307
+ for (const entry of renames) {
308
+ const style = allStyles.find((item) => item.id === entry.id);
309
+ if (!style || !entry.to) {
310
+ skipped.push(entry);
311
+ continue;
312
+ }
313
+ style.name = entry.to;
314
+ renamed.push(entry);
315
+ }
316
+ return { renamed, skipped };
317
+ `);
318
+
319
+ if (!exec.success) {
320
+ throw new Error(exec.error);
321
+ }
322
+
323
+ const result = exec.result as { renamed?: Array<{ id: string; from: string; to: string }> };
324
+ return (result.renamed ?? []).map((item) => ({
325
+ kind: "style" as const,
326
+ id: item.id,
327
+ from: item.from,
328
+ to: item.to,
329
+ }));
330
+ }
331
+
332
+ async function createVariableAliases(
333
+ collections: VariableCollectionSummary[],
334
+ items: TokenMigrationItem[]
335
+ ): Promise<Array<{ kind: "variable-alias"; id: string; to: string }>> {
336
+ const bridge = await getBridge();
337
+ const collectionMap = new Map(collections.map((collection) => [collection.id, collection]));
338
+ const aliases: Array<{ kind: "variable-alias"; id: string; to: string }> = [];
339
+
340
+ for (const item of items) {
341
+ if (item.kind !== "variable" || !item.collectionId) continue;
342
+ const collection = collectionMap.get(item.collectionId);
343
+ if (!collection || !item.suggestedName) continue;
344
+ const variable = collection.variables.find((entry) => entry.id === item.id);
345
+ if (!variable) continue;
346
+
347
+ const valuesByMode = Object.fromEntries(
348
+ collection.modes.map((mode) => [
349
+ mode.modeId,
350
+ { type: "VARIABLE_ALIAS", variableId: item.id },
351
+ ])
352
+ );
353
+
354
+ const created = await bridge.createVariable(
355
+ item.originalName,
356
+ collection.id,
357
+ variable.type,
358
+ valuesByMode,
359
+ `Alias created by figma_token_migrate for ${item.suggestedName}`
360
+ ) as { id: string };
361
+
362
+ aliases.push({
363
+ kind: "variable-alias",
364
+ id: created.id,
365
+ to: item.originalName,
366
+ });
367
+ }
368
+
369
+ return aliases;
370
+ }
371
+
372
+ export async function tokenMigrateHandler(args: TokenMigrateArgs): Promise<TokenMigrateResult> {
373
+ const scope = args.scope ?? "all";
374
+ const canonicalSchema = args.canonicalSchema ?? "compact";
375
+ const renameInPlace = args.renameInPlace ?? args.action === "apply";
376
+ const createAliases = args.createAliases ?? false;
377
+ const dryRun = args.dryRun ?? args.action !== "apply";
378
+ const bridge = await getBridge();
379
+
380
+ const collections =
381
+ scope === "styles"
382
+ ? []
383
+ : (await bridge.getVariables(undefined, "full") as VariableCollectionSummary[]).filter(
384
+ (collection) => !args.collectionName || collection.name === args.collectionName
385
+ );
386
+ const styles =
387
+ scope === "variables"
388
+ ? {}
389
+ : (await bridge.getStyles() as StyleSummaryResult);
390
+
391
+ const variableItems = scope === "styles" ? [] : planVariableItems(collections, canonicalSchema);
392
+ const styleItems = scope === "variables" ? [] : planStyleItems(styles, canonicalSchema);
393
+ const items = [...variableItems, ...styleItems];
394
+
395
+ const safeItems = items.filter((item) => item.safeToApply && item.suggestedName);
396
+ const ambiguousItems = items.filter((item) => !item.safeToApply);
397
+ const appliedChanges: Array<{ kind: "variable" | "style" | "variable-alias"; id: string; from?: string; to: string }> = [];
398
+ const notes: string[] = [];
399
+
400
+ if (args.action === "apply" && renameInPlace && !dryRun) {
401
+ for (const item of safeItems.filter((entry) => entry.kind === "variable")) {
402
+ await bridge.renameVariable(item.id, item.suggestedName!);
403
+ appliedChanges.push({
404
+ kind: "variable",
405
+ id: item.id,
406
+ from: item.originalName,
407
+ to: item.suggestedName!,
408
+ });
409
+ }
410
+
411
+ const renamedStyles = await renameStyles(safeItems.filter((entry) => entry.kind === "style"));
412
+ appliedChanges.push(...renamedStyles);
413
+
414
+ if (createAliases) {
415
+ const aliases = await createVariableAliases(collections, safeItems.filter((entry) => entry.kind === "variable"));
416
+ appliedChanges.push(...aliases);
417
+ if (styleItems.length > 0) {
418
+ notes.push("Style aliases are not supported; style migrations rename in place only.");
419
+ }
420
+ }
421
+ } else if (args.action === "apply" && dryRun) {
422
+ notes.push("Apply requested with dryRun enabled, so no changes were written.");
423
+ }
424
+
425
+ if (!renameInPlace) {
426
+ notes.push("renameInPlace is disabled, so the result is preview-only.");
427
+ }
428
+ if (ambiguousItems.length > 0) {
429
+ notes.push("Some names were flagged as ambiguous and were left for manual review.");
430
+ }
431
+ if (scope !== "variables" && !createAliases) {
432
+ notes.push("Style migration currently supports rename-in-place only; alias-style compatibility is not available.");
433
+ }
434
+
435
+ const scannedStyleCount = (styles.paint?.length ?? 0) + (styles.text?.length ?? 0) + (styles.effect?.length ?? 0);
436
+
437
+ return {
438
+ ok: true,
439
+ action: args.action,
440
+ scope,
441
+ canonicalSchema,
442
+ scanned: {
443
+ variables: collections.reduce((count, collection) => count + collection.variables.length, 0),
444
+ styles: scannedStyleCount,
445
+ },
446
+ summary: {
447
+ proposed: items.length,
448
+ safe: safeItems.length,
449
+ ambiguous: ambiguousItems.length,
450
+ applied: appliedChanges.filter((change) => change.kind !== "variable-alias").length,
451
+ aliased: appliedChanges.filter((change) => change.kind === "variable-alias").length,
452
+ skipped: items.length - safeItems.length,
453
+ },
454
+ items,
455
+ appliedChanges,
456
+ notes,
457
+ };
458
+ }
@@ -0,0 +1,134 @@
1
+ import { getBridge } from "../../../shared/figma-bridge.js";
2
+ import {
3
+ analyzeTokenNames,
4
+ getDefaultTokenNamingRules,
5
+ validateSemanticGrammar,
6
+ TokenNamingAnalysis,
7
+ TokenNamingRuleSet,
8
+ } from "../../../shared/token-naming.js";
9
+
10
+ export interface TokenNamingArgs {
11
+ action: "define" | "validate" | "suggest-renames" | "audit-current-file" | "validate-semantic";
12
+ names?: string[];
13
+ collectionName?: string;
14
+ }
15
+
16
+ export interface TokenNamingResult {
17
+ ok: boolean;
18
+ action: TokenNamingArgs["action"];
19
+ ruleSet: TokenNamingRuleSet;
20
+ analyzedCount: number;
21
+ summary: {
22
+ valid: number;
23
+ invalid: number;
24
+ warnings: number;
25
+ };
26
+ analyses: TokenNamingAnalysis[];
27
+ recommendations: string[];
28
+ }
29
+
30
+ interface VariableCollectionSummary {
31
+ id: string;
32
+ name: string;
33
+ variables: Array<{ id: string; name: string; type: string }>;
34
+ }
35
+
36
+ function summarize(analyses: TokenNamingAnalysis[]) {
37
+ return {
38
+ valid: analyses.filter((item) => item.isValid).length,
39
+ invalid: analyses.filter((item) => !item.isValid).length,
40
+ warnings: analyses.reduce(
41
+ (count, item) => count + item.issues.filter((issue) => issue.severity === "warning").length,
42
+ 0
43
+ ),
44
+ };
45
+ }
46
+
47
+ function buildRecommendations(analyses: TokenNamingAnalysis[], rules: TokenNamingRuleSet): string[] {
48
+ const recommendations: string[] = [];
49
+ if (analyses.some((item) => item.issues.some((issue) => issue.code === "typo"))) {
50
+ recommendations.push("Fix token typos before creating aliases so naming drift does not spread.");
51
+ }
52
+ if (analyses.some((item) => item.issues.some((issue) => issue.code === "component-prefix"))) {
53
+ recommendations.push(`Standardize component tokens on '${rules.componentPrefix}/...' instead of plural prefixes.`);
54
+ }
55
+ if (analyses.some((item) => item.issues.some((issue) => issue.code === "semantic-prefix"))) {
56
+ recommendations.push(`Namespace semantic tokens under '${rules.semanticPrefix}/...' for cleaner separation from primitives.`);
57
+ }
58
+ if (analyses.some((item) => item.issues.some((issue) => issue.code === "uppercase"))) {
59
+ recommendations.push("Normalize names to lowercase slash-separated paths.");
60
+ }
61
+ if (recommendations.length === 0) {
62
+ recommendations.push("The token names already follow the current naming convention.");
63
+ }
64
+ return recommendations;
65
+ }
66
+
67
+ async function getCurrentFileTokenNames(collectionName?: string): Promise<string[]> {
68
+ const bridge = await getBridge();
69
+ const collections = await bridge.getVariables(undefined, "full") as VariableCollectionSummary[];
70
+ return collections
71
+ .filter((collection) => !collectionName || collection.name === collectionName)
72
+ .flatMap((collection) => collection.variables.map((variable) => variable.name));
73
+ }
74
+
75
+ export async function tokenNamingHandler(args: TokenNamingArgs): Promise<TokenNamingResult> {
76
+ const ruleSet = getDefaultTokenNamingRules();
77
+
78
+ if (args.action === "define") {
79
+ return {
80
+ ok: true,
81
+ action: args.action,
82
+ ruleSet,
83
+ analyzedCount: 0,
84
+ summary: { valid: 0, invalid: 0, warnings: 0 },
85
+ analyses: [],
86
+ recommendations: [
87
+ "Primitive tokens: color/brand/500, space/16, typography/font-size/md",
88
+ "Semantic tokens: semantic/text/primary, semantic/surface/default",
89
+ "Component tokens: component/button/primary/background/default",
90
+ ],
91
+ };
92
+ }
93
+
94
+ // Resolve names from file or args
95
+ const names =
96
+ args.action === "audit-current-file" || args.action === "validate-semantic"
97
+ ? await getCurrentFileTokenNames(args.collectionName)
98
+ : args.names ?? [];
99
+
100
+ // For validate-semantic, also allow explicitly provided names
101
+ const resolvedNames = args.action === "validate-semantic" && args.names?.length
102
+ ? args.names
103
+ : names;
104
+
105
+ const analyses = analyzeTokenNames(resolvedNames, ruleSet);
106
+
107
+ // Semantic grammar validation: merge concept-taxonomy issues
108
+ if (args.action === "validate-semantic") {
109
+ for (const analysis of analyses) {
110
+ const grammarResult = validateSemanticGrammar(analysis.normalizedName);
111
+ if (grammarResult.issues.length > 0) {
112
+ analysis.issues.push(...grammarResult.issues);
113
+ if (!grammarResult.isValid) {
114
+ analysis.isValid = false;
115
+ }
116
+ }
117
+ }
118
+ }
119
+
120
+ const filteredAnalyses =
121
+ args.action === "suggest-renames"
122
+ ? analyses.filter((item) => item.suggestedName && item.suggestedName !== item.normalizedName)
123
+ : analyses;
124
+
125
+ return {
126
+ ok: true,
127
+ action: args.action,
128
+ ruleSet,
129
+ analyzedCount: filteredAnalyses.length,
130
+ summary: summarize(filteredAnalyses),
131
+ analyses: filteredAnalyses,
132
+ recommendations: buildRecommendations(filteredAnalyses, ruleSet),
133
+ };
134
+ }
@@ -0,0 +1,101 @@
1
+ import { guessPattern, shouldFallbackToGeneratedPage } from "../src/tools/phase5-governance/apg-doc/index";
2
+ import { NodeSnapshot } from "../src/tools/phase5-governance/spec-generator/index";
3
+
4
+ function makeSnapshot(overrides: Partial<NodeSnapshot>): NodeSnapshot {
5
+ return {
6
+ id: "1:1",
7
+ name: "Button/Primary",
8
+ type: "COMPONENT_SET",
9
+ description: "",
10
+ width: 120,
11
+ height: 44,
12
+ layoutMode: "HORIZONTAL",
13
+ itemSpacing: 8,
14
+ paddingTop: 0,
15
+ paddingRight: 0,
16
+ paddingBottom: 0,
17
+ paddingLeft: 0,
18
+ childCount: 0,
19
+ childNames: [],
20
+ textLayers: [],
21
+ fills: [],
22
+ strokes: [],
23
+ effects: [],
24
+ tokenAliases: [],
25
+ componentProperties: [],
26
+ variantProperties: {},
27
+ variantGroupProperties: {},
28
+ variants: [],
29
+ ...overrides,
30
+ };
31
+ }
32
+
33
+ describe("figma_apg_doc pattern matcher", () => {
34
+ test("matches tabs from component naming and variants", () => {
35
+ const snapshot = makeSnapshot({
36
+ name: "Navigation/Tabs",
37
+ variantGroupProperties: {
38
+ State: ["Default", "Selected"],
39
+ Size: ["Sm", "Md"],
40
+ },
41
+ childNames: ["Tab list", "Tab panel"],
42
+ });
43
+
44
+ const match = guessPattern(snapshot);
45
+ expect(match.definition.id).toBe("tabs");
46
+ expect(match.confidence).toBeGreaterThan(0.5);
47
+ });
48
+
49
+ test("uses hint to disambiguate tricky patterns", () => {
50
+ const snapshot = makeSnapshot({
51
+ name: "Filters/Picker",
52
+ textLayers: [{ name: "Label", characters: "Choose a city", fontFamily: "Inter", fontStyle: "Regular", fontSize: 14, lineHeightPx: 20 }],
53
+ });
54
+
55
+ const match = guessPattern(snapshot, "combobox");
56
+ expect(match.definition.id).toBe("combobox");
57
+ expect(match.matchedBy.some((entry) => entry.startsWith("hint:"))).toBe(true);
58
+ });
59
+
60
+ test("matches treeview for hierarchical file-nav patterns", () => {
61
+ const snapshot = makeSnapshot({
62
+ name: "Navigation/File Tree",
63
+ childNames: ["Tree", "Group", "Tree item"],
64
+ textLayers: [{ name: "Node label", characters: "src", fontFamily: "Inter", fontStyle: "Regular", fontSize: 14, lineHeightPx: 20 }],
65
+ variantGroupProperties: {
66
+ State: ["Expanded", "Collapsed", "Selected"],
67
+ },
68
+ });
69
+
70
+ const match = guessPattern(snapshot);
71
+ expect(match.definition.id).toBe("treeview");
72
+ });
73
+
74
+ test("matches slider for range controls", () => {
75
+ const snapshot = makeSnapshot({
76
+ name: "Media/Volume Slider",
77
+ childNames: ["Track", "Thumb", "Value label"],
78
+ textLayers: [{ name: "Label", characters: "Volume", fontFamily: "Inter", fontStyle: "Regular", fontSize: 14, lineHeightPx: 20 }],
79
+ });
80
+
81
+ const match = guessPattern(snapshot);
82
+ expect(match.definition.id).toBe("slider");
83
+ });
84
+
85
+ test("falls back to a generated page for plugin description write errors", () => {
86
+ expect(shouldFallbackToGeneratedPage(new Error("figma_apg_doc: failed to update node description: Internal plugin write failure"))).toBe(true);
87
+ expect(shouldFallbackToGeneratedPage(new Error("Target node does not support description updates."))).toBe(true);
88
+ });
89
+
90
+ test("returns a low-confidence fallback match for generic components", () => {
91
+ const snapshot = makeSnapshot({
92
+ name: "Surface/Primitive",
93
+ type: "FRAME",
94
+ childNames: ["Container", "Content"],
95
+ });
96
+
97
+ const match = guessPattern(snapshot);
98
+ expect(match.confidence).toBeLessThan(0.55);
99
+ expect(match.matchedBy).toContain("fallback:best-name-match");
100
+ });
101
+ });