@calibrate-ds/core 0.1.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 (529) hide show
  1. package/dist/__tests__/check-component.test.d.ts +2 -0
  2. package/dist/__tests__/check-component.test.d.ts.map +1 -0
  3. package/dist/__tests__/check-component.test.js +103 -0
  4. package/dist/__tests__/check-component.test.js.map +1 -0
  5. package/dist/__tests__/compare-components.test.d.ts +2 -0
  6. package/dist/__tests__/compare-components.test.d.ts.map +1 -0
  7. package/dist/__tests__/compare-components.test.js +145 -0
  8. package/dist/__tests__/compare-components.test.js.map +1 -0
  9. package/dist/__tests__/naming-strategy.test.d.ts +2 -0
  10. package/dist/__tests__/naming-strategy.test.d.ts.map +1 -0
  11. package/dist/__tests__/naming-strategy.test.js +71 -0
  12. package/dist/__tests__/naming-strategy.test.js.map +1 -0
  13. package/dist/ai/index.d.ts +3 -0
  14. package/dist/ai/index.d.ts.map +1 -0
  15. package/dist/ai/index.js +3 -0
  16. package/dist/ai/index.js.map +1 -0
  17. package/dist/ai/provider.d.ts +14 -0
  18. package/dist/ai/provider.d.ts.map +1 -0
  19. package/dist/ai/provider.js +63 -0
  20. package/dist/ai/provider.js.map +1 -0
  21. package/dist/ai/resolve-provider.d.ts +3 -0
  22. package/dist/ai/resolve-provider.d.ts.map +1 -0
  23. package/dist/ai/resolve-provider.js +61 -0
  24. package/dist/ai/resolve-provider.js.map +1 -0
  25. package/dist/bootstrap/generate-library-files.d.ts +7 -0
  26. package/dist/bootstrap/generate-library-files.d.ts.map +1 -0
  27. package/dist/bootstrap/generate-library-files.js +97 -0
  28. package/dist/bootstrap/generate-library-files.js.map +1 -0
  29. package/dist/bootstrap/index.d.ts +4 -0
  30. package/dist/bootstrap/index.d.ts.map +1 -0
  31. package/dist/bootstrap/index.js +4 -0
  32. package/dist/bootstrap/index.js.map +1 -0
  33. package/dist/bootstrap/types.d.ts +27 -0
  34. package/dist/bootstrap/types.d.ts.map +1 -0
  35. package/dist/bootstrap/types.js +2 -0
  36. package/dist/bootstrap/types.js.map +1 -0
  37. package/dist/bootstrap/write-library-bootstrap.d.ts +7 -0
  38. package/dist/bootstrap/write-library-bootstrap.d.ts.map +1 -0
  39. package/dist/bootstrap/write-library-bootstrap.js +35 -0
  40. package/dist/bootstrap/write-library-bootstrap.js.map +1 -0
  41. package/dist/config/config-schema.d.ts +131 -0
  42. package/dist/config/config-schema.d.ts.map +1 -0
  43. package/dist/config/config-schema.js +93 -0
  44. package/dist/config/config-schema.js.map +1 -0
  45. package/dist/config/index.d.ts +3 -0
  46. package/dist/config/index.d.ts.map +1 -0
  47. package/dist/config/index.js +3 -0
  48. package/dist/config/index.js.map +1 -0
  49. package/dist/config/load-config.d.ts +7 -0
  50. package/dist/config/load-config.d.ts.map +1 -0
  51. package/dist/config/load-config.js +63 -0
  52. package/dist/config/load-config.js.map +1 -0
  53. package/dist/context/compressed-context.d.ts +3 -0
  54. package/dist/context/compressed-context.d.ts.map +1 -0
  55. package/dist/context/compressed-context.js +145 -0
  56. package/dist/context/compressed-context.js.map +1 -0
  57. package/dist/context/context-index.d.ts +18 -0
  58. package/dist/context/context-index.d.ts.map +1 -0
  59. package/dist/context/context-index.js +59 -0
  60. package/dist/context/context-index.js.map +1 -0
  61. package/dist/context/export-context.d.ts +61 -0
  62. package/dist/context/export-context.d.ts.map +1 -0
  63. package/dist/context/export-context.js +191 -0
  64. package/dist/context/export-context.js.map +1 -0
  65. package/dist/context/get-component-context.d.ts +3 -0
  66. package/dist/context/get-component-context.d.ts.map +1 -0
  67. package/dist/context/get-component-context.js +898 -0
  68. package/dist/context/get-component-context.js.map +1 -0
  69. package/dist/context/hashing.d.ts +14 -0
  70. package/dist/context/hashing.d.ts.map +1 -0
  71. package/dist/context/hashing.js +53 -0
  72. package/dist/context/hashing.js.map +1 -0
  73. package/dist/context/metadata-extraction.d.ts +15 -0
  74. package/dist/context/metadata-extraction.d.ts.map +1 -0
  75. package/dist/context/metadata-extraction.js +47 -0
  76. package/dist/context/metadata-extraction.js.map +1 -0
  77. package/dist/design-tool/figma-adapter.d.ts +20 -0
  78. package/dist/design-tool/figma-adapter.d.ts.map +1 -0
  79. package/dist/design-tool/figma-adapter.js +46 -0
  80. package/dist/design-tool/figma-adapter.js.map +1 -0
  81. package/dist/design-tool/index.d.ts +4 -0
  82. package/dist/design-tool/index.d.ts.map +1 -0
  83. package/dist/design-tool/index.js +3 -0
  84. package/dist/design-tool/index.js.map +1 -0
  85. package/dist/design-tool/registry.d.ts +12 -0
  86. package/dist/design-tool/registry.d.ts.map +1 -0
  87. package/dist/design-tool/registry.js +23 -0
  88. package/dist/design-tool/registry.js.map +1 -0
  89. package/dist/design-tool/types.d.ts +28 -0
  90. package/dist/design-tool/types.d.ts.map +1 -0
  91. package/dist/design-tool/types.js +2 -0
  92. package/dist/design-tool/types.js.map +1 -0
  93. package/dist/diff/compare-components.d.ts +3 -0
  94. package/dist/diff/compare-components.d.ts.map +1 -0
  95. package/dist/diff/compare-components.js +198 -0
  96. package/dist/diff/compare-components.js.map +1 -0
  97. package/dist/diff/compare-dependencies.d.ts +3 -0
  98. package/dist/diff/compare-dependencies.d.ts.map +1 -0
  99. package/dist/diff/compare-dependencies.js +30 -0
  100. package/dist/diff/compare-dependencies.js.map +1 -0
  101. package/dist/diff/compare-tokens.d.ts +3 -0
  102. package/dist/diff/compare-tokens.d.ts.map +1 -0
  103. package/dist/diff/compare-tokens.js +52 -0
  104. package/dist/diff/compare-tokens.js.map +1 -0
  105. package/dist/diff/compute-design-diff.d.ts +3 -0
  106. package/dist/diff/compute-design-diff.d.ts.map +1 -0
  107. package/dist/diff/compute-design-diff.js +27 -0
  108. package/dist/diff/compute-design-diff.js.map +1 -0
  109. package/dist/diff/format-diff-summary.d.ts +3 -0
  110. package/dist/diff/format-diff-summary.d.ts.map +1 -0
  111. package/dist/diff/format-diff-summary.js +59 -0
  112. package/dist/diff/format-diff-summary.js.map +1 -0
  113. package/dist/diff/index.d.ts +6 -0
  114. package/dist/diff/index.d.ts.map +1 -0
  115. package/dist/diff/index.js +6 -0
  116. package/dist/diff/index.js.map +1 -0
  117. package/dist/docs/generate-component-doc.d.ts +34 -0
  118. package/dist/docs/generate-component-doc.d.ts.map +1 -0
  119. package/dist/docs/generate-component-doc.js +269 -0
  120. package/dist/docs/generate-component-doc.js.map +1 -0
  121. package/dist/docs/generate-component-stories.d.ts +3 -0
  122. package/dist/docs/generate-component-stories.d.ts.map +1 -0
  123. package/dist/docs/generate-component-stories.js +116 -0
  124. package/dist/docs/generate-component-stories.js.map +1 -0
  125. package/dist/docs/generate-system-doc.d.ts +23 -0
  126. package/dist/docs/generate-system-doc.d.ts.map +1 -0
  127. package/dist/docs/generate-system-doc.js +337 -0
  128. package/dist/docs/generate-system-doc.js.map +1 -0
  129. package/dist/docs/index.d.ts +5 -0
  130. package/dist/docs/index.d.ts.map +1 -0
  131. package/dist/docs/index.js +5 -0
  132. package/dist/docs/index.js.map +1 -0
  133. package/dist/docs/setup-storybook.d.ts +26 -0
  134. package/dist/docs/setup-storybook.d.ts.map +1 -0
  135. package/dist/docs/setup-storybook.js +216 -0
  136. package/dist/docs/setup-storybook.js.map +1 -0
  137. package/dist/doctor/check-component.d.ts +5 -0
  138. package/dist/doctor/check-component.d.ts.map +1 -0
  139. package/dist/doctor/check-component.js +120 -0
  140. package/dist/doctor/check-component.js.map +1 -0
  141. package/dist/doctor/check-config.d.ts +4 -0
  142. package/dist/doctor/check-config.d.ts.map +1 -0
  143. package/dist/doctor/check-config.js +65 -0
  144. package/dist/doctor/check-config.js.map +1 -0
  145. package/dist/doctor/check-tokens.d.ts +4 -0
  146. package/dist/doctor/check-tokens.d.ts.map +1 -0
  147. package/dist/doctor/check-tokens.js +17 -0
  148. package/dist/doctor/check-tokens.js.map +1 -0
  149. package/dist/doctor/index.d.ts +5 -0
  150. package/dist/doctor/index.d.ts.map +1 -0
  151. package/dist/doctor/index.js +5 -0
  152. package/dist/doctor/index.js.map +1 -0
  153. package/dist/doctor/types.d.ts +30 -0
  154. package/dist/doctor/types.d.ts.map +1 -0
  155. package/dist/doctor/types.js +2 -0
  156. package/dist/doctor/types.js.map +1 -0
  157. package/dist/filesystem/ensure-dir.d.ts +5 -0
  158. package/dist/filesystem/ensure-dir.d.ts.map +1 -0
  159. package/dist/filesystem/ensure-dir.js +17 -0
  160. package/dist/filesystem/ensure-dir.js.map +1 -0
  161. package/dist/filesystem/index.d.ts +6 -0
  162. package/dist/filesystem/index.d.ts.map +1 -0
  163. package/dist/filesystem/index.js +6 -0
  164. package/dist/filesystem/index.js.map +1 -0
  165. package/dist/filesystem/resolve-component-path.d.ts +10 -0
  166. package/dist/filesystem/resolve-component-path.d.ts.map +1 -0
  167. package/dist/filesystem/resolve-component-path.js +32 -0
  168. package/dist/filesystem/resolve-component-path.js.map +1 -0
  169. package/dist/filesystem/resolve-ds-paths.d.ts +15 -0
  170. package/dist/filesystem/resolve-ds-paths.d.ts.map +1 -0
  171. package/dist/filesystem/resolve-ds-paths.js +51 -0
  172. package/dist/filesystem/resolve-ds-paths.js.map +1 -0
  173. package/dist/filesystem/workspace-root.d.ts +6 -0
  174. package/dist/filesystem/workspace-root.d.ts.map +1 -0
  175. package/dist/filesystem/workspace-root.js +21 -0
  176. package/dist/filesystem/workspace-root.js.map +1 -0
  177. package/dist/filesystem/write-json.d.ts +6 -0
  178. package/dist/filesystem/write-json.d.ts.map +1 -0
  179. package/dist/filesystem/write-json.js +10 -0
  180. package/dist/filesystem/write-json.js.map +1 -0
  181. package/dist/filesystem/write-text.d.ts +10 -0
  182. package/dist/filesystem/write-text.d.ts.map +1 -0
  183. package/dist/filesystem/write-text.js +22 -0
  184. package/dist/filesystem/write-text.js.map +1 -0
  185. package/dist/generators/components/generate-component-css.d.ts +6 -0
  186. package/dist/generators/components/generate-component-css.d.ts.map +1 -0
  187. package/dist/generators/components/generate-component-css.js +92 -0
  188. package/dist/generators/components/generate-component-css.js.map +1 -0
  189. package/dist/generators/components/generate-component-file.d.ts +8 -0
  190. package/dist/generators/components/generate-component-file.d.ts.map +1 -0
  191. package/dist/generators/components/generate-component-file.js +209 -0
  192. package/dist/generators/components/generate-component-file.js.map +1 -0
  193. package/dist/generators/components/generate-composite-file.d.ts +3 -0
  194. package/dist/generators/components/generate-composite-file.d.ts.map +1 -0
  195. package/dist/generators/components/generate-composite-file.js +77 -0
  196. package/dist/generators/components/generate-composite-file.js.map +1 -0
  197. package/dist/generators/components/generate-composite-types.d.ts +7 -0
  198. package/dist/generators/components/generate-composite-types.d.ts.map +1 -0
  199. package/dist/generators/components/generate-composite-types.js +43 -0
  200. package/dist/generators/components/generate-composite-types.js.map +1 -0
  201. package/dist/generators/components/generate-types-file.d.ts +8 -0
  202. package/dist/generators/components/generate-types-file.d.ts.map +1 -0
  203. package/dist/generators/components/generate-types-file.js +64 -0
  204. package/dist/generators/components/generate-types-file.js.map +1 -0
  205. package/dist/generators/components/helpers.d.ts +33 -0
  206. package/dist/generators/components/helpers.d.ts.map +1 -0
  207. package/dist/generators/components/helpers.js +124 -0
  208. package/dist/generators/components/helpers.js.map +1 -0
  209. package/dist/generators/components/index.d.ts +9 -0
  210. package/dist/generators/components/index.d.ts.map +1 -0
  211. package/dist/generators/components/index.js +10 -0
  212. package/dist/generators/components/index.js.map +1 -0
  213. package/dist/generators/components/layout-jsx.d.ts +14 -0
  214. package/dist/generators/components/layout-jsx.d.ts.map +1 -0
  215. package/dist/generators/components/layout-jsx.js +271 -0
  216. package/dist/generators/components/layout-jsx.js.map +1 -0
  217. package/dist/generators/components/prune-components.d.ts +15 -0
  218. package/dist/generators/components/prune-components.d.ts.map +1 -0
  219. package/dist/generators/components/prune-components.js +88 -0
  220. package/dist/generators/components/prune-components.js.map +1 -0
  221. package/dist/generators/components/token-helpers.d.ts +32 -0
  222. package/dist/generators/components/token-helpers.d.ts.map +1 -0
  223. package/dist/generators/components/token-helpers.js +188 -0
  224. package/dist/generators/components/token-helpers.js.map +1 -0
  225. package/dist/generators/components/write-components.d.ts +17 -0
  226. package/dist/generators/components/write-components.d.ts.map +1 -0
  227. package/dist/generators/components/write-components.js +212 -0
  228. package/dist/generators/components/write-components.js.map +1 -0
  229. package/dist/generators/components/write-composites.d.ts +4 -0
  230. package/dist/generators/components/write-composites.d.ts.map +1 -0
  231. package/dist/generators/components/write-composites.js +116 -0
  232. package/dist/generators/components/write-composites.js.map +1 -0
  233. package/dist/generators/composites/generate-composite-file.d.ts +3 -0
  234. package/dist/generators/composites/generate-composite-file.d.ts.map +1 -0
  235. package/dist/generators/composites/generate-composite-file.js +101 -0
  236. package/dist/generators/composites/generate-composite-file.js.map +1 -0
  237. package/dist/generators/composites/generate-composite-types.d.ts +7 -0
  238. package/dist/generators/composites/generate-composite-types.d.ts.map +1 -0
  239. package/dist/generators/composites/generate-composite-types.js +43 -0
  240. package/dist/generators/composites/generate-composite-types.js.map +1 -0
  241. package/dist/generators/composites/index.d.ts +4 -0
  242. package/dist/generators/composites/index.d.ts.map +1 -0
  243. package/dist/generators/composites/index.js +4 -0
  244. package/dist/generators/composites/index.js.map +1 -0
  245. package/dist/generators/composites/write-composites.d.ts +4 -0
  246. package/dist/generators/composites/write-composites.d.ts.map +1 -0
  247. package/dist/generators/composites/write-composites.js +116 -0
  248. package/dist/generators/composites/write-composites.js.map +1 -0
  249. package/dist/generators/registry.d.ts +9 -0
  250. package/dist/generators/registry.d.ts.map +1 -0
  251. package/dist/generators/registry.js +11 -0
  252. package/dist/generators/registry.js.map +1 -0
  253. package/dist/generators/scaffold/generate-placeholder-component-content.d.ts +9 -0
  254. package/dist/generators/scaffold/generate-placeholder-component-content.d.ts.map +1 -0
  255. package/dist/generators/scaffold/generate-placeholder-component-content.js +68 -0
  256. package/dist/generators/scaffold/generate-placeholder-component-content.js.map +1 -0
  257. package/dist/generators/scaffold/index.d.ts +3 -0
  258. package/dist/generators/scaffold/index.d.ts.map +1 -0
  259. package/dist/generators/scaffold/index.js +3 -0
  260. package/dist/generators/scaffold/index.js.map +1 -0
  261. package/dist/generators/scaffold/write-scaffold.d.ts +14 -0
  262. package/dist/generators/scaffold/write-scaffold.d.ts.map +1 -0
  263. package/dist/generators/scaffold/write-scaffold.js +87 -0
  264. package/dist/generators/scaffold/write-scaffold.js.map +1 -0
  265. package/dist/generators/tokens/generate-token-css.d.ts +6 -0
  266. package/dist/generators/tokens/generate-token-css.d.ts.map +1 -0
  267. package/dist/generators/tokens/generate-token-css.js +31 -0
  268. package/dist/generators/tokens/generate-token-css.js.map +1 -0
  269. package/dist/generators/tokens/generate-token-file-content.d.ts +6 -0
  270. package/dist/generators/tokens/generate-token-file-content.d.ts.map +1 -0
  271. package/dist/generators/tokens/generate-token-file-content.js +27 -0
  272. package/dist/generators/tokens/generate-token-file-content.js.map +1 -0
  273. package/dist/generators/tokens/index.d.ts +3 -0
  274. package/dist/generators/tokens/index.d.ts.map +1 -0
  275. package/dist/generators/tokens/index.js +3 -0
  276. package/dist/generators/tokens/index.js.map +1 -0
  277. package/dist/generators/tokens/write-tokens.d.ts +14 -0
  278. package/dist/generators/tokens/write-tokens.d.ts.map +1 -0
  279. package/dist/generators/tokens/write-tokens.js +96 -0
  280. package/dist/generators/tokens/write-tokens.js.map +1 -0
  281. package/dist/generators/types.d.ts +11 -0
  282. package/dist/generators/types.d.ts.map +1 -0
  283. package/dist/generators/types.js +2 -0
  284. package/dist/generators/types.js.map +1 -0
  285. package/dist/icons/enrich-icon-svgs.d.ts +10 -0
  286. package/dist/icons/enrich-icon-svgs.d.ts.map +1 -0
  287. package/dist/icons/enrich-icon-svgs.js +88 -0
  288. package/dist/icons/enrich-icon-svgs.js.map +1 -0
  289. package/dist/index.d.ts +31 -0
  290. package/dist/index.d.ts.map +1 -0
  291. package/dist/index.js +31 -0
  292. package/dist/index.js.map +1 -0
  293. package/dist/manifest/index.d.ts +8 -0
  294. package/dist/manifest/index.d.ts.map +1 -0
  295. package/dist/manifest/index.js +80 -0
  296. package/dist/manifest/index.js.map +1 -0
  297. package/dist/mappings/build-file-mappings.d.ts +6 -0
  298. package/dist/mappings/build-file-mappings.d.ts.map +1 -0
  299. package/dist/mappings/build-file-mappings.js +37 -0
  300. package/dist/mappings/build-file-mappings.js.map +1 -0
  301. package/dist/mappings/index.d.ts +3 -0
  302. package/dist/mappings/index.d.ts.map +1 -0
  303. package/dist/mappings/index.js +3 -0
  304. package/dist/mappings/index.js.map +1 -0
  305. package/dist/mappings/naming-strategy.d.ts +20 -0
  306. package/dist/mappings/naming-strategy.d.ts.map +1 -0
  307. package/dist/mappings/naming-strategy.js +78 -0
  308. package/dist/mappings/naming-strategy.js.map +1 -0
  309. package/dist/model/build-design-system-model.d.ts +7 -0
  310. package/dist/model/build-design-system-model.d.ts.map +1 -0
  311. package/dist/model/build-design-system-model.js +78 -0
  312. package/dist/model/build-design-system-model.js.map +1 -0
  313. package/dist/model/index.d.ts +2 -0
  314. package/dist/model/index.d.ts.map +1 -0
  315. package/dist/model/index.js +2 -0
  316. package/dist/model/index.js.map +1 -0
  317. package/dist/model/resolve-component.d.ts +11 -0
  318. package/dist/model/resolve-component.d.ts.map +1 -0
  319. package/dist/model/resolve-component.js +110 -0
  320. package/dist/model/resolve-component.js.map +1 -0
  321. package/dist/normalizer/classify-entities.d.ts +12 -0
  322. package/dist/normalizer/classify-entities.d.ts.map +1 -0
  323. package/dist/normalizer/classify-entities.js +62 -0
  324. package/dist/normalizer/classify-entities.js.map +1 -0
  325. package/dist/normalizer/helpers.d.ts +13 -0
  326. package/dist/normalizer/helpers.d.ts.map +1 -0
  327. package/dist/normalizer/helpers.js +27 -0
  328. package/dist/normalizer/helpers.js.map +1 -0
  329. package/dist/normalizer/index.d.ts +7 -0
  330. package/dist/normalizer/index.d.ts.map +1 -0
  331. package/dist/normalizer/index.js +7 -0
  332. package/dist/normalizer/index.js.map +1 -0
  333. package/dist/normalizer/instance-resolver.d.ts +13 -0
  334. package/dist/normalizer/instance-resolver.d.ts.map +1 -0
  335. package/dist/normalizer/instance-resolver.js +747 -0
  336. package/dist/normalizer/instance-resolver.js.map +1 -0
  337. package/dist/normalizer/layout-tree.d.ts +12 -0
  338. package/dist/normalizer/layout-tree.d.ts.map +1 -0
  339. package/dist/normalizer/layout-tree.js +312 -0
  340. package/dist/normalizer/layout-tree.js.map +1 -0
  341. package/dist/normalizer/naming.d.ts +11 -0
  342. package/dist/normalizer/naming.d.ts.map +1 -0
  343. package/dist/normalizer/naming.js +44 -0
  344. package/dist/normalizer/naming.js.map +1 -0
  345. package/dist/normalizer/normalize-components.d.ts +13 -0
  346. package/dist/normalizer/normalize-components.d.ts.map +1 -0
  347. package/dist/normalizer/normalize-components.js +520 -0
  348. package/dist/normalizer/normalize-components.js.map +1 -0
  349. package/dist/normalizer/normalize-composites.d.ts +8 -0
  350. package/dist/normalizer/normalize-composites.d.ts.map +1 -0
  351. package/dist/normalizer/normalize-composites.js +22 -0
  352. package/dist/normalizer/normalize-composites.js.map +1 -0
  353. package/dist/normalizer/normalize-instances.d.ts +9 -0
  354. package/dist/normalizer/normalize-instances.d.ts.map +1 -0
  355. package/dist/normalizer/normalize-instances.js +32 -0
  356. package/dist/normalizer/normalize-instances.js.map +1 -0
  357. package/dist/normalizer/types.d.ts +22 -0
  358. package/dist/normalizer/types.d.ts.map +1 -0
  359. package/dist/normalizer/types.js +2 -0
  360. package/dist/normalizer/types.js.map +1 -0
  361. package/dist/normalizer/variant-diff.d.ts +101 -0
  362. package/dist/normalizer/variant-diff.d.ts.map +1 -0
  363. package/dist/normalizer/variant-diff.js +307 -0
  364. package/dist/normalizer/variant-diff.js.map +1 -0
  365. package/dist/plan/implementation-plan.d.ts +28 -0
  366. package/dist/plan/implementation-plan.d.ts.map +1 -0
  367. package/dist/plan/implementation-plan.js +60 -0
  368. package/dist/plan/implementation-plan.js.map +1 -0
  369. package/dist/plan/index.d.ts +3 -0
  370. package/dist/plan/index.d.ts.map +1 -0
  371. package/dist/plan/index.js +3 -0
  372. package/dist/plan/index.js.map +1 -0
  373. package/dist/plan/resolve-affected-files.d.ts +11 -0
  374. package/dist/plan/resolve-affected-files.d.ts.map +1 -0
  375. package/dist/plan/resolve-affected-files.js +73 -0
  376. package/dist/plan/resolve-affected-files.js.map +1 -0
  377. package/dist/prompt/generate-component-prompt.d.ts +6 -0
  378. package/dist/prompt/generate-component-prompt.d.ts.map +1 -0
  379. package/dist/prompt/generate-component-prompt.js +1644 -0
  380. package/dist/prompt/generate-component-prompt.js.map +1 -0
  381. package/dist/registry/ai-provider-registry.d.ts +7 -0
  382. package/dist/registry/ai-provider-registry.d.ts.map +1 -0
  383. package/dist/registry/ai-provider-registry.js +21 -0
  384. package/dist/registry/ai-provider-registry.js.map +1 -0
  385. package/dist/registry/build-component-registry.d.ts +6 -0
  386. package/dist/registry/build-component-registry.d.ts.map +1 -0
  387. package/dist/registry/build-component-registry.js +43 -0
  388. package/dist/registry/build-component-registry.js.map +1 -0
  389. package/dist/registry/build-dependency-graph.d.ts +7 -0
  390. package/dist/registry/build-dependency-graph.d.ts.map +1 -0
  391. package/dist/registry/build-dependency-graph.js +36 -0
  392. package/dist/registry/build-dependency-graph.js.map +1 -0
  393. package/dist/registry/generator-registry.d.ts +12 -0
  394. package/dist/registry/generator-registry.d.ts.map +1 -0
  395. package/dist/registry/generator-registry.js +22 -0
  396. package/dist/registry/generator-registry.js.map +1 -0
  397. package/dist/registry/index.d.ts +3 -0
  398. package/dist/registry/index.d.ts.map +1 -0
  399. package/dist/registry/index.js +3 -0
  400. package/dist/registry/index.js.map +1 -0
  401. package/dist/scaffold-plan/build-scaffold-plan.d.ts +16 -0
  402. package/dist/scaffold-plan/build-scaffold-plan.d.ts.map +1 -0
  403. package/dist/scaffold-plan/build-scaffold-plan.js +91 -0
  404. package/dist/scaffold-plan/build-scaffold-plan.js.map +1 -0
  405. package/dist/scaffold-plan/index.d.ts +2 -0
  406. package/dist/scaffold-plan/index.d.ts.map +1 -0
  407. package/dist/scaffold-plan/index.js +2 -0
  408. package/dist/scaffold-plan/index.js.map +1 -0
  409. package/dist/scanner/collect-components.d.ts +10 -0
  410. package/dist/scanner/collect-components.d.ts.map +1 -0
  411. package/dist/scanner/collect-components.js +103 -0
  412. package/dist/scanner/collect-components.js.map +1 -0
  413. package/dist/scanner/collect-instances.d.ts +6 -0
  414. package/dist/scanner/collect-instances.d.ts.map +1 -0
  415. package/dist/scanner/collect-instances.js +31 -0
  416. package/dist/scanner/collect-instances.js.map +1 -0
  417. package/dist/scanner/index.d.ts +6 -0
  418. package/dist/scanner/index.d.ts.map +1 -0
  419. package/dist/scanner/index.js +6 -0
  420. package/dist/scanner/index.js.map +1 -0
  421. package/dist/scanner/scan-file.d.ts +6 -0
  422. package/dist/scanner/scan-file.d.ts.map +1 -0
  423. package/dist/scanner/scan-file.js +28 -0
  424. package/dist/scanner/scan-file.js.map +1 -0
  425. package/dist/scanner/traverse-nodes.d.ts +15 -0
  426. package/dist/scanner/traverse-nodes.d.ts.map +1 -0
  427. package/dist/scanner/traverse-nodes.js +18 -0
  428. package/dist/scanner/traverse-nodes.js.map +1 -0
  429. package/dist/scanner/types.d.ts +89 -0
  430. package/dist/scanner/types.d.ts.map +1 -0
  431. package/dist/scanner/types.js +2 -0
  432. package/dist/scanner/types.js.map +1 -0
  433. package/dist/snapshots/index.d.ts +6 -0
  434. package/dist/snapshots/index.d.ts.map +1 -0
  435. package/dist/snapshots/index.js +6 -0
  436. package/dist/snapshots/index.js.map +1 -0
  437. package/dist/snapshots/load-imported-tokens.d.ts +8 -0
  438. package/dist/snapshots/load-imported-tokens.d.ts.map +1 -0
  439. package/dist/snapshots/load-imported-tokens.js +27 -0
  440. package/dist/snapshots/load-imported-tokens.js.map +1 -0
  441. package/dist/snapshots/load-latest-snapshot.d.ts +3 -0
  442. package/dist/snapshots/load-latest-snapshot.d.ts.map +1 -0
  443. package/dist/snapshots/load-latest-snapshot.js +16 -0
  444. package/dist/snapshots/load-latest-snapshot.js.map +1 -0
  445. package/dist/snapshots/load-previous-snapshot.d.ts +7 -0
  446. package/dist/snapshots/load-previous-snapshot.d.ts.map +1 -0
  447. package/dist/snapshots/load-previous-snapshot.js +39 -0
  448. package/dist/snapshots/load-previous-snapshot.js.map +1 -0
  449. package/dist/snapshots/save-imported-tokens.d.ts +4 -0
  450. package/dist/snapshots/save-imported-tokens.d.ts.map +1 -0
  451. package/dist/snapshots/save-imported-tokens.js +16 -0
  452. package/dist/snapshots/save-imported-tokens.js.map +1 -0
  453. package/dist/snapshots/save-snapshot.d.ts +3 -0
  454. package/dist/snapshots/save-snapshot.d.ts.map +1 -0
  455. package/dist/snapshots/save-snapshot.js +49 -0
  456. package/dist/snapshots/save-snapshot.js.map +1 -0
  457. package/dist/test-null-safety.d.ts +2 -0
  458. package/dist/test-null-safety.d.ts.map +1 -0
  459. package/dist/test-null-safety.js +67 -0
  460. package/dist/test-null-safety.js.map +1 -0
  461. package/dist/test-regex.d.ts +2 -0
  462. package/dist/test-regex.d.ts.map +1 -0
  463. package/dist/test-regex.js +25 -0
  464. package/dist/test-regex.js.map +1 -0
  465. package/dist/test-token-resolution.d.ts +2 -0
  466. package/dist/test-token-resolution.d.ts.map +1 -0
  467. package/dist/test-token-resolution.js +54 -0
  468. package/dist/test-token-resolution.js.map +1 -0
  469. package/dist/test-typography.d.ts +2 -0
  470. package/dist/test-typography.d.ts.map +1 -0
  471. package/dist/test-typography.js +69 -0
  472. package/dist/test-typography.js.map +1 -0
  473. package/dist/tokens/adapters/generic-adapter.d.ts +13 -0
  474. package/dist/tokens/adapters/generic-adapter.d.ts.map +1 -0
  475. package/dist/tokens/adapters/generic-adapter.js +74 -0
  476. package/dist/tokens/adapters/generic-adapter.js.map +1 -0
  477. package/dist/tokens/adapters/index.d.ts +3 -0
  478. package/dist/tokens/adapters/index.d.ts.map +1 -0
  479. package/dist/tokens/adapters/index.js +3 -0
  480. package/dist/tokens/adapters/index.js.map +1 -0
  481. package/dist/tokens/adapters/ptb-adapter.d.ts +13 -0
  482. package/dist/tokens/adapters/ptb-adapter.d.ts.map +1 -0
  483. package/dist/tokens/adapters/ptb-adapter.js +13 -0
  484. package/dist/tokens/adapters/ptb-adapter.js.map +1 -0
  485. package/dist/tokens/build-token-model.d.ts +12 -0
  486. package/dist/tokens/build-token-model.d.ts.map +1 -0
  487. package/dist/tokens/build-token-model.js +50 -0
  488. package/dist/tokens/build-token-model.js.map +1 -0
  489. package/dist/tokens/classify-token-kind.d.ts +7 -0
  490. package/dist/tokens/classify-token-kind.d.ts.map +1 -0
  491. package/dist/tokens/classify-token-kind.js +24 -0
  492. package/dist/tokens/classify-token-kind.js.map +1 -0
  493. package/dist/tokens/detect-format.d.ts +6 -0
  494. package/dist/tokens/detect-format.d.ts.map +1 -0
  495. package/dist/tokens/detect-format.js +23 -0
  496. package/dist/tokens/detect-format.js.map +1 -0
  497. package/dist/tokens/import-schema.d.ts +111 -0
  498. package/dist/tokens/import-schema.d.ts.map +1 -0
  499. package/dist/tokens/import-schema.js +45 -0
  500. package/dist/tokens/import-schema.js.map +1 -0
  501. package/dist/tokens/import-tokens.d.ts +16 -0
  502. package/dist/tokens/import-tokens.d.ts.map +1 -0
  503. package/dist/tokens/import-tokens.js +40 -0
  504. package/dist/tokens/import-tokens.js.map +1 -0
  505. package/dist/tokens/index.d.ts +12 -0
  506. package/dist/tokens/index.d.ts.map +1 -0
  507. package/dist/tokens/index.js +12 -0
  508. package/dist/tokens/index.js.map +1 -0
  509. package/dist/tokens/naming.d.ts +19 -0
  510. package/dist/tokens/naming.d.ts.map +1 -0
  511. package/dist/tokens/naming.js +27 -0
  512. package/dist/tokens/naming.js.map +1 -0
  513. package/dist/tokens/normalize-token-collections.d.ts +7 -0
  514. package/dist/tokens/normalize-token-collections.d.ts.map +1 -0
  515. package/dist/tokens/normalize-token-collections.js +68 -0
  516. package/dist/tokens/normalize-token-collections.js.map +1 -0
  517. package/dist/tokens/resolution.d.ts +7 -0
  518. package/dist/tokens/resolution.d.ts.map +1 -0
  519. package/dist/tokens/resolution.js +223 -0
  520. package/dist/tokens/resolution.js.map +1 -0
  521. package/dist/tokens/resolve-token-source.d.ts +12 -0
  522. package/dist/tokens/resolve-token-source.d.ts.map +1 -0
  523. package/dist/tokens/resolve-token-source.js +37 -0
  524. package/dist/tokens/resolve-token-source.js.map +1 -0
  525. package/dist/tokens/types.d.ts +40 -0
  526. package/dist/tokens/types.d.ts.map +1 -0
  527. package/dist/tokens/types.js +2 -0
  528. package/dist/tokens/types.js.map +1 -0
  529. package/package.json +34 -0
@@ -0,0 +1,898 @@
1
+ import * as path from "node:path";
2
+ import { checkComponentReadiness } from "../plan/implementation-plan.js";
3
+ import { getPTBTokenVariableName } from "../tokens/naming.js";
4
+ import { calculateContextHash, hashComponentDefinition } from "./hashing.js";
5
+ import { resolveTokenBinding } from "../tokens/resolution.js";
6
+ import { relinkTreeRecipes } from "../normalizer/instance-resolver.js";
7
+ import { buildCompressedContext } from "./compressed-context.js";
8
+ import { resolveDSPaths } from "../filesystem/resolve-ds-paths.js";
9
+ import { createNamingStrategy, normalizeIconDisplayName } from "../mappings/naming-strategy.js";
10
+ import { isIconComponent } from "../icons/enrich-icon-svgs.js";
11
+ /**
12
+ * Constructs a formalized v1 ComponentContext for a given component.
13
+ * This acts as the stable design-system truth for tooling.
14
+ */
15
+ function safeObject(val) {
16
+ return val && typeof val === 'object' && !Array.isArray(val) ? val : {};
17
+ }
18
+ function safeArray(val) {
19
+ return Array.isArray(val) ? val : [];
20
+ }
21
+ /**
22
+ * Normalizes a property name into camelCase for implementation usage.
23
+ */
24
+ function cleanPropName(name) {
25
+ return name.trim()
26
+ .toLowerCase()
27
+ .replace(/[^a-z0-9]+(.)/g, (_, c) => c.toUpperCase())
28
+ .replace(/[^a-zA-Z0-9]/g, "");
29
+ }
30
+ /**
31
+ * Resolves an implementation-ready content contract for a text node,
32
+ * awareness of both props and state-specific defaults.
33
+ */
34
+ function resolveContentContract(node, variantDiffs) {
35
+ const name = (node.name || "").trim();
36
+ const role = node.role || "";
37
+ const baseValue = node.textContent || "";
38
+ const contract = {
39
+ bindingMode: "static",
40
+ dataType: "string",
41
+ required: true,
42
+ baseValue: baseValue,
43
+ sourceRole: role
44
+ };
45
+ // 1. Scan variantDiffs for state-specific text content
46
+ const stateDefaults = {};
47
+ let hasStateChanges = false;
48
+ for (const diff of safeArray(variantDiffs)) {
49
+ const foundNode = safeArray(diff.changedNodes).find((n) => n.nodeName === name);
50
+ if (foundNode) {
51
+ const textChange = safeArray(foundNode.changes).find((c) => c.property === "textContent");
52
+ if (textChange && textChange.to !== undefined) {
53
+ const stateKey = diff.variantName || Object.values(diff.variantSelection || {}).join("-");
54
+ stateDefaults[stateKey] = textChange.to;
55
+ hasStateChanges = true;
56
+ }
57
+ }
58
+ }
59
+ if (hasStateChanges) {
60
+ contract.stateDefaults = stateDefaults;
61
+ }
62
+ // 2. Heuristics for dynamic prop mapping
63
+ const lowerName = name.toLowerCase();
64
+ let propCandidate;
65
+ if (lowerName.includes("title") || lowerName.includes("header") || role === "title")
66
+ propCandidate = "title";
67
+ else if (lowerName.includes("description") || lowerName.includes("body") || lowerName.includes("summary") || role === "description")
68
+ propCandidate = "description";
69
+ else if (lowerName.includes("time") || lowerName.includes("date") || lowerName.includes("timestamp"))
70
+ propCandidate = "time";
71
+ else if (lowerName.includes("label") || role === "label")
72
+ propCandidate = "label";
73
+ else if (lowerName.includes("button text") || lowerName.includes("btn text") || (lowerName === "text" && role === "text"))
74
+ propCandidate = "text";
75
+ else if (lowerName.includes("helper") || role === "helper-text")
76
+ propCandidate = "helperText";
77
+ else if (lowerName.includes("error") || role === "error-text")
78
+ propCandidate = "errorText";
79
+ const hasProp = !!propCandidate;
80
+ // 3. Determine Binding Mode
81
+ if (hasProp && hasStateChanges) {
82
+ contract.bindingMode = "state-default-with-prop-override";
83
+ contract.propName = propCandidate;
84
+ contract.overridePriority = ["explicitProp", "stateDefault", "baseValue"];
85
+ }
86
+ else if (hasProp) {
87
+ contract.bindingMode = "prop-only";
88
+ contract.propName = propCandidate;
89
+ }
90
+ else if (hasStateChanges) {
91
+ contract.bindingMode = "state-only";
92
+ }
93
+ else if (role === "placeholder-text" || lowerName.includes("placeholder")) {
94
+ contract.bindingMode = "prop-only";
95
+ contract.propName = propCandidate || "placeholder";
96
+ }
97
+ else if (name.length > 2 && !name.includes("Layer") && !name.includes("Frame") && !name.includes("Group")) {
98
+ contract.bindingMode = "dynamicHint";
99
+ contract.propName = cleanPropName(name);
100
+ contract.warning = "Inferred from node name; verify if this should be a prop/state binding.";
101
+ }
102
+ return contract;
103
+ }
104
+ /**
105
+ * Extracts a semantic text style reference (e.g. body/sm) from raw Figma style data.
106
+ */
107
+ function resolveTextStyleRef(node, designSystemStyles) {
108
+ const styleId = node.rawStyles?.figmaStyles?.text;
109
+ const styleDef = styleId && designSystemStyles ? designSystemStyles[styleId] : undefined;
110
+ // Use style library name first, fallback to node-level name if available
111
+ const displayName = styleDef?.name || node.rawStyles?.textStyle?.name;
112
+ if (!displayName)
113
+ return undefined;
114
+ if (displayName.includes("/")) {
115
+ const parts = displayName.split("/");
116
+ return {
117
+ group: parts[0].trim().toLowerCase(),
118
+ name: parts[1].trim().toLowerCase(),
119
+ displayName
120
+ };
121
+ }
122
+ return {
123
+ displayName,
124
+ name: displayName.trim().toLowerCase()
125
+ };
126
+ }
127
+ /**
128
+ * Compiles a transition summary between variants.
129
+ */
130
+ function resolveTransitionSummary(variantDiffs) {
131
+ const summary = {};
132
+ for (const diff of safeArray(variantDiffs)) {
133
+ if (!diff.variantName)
134
+ continue;
135
+ // For simplicity in Phase 3, we summarize "base -> variant"
136
+ const key = `base -> ${diff.variantName}`;
137
+ summary[key] = {
138
+ contentChanges: safeArray(diff.changedNodes)
139
+ .filter((n) => safeArray(n.changes).some((c) => c.property === "textContent"))
140
+ .map((n) => n.nodeName),
141
+ slotVisibilityChanges: [
142
+ ...safeArray(diff.addedNodes).map((n) => n.name),
143
+ ...safeArray(diff.removedNodes).map((n) => n.name)
144
+ ],
145
+ styleChanges: safeArray(diff.changedNodes)
146
+ .filter((n) => safeArray(n.changes).some((c) => c.property !== "textContent"))
147
+ .map((n) => n.nodeName),
148
+ dependencyChanges: safeArray(diff.changedNodes)
149
+ .filter((n) => safeArray(n.changes).some((c) => c.property === "componentId"))
150
+ .map((n) => n.nodeName)
151
+ };
152
+ }
153
+ return summary;
154
+ }
155
+ /**
156
+ * Infers a state contract for components with variants.
157
+ */
158
+ function resolveStateContract(component, variantDiffs) {
159
+ if (!component.variantAxes || component.variantAxes.length === 0)
160
+ return undefined;
161
+ // Use the first axis as the primary state axis for now
162
+ const primaryAxis = component.variantAxes[0];
163
+ const stateDefaults = {};
164
+ for (const diff of safeArray(variantDiffs)) {
165
+ const stateKey = diff.variantName || Object.values(diff.variantSelection || {}).join("-");
166
+ stateDefaults[stateKey] = {
167
+ content: {},
168
+ slotVisibility: {},
169
+ style: {},
170
+ dependency: {}
171
+ };
172
+ // Compile content and style defaults
173
+ for (const node of safeArray(diff.changedNodes)) {
174
+ const textChange = safeArray(node.changes).find((c) => c.property === "textContent");
175
+ if (textChange) {
176
+ stateDefaults[stateKey].content[node.nodeName] = textChange.to;
177
+ }
178
+ const styleChanges = safeArray(node.changes).filter((c) => c.property !== "textContent" && c.property !== "componentId");
179
+ if (styleChanges.length > 0) {
180
+ stateDefaults[stateKey].style[node.nodeName] = styleChanges.reduce((acc, c) => {
181
+ acc[c.property] = c.to;
182
+ return acc;
183
+ }, {});
184
+ }
185
+ const dependencyChange = safeArray(node.changes).find((c) => c.property === "componentId");
186
+ if (dependencyChange) {
187
+ stateDefaults[stateKey].dependency[node.nodeName] = dependencyChange.to;
188
+ }
189
+ }
190
+ // Compile visibility defaults
191
+ for (const node of safeArray(diff.addedNodes)) {
192
+ stateDefaults[stateKey].slotVisibility[node.name] = true;
193
+ }
194
+ for (const node of safeArray(diff.removedNodes)) {
195
+ stateDefaults[stateKey].slotVisibility[node.name] = false;
196
+ }
197
+ }
198
+ return {
199
+ controller: {
200
+ kind: "prop",
201
+ name: cleanPropName(primaryAxis.name),
202
+ dataType: "string",
203
+ defaultValue: primaryAxis.defaultValue
204
+ },
205
+ stateAxis: {
206
+ name: primaryAxis.name,
207
+ options: primaryAxis.options
208
+ },
209
+ stateDefaults,
210
+ overridePriority: ["explicitProp", "stateDefault", "baseValue"]
211
+ };
212
+ }
213
+ /**
214
+ * Extracts interactions from Figma prototype data if available.
215
+ */
216
+ function resolveInteractionContract(component) {
217
+ const events = [];
218
+ const warnings = [];
219
+ // Heuristic: If it's a button or has "click" in name, expect interaction
220
+ const hasClickableName = component.name.toLowerCase().includes("button") ||
221
+ component.name.toLowerCase().includes("btn") ||
222
+ component.name.toLowerCase().includes("link");
223
+ if (hasClickableName) {
224
+ // We lack deep prototype parsing in this version, so we provide a hint/placeholder
225
+ warnings.push("Interactive affordance detected based on component name; verify Figma prototyping for exact behavior.");
226
+ }
227
+ return {
228
+ events,
229
+ interactionModel: "declarative",
230
+ warnings: warnings.length > 0 ? warnings : undefined
231
+ };
232
+ }
233
+ /**
234
+ * Normalizes a Figma trigger into a runtime event and category.
235
+ */
236
+ function normalizeTrigger(figmaTrigger) {
237
+ const type = figmaTrigger?.type || "unknown";
238
+ switch (type) {
239
+ case "ON_CLICK": return { runtime: "onClick", category: "click" };
240
+ case "MOUSE_ENTER": return { runtime: "onMouseEnter", category: "pointer-enter" };
241
+ case "MOUSE_LEAVE": return { runtime: "onMouseLeave", category: "pointer-leave" };
242
+ case "MOUSE_DOWN": return { runtime: "onMouseDown", category: "pointer-down" };
243
+ case "MOUSE_UP": return { runtime: "onMouseUp", category: "pointer-up" };
244
+ case "AFTER_DELAY": return { runtime: "afterDelay", category: "timer" };
245
+ case "ON_DRAG": return { runtime: "onDrag", category: "gesture" };
246
+ case "ON_HOVER": return { runtime: "onMouseEnter", category: "pointer-enter" }; // Map hover to enter for simplicity
247
+ default: return { runtime: "unknown", category: "unknown" };
248
+ }
249
+ }
250
+ /**
251
+ * Normalizes a Figma action.
252
+ */
253
+ function normalizeAction(figmaAction) {
254
+ const type = figmaAction?.type || "unknown";
255
+ switch (type) {
256
+ case "NODE":
257
+ if (figmaAction.navigation === "CHANGE_TO") {
258
+ return { type: "changeState", targetState: figmaAction.destinationId };
259
+ }
260
+ if (figmaAction.navigation === "NAVIGATE") {
261
+ return { type: "navigate", targetFrame: figmaAction.destinationId };
262
+ }
263
+ return { type: "unknown" };
264
+ case "OPEN_OVERLAY": return { type: "openOverlay", targetOverlay: figmaAction.destinationId };
265
+ case "CLOSE_OVERLAY": return { type: "closeOverlay" };
266
+ case "BACK": return { type: "back" };
267
+ case "URL": return { type: "navigate", targetFrame: figmaAction.url };
268
+ default: return { type: "unknown" };
269
+ }
270
+ }
271
+ /**
272
+ * Normalizes Figma animation metadata.
273
+ */
274
+ function normalizeAnimation(figmaAnimation) {
275
+ if (!figmaAnimation)
276
+ return undefined;
277
+ const type = figmaAnimation.type || "instant";
278
+ return {
279
+ figma: type,
280
+ type: type.toLowerCase().replace(/_([a-z])/g, (g) => g[1].toUpperCase()), // e.g. SMART_ANIMATE -> smartAnimate
281
+ curve: figmaAnimation.easing?.toLowerCase() || "ease-out",
282
+ durationMs: figmaAnimation.duration !== undefined ? Math.round(figmaAnimation.duration * 1000) : 300,
283
+ };
284
+ }
285
+ /**
286
+ * Infers animation implementation hints based on state differences.
287
+ */
288
+ function resolveAnimationHints(action, component) {
289
+ if (action.type !== "changeState" || !action.targetState) {
290
+ return { preferredImplementation: "state-swap" };
291
+ }
292
+ // Try to find the diff for the target state
293
+ const diffs = safeArray(component.variantDiffs);
294
+ const targetDiff = diffs.find(d => d.variantName === action.targetState ||
295
+ Object.values(d.variantSelection || {}).join("-") === action.targetState);
296
+ if (!targetDiff) {
297
+ return { preferredImplementation: "layout-transition" }; // Default for smart animate
298
+ }
299
+ const changedProps = new Set();
300
+ for (const node of safeArray(targetDiff.changedNodes)) {
301
+ for (const change of safeArray(node.changes)) {
302
+ if (change.property === "absoluteBoundingBox" || change.property === "size")
303
+ changedProps.add("size");
304
+ if (change.property === "opacity")
305
+ changedProps.add("opacity");
306
+ if (change.property === "fills" || change.property === "color")
307
+ changedProps.add("color");
308
+ }
309
+ }
310
+ return {
311
+ changedProperties: changedProps.size > 0 ? Array.from(changedProps) : undefined,
312
+ preferredImplementation: changedProps.has("size") ? "layout-transition" : "opacity-transition"
313
+ };
314
+ }
315
+ /**
316
+ * Resolves high-fidelity prototype interactions.
317
+ */
318
+ function resolvePrototypeInteractionContract(component) {
319
+ const interactions = [];
320
+ const warnings = [];
321
+ const stateTransitions = new Set();
322
+ const processReactions = (node, path = "root") => {
323
+ const reactions = safeArray(node.reactions);
324
+ for (const reaction of reactions) {
325
+ const trigger = normalizeTrigger(reaction.trigger);
326
+ const action = normalizeAction(reaction.action);
327
+ const animation = normalizeAnimation(reaction.action?.transition);
328
+ const animationHints = resolveAnimationHints(action, component);
329
+ if (trigger.runtime === "unknown" || action.type === "unknown") {
330
+ warnings.push(`Incomplete normalization for interaction on node '${node.name}' (type: ${reaction.trigger?.type})`);
331
+ }
332
+ const interaction = {
333
+ source: {
334
+ nodeName: node.name || "unknown",
335
+ path,
336
+ role: node.role || "generic"
337
+ },
338
+ trigger: {
339
+ figma: reaction.trigger?.type || "unknown",
340
+ runtime: trigger.runtime,
341
+ category: trigger.category
342
+ },
343
+ action: {
344
+ figma: reaction.action?.type || "unknown",
345
+ ...action
346
+ },
347
+ animation,
348
+ animationHints
349
+ };
350
+ // Detect state transitions for reverse logic checking
351
+ if (interaction.action.type === "changeState" && interaction.action.targetState) {
352
+ stateTransitions.add(`${interaction.trigger.category}->${interaction.action.targetState}`);
353
+ }
354
+ interactions.push(interaction);
355
+ }
356
+ if (node.children) {
357
+ for (const child of safeArray(node.children)) {
358
+ processReactions(child, `${path}/${child.name}`);
359
+ }
360
+ }
361
+ };
362
+ // Process the render tree (canonical view for all components)
363
+ if (component.renderTree) {
364
+ processReactions(component.renderTree);
365
+ }
366
+ else if (component.baseRenderTree) {
367
+ // Fallback for sets if renderTree is somehow missing or distinct
368
+ processReactions(component.baseRenderTree);
369
+ }
370
+ // Check for reverse transition gaps (e.g. hover without leave)
371
+ const hoverTransitions = interactions.filter(i => i.trigger.category === "pointer-enter");
372
+ for (const hover of hoverTransitions) {
373
+ const hasReverse = interactions.some(i => i.trigger.category === "pointer-leave" &&
374
+ i.source.nodeName === hover.source.nodeName);
375
+ if (!hasReverse) {
376
+ warnings.push(`One-way hover transition detected on '${hover.source.nodeName}'; reverse transition (pointer-leave) not found.`);
377
+ }
378
+ }
379
+ return {
380
+ interactions,
381
+ warnings: warnings.length > 0 ? warnings : undefined
382
+ };
383
+ }
384
+ export async function getComponentContext(componentId, model, config, manifest) {
385
+ const component = model.components.find(c => c.id === componentId);
386
+ if (!component)
387
+ return undefined;
388
+ const manifestEntry = manifest?.components[componentId];
389
+ // Precompute import path helpers once for all dependency lookups
390
+ const { componentsDir } = resolveDSPaths(config);
391
+ const naming = createNamingStrategy(config.naming);
392
+ const currentCategoryDir = component.categoryPath
393
+ ? path.join(componentsDir, naming.formatFolderName(component.categoryPath), naming.formatFolderName(component.name))
394
+ : path.join(componentsDir, naming.formatFolderName(component.name));
395
+ const dependencies = await (async () => {
396
+ const grouped = new Map();
397
+ for (const id of (component.dependencies || [])) {
398
+ // id is usually a PTB internal ID (comp_N_M), but falls back to the raw
399
+ // Figma componentId when the normalizer couldn't map it. Support both.
400
+ const dep = model.components.find((c) => c.id === id ||
401
+ c.designToolNodeId === id ||
402
+ (/^\d+:\d+$/.test(id) && c.id === `comp_${id.replace(/:/g, "_")}`));
403
+ const name = dep ? dep.name : `unknown (${id})`;
404
+ const existing = grouped.get(name);
405
+ if (existing) {
406
+ existing.count++;
407
+ }
408
+ else {
409
+ let status = "external";
410
+ let importPath;
411
+ if (dep) {
412
+ const readiness = await checkComponentReadiness(dep, config, manifest);
413
+ status = readiness.isReady ? "ready" : "missing";
414
+ // Compute the correct relative import path from this component to the dependency.
415
+ // Icon components use a fixed ../../icons/ prefix handled separately by post-processing.
416
+ if (!isIconComponent(dep.name)) {
417
+ const depName = dep.name;
418
+ const depFolderName = naming.formatFolderName(depName);
419
+ const depDir = dep.categoryPath
420
+ ? path.join(componentsDir, naming.formatFolderName(dep.categoryPath), depFolderName)
421
+ : path.join(componentsDir, depFolderName);
422
+ const rel = path.relative(currentCategoryDir, depDir).replace(/\\/g, "/") + "/index.js";
423
+ importPath = rel.startsWith(".") ? rel : "./" + rel;
424
+ }
425
+ else {
426
+ const normalized = normalizeIconDisplayName(dep.name);
427
+ importPath = `../../icons/${naming.formatFolderName(normalized)}/index.js`;
428
+ }
429
+ }
430
+ const propHints = [];
431
+ if (dep) {
432
+ for (const axis of (dep.variantAxes || [])) {
433
+ const propName = cleanPropName(axis.name);
434
+ const union = axis.options.map((o) => `'${o}'`).join(" | ");
435
+ const defNote = axis.defaultValue ? ` /* default: '${axis.defaultValue}' */` : "";
436
+ propHints.push(`${propName}?: ${union}${defNote}`);
437
+ }
438
+ for (const prop of (dep.properties || [])) {
439
+ const propName = cleanPropName(prop.name);
440
+ if (prop.type === "text") {
441
+ const defNote = prop.defaultValue ? ` /* default: "${prop.defaultValue}" */` : "";
442
+ propHints.push(`${propName}?: string${defNote}`);
443
+ }
444
+ else if (prop.type === "boolean") {
445
+ const defNote = prop.defaultValue !== undefined ? ` /* default: ${prop.defaultValue} */` : "";
446
+ propHints.push(`${propName}?: boolean${defNote}`);
447
+ }
448
+ else if (prop.type === "instance") {
449
+ propHints.push(`${propName}?: React.ReactNode`);
450
+ }
451
+ }
452
+ }
453
+ grouped.set(name, { id, name, count: 1, kind: "nested-instance", source: "figma-nested-instance", status, importPath, propHints });
454
+ }
455
+ }
456
+ return Array.from(grouped.values()).sort((a, b) => a.name.localeCompare(b.name));
457
+ })();
458
+ const resolvedBindings = {};
459
+ const resolveAndAdd = (slot, sourceVarId, targetObj = resolvedBindings) => {
460
+ if (!sourceVarId)
461
+ return;
462
+ const resolved = resolveTokenBinding(sourceVarId, model.tokens);
463
+ if (resolved) {
464
+ targetObj[slot] = resolved;
465
+ }
466
+ };
467
+ // 1. Resolve explicit token bindings
468
+ for (const b of (component.tokenBindings || [])) {
469
+ if (b.boundToken?.id) {
470
+ resolveAndAdd(b.slot, b.boundToken.id);
471
+ }
472
+ else if (b.resolvedToken?.id) {
473
+ resolveAndAdd(b.slot, b.resolvedToken.id);
474
+ }
475
+ }
476
+ // 2. Resolve layout tokens
477
+ if (component.layout) {
478
+ if (component.layout.gap?.resolvedToken?.id) {
479
+ resolveAndAdd("gap", component.layout.gap.resolvedToken.id);
480
+ }
481
+ if (component.layout.padding) {
482
+ const p = component.layout.padding;
483
+ if (p.top?.resolvedToken?.id)
484
+ resolveAndAdd("paddingTop", p.top.resolvedToken.id);
485
+ if (p.right?.resolvedToken?.id)
486
+ resolveAndAdd("paddingRight", p.right.resolvedToken.id);
487
+ if (p.bottom?.resolvedToken?.id)
488
+ resolveAndAdd("paddingBottom", p.bottom.resolvedToken.id);
489
+ if (p.left?.resolvedToken?.id)
490
+ resolveAndAdd("paddingLeft", p.left.resolvedToken.id);
491
+ }
492
+ }
493
+ // 3. Resolve sizing tokens
494
+ if (component.size) {
495
+ if (component.size.width?.resolvedToken?.id)
496
+ resolveAndAdd("width", component.size.width.resolvedToken.id);
497
+ if (component.size.height?.resolvedToken?.id)
498
+ resolveAndAdd("height", component.size.height.resolvedToken.id);
499
+ }
500
+ // 4. Resolve stylistic metadata if it contains variable IDs (rare but possible)
501
+ if (component.styleMetadata) {
502
+ for (const [key, value] of Object.entries(component.styleMetadata)) {
503
+ if (typeof value === "string" && value.startsWith("VariableID:")) {
504
+ resolveAndAdd(key, value);
505
+ }
506
+ }
507
+ }
508
+ const contentSourceMap = {};
509
+ const variantDiffs = component.variantDiffs || [];
510
+ const context = {
511
+ component: {
512
+ name: component.name,
513
+ id: component.id,
514
+ kind: typeof component.kind === "string"
515
+ ? { value: component.kind, inferred: true }
516
+ : component.kind ?? { value: "unclassified", inferred: true },
517
+ category: component.categoryPath || "unclassified",
518
+ framework: config.framework.name,
519
+ artifacts: manifestEntry ? {
520
+ folder: manifestEntry.folder,
521
+ files: manifestEntry.artifacts,
522
+ isManaged: true
523
+ } : {
524
+ isManaged: false
525
+ },
526
+ description: component.description || null
527
+ },
528
+ variantAxes: (component.variantAxes || []).map(p => ({
529
+ ...p,
530
+ source: p.source || "figma-component-set"
531
+ })),
532
+ properties: (component.properties || []).map(p => ({
533
+ ...p,
534
+ source: p.source || "figma-component-property"
535
+ })),
536
+ dependencies,
537
+ slots: component.styleMetadata ? Object.keys(component.styleMetadata).map(name => ({ name })) : [],
538
+ tokenBindings: (component.tokenBindings || []).map(b => {
539
+ const resolved = typeof b.resolvedToken === "string"
540
+ ? { name: b.resolvedToken }
541
+ : b.resolvedToken;
542
+ if (resolved && resolved.name && resolved.collection?.name) {
543
+ resolved.cssVariable = getPTBTokenVariableName(resolved.collection.name, resolved.name);
544
+ }
545
+ return {
546
+ ...b,
547
+ resolvedToken: resolved,
548
+ boundToken: typeof b.boundToken === "string"
549
+ ? { name: b.boundToken }
550
+ : b.boundToken,
551
+ source: b.source || (b.boundToken ? "figma-variable-binding" : undefined)
552
+ };
553
+ }),
554
+ resolvedBindings,
555
+ layout: component.layout ? {
556
+ ...component.layout,
557
+ mainAlignment: component.layout.mainAlignment || component.layout.alignment || "start",
558
+ crossAlignment: component.layout.crossAlignment || "center",
559
+ gap: component.layout.gap ? {
560
+ ...component.layout.gap,
561
+ resolvedToken: typeof component.layout.gap.resolvedToken === "string"
562
+ ? { name: component.layout.gap.resolvedToken }
563
+ : component.layout.gap.resolvedToken
564
+ } : undefined,
565
+ padding: component.layout.padding ? {
566
+ top: {
567
+ ...component.layout.padding.top,
568
+ resolvedToken: typeof component.layout.padding.top.resolvedToken === "string"
569
+ ? { name: component.layout.padding.top.resolvedToken }
570
+ : component.layout.padding.top.resolvedToken
571
+ },
572
+ right: {
573
+ ...component.layout.padding.right,
574
+ resolvedToken: typeof component.layout.padding.right.resolvedToken === "string"
575
+ ? { name: component.layout.padding.right.resolvedToken }
576
+ : component.layout.padding.right.resolvedToken
577
+ },
578
+ bottom: {
579
+ ...component.layout.padding.bottom,
580
+ resolvedToken: typeof component.layout.padding.bottom.resolvedToken === "string"
581
+ ? { name: component.layout.padding.bottom.resolvedToken }
582
+ : component.layout.padding.bottom.resolvedToken
583
+ },
584
+ left: {
585
+ ...component.layout.padding.left,
586
+ resolvedToken: typeof component.layout.padding.left.resolvedToken === "string"
587
+ ? { name: component.layout.padding.left.resolvedToken }
588
+ : component.layout.padding.left.resolvedToken
589
+ },
590
+ } : undefined
591
+ } : null,
592
+ size: component.size ? {
593
+ width: {
594
+ ...component.size.width,
595
+ resolvedToken: typeof component.size.width.resolvedToken === "string"
596
+ ? { name: component.size.width.resolvedToken }
597
+ : component.size.width.resolvedToken
598
+ },
599
+ height: {
600
+ ...component.size.height,
601
+ resolvedToken: typeof component.size.height.resolvedToken === "string"
602
+ ? { name: component.size.height.resolvedToken }
603
+ : component.size.height.resolvedToken
604
+ }
605
+ } : null,
606
+ renderTree: component.renderTree,
607
+ baseRenderTree: component.baseRenderTree,
608
+ defaultVariantSelection: component.defaultVariantSelection,
609
+ variantDiffs: component.variantDiffs,
610
+ childNodes: component.childNodes,
611
+ dependencyInstances: component.dependencyInstances,
612
+ contentSourceMap: {},
613
+ stateContract: resolveStateContract(component, variantDiffs),
614
+ interactionContract: resolveInteractionContract(component),
615
+ transitionSummary: resolveTransitionSummary(variantDiffs),
616
+ prototypeInteractionContract: resolvePrototypeInteractionContract(component)
617
+ };
618
+ // 5. Relink recipes first to ensure engineering contracts are ready
619
+ if (context.renderTree)
620
+ relinkTreeRecipes(context.renderTree, model.components);
621
+ if (context.baseRenderTree)
622
+ relinkTreeRecipes(context.baseRenderTree, model.components);
623
+ // 6. Populate resolvedBindings and contentBindings onto tree nodes recursively
624
+ function populateTreeBindings(node) {
625
+ if (!node)
626
+ return;
627
+ try {
628
+ doPopulateTreeBindings(node);
629
+ }
630
+ catch (e) {
631
+ node.warnings = safeArray(node.warnings);
632
+ node.warnings.push({
633
+ type: "enrichment-fallback",
634
+ nodeName: node.name || "unknown",
635
+ reason: e.message
636
+ });
637
+ }
638
+ }
639
+ function doPopulateTreeBindings(node) {
640
+ const nodeBoundVars = safeObject(node.boundVariables);
641
+ const styleBoundVars = safeObject(node.rawStyles?.textStyle?.boundVariables);
642
+ const allBoundVars = { ...styleBoundVars, ...nodeBoundVars }; // Node direct bindings take precedence
643
+ if (Object.keys(allBoundVars).length > 0) {
644
+ node.resolvedBindings = node.resolvedBindings || {};
645
+ for (const [key, val] of Object.entries(allBoundVars)) {
646
+ if (!val)
647
+ continue;
648
+ if (Array.isArray(val) && val[0] && val[0].id) {
649
+ if (key === "fills") {
650
+ resolveAndAdd("fill", val[0].id, node.resolvedBindings);
651
+ resolveAndAdd("color", val[0].id, node.resolvedBindings);
652
+ }
653
+ else {
654
+ const slot = key === "strokes" ? "stroke" : key;
655
+ resolveAndAdd(slot, val[0].id, node.resolvedBindings);
656
+ }
657
+ }
658
+ else if (typeof val === "object" && val.id) {
659
+ resolveAndAdd(key, val.id, node.resolvedBindings);
660
+ }
661
+ }
662
+ }
663
+ if (node.rawStyles && Array.isArray(node.rawStyles.fills)) {
664
+ for (const fill of safeArray(node.rawStyles.fills)) {
665
+ const fillBoundVars = safeObject(fill?.boundVariables);
666
+ if (fillBoundVars.color && fillBoundVars.color.id) {
667
+ node.resolvedBindings = node.resolvedBindings || {};
668
+ resolveAndAdd("color", fillBoundVars.color.id, node.resolvedBindings);
669
+ resolveAndAdd("fill", fillBoundVars.color.id, node.resolvedBindings);
670
+ break;
671
+ }
672
+ }
673
+ }
674
+ if (node.role === "text" || node.role === "title" || node.role === "label" || node.role === "placeholder-text" || node.role === "error-text" || node.role === "helper-text" || (node.type === "leaf" && (node.textContent !== undefined || (node.name || "").includes("Text"))) || node.rawStyles?.nodeType === "TEXT") {
675
+ // Refined Typography Contract v2
676
+ const rawStyle = node.rawStyles?.textStyle || {};
677
+ const textStyleRef = resolveTextStyleRef(node, model.styles);
678
+ // Derive preferredClassName from the resolved style ref, or fall back to any
679
+ // raw style name on the node itself (covers externally-defined text styles
680
+ // that aren't synced into model.styles but whose name is present on the node).
681
+ let preferredClassName;
682
+ if (textStyleRef?.displayName) {
683
+ preferredClassName = `type-${textStyleRef.displayName.toLowerCase().replace(/[/\s]+/g, "-")}`;
684
+ }
685
+ else {
686
+ const rawName = node.rawStyles?.figmaStyles?.textStyleName ?? node.rawStyles?.textStyle?.name;
687
+ if (rawName) {
688
+ preferredClassName = `type-${String(rawName).toLowerCase().replace(/[/\s]+/g, "-")}`;
689
+ }
690
+ }
691
+ node.typographyContract = {
692
+ textStyleRef,
693
+ resolved: {},
694
+ codeHint: preferredClassName ? { preferredClassName } : undefined,
695
+ textAutoResize: rawStyle.textAutoResize
696
+ };
697
+ const resolveTypographySlot = (slot, cssFallbackKey, formatFallback) => {
698
+ const styleBoundVars = safeObject(rawStyle?.boundVariables);
699
+ const nodeBoundVars = safeObject(node?.boundVariables);
700
+ // Tier 1: Assigned Style Property (Variable-backed first, then Literal)
701
+ // This prioritizes the "Style Truth" as requested.
702
+ if (styleBoundVars[slot]) {
703
+ const varArr = safeArray(styleBoundVars[slot]);
704
+ const varId = styleBoundVars[slot]?.id || varArr?.[0]?.id;
705
+ if (varId) {
706
+ const resolved = resolveTokenBinding(varId, model.tokens);
707
+ if (resolved)
708
+ return resolved;
709
+ }
710
+ }
711
+ // If no style variable, check for style literal (Semantic Truth)
712
+ // Only treat it as "Semantic Truth" if it's from a named style.
713
+ const styleVal = safeObject(rawStyle)[cssFallbackKey];
714
+ if (styleVal !== undefined && styleVal !== null && rawStyle.name) {
715
+ return {
716
+ sourceTokenName: "literal",
717
+ cssValue: formatFallback(styleVal),
718
+ cssVar: "",
719
+ canonicalCssVar: "",
720
+ valueType: slot === "fontWeight" ? "NUMBER" : (slot === "fontFamily" ? "STRING" : "DIMENSION"),
721
+ resolutionPath: ["literal"]
722
+ };
723
+ }
724
+ // Tier 2: Node-level bound variables (Instance Overrides)
725
+ if (nodeBoundVars[slot]) {
726
+ const varArr = safeArray(nodeBoundVars[slot]);
727
+ const varId = nodeBoundVars[slot]?.id || varArr?.[0]?.id;
728
+ if (varId) {
729
+ const resolved = resolveTokenBinding(varId, model.tokens);
730
+ if (resolved)
731
+ return resolved;
732
+ }
733
+ }
734
+ // Tier 3: Rendered fallback measurements (Node raw styles if no style is present)
735
+ const rawVal = safeObject(rawStyle)[cssFallbackKey];
736
+ if (rawVal !== undefined && rawVal !== null) {
737
+ return {
738
+ sourceTokenName: "rendered-fallback",
739
+ cssValue: formatFallback(rawVal),
740
+ cssVar: "",
741
+ canonicalCssVar: "",
742
+ valueType: slot === "fontWeight" ? "NUMBER" : (slot === "fontFamily" ? "STRING" : "DIMENSION"),
743
+ resolutionPath: ["rendered-fallback"]
744
+ };
745
+ }
746
+ return undefined;
747
+ };
748
+ const fontSize = resolveTypographySlot("fontSize", "fontSize", v => `${v}px`);
749
+ const lineHeight = resolveTypographySlot("lineHeight", "lineHeightPx", v => `${v}px`);
750
+ const fontWeight = resolveTypographySlot("fontWeight", "fontWeight", v => `${v}`);
751
+ const fontFamily = resolveTypographySlot("fontFamily", "fontFamily", v => `${v}`);
752
+ const letterSpacing = resolveTypographySlot("letterSpacing", "letterSpacing", v => `${v}px`);
753
+ if (fontSize)
754
+ node.typographyContract.resolved.fontSize = fontSize;
755
+ if (lineHeight)
756
+ node.typographyContract.resolved.lineHeight = lineHeight;
757
+ if (fontWeight)
758
+ node.typographyContract.resolved.fontWeight = fontWeight;
759
+ if (fontFamily)
760
+ node.typographyContract.resolved.fontFamily = fontFamily;
761
+ if (letterSpacing)
762
+ node.typographyContract.resolved.letterSpacing = letterSpacing;
763
+ // Extract Content Contract
764
+ const contract = resolveContentContract(node, variantDiffs);
765
+ node.contentContract = contract;
766
+ if (contract.propName) {
767
+ contentSourceMap[node.name || "Text"] = contract.propName;
768
+ }
769
+ }
770
+ if (node.children) {
771
+ for (const child of safeArray(node.children))
772
+ populateTreeBindings(child);
773
+ }
774
+ if (node.childOverrides) {
775
+ for (const child of safeArray(node.childOverrides))
776
+ populateTreeBindings(child);
777
+ }
778
+ }
779
+ if (context.renderTree)
780
+ populateTreeBindings(context.renderTree);
781
+ if (context.baseRenderTree)
782
+ populateTreeBindings(context.baseRenderTree);
783
+ if (context.childNodes) {
784
+ for (const child of context.childNodes)
785
+ populateTreeBindings(child);
786
+ }
787
+ // Calculate metadata and add it to the final context
788
+ const metadata = {
789
+ schemaVersion: "1.0.0",
790
+ componentId: component.id,
791
+ componentName: component.name,
792
+ sourceSnapshotId: model.version || "unknown",
793
+ contextHash: "", // filled in next step
794
+ generatedAt: new Date().toISOString(),
795
+ dependencyContextHashes: (() => {
796
+ const hashes = {};
797
+ for (const dep of dependencies) {
798
+ // Include "missing" (in model, not yet implemented) as well as "ready" —
799
+ // the hash tracks what the design snapshot says about this dep, not its build state.
800
+ if (dep.status === "ready" || dep.status === "missing") {
801
+ const depDef = model.components.find((c) => c.id === dep.id || c.figmaNodeId === dep.id);
802
+ if (depDef)
803
+ hashes[dep.name] = hashComponentDefinition(depDef);
804
+ }
805
+ }
806
+ return hashes;
807
+ })()
808
+ };
809
+ const finalContext = {
810
+ metadata,
811
+ ...context
812
+ };
813
+ finalContext.metadata.contextHash = calculateContextHash(finalContext);
814
+ finalContext.contentSourceMap = contentSourceMap;
815
+ // 8. Build Compressed Context Layer
816
+ if (finalContext.variantDiffs && finalContext.variantDiffs.length > 0) {
817
+ finalContext.compressedContext = buildCompressedContext(component, finalContext, model.tokens);
818
+ }
819
+ // 9. Update Implementation Hints
820
+ finalContext.implementationHints = finalContext.implementationHints || {};
821
+ if (finalContext.compressedContext) {
822
+ finalContext.implementationHints.notes = finalContext.implementationHints.notes || [];
823
+ finalContext.implementationHints.notes.push("Prefer compressedContext (Base + Patch) over raw variantDiffs when possible.");
824
+ }
825
+ // 10. Derive semanticElement — the recommended HTML root element.
826
+ // Computed deterministically from name patterns, componentType, and contracts.
827
+ // Omitted when "div" is the correct default. Rules are first-match-wins.
828
+ const semanticElement = (() => {
829
+ const n = component.name.toLowerCase();
830
+ const ic = finalContext.interactionContract;
831
+ const ct = component.componentType;
832
+ const events = ic?.events ?? [];
833
+ // ── Navigation structures ──────────────────────────────────────────────
834
+ const hasNavigateAction = events.some((e) => e.action?.type === "navigate" || e.action?.type === "navigate-back");
835
+ if (/\bnav(igation|bar|rail|menu)?\b/.test(n) || hasNavigateAction)
836
+ return "nav";
837
+ if (/\b(tab-?bar|tab-?list|breadcrumb|pagination)\b/.test(n))
838
+ return "nav";
839
+ if (/\b(sidebar|side-?nav)\b/.test(n))
840
+ return "nav";
841
+ // ── List containers ────────────────────────────────────────────────────
842
+ if (/\bmenu\b/.test(n) && !/\bmenu-?item\b/.test(n))
843
+ return "ul";
844
+ if (/\b(list|item-?list)\b/.test(n) && !/\bdrop/.test(n))
845
+ return "ul";
846
+ // ── List items — strong suffix signals only ────────────────────────────
847
+ // "Menu Item", "List Item", "Dropdown Item", "Select Option" etc.
848
+ if (/\b(menu-?item|list-?item|dropdown-?item|select-?item|select-?option|option)\b/.test(n))
849
+ return "li";
850
+ // ── Explicit button names ──────────────────────────────────────────────
851
+ if (/\b(btn|button)\b/.test(n))
852
+ return "button";
853
+ // ── Tab / accordion triggers ───────────────────────────────────────────
854
+ // The item/trigger itself is interactive; the container is nav/ul.
855
+ if (/\btab\b/.test(n) && /\b(item|trigger|tab)\b/.test(n) && !/\bbar\b/.test(n))
856
+ return "button";
857
+ if (/\baccordion\b/.test(n) && /\b(item|trigger|header)\b/.test(n))
858
+ return "button";
859
+ // ── Form controls — label wraps the native input ───────────────────────
860
+ // checkbox / radio: root is <label> so clicking anywhere toggles the input.
861
+ if (/\b(checkbox|radio-?button?)\b/.test(n))
862
+ return "label";
863
+ // toggle / switch: stateful binary control, semantically a <button role="switch">
864
+ if (/\b(toggle|switch)\b/.test(n) && ct === "formControl")
865
+ return "button";
866
+ // text inputs / search: root <label> groups the visible field with its label text.
867
+ if (/\b(input|text-?field|text-?area|search-?bar|search-?field)\b/.test(n))
868
+ return "label";
869
+ // ── Interaction-driven atomics ─────────────────────────────────────────
870
+ // A non-composite component whose primary contract is a click/tap is a button.
871
+ const hasClickTrigger = events.some((e) => e.trigger?.category === "click" || e.trigger?.category === "pointer-down");
872
+ if (hasClickTrigger && ct !== "composite")
873
+ return "button";
874
+ // ── Document-level landmarks ───────────────────────────────────────────
875
+ if (/\b(form|sign-?in|sign-?up|login|register)\b/.test(n))
876
+ return "form";
877
+ if (/\b(dialog|modal|sheet|drawer|overlay)\b/.test(n))
878
+ return "dialog";
879
+ if (/\bheader\b/.test(n))
880
+ return "header";
881
+ if (/\bfooter\b/.test(n))
882
+ return "footer";
883
+ if (/\b(main|page-?content|content-?area)\b/.test(n))
884
+ return "main";
885
+ if (/\baside\b/.test(n))
886
+ return "aside";
887
+ if (/\bsection\b/.test(n))
888
+ return "section";
889
+ if (/\barticle\b/.test(n))
890
+ return "article";
891
+ return undefined; // div is the correct default — no hint needed
892
+ })();
893
+ if (semanticElement) {
894
+ finalContext.implementationHints.semanticElement = semanticElement;
895
+ }
896
+ return finalContext;
897
+ }
898
+ //# sourceMappingURL=get-component-context.js.map