@zyncat/ui 0.10.0 → 0.12.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 (597) hide show
  1. package/README.md +135 -40
  2. package/dist/alert.css +126 -121
  3. package/dist/alert.js +12 -14
  4. package/dist/alert.js.map +1 -1
  5. package/dist/avatar-group.js.map +1 -1
  6. package/dist/avatar.css +179 -174
  7. package/dist/avatar.js.map +1 -1
  8. package/dist/badge.css +166 -160
  9. package/dist/badge.js +1 -1
  10. package/dist/button.css +272 -246
  11. package/dist/button.js +1 -1
  12. package/dist/checkbox.css +158 -153
  13. package/dist/checkbox.js +2 -2
  14. package/dist/{chunk-UXONUUPI.js → chunk-227ZW4V7.js} +40 -32
  15. package/dist/chunk-227ZW4V7.js.map +1 -0
  16. package/dist/{chunk-2ERBBFZS.js → chunk-3MPF7FZV.js} +2 -2
  17. package/dist/chunk-3MPF7FZV.js.map +1 -0
  18. package/dist/{chunk-OMHQ4U4J.js → chunk-43M6GQ4Q.js} +86 -79
  19. package/dist/chunk-43M6GQ4Q.js.map +1 -0
  20. package/dist/{chunk-7SZCJ7WI.js → chunk-45R4Z5XN.js} +3 -3
  21. package/dist/chunk-45R4Z5XN.js.map +1 -0
  22. package/dist/{chunk-I4XQ4PV2.js → chunk-4BSHB7R3.js} +9 -7
  23. package/dist/chunk-4BSHB7R3.js.map +1 -0
  24. package/dist/{chunk-YGGCQNNU.js → chunk-4C5RZXBT.js} +33 -34
  25. package/dist/chunk-4C5RZXBT.js.map +1 -0
  26. package/dist/{chunk-2QWJ6FAX.js → chunk-5PZ43DCG.js} +31 -15
  27. package/dist/chunk-5PZ43DCG.js.map +1 -0
  28. package/dist/{chunk-S5ZTZANS.js → chunk-7IZJERGA.js} +35 -12
  29. package/dist/chunk-7IZJERGA.js.map +1 -0
  30. package/dist/{chunk-ZCOUPPTI.js → chunk-A5WTZACK.js} +22 -12
  31. package/dist/chunk-A5WTZACK.js.map +1 -0
  32. package/dist/{chunk-64UU4LGU.js → chunk-AADAJL7D.js} +3 -3
  33. package/dist/{chunk-64UU4LGU.js.map → chunk-AADAJL7D.js.map} +1 -1
  34. package/dist/{chunk-FTOAUJL5.js → chunk-CF4QHO4N.js} +21 -11
  35. package/dist/chunk-CF4QHO4N.js.map +1 -0
  36. package/dist/{chunk-WM5J5TDI.js → chunk-CNWTIMIP.js} +13 -17
  37. package/dist/chunk-CNWTIMIP.js.map +1 -0
  38. package/dist/{chunk-356HZMT4.js → chunk-DDRSMHN4.js} +31 -22
  39. package/dist/chunk-DDRSMHN4.js.map +1 -0
  40. package/dist/{chunk-VTJTGVZZ.js → chunk-DMX2F6B4.js} +2 -2
  41. package/dist/chunk-DMX2F6B4.js.map +1 -0
  42. package/dist/{chunk-3SBCBYB7.js → chunk-EAI4POPB.js} +2 -2
  43. package/dist/{chunk-3SBCBYB7.js.map → chunk-EAI4POPB.js.map} +1 -1
  44. package/dist/{chunk-Y7AJQVWJ.js → chunk-EF6RPXU7.js} +17 -15
  45. package/dist/chunk-EF6RPXU7.js.map +1 -0
  46. package/dist/{chunk-K5X2GCXU.js → chunk-FONOS5RN.js} +14 -15
  47. package/dist/chunk-FONOS5RN.js.map +1 -0
  48. package/dist/{chunk-PMECHR3A.js → chunk-FQEHSKEI.js} +2 -2
  49. package/dist/chunk-FQEHSKEI.js.map +1 -0
  50. package/dist/chunk-HDSFWZ7L.js +12 -0
  51. package/dist/chunk-HDSFWZ7L.js.map +1 -0
  52. package/dist/{chunk-2F5PITAO.js → chunk-HY5MPISE.js} +2 -2
  53. package/dist/chunk-HY5MPISE.js.map +1 -0
  54. package/dist/{chunk-QDK66S4G.js → chunk-I45AU6KH.js} +3 -3
  55. package/dist/chunk-I45AU6KH.js.map +1 -0
  56. package/dist/{chunk-YGCVWGUG.js → chunk-IJS7TPGV.js} +153 -46
  57. package/dist/chunk-IJS7TPGV.js.map +1 -0
  58. package/dist/{chunk-62P3KD57.js → chunk-IUQAUBVM.js} +18 -11
  59. package/dist/chunk-IUQAUBVM.js.map +1 -0
  60. package/dist/chunk-JY6A2ZJZ.js +44 -0
  61. package/dist/chunk-JY6A2ZJZ.js.map +1 -0
  62. package/dist/{chunk-XWUWYSCT.js → chunk-M43IOM5C.js} +20 -10
  63. package/dist/chunk-M43IOM5C.js.map +1 -0
  64. package/dist/{chunk-S7B34VGN.js → chunk-OWNMRMPN.js} +3 -3
  65. package/dist/{chunk-S7B34VGN.js.map → chunk-OWNMRMPN.js.map} +1 -1
  66. package/dist/chunk-RFRE4WKX.js +22 -0
  67. package/dist/chunk-RFRE4WKX.js.map +1 -0
  68. package/dist/{chunk-NNXJCLTV.js → chunk-RJFGWJ4W.js} +2 -2
  69. package/dist/chunk-RJFGWJ4W.js.map +1 -0
  70. package/dist/{chunk-NEF5XAHG.js → chunk-TUTXXC3W.js} +4 -4
  71. package/dist/chunk-TUTXXC3W.js.map +1 -0
  72. package/dist/chunk-TVYH4AN7.js +70 -0
  73. package/dist/chunk-TVYH4AN7.js.map +1 -0
  74. package/dist/{chunk-RCONNA7I.js → chunk-VAXCXZ53.js} +34 -22
  75. package/dist/chunk-VAXCXZ53.js.map +1 -0
  76. package/dist/chunk-XNIYSAMJ.js +52 -0
  77. package/dist/chunk-XNIYSAMJ.js.map +1 -0
  78. package/dist/{chunk-CONSWNIV.js → chunk-Y2YA7QRF.js} +6 -6
  79. package/dist/chunk-Y2YA7QRF.js.map +1 -0
  80. package/dist/cli.js +1809 -0
  81. package/dist/collapse.css +70 -61
  82. package/dist/collapse.js +2 -2
  83. package/dist/confetti.css +45 -0
  84. package/dist/confetti.js +540 -0
  85. package/dist/confetti.js.map +1 -0
  86. package/dist/count-badge.js +3 -3
  87. package/dist/count-badge.js.map +1 -1
  88. package/dist/date-field.js +24 -19
  89. package/dist/date-field.js.map +1 -1
  90. package/dist/date-picker.css +563 -559
  91. package/dist/date-range-field.js +58 -41
  92. package/dist/date-range-field.js.map +1 -1
  93. package/dist/datetime-field.js +24 -19
  94. package/dist/datetime-field.js.map +1 -1
  95. package/dist/dialog.css +176 -172
  96. package/dist/dialog.js +30 -19
  97. package/dist/dialog.js.map +1 -1
  98. package/dist/digit-strip.css +65 -0
  99. package/dist/dropdown.css +65 -0
  100. package/dist/dropdown.js +350 -0
  101. package/dist/dropdown.js.map +1 -0
  102. package/dist/emoji-picker.js +713 -0
  103. package/dist/emoji-picker.js.map +1 -0
  104. package/dist/facebook-feed.css +880 -0
  105. package/dist/facebook-feed.js +697 -0
  106. package/dist/facebook-feed.js.map +1 -0
  107. package/dist/flow-field.css +49 -0
  108. package/dist/flow-field.js +269 -0
  109. package/dist/flow-field.js.map +1 -0
  110. package/dist/glide.js +3 -3
  111. package/dist/icon.css +34 -30
  112. package/dist/input.css +296 -318
  113. package/dist/instagram-feed.css +378 -0
  114. package/dist/instagram-feed.js +272 -0
  115. package/dist/instagram-feed.js.map +1 -0
  116. package/dist/lens.css +119 -0
  117. package/dist/lens.js +307 -0
  118. package/dist/lens.js.map +1 -0
  119. package/dist/mcp.js +379 -184
  120. package/dist/menu-surface.css +127 -0
  121. package/dist/modal.css +11 -7
  122. package/dist/modal.js +24 -17
  123. package/dist/modal.js.map +1 -1
  124. package/dist/morphing-text.css +84 -0
  125. package/dist/morphing-text.js +256 -0
  126. package/dist/morphing-text.js.map +1 -0
  127. package/dist/motion-devtools.css +237 -233
  128. package/dist/motion-devtools.js +7 -6
  129. package/dist/motion-devtools.js.map +1 -1
  130. package/dist/motion-tokens.js +1 -1
  131. package/dist/multi-select.js +20 -17
  132. package/dist/multi-select.js.map +1 -1
  133. package/dist/number-field.js +11 -7
  134. package/dist/number-field.js.map +1 -1
  135. package/dist/odometer.css +58 -59
  136. package/dist/odometer.js +109 -0
  137. package/dist/odometer.js.map +1 -0
  138. package/dist/otp-field.js.map +1 -1
  139. package/dist/overlay.css +24 -20
  140. package/dist/pagination.css +42 -38
  141. package/dist/pagination.js +6 -12
  142. package/dist/pagination.js.map +1 -1
  143. package/dist/popover.css +69 -65
  144. package/dist/popover.js +12 -10
  145. package/dist/radio-group.css +275 -276
  146. package/dist/radio-group.js +70 -95
  147. package/dist/radio-group.js.map +1 -1
  148. package/dist/select.css +291 -386
  149. package/dist/select.js +18 -15
  150. package/dist/select.js.map +1 -1
  151. package/dist/sheet.css +47 -23
  152. package/dist/sheet.js +11 -10
  153. package/dist/status-badge.js +3 -3
  154. package/dist/status-badge.js.map +1 -1
  155. package/dist/styles.css +221 -0
  156. package/dist/support-rail.css +421 -0
  157. package/dist/support-rail.js +243 -0
  158. package/dist/support-rail.js.map +1 -0
  159. package/dist/table.css +333 -323
  160. package/dist/table.js +32 -21
  161. package/dist/table.js.map +1 -1
  162. package/dist/tabs.css +163 -156
  163. package/dist/tabs.js +26 -20
  164. package/dist/tabs.js.map +1 -1
  165. package/dist/tag.css +209 -231
  166. package/dist/tag.js +11 -10
  167. package/dist/tag.js.map +1 -1
  168. package/dist/text-field.js +7 -67
  169. package/dist/text-field.js.map +1 -1
  170. package/dist/textarea.css +205 -211
  171. package/dist/textarea.js +12 -12
  172. package/dist/textarea.js.map +1 -1
  173. package/dist/theme.js +69 -0
  174. package/dist/theme.js.map +1 -0
  175. package/dist/tiktok.css +662 -0
  176. package/dist/tiktok.js +494 -0
  177. package/dist/tiktok.js.map +1 -0
  178. package/dist/time-field.js +6 -6
  179. package/dist/time-field.js.map +1 -1
  180. package/dist/toast.css +237 -233
  181. package/dist/toast.js +43 -47
  182. package/dist/toast.js.map +1 -1
  183. package/dist/toggle-tag.js +1 -1
  184. package/dist/toggle-tag.js.map +1 -1
  185. package/dist/toggle.css +139 -135
  186. package/dist/toggle.js.map +1 -1
  187. package/dist/tooltip.css +79 -78
  188. package/dist/tooltip.js +50 -60
  189. package/dist/tooltip.js.map +1 -1
  190. package/dist/trigger.css +13 -0
  191. package/dist/{alert.d.ts → types/components/composites/alert/Alert.d.ts} +13 -15
  192. package/dist/{date-field.d.ts → types/components/composites/date-picker/DateField.d.ts} +4 -10
  193. package/dist/types/components/composites/date-picker/DateRangeField.d.ts +21 -0
  194. package/dist/{datetime-field.d.ts → types/components/composites/date-picker/DateTimeField.d.ts} +4 -10
  195. package/dist/{time-field.d.ts → types/components/composites/date-picker/TimeField.d.ts} +5 -11
  196. package/dist/types/components/composites/date-picker/calendar-panel.d.ts +16 -0
  197. package/dist/types/components/composites/date-picker/date-utils.d.ts +12 -0
  198. package/dist/types/components/composites/date-picker/field-shell.d.ts +46 -0
  199. package/dist/types/components/composites/date-picker/range-panel.d.ts +24 -0
  200. package/dist/types/components/composites/date-picker/time-core.d.ts +14 -0
  201. package/dist/types/components/composites/date-picker/use-day-focus.d.ts +2 -0
  202. package/dist/{dialog.d.ts → types/components/composites/dialog/Dialog.d.ts} +10 -11
  203. package/dist/types/components/composites/dropdown/Dropdown.d.ts +37 -0
  204. package/dist/types/components/composites/dropdown/menu-panel.d.ts +7 -0
  205. package/dist/types/components/composites/dropdown/types.d.ts +71 -0
  206. package/dist/types/components/composites/emoji-picker/EmojiPickerPanel.d.ts +45 -0
  207. package/dist/types/components/composites/emoji-picker/category-icons.d.ts +9 -0
  208. package/dist/types/components/composites/emoji-picker/data.d.ts +33 -0
  209. package/dist/types/components/composites/emoji-picker/dom.d.ts +19 -0
  210. package/dist/types/components/composites/emoji-picker/getEmojiUrl.d.ts +2 -0
  211. package/dist/types/components/composites/emoji-picker/navigation.d.ts +7 -0
  212. package/dist/types/components/composites/emoji-picker/picker.d.ts +20 -0
  213. package/dist/types/components/composites/emoji-picker/react/category-bar.d.ts +6 -0
  214. package/dist/types/components/composites/emoji-picker/react/useEmojiPicker.d.ts +50 -0
  215. package/dist/types/components/composites/emoji-picker/scaffold.d.ts +8 -0
  216. package/dist/types/components/composites/emoji-picker/search.d.ts +1 -0
  217. package/dist/types/components/composites/emoji-picker/types.d.ts +13 -0
  218. package/dist/{modal.d.ts → types/components/composites/modal/Modal.d.ts} +10 -11
  219. package/dist/{pagination.d.ts → types/components/composites/pagination/Pagination.d.ts} +5 -8
  220. package/dist/{popover.d.ts → types/components/composites/popover/Popover.d.ts} +11 -14
  221. package/dist/{multi-select.d.ts → types/components/composites/select/MultiSelect.d.ts} +12 -11
  222. package/dist/{select.d.ts → types/components/composites/select/Select.d.ts} +16 -14
  223. package/dist/types/components/composites/select/core/index.d.ts +4 -0
  224. package/dist/types/components/composites/select/core/menu.d.ts +13 -0
  225. package/dist/types/components/composites/select/core/panel.d.ts +18 -0
  226. package/dist/types/components/composites/select/core/trigger.d.ts +16 -0
  227. package/dist/{types-SGMShK7R.d.ts → types/components/composites/select/core/types.d.ts} +13 -6
  228. package/dist/types/components/composites/select/core/use-listbox.d.ts +42 -0
  229. package/dist/{sheet.d.ts → types/components/composites/sheet/Sheet.d.ts} +10 -11
  230. package/dist/types/components/composites/sheet/use-sheet-drag.d.ts +13 -0
  231. package/dist/{table.d.ts → types/components/composites/table/Table.d.ts} +12 -12
  232. package/dist/{tabs.d.ts → types/components/composites/tabs/Tabs.d.ts} +13 -13
  233. package/dist/types/components/composites/toast/Toast.d.ts +10 -0
  234. package/dist/{toast-store.d.ts → types/components/composites/toast/toast-store.d.ts} +12 -14
  235. package/dist/{tooltip.d.ts → types/components/composites/tooltip/Tooltip.d.ts} +6 -10
  236. package/dist/types/components/composites/tooltip/tooltip-host.d.ts +1 -0
  237. package/dist/types/components/composites/tooltip/tooltip-store.d.ts +29 -0
  238. package/dist/types/components/compound/support-rail/SupportRail.d.ts +41 -0
  239. package/dist/types/components/dev/MotionDevtools.d.ts +24 -0
  240. package/dist/types/components/dev/slowmo-engine.d.ts +27 -0
  241. package/dist/types/components/expressive/confetti/Confetti.d.ts +43 -0
  242. package/dist/types/components/expressive/facebook-feed/FacebookFeed.d.ts +73 -0
  243. package/dist/types/components/expressive/facebook-feed/chrome.d.ts +30 -0
  244. package/dist/types/components/expressive/facebook-feed/icons.d.ts +21 -0
  245. package/dist/types/components/expressive/facebook-feed/post.d.ts +25 -0
  246. package/dist/types/components/expressive/facebook-feed/reel.d.ts +26 -0
  247. package/dist/types/components/expressive/facebook-feed/story.d.ts +20 -0
  248. package/dist/types/components/expressive/flow-field/FlowField.d.ts +23 -0
  249. package/dist/types/components/expressive/instagram-feed/InstagramFeed.d.ts +59 -0
  250. package/dist/types/components/expressive/lens/Lens.d.ts +23 -0
  251. package/dist/types/components/expressive/morphing-text/MorphingText.d.ts +21 -0
  252. package/dist/types/components/expressive/odometer/Odometer.d.ts +21 -0
  253. package/dist/types/components/expressive/tiktok/TikTok.d.ts +85 -0
  254. package/dist/types/components/expressive/tiktok/glyphs.d.ts +40 -0
  255. package/dist/types/components/expressive/typing-lines/TypingLines.d.ts +25 -0
  256. package/dist/types/components/expressive/weight-field/WeightField.d.ts +19 -0
  257. package/dist/types/components/expressive/youtube/YouTube.d.ts +73 -0
  258. package/dist/types/components/expressive/youtube/format.d.ts +2 -0
  259. package/dist/types/components/expressive/youtube/glyphs.d.ts +16 -0
  260. package/dist/types/components/expressive/youtube/media.d.ts +8 -0
  261. package/dist/types/components/expressive/youtube/post.d.ts +19 -0
  262. package/dist/types/components/expressive/youtube/short.d.ts +18 -0
  263. package/dist/types/components/expressive/youtube/video.d.ts +14 -0
  264. package/dist/types/components/internal/collection/collection.d.ts +19 -0
  265. package/dist/types/components/internal/glass/glint.d.ts +1 -0
  266. package/dist/types/components/internal/hooks/use-controllable.d.ts +1 -0
  267. package/dist/types/components/internal/hooks/use-media-query.d.ts +1 -0
  268. package/dist/types/components/internal/hooks/use-scroll-edges.d.ts +10 -0
  269. package/dist/types/components/internal/hooks/use-typeahead.d.ts +5 -0
  270. package/dist/types/components/internal/icon/Icon.d.ts +33 -0
  271. package/dist/types/components/internal/icon/IconSlot.d.ts +7 -0
  272. package/dist/types/components/internal/menu/menu-row.d.ts +11 -0
  273. package/dist/types/components/internal/overlay/focus.d.ts +8 -0
  274. package/dist/types/components/internal/overlay/layer.d.ts +38 -0
  275. package/dist/types/components/internal/overlay/modal.d.ts +18 -0
  276. package/dist/types/components/internal/overlay/position.d.ts +14 -0
  277. package/dist/types/components/internal/support/types.d.ts +15 -0
  278. package/dist/types/components/internal/utils/activation.d.ts +23 -0
  279. package/dist/types/components/internal/utils/cx.d.ts +1 -0
  280. package/dist/types/components/internal/utils/token-px.d.ts +1 -0
  281. package/dist/{avatar.d.ts → types/components/primitives/avatar/Avatar.d.ts} +10 -12
  282. package/dist/{avatar-group.d.ts → types/components/primitives/avatar/AvatarGroup.d.ts} +7 -9
  283. package/dist/{badge.d.ts → types/components/primitives/badge/Badge.d.ts} +8 -10
  284. package/dist/types/components/primitives/badge/CountBadge.d.ts +8 -0
  285. package/dist/types/components/primitives/badge/StatusBadge.d.ts +15 -0
  286. package/dist/types/components/primitives/badge/digit-strip.d.ts +5 -0
  287. package/dist/{button.d.ts → types/components/primitives/button/Button.d.ts} +6 -8
  288. package/dist/{checkbox.d.ts → types/components/primitives/checkbox/Checkbox.d.ts} +6 -8
  289. package/dist/types/components/primitives/checkbox/check-glyph.d.ts +6 -0
  290. package/dist/{collapse.d.ts → types/components/primitives/collapse/Collapse.d.ts} +12 -13
  291. package/dist/types/components/primitives/collapse/collapse.typecheck.d.ts +2 -0
  292. package/dist/{number-field.d.ts → types/components/primitives/input/NumberField.d.ts} +7 -9
  293. package/dist/{otp-field.d.ts → types/components/primitives/input/OtpField.d.ts} +6 -8
  294. package/dist/{text-field.d.ts → types/components/primitives/input/TextField.d.ts} +7 -9
  295. package/dist/types/components/primitives/input/field-chrome.d.ts +45 -0
  296. package/dist/{radio-group.d.ts → types/components/primitives/radio-group/RadioGroup.d.ts} +8 -10
  297. package/dist/{tag.d.ts → types/components/primitives/tag/Tag.d.ts} +9 -12
  298. package/dist/{toggle-tag.d.ts → types/components/primitives/tag/ToggleTag.d.ts} +7 -8
  299. package/dist/{textarea.d.ts → types/components/primitives/textarea/Textarea.d.ts} +7 -9
  300. package/dist/{toggle.d.ts → types/components/primitives/toggle/Toggle.d.ts} +6 -8
  301. package/dist/{dom-props-C0jrllBw.d.ts → types/dom-props.d.ts} +1 -3
  302. package/dist/types/engine/animate.d.ts +30 -0
  303. package/dist/types/engine/drag.d.ts +17 -0
  304. package/dist/types/engine/ease.d.ts +15 -0
  305. package/dist/types/engine/flip.d.ts +18 -0
  306. package/dist/types/engine/index.d.ts +4 -0
  307. package/dist/types/engine/loop.d.ts +9 -0
  308. package/dist/types/motion/element.d.ts +17 -0
  309. package/dist/types/motion/flip.d.ts +4 -0
  310. package/dist/types/motion/glide.d.ts +11 -0
  311. package/dist/types/motion/motion-timing.d.ts +16 -0
  312. package/dist/types/motion/presence-context.d.ts +11 -0
  313. package/dist/types/motion/presence.d.ts +12 -0
  314. package/dist/types/motion/presets.d.ts +6 -0
  315. package/dist/{timing-7JA_zQHP.d.ts → types/motion/timing.d.ts} +9 -9
  316. package/dist/types/motion/use-motion.d.ts +17 -0
  317. package/dist/types/tokens/component-styles.generated.d.ts +262 -0
  318. package/dist/{motion-scale-Canq4stZ.d.ts → types/tokens/motion-scale.d.ts} +4 -4
  319. package/dist/{motion-tokens.d.ts → types/tokens/motion-tokens.d.ts} +9 -9
  320. package/dist/types/tokens/theme-tokens.generated.d.ts +1249 -0
  321. package/dist/types/tokens/theme.d.ts +12 -0
  322. package/dist/typing-lines.css +92 -0
  323. package/dist/typing-lines.js +139 -0
  324. package/dist/typing-lines.js.map +1 -0
  325. package/dist/weight-field.css +84 -0
  326. package/dist/weight-field.js +17 -0
  327. package/dist/weight-field.js.map +1 -0
  328. package/dist/youtube.css +611 -0
  329. package/dist/youtube.js +814 -0
  330. package/dist/youtube.js.map +1 -0
  331. package/package.json +155 -49
  332. package/skills/zyncat-ui/SKILL.md +95 -0
  333. package/skills/zyncat-ui/references/components.md +85 -0
  334. package/skills/zyncat-ui/references/recipes.md +171 -0
  335. package/skills/zyncat-ui/references/theming.md +83 -0
  336. package/src/components/composites/alert/Alert.tsx +13 -11
  337. package/src/components/composites/alert/Alert.usage.md +15 -0
  338. package/src/components/composites/alert/alert.css +126 -121
  339. package/src/components/composites/date-picker/DateField.tsx +7 -2
  340. package/src/components/composites/date-picker/DateField.usage.md +10 -0
  341. package/src/components/composites/date-picker/DateRangeField.tsx +18 -16
  342. package/src/components/composites/date-picker/DateRangeField.usage.md +10 -0
  343. package/src/components/composites/date-picker/DateTimeField.tsx +10 -5
  344. package/src/components/composites/date-picker/DateTimeField.usage.md +12 -0
  345. package/src/components/composites/date-picker/TimeField.tsx +3 -1
  346. package/src/components/composites/date-picker/TimeField.usage.md +12 -0
  347. package/src/components/composites/date-picker/calendar-panel.tsx +15 -10
  348. package/src/components/composites/date-picker/date-picker.css +563 -559
  349. package/src/components/composites/date-picker/field-shell.tsx +9 -3
  350. package/src/components/composites/date-picker/range-panel.tsx +23 -8
  351. package/src/components/composites/date-picker/time-core.tsx +2 -0
  352. package/src/components/composites/dialog/Dialog.tsx +30 -15
  353. package/src/components/composites/dialog/Dialog.usage.md +17 -0
  354. package/src/components/composites/dialog/dialog.css +176 -172
  355. package/src/components/composites/dropdown/Dropdown.tsx +184 -0
  356. package/src/components/composites/dropdown/Dropdown.usage.md +19 -0
  357. package/src/components/composites/dropdown/dropdown.css +65 -0
  358. package/src/components/composites/dropdown/menu-panel.tsx +255 -0
  359. package/src/components/composites/dropdown/types.ts +95 -0
  360. package/src/components/composites/emoji-picker/EmojiPickerPanel.tsx +153 -0
  361. package/src/components/composites/emoji-picker/EmojiPickerPanel.usage.md +26 -0
  362. package/src/components/composites/emoji-picker/category-icons.ts +29 -0
  363. package/src/components/composites/emoji-picker/data.ts +83 -0
  364. package/src/components/composites/emoji-picker/dom.ts +79 -0
  365. package/src/components/composites/emoji-picker/getEmojiUrl.ts +17 -0
  366. package/src/components/composites/emoji-picker/navigation.ts +86 -0
  367. package/src/components/composites/emoji-picker/picker.ts +169 -0
  368. package/src/components/composites/emoji-picker/react/category-bar.tsx +77 -0
  369. package/src/components/composites/emoji-picker/react/useEmojiPicker.ts +139 -0
  370. package/src/components/composites/emoji-picker/scaffold.ts +74 -0
  371. package/src/components/composites/emoji-picker/search.ts +79 -0
  372. package/src/components/composites/emoji-picker/styles.css +221 -0
  373. package/src/components/composites/emoji-picker/types.ts +14 -0
  374. package/src/components/composites/modal/Modal.tsx +24 -13
  375. package/src/components/composites/modal/Modal.usage.md +24 -0
  376. package/src/components/composites/modal/modal.css +11 -7
  377. package/src/components/composites/pagination/Pagination.tsx +6 -11
  378. package/src/components/composites/pagination/Pagination.usage.md +12 -0
  379. package/src/components/composites/pagination/pagination.css +42 -38
  380. package/src/components/composites/popover/Popover.tsx +22 -7
  381. package/src/components/composites/popover/Popover.usage.md +15 -0
  382. package/src/components/composites/popover/popover.css +69 -65
  383. package/src/components/composites/select/MultiSelect.tsx +13 -5
  384. package/src/components/composites/select/MultiSelect.usage.md +12 -0
  385. package/src/components/composites/select/Select.tsx +23 -7
  386. package/src/components/composites/select/Select.usage.md +20 -0
  387. package/src/components/composites/select/core/index.ts +1 -1
  388. package/src/components/composites/select/core/menu.tsx +8 -6
  389. package/src/components/composites/select/core/panel.tsx +25 -26
  390. package/src/components/composites/select/core/trigger.tsx +36 -24
  391. package/src/components/composites/select/core/types.ts +17 -15
  392. package/src/components/composites/select/core/use-listbox.ts +22 -21
  393. package/src/components/composites/select/select.css +291 -386
  394. package/src/components/composites/sheet/Sheet.tsx +28 -18
  395. package/src/components/composites/sheet/Sheet.usage.md +15 -0
  396. package/src/components/composites/sheet/sheet.css +47 -23
  397. package/src/components/composites/sheet/use-sheet-drag.ts +19 -15
  398. package/src/components/composites/table/Table.tsx +17 -6
  399. package/src/components/composites/table/Table.usage.md +19 -0
  400. package/src/components/composites/table/table.css +333 -323
  401. package/src/components/composites/tabs/Tabs.tsx +31 -23
  402. package/src/components/composites/tabs/Tabs.usage.md +13 -0
  403. package/src/components/composites/tabs/tabs.css +163 -156
  404. package/src/components/composites/toast/Toast.tsx +48 -51
  405. package/src/components/composites/toast/Toast.usage.md +23 -0
  406. package/src/components/composites/toast/toast-store.usage.md +16 -0
  407. package/src/components/composites/toast/toast.css +237 -233
  408. package/src/components/composites/tooltip/Tooltip.tsx +13 -8
  409. package/src/components/composites/tooltip/Tooltip.usage.md +14 -0
  410. package/src/components/composites/tooltip/tooltip-host.tsx +29 -61
  411. package/src/components/composites/tooltip/tooltip-store.ts +10 -0
  412. package/src/components/composites/tooltip/tooltip.css +79 -78
  413. package/src/components/compound/support-rail/SupportRail.tsx +343 -0
  414. package/src/components/compound/support-rail/SupportRail.usage.md +18 -0
  415. package/src/components/compound/support-rail/support-rail.css +421 -0
  416. package/src/components/dev/MotionDevtools.tsx +3 -1
  417. package/src/components/dev/MotionDevtools.usage.md +16 -0
  418. package/src/components/dev/motion-devtools.css +237 -233
  419. package/src/components/expressive/confetti/Confetti.tsx +727 -0
  420. package/src/components/expressive/confetti/Confetti.usage.md +18 -0
  421. package/src/components/expressive/confetti/confetti.css +45 -0
  422. package/src/components/expressive/facebook-feed/FacebookFeed.tsx +200 -0
  423. package/src/components/expressive/facebook-feed/FacebookFeed.usage.md +18 -0
  424. package/src/components/expressive/facebook-feed/chrome.tsx +120 -0
  425. package/src/components/expressive/facebook-feed/facebook-feed.css +880 -0
  426. package/src/components/expressive/facebook-feed/icons.tsx +145 -0
  427. package/src/components/expressive/facebook-feed/post.tsx +213 -0
  428. package/src/components/expressive/facebook-feed/reel.tsx +199 -0
  429. package/src/components/expressive/facebook-feed/story.tsx +132 -0
  430. package/src/components/expressive/flow-field/FlowField.tsx +348 -0
  431. package/src/components/expressive/flow-field/FlowField.usage.md +19 -0
  432. package/src/components/expressive/flow-field/flow-field.css +49 -0
  433. package/src/components/expressive/instagram-feed/InstagramFeed.tsx +374 -0
  434. package/src/components/expressive/instagram-feed/InstagramFeed.usage.md +18 -0
  435. package/src/components/expressive/instagram-feed/instagram-feed.css +378 -0
  436. package/src/components/expressive/lens/Lens.tsx +415 -0
  437. package/src/components/expressive/lens/Lens.usage.md +20 -0
  438. package/src/components/expressive/lens/lens.css +119 -0
  439. package/src/components/expressive/morphing-text/MorphingText.tsx +328 -0
  440. package/src/components/expressive/morphing-text/MorphingText.usage.md +19 -0
  441. package/src/components/expressive/morphing-text/morphing-text.css +84 -0
  442. package/src/components/expressive/odometer/Odometer.tsx +158 -0
  443. package/src/components/expressive/odometer/Odometer.usage.md +17 -0
  444. package/src/components/expressive/odometer/odometer.css +61 -0
  445. package/src/components/expressive/tiktok/TikTok.tsx +542 -0
  446. package/src/components/expressive/tiktok/TikTok.usage.md +17 -0
  447. package/src/components/expressive/tiktok/glyphs.tsx +163 -0
  448. package/src/components/expressive/tiktok/tiktok.css +662 -0
  449. package/src/components/expressive/typing-lines/TypingLines.tsx +0 -0
  450. package/src/components/expressive/typing-lines/TypingLines.usage.md +17 -0
  451. package/src/components/expressive/typing-lines/typing-lines.css +92 -0
  452. package/src/components/expressive/weight-field/WeightField.tsx +41 -0
  453. package/src/components/expressive/weight-field/WeightField.usage.md +20 -0
  454. package/src/components/expressive/weight-field/weight-field.css +84 -0
  455. package/src/components/expressive/youtube/YouTube.tsx +192 -0
  456. package/src/components/expressive/youtube/YouTube.usage.md +18 -0
  457. package/src/components/expressive/youtube/format.ts +22 -0
  458. package/src/components/expressive/youtube/glyphs.tsx +235 -0
  459. package/src/components/expressive/youtube/media.tsx +18 -0
  460. package/src/components/expressive/youtube/post.tsx +282 -0
  461. package/src/components/expressive/youtube/short.tsx +212 -0
  462. package/src/components/expressive/youtube/video.tsx +75 -0
  463. package/src/components/expressive/youtube/youtube.css +611 -0
  464. package/src/components/internal/collection/collection.ts +44 -0
  465. package/src/components/internal/glass/glass.css +88 -84
  466. package/src/components/internal/hooks/use-media-query.ts +20 -0
  467. package/src/components/internal/hooks/use-typeahead.ts +28 -0
  468. package/src/components/internal/icon/Icon.tsx +2 -0
  469. package/src/components/internal/icon/IconSlot.tsx +2 -0
  470. package/src/components/internal/icon/icon.css +34 -30
  471. package/src/components/internal/menu/menu-row.tsx +34 -0
  472. package/src/components/internal/menu/menu-surface.css +127 -0
  473. package/src/components/internal/overlay/focus.ts +26 -10
  474. package/src/components/internal/overlay/layer.tsx +50 -19
  475. package/src/components/internal/overlay/modal.tsx +14 -12
  476. package/src/components/internal/overlay/overlay.css +24 -20
  477. package/src/components/internal/overlay/position.ts +19 -9
  478. package/src/components/internal/overlay/trigger.css +13 -0
  479. package/src/components/internal/support/types.ts +16 -0
  480. package/src/components/internal/utils/activation.ts +78 -0
  481. package/src/components/primitives/avatar/Avatar.tsx +2 -0
  482. package/src/components/primitives/avatar/Avatar.usage.md +12 -0
  483. package/src/components/primitives/avatar/AvatarGroup.tsx +3 -1
  484. package/src/components/primitives/avatar/AvatarGroup.usage.md +15 -0
  485. package/src/components/primitives/avatar/avatar.css +179 -174
  486. package/src/components/primitives/badge/Badge.tsx +3 -1
  487. package/src/components/primitives/badge/Badge.usage.md +14 -0
  488. package/src/components/primitives/badge/CountBadge.tsx +2 -2
  489. package/src/components/primitives/badge/CountBadge.usage.md +13 -0
  490. package/src/components/primitives/badge/StatusBadge.tsx +3 -1
  491. package/src/components/primitives/badge/StatusBadge.usage.md +14 -0
  492. package/src/components/primitives/badge/badge.css +166 -160
  493. package/src/components/primitives/badge/digit-strip.css +65 -0
  494. package/src/components/primitives/badge/{odometer.tsx → digit-strip.tsx} +3 -3
  495. package/src/components/primitives/button/Button.tsx +2 -0
  496. package/src/components/primitives/button/Button.usage.md +14 -0
  497. package/src/components/primitives/button/button.css +272 -246
  498. package/src/components/primitives/checkbox/Checkbox.tsx +3 -1
  499. package/src/components/primitives/checkbox/Checkbox.usage.md +12 -0
  500. package/src/components/primitives/checkbox/check-glyph.tsx +1 -0
  501. package/src/components/primitives/checkbox/checkbox.css +158 -153
  502. package/src/components/primitives/collapse/Collapse.tsx +3 -1
  503. package/src/components/primitives/collapse/Collapse.usage.md +17 -0
  504. package/src/components/primitives/collapse/collapse.css +70 -61
  505. package/src/components/primitives/collapse/collapse.typecheck.tsx +2 -0
  506. package/src/components/primitives/input/NumberField.tsx +18 -5
  507. package/src/components/primitives/input/NumberField.usage.md +12 -0
  508. package/src/components/primitives/input/OtpField.tsx +2 -0
  509. package/src/components/primitives/input/OtpField.usage.md +12 -0
  510. package/src/components/primitives/input/TextField.tsx +16 -4
  511. package/src/components/primitives/input/TextField.usage.md +13 -0
  512. package/src/components/primitives/input/field-chrome.tsx +11 -2
  513. package/src/components/primitives/input/input.css +296 -318
  514. package/src/components/primitives/radio-group/RadioGroup.tsx +20 -44
  515. package/src/components/primitives/radio-group/RadioGroup.usage.md +13 -0
  516. package/src/components/primitives/radio-group/radio-group.css +275 -276
  517. package/src/components/primitives/tag/Tag.tsx +10 -6
  518. package/src/components/primitives/tag/Tag.usage.md +14 -0
  519. package/src/components/primitives/tag/ToggleTag.tsx +4 -2
  520. package/src/components/primitives/tag/ToggleTag.usage.md +14 -0
  521. package/src/components/primitives/tag/tag.css +209 -231
  522. package/src/components/primitives/textarea/Textarea.tsx +17 -7
  523. package/src/components/primitives/textarea/Textarea.usage.md +12 -0
  524. package/src/components/primitives/textarea/textarea.css +205 -211
  525. package/src/components/primitives/toggle/Toggle.tsx +3 -1
  526. package/src/components/primitives/toggle/Toggle.usage.md +12 -0
  527. package/src/components/primitives/toggle/toggle.css +139 -135
  528. package/src/engine/animate.ts +40 -13
  529. package/src/engine/ease.ts +1 -0
  530. package/src/engine/flip.ts +32 -15
  531. package/src/engine/index.ts +2 -1
  532. package/src/engine/loop.ts +97 -0
  533. package/src/mcp/server.ts +315 -221
  534. package/src/motion/element.tsx +1 -0
  535. package/src/motion/flip.ts +29 -10
  536. package/src/motion/glide.tsx +11 -14
  537. package/src/motion/glide.usage.md +15 -0
  538. package/src/motion/motion-timing.ts +3 -3
  539. package/src/motion/presence.tsx +38 -21
  540. package/src/motion/presets.ts +13 -0
  541. package/src/motion/timing.ts +1 -0
  542. package/src/motion/use-motion.ts +16 -3
  543. package/src/styles.css +5 -0
  544. package/src/tokens/avatar.css +20 -16
  545. package/src/tokens/color.css +67 -56
  546. package/src/tokens/component-styles.generated.ts +270 -0
  547. package/src/tokens/elevation.css +28 -17
  548. package/src/tokens/fonts.css +1 -1
  549. package/src/tokens/glass.css +19 -15
  550. package/src/tokens/icons.css +8 -4
  551. package/src/tokens/layers.css +9 -4
  552. package/src/tokens/motion-scale.ts +4 -0
  553. package/src/tokens/motion-tokens.ts +42 -12
  554. package/src/tokens/motion-tokens.usage.md +16 -0
  555. package/src/tokens/motion.css +63 -45
  556. package/src/tokens/radius.css +12 -8
  557. package/src/tokens/semantic.css +62 -54
  558. package/src/tokens/spacing.css +25 -21
  559. package/src/tokens/theme-tokens.generated.ts +1278 -0
  560. package/src/tokens/theme.tsx +83 -0
  561. package/src/tokens/theme.usage.md +36 -0
  562. package/src/tokens/typography.css +53 -49
  563. package/dist/chunk-2ERBBFZS.js.map +0 -1
  564. package/dist/chunk-2F5PITAO.js.map +0 -1
  565. package/dist/chunk-2QWJ6FAX.js.map +0 -1
  566. package/dist/chunk-356HZMT4.js.map +0 -1
  567. package/dist/chunk-62P3KD57.js.map +0 -1
  568. package/dist/chunk-7SZCJ7WI.js.map +0 -1
  569. package/dist/chunk-CONSWNIV.js.map +0 -1
  570. package/dist/chunk-FTOAUJL5.js.map +0 -1
  571. package/dist/chunk-I4XQ4PV2.js.map +0 -1
  572. package/dist/chunk-K5X2GCXU.js.map +0 -1
  573. package/dist/chunk-NEF5XAHG.js.map +0 -1
  574. package/dist/chunk-NNXJCLTV.js.map +0 -1
  575. package/dist/chunk-OMHQ4U4J.js.map +0 -1
  576. package/dist/chunk-PMECHR3A.js.map +0 -1
  577. package/dist/chunk-QDK66S4G.js.map +0 -1
  578. package/dist/chunk-RCONNA7I.js.map +0 -1
  579. package/dist/chunk-S5ZTZANS.js.map +0 -1
  580. package/dist/chunk-UXONUUPI.js.map +0 -1
  581. package/dist/chunk-VTJTGVZZ.js.map +0 -1
  582. package/dist/chunk-WM5J5TDI.js.map +0 -1
  583. package/dist/chunk-XWUWYSCT.js.map +0 -1
  584. package/dist/chunk-Y7AJQVWJ.js.map +0 -1
  585. package/dist/chunk-YGCVWGUG.js.map +0 -1
  586. package/dist/chunk-YGGCQNNU.js.map +0 -1
  587. package/dist/chunk-ZCOUPPTI.js.map +0 -1
  588. package/dist/count-badge.d.ts +0 -13
  589. package/dist/date-range-field.d.ts +0 -33
  590. package/dist/field-chrome-CMPOQSLs.d.ts +0 -28
  591. package/dist/field-shell-Cuda-feL.d.ts +0 -24
  592. package/dist/glide.d.ts +0 -15
  593. package/dist/motion-devtools.d.ts +0 -51
  594. package/dist/status-badge.d.ts +0 -19
  595. package/dist/toast.d.ts +0 -12
  596. package/llms.txt +0 -220
  597. package/src/components/primitives/badge/odometer.css +0 -62
package/dist/mcp.js CHANGED
@@ -1,16 +1,143 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/mcp/server.ts
4
- import { existsSync, readFileSync, readdirSync } from "fs";
5
- import { dirname, join } from "path";
4
+ import { existsSync as existsSync2, readdirSync, readFileSync as readFileSync2 } from "fs";
5
+ import { dirname, join as join2, relative, resolve } from "path";
6
6
  import { fileURLToPath } from "url";
7
+
8
+ // scripts/lib/usage-format.mjs
9
+ import { existsSync, readFileSync } from "fs";
10
+ import { join } from "path";
11
+ var HEADING_RE = /^# ([A-Za-z][\w /-]*?) - @zyncat\/ui\/([a-z][a-z0-9-]*)\s*$/;
12
+ var META_RE = /^(Group|Docs): (.+?)\s*$/;
13
+ var FENCE_RE = /^```(\w*)\s*$/;
14
+ var GROUPS = [
15
+ { id: "primitives", title: "Primitives", note: "" },
16
+ {
17
+ id: "forms",
18
+ title: "Forms",
19
+ note: "Every form field takes label, helper/error/warning/success, size sm|md|lg, disabled."
20
+ },
21
+ { id: "data-display", title: "Data display", note: "" },
22
+ {
23
+ id: "date-time",
24
+ title: "Date, time & tabs",
25
+ note: "The date and time fields share: value is a string, onChange(value | null), timezone, min/max, disabled."
26
+ },
27
+ { id: "overlays", title: "Overlays & feedback", note: "" },
28
+ {
29
+ id: "expressive",
30
+ title: "Expressive",
31
+ note: "Creative motion components. Each publishes scoped --<component>-* custom properties as its theming surface."
32
+ },
33
+ {
34
+ id: "compound",
35
+ title: "Compound",
36
+ note: "Whole assembled patterns on the expressive contract - scoped --support-rail-* properties, no tone/corner/density enums. Actions are a SupportAction[]: id, label, icon, meta, description, onSelect."
37
+ },
38
+ {
39
+ id: "replicas",
40
+ title: "Replicas",
41
+ note: "Each reproduces an external platform surface; fidelity is the contract. Platform metrics are pinned constants - only --font-sans, --focus-ring and the duration tokens are read, so your theme cannot move them. None ever fetches media or autoplays: media and avatar take a URL string or your own node, with CSS-only placeholders."
42
+ },
43
+ { id: "dev", title: "Dev tools", note: "" }
44
+ ];
45
+ var GROUP_IDS = new Set(GROUPS.map((g) => g.id));
46
+ function parseUsage(text) {
47
+ const lines = text.split("\n");
48
+ const errors = [];
49
+ const doc = { title: "", subpath: "", group: "", docs: "", summary: "", prose: [], examples: [] };
50
+ const heading = lines[0]?.match(HEADING_RE);
51
+ if (!heading) {
52
+ errors.push(`line 1 must be "# <Title> - @zyncat/ui/<subpath>", got "${lines[0] ?? ""}"`);
53
+ return { doc, errors };
54
+ }
55
+ doc.title = heading[1].trim();
56
+ doc.subpath = heading[2];
57
+ let i = 1;
58
+ while (i < lines.length && !lines[i].trim()) i++;
59
+ for (; i < lines.length; i++) {
60
+ const meta = lines[i].match(META_RE);
61
+ if (!meta) break;
62
+ if (meta[1] === "Group") doc.group = meta[2];
63
+ else doc.docs = meta[2];
64
+ }
65
+ while (i < lines.length && !lines[i].trim()) i++;
66
+ if (i < lines.length && !FENCE_RE.test(lines[i])) {
67
+ doc.summary = lines[i].trim();
68
+ i++;
69
+ if (i < lines.length && lines[i].trim()) errors.push(`the summary (line ${i}) must be a single line`);
70
+ }
71
+ let fence = null;
72
+ for (; i < lines.length; i++) {
73
+ const open = lines[i].match(FENCE_RE);
74
+ if (open && !fence) {
75
+ fence = { lang: open[1] || "tsx", line: i + 1, code: [] };
76
+ continue;
77
+ }
78
+ if (fence && /^```\s*$/.test(lines[i])) {
79
+ doc.examples.push({ ...fence, code: fence.code.join("\n") });
80
+ fence = null;
81
+ continue;
82
+ }
83
+ if (fence) fence.code.push(lines[i]);
84
+ else doc.prose.push({ text: lines[i], line: i + 1 });
85
+ }
86
+ if (fence) errors.push(`unclosed \`\`\` fence opened at line ${fence.line}`);
87
+ while (doc.prose.length && !doc.prose[doc.prose.length - 1].text.trim()) doc.prose.pop();
88
+ while (doc.prose.length && !doc.prose[0].text.trim()) doc.prose.shift();
89
+ if (!doc.group) errors.push('missing "Group:" line');
90
+ else if (!GROUP_IDS.has(doc.group))
91
+ errors.push(`unknown group "${doc.group}" - one of: ${[...GROUP_IDS].join(", ")}`);
92
+ if (!doc.summary) errors.push("missing summary - one line of prose after the metadata block");
93
+ return { doc, errors };
94
+ }
95
+ function usagePathFor(source) {
96
+ return source ? source.replace(/^\.\//, "").replace(/\.(tsx|ts)$/, ".usage.md") : null;
97
+ }
98
+ function loadModules(root) {
99
+ const pkg = JSON.parse(readFileSync(join(root, "package.json"), "utf8"));
100
+ const modules = [];
101
+ for (const [key, value] of Object.entries(pkg.exports ?? {})) {
102
+ if (!value || typeof value !== "object" || typeof value.types !== "string") continue;
103
+ const subpath = key.replace(/^\.\//, "");
104
+ const usagePath = usagePathFor(value.source);
105
+ const module = { subpath, typesPath: value.types.replace(/^\.\//, ""), sourcePath: value.source, usagePath };
106
+ if (usagePath && existsSync(join(root, usagePath))) {
107
+ const { doc, errors } = parseUsage(readFileSync(join(root, usagePath), "utf8"));
108
+ module.usage = doc;
109
+ module.usageErrors = errors;
110
+ }
111
+ modules.push(module);
112
+ }
113
+ return { version: String(pkg.version ?? "0"), modules };
114
+ }
115
+ function buildIndex(modules) {
116
+ const out = [];
117
+ for (const group of GROUPS) {
118
+ const inGroup = modules.filter((m) => m.usage?.group === group.id);
119
+ if (!inGroup.length) continue;
120
+ out.push(`== ${group.title} ==`);
121
+ if (group.note) out.push(group.note);
122
+ for (const m of inGroup) out.push(`${m.usage.title} - @zyncat/ui/${m.subpath} - ${m.usage.summary}`);
123
+ out.push("");
124
+ }
125
+ const typesOnly = modules.filter((m) => !m.usage);
126
+ if (typesOnly.length) {
127
+ out.push("== Types-only modules (documented by their .d.ts alone) ==");
128
+ for (const m of typesOnly) out.push(`@zyncat/ui/${m.subpath} - get_component("${m.subpath}")`);
129
+ }
130
+ return out.join("\n").trim();
131
+ }
132
+
133
+ // src/mcp/server.ts
7
134
  function findRoot() {
8
135
  let dir = dirname(fileURLToPath(import.meta.url));
9
136
  for (; ; ) {
10
- const pj = join(dir, "package.json");
11
- if (existsSync(pj)) {
137
+ const pj = join2(dir, "package.json");
138
+ if (existsSync2(pj)) {
12
139
  try {
13
- if (JSON.parse(readFileSync(pj, "utf8")).name === "@zyncat/ui") return dir;
140
+ if (JSON.parse(readFileSync2(pj, "utf8")).name === "@zyncat/ui") return dir;
14
141
  } catch {
15
142
  }
16
143
  }
@@ -19,188 +146,167 @@ function findRoot() {
19
146
  dir = parent;
20
147
  }
21
148
  }
22
- var SECTION_RE = /^=+\s+(.+?)\s*$/;
23
- var HEADING_RE = /^([A-Za-z][\w /]*?) - @zyncat\/ui\/([a-z][a-z0-9-]*)\b.*$/;
24
- var cached = null;
25
149
  function db() {
26
- if (cached) return cached;
27
150
  const root = findRoot();
28
- const pkg = JSON.parse(readFileSync(join(root, "package.json"), "utf8"));
29
- const subpaths = Object.entries(pkg.exports ?? {}).filter(([, v]) => typeof v === "object" && v !== null && "types" in v).map(([k]) => k.replace(/^\.\//, ""));
30
- const preamble = [];
31
- const sections = [];
32
- const entries = [];
33
- let section = null;
34
- let entry = null;
35
- const close = (e) => {
36
- if (!e) return;
37
- while (e.lines.length && !e.lines[e.lines.length - 1].trim()) e.lines.pop();
38
- entries.push(e);
39
- };
40
- for (const line of readFileSync(join(root, "llms.txt"), "utf8").split("\n")) {
41
- const sec = line.match(SECTION_RE);
42
- const head = line.match(HEADING_RE);
43
- if (sec) {
44
- close(entry);
45
- entry = null;
46
- section = { title: sec[1], body: [] };
47
- sections.push(section);
48
- } else if (head) {
49
- close(entry);
50
- entry = { title: head[1].trim(), subpath: head[2], section: section?.title ?? "", lines: [line] };
51
- } else if (entry) {
52
- entry.lines.push(line);
53
- } else if (section) {
54
- section.body.push(line);
55
- } else {
56
- preamble.push(line);
57
- }
58
- }
59
- close(entry);
60
- for (const s of sections) {
61
- while (s.body.length && !s.body[s.body.length - 1].trim()) s.body.pop();
62
- while (s.body.length && !s.body[0].trim()) s.body.shift();
63
- }
64
- while (preamble.length && !preamble[preamble.length - 1].trim()) preamble.pop();
65
- cached = { root, version: String(pkg.version ?? "0"), subpaths, preamble, sections, entries };
66
- return cached;
151
+ const { version, modules } = loadModules(root);
152
+ return { root, version, modules, index: buildIndex(modules) };
67
153
  }
68
154
  var norm = (s) => s.toLowerCase().replace(/^@zyncat\/ui\//, "").replace(/[^a-z0-9]/g, "");
69
- function resolveSubpath(input) {
70
- const d = db();
71
- const q = norm(input);
72
- if (!q) throw new Error('Pass a component name or subpath, e.g. "Button" or "text-field".');
155
+ function resolveModules(d, inputs) {
156
+ const bySubpath = new Map(d.modules.map((m) => [m.subpath, m]));
73
157
  const candidates = /* @__PURE__ */ new Map();
74
- for (const sub of d.subpaths) candidates.set(norm(sub), sub);
75
- for (const e of d.entries) for (const part of e.title.split("/")) candidates.set(norm(part), e.subpath);
76
- const exact = candidates.get(q);
77
- if (exact) return exact;
78
- const loose = /* @__PURE__ */ new Set();
79
- for (const [name, sub] of candidates) if (name.includes(q) || q.includes(name)) loose.add(sub);
80
- if (loose.size === 1) return [...loose][0];
81
- const all = d.entries.map((e) => `${e.title} (${e.subpath})`).join(", ");
82
- const extras = d.subpaths.filter((s) => !d.entries.some((e) => e.subpath === s)).join(", ");
83
- throw new Error(
84
- (loose.size ? `"${input}" is ambiguous: ${[...loose].join(", ")}. ` : `No component matches "${input}". `) + `Available: ${all}${extras ? `; types-only modules: ${extras}` : ""}.`
85
- );
158
+ for (const m of d.modules) {
159
+ candidates.set(norm(m.subpath), m);
160
+ if (m.usage) {
161
+ for (const part of m.usage.title.split("/")) {
162
+ const key = norm(part);
163
+ if (key) candidates.set(key, m);
164
+ }
165
+ }
166
+ }
167
+ const misses = [];
168
+ const found = [];
169
+ for (const input of inputs) {
170
+ const q = norm(input);
171
+ if (!q) {
172
+ misses.push(`"${input}"`);
173
+ continue;
174
+ }
175
+ const exact = candidates.get(q) ?? bySubpath.get(q);
176
+ if (exact) {
177
+ found.push(exact);
178
+ continue;
179
+ }
180
+ const loose = /* @__PURE__ */ new Set();
181
+ for (const [name, m] of candidates) if (name.includes(q) || q.includes(name)) loose.add(m);
182
+ if (loose.size === 1) found.push([...loose][0]);
183
+ else if (loose.size > 1) misses.push(`"${input}" (ambiguous: ${[...loose].map((m) => m.subpath).join(", ")})`);
184
+ else misses.push(`"${input}"`);
185
+ }
186
+ if (misses.length) {
187
+ throw new Error(`No component matches ${misses.join(", ")}. The catalog:
188
+
189
+ ${d.index}`);
190
+ }
191
+ return [...new Set(found)];
86
192
  }
87
- function readTypes(root, subpath) {
193
+ var RELATIVE_SPEC_RE = /(?:from\s+['"]|import\(['"])(\.[^'"]+)['"]/g;
194
+ function readTypes(root, typesPath) {
88
195
  const out = [];
89
196
  const seen = /* @__PURE__ */ new Set();
90
- const walk = (base) => {
91
- if (seen.has(base)) return;
92
- seen.add(base);
93
- const p = join(root, "dist", `${base}.d.ts`);
94
- if (!existsSync(p)) return;
95
- const text = readFileSync(p, "utf8");
96
- out.push(`--- dist/${base}.d.ts ---
197
+ const walk = (path) => {
198
+ const full = resolve(root, path);
199
+ if (seen.has(full) || !existsSync2(full)) return;
200
+ seen.add(full);
201
+ const text = readFileSync2(full, "utf8");
202
+ out.push(`--- ${relative(root, full)} ---
97
203
  ${text.trimEnd()}`);
98
- for (const m of text.matchAll(/from\s+['"]\.\/([\w.-]+)\.js['"]/g)) walk(m[1]);
204
+ for (const m of text.matchAll(RELATIVE_SPEC_RE)) {
205
+ const base = join2(dirname(full), m[1].replace(/\.js$/, ""));
206
+ for (const candidate of [`${base}.d.ts`, `${base}.d.mts`, join2(base, "index.d.ts")]) {
207
+ if (existsSync2(candidate)) {
208
+ walk(relative(root, candidate));
209
+ break;
210
+ }
211
+ }
212
+ }
99
213
  };
100
- walk(subpath);
214
+ walk(typesPath);
101
215
  if (!out.length) {
102
216
  throw new Error(
103
- `dist/${subpath}.d.ts not found - the package is not built. In the zyncat-ui repo run "pnpm build"; in a consumer, reinstall the package.`
217
+ `${typesPath} not found in the installed package - reinstall @zyncat/ui; in the zyncat-ui repo, run "pnpm build" first.`
104
218
  );
105
219
  }
106
220
  return out.join("\n\n");
107
221
  }
108
- var tokenFiles = (root) => existsSync(join(root, "src/tokens")) ? readdirSync(join(root, "src/tokens")).filter((f) => f.endsWith(".css")).sort() : [];
109
- var CODE_LINE_RE = /^(?:[<{]|import\s|const\s|let\s|function\s)/;
110
- function entryTeaser(e) {
111
- const parts = [];
112
- for (let i = 1; i < e.lines.length; i++) {
113
- const line = e.lines[i].trim();
114
- if (!line) break;
115
- if (i > 1 && CODE_LINE_RE.test(line)) break;
116
- parts.push(line);
222
+ function renderModule(d, m) {
223
+ const out = [];
224
+ if (m.usage) {
225
+ out.push(`# ${m.usage.title} - @zyncat/ui/${m.subpath}`, "");
226
+ if (m.usage.docs) out.push(`Live docs page (see it rendered): ${m.usage.docs}`, "");
227
+ out.push(m.usage.summary, "");
228
+ const note = GROUPS.find((g) => g.id === m.usage.group)?.note;
229
+ if (note) out.push(`Applies to the whole ${m.usage.group} group: ${note}`, "");
230
+ const prose = m.usage.prose.map((l) => l.text);
231
+ if (prose.length) out.push(...prose, "");
232
+ for (const example of m.usage.examples) out.push("## Example", "", "```" + example.lang, example.code, "```", "");
233
+ } else {
234
+ out.push(`# @zyncat/ui/${m.subpath}`, "", "No usage doc - this module is documented by its types below.", "");
117
235
  }
118
- return parts.join(" ");
236
+ out.push("## Complete prop types (entry .d.ts + the shared chunks it imports)", "", readTypes(d.root, m.typesPath));
237
+ return out.join("\n");
119
238
  }
120
- function listComponents() {
239
+ function getComponent(raw) {
240
+ const inputs = (Array.isArray(raw) ? raw : [raw]).filter((v) => typeof v === "string");
241
+ if (!inputs.length) throw new Error('Pass one or more component names, e.g. ["select", "text-field"].');
121
242
  const d = db();
122
- const out = [...d.preamble, ""];
123
- for (const s of d.sections) {
124
- const inSection = d.entries.filter((e) => e.section === s.title);
125
- if (!inSection.length && !s.body.length) continue;
126
- out.push(`== ${s.title} ==`);
127
- out.push(...s.body);
128
- for (const e of inSection) {
129
- const first = entryTeaser(e);
130
- out.push(`${e.title} - @zyncat/ui/${e.subpath}${first ? ` - ${first}` : ""}`);
131
- }
132
- out.push("");
133
- }
134
- const extras = d.subpaths.filter((sub) => !d.entries.some((e) => e.subpath === sub));
135
- if (extras.length) {
136
- out.push("== SUPPORTING MODULES (no llms.txt entry - full docs live in their types) ==");
137
- for (const sub of extras) out.push(`@zyncat/ui/${sub} - call get_component("${sub}")`);
138
- }
139
- return out.join("\n").trim();
243
+ const modules = resolveModules(d, inputs);
244
+ return modules.map((m) => renderModule(d, m)).join("\n\n");
140
245
  }
141
- function getComponent(input) {
142
- const d = db();
143
- const sub = resolveSubpath(input);
144
- const entry = d.entries.find((e) => e.subpath === sub);
145
- const out = [`# ${entry ? entry.title : sub} - @zyncat/ui/${sub}`, ""];
146
- if (entry) {
147
- const note = d.sections.find((s) => s.title === entry.section)?.body ?? [];
148
- if (note.length) out.push(`Applies to every ${entry.section} component:`, ...note, "");
149
- out.push("## Usage (llms.txt)", ...entry.lines, "");
150
- } else {
151
- out.push("No llms.txt entry - this module is documented by its types below.", "");
246
+ var tokenFiles = (root) => existsSync2(join2(root, "src/tokens")) ? readdirSync(join2(root, "src/tokens")).filter((f) => f.endsWith(".css")).sort() : [];
247
+ function corpusFor(d, m) {
248
+ const parts = [];
249
+ if (m.usagePath && existsSync2(join2(d.root, m.usagePath))) {
250
+ parts.push({ label: "usage", text: readFileSync2(join2(d.root, m.usagePath), "utf8") });
152
251
  }
153
- out.push("## Types (entry .d.ts + the shared chunks it imports)", readTypes(d.root, sub));
154
- return out.join("\n");
252
+ try {
253
+ parts.push({ label: "types", text: readTypes(d.root, m.typesPath) });
254
+ } catch {
255
+ }
256
+ return parts;
155
257
  }
156
258
  function searchApi(query) {
157
- const d = db();
158
259
  const words = query.toLowerCase().split(/\s+/).filter(Boolean);
159
260
  if (!words.length) throw new Error('Pass one or more keywords, e.g. "searchable" or "drag dismiss".');
160
- const hits = /* @__PURE__ */ new Map();
161
- const scan = (label, text, lineLabel) => {
162
- text.split("\n").forEach((line, i) => {
163
- const l = line.toLowerCase();
164
- if (!words.every((w) => l.includes(w))) return;
165
- const key = lineLabel ? lineLabel(line, i) : label;
166
- if (!hits.has(key)) hits.set(key, []);
167
- hits.get(key).push(` L${i + 1}: ${line.trim()}`);
168
- });
169
- };
170
- {
171
- const raw = readFileSync(join(d.root, "llms.txt"), "utf8");
172
- const labels = [];
173
- let current = "llms.txt";
174
- for (const line of raw.split("\n")) {
175
- const sec = line.match(SECTION_RE);
176
- const head = line.match(HEADING_RE);
177
- if (sec) current = `llms.txt \xBB ${sec[1]}`;
178
- else if (head) current = `llms.txt \xBB ${head[1].trim()}`;
179
- labels.push(current);
261
+ const d = db();
262
+ const hits = [];
263
+ for (const m of d.modules) {
264
+ const hit = { module: m, score: 0, matched: /* @__PURE__ */ new Set(), lines: [] };
265
+ const head = `${m.usage?.title ?? ""} ${m.subpath} ${m.usage?.summary ?? ""}`.toLowerCase();
266
+ for (const w of words) {
267
+ if (head.includes(w)) {
268
+ hit.score += 4;
269
+ hit.matched.add(w);
270
+ }
180
271
  }
181
- scan("llms.txt", raw, (_line, i) => labels[i]);
272
+ for (const { label, text } of corpusFor(d, m)) {
273
+ for (const line of text.split("\n")) {
274
+ const lower = line.toLowerCase();
275
+ const inLine = words.filter((w) => lower.includes(w));
276
+ if (!inLine.length) continue;
277
+ for (const w of inLine) hit.matched.add(w);
278
+ hit.score += inLine.length * (label === "usage" ? 2 : 1);
279
+ const shown = line.trim();
280
+ if (hit.lines.length < 4 && shown && !line.startsWith("---") && shown !== m.usage?.summary && !shown.startsWith("# "))
281
+ hit.lines.push(shown);
282
+ }
283
+ }
284
+ if (hit.matched.size) hits.push(hit);
182
285
  }
183
- const distDir = join(d.root, "dist");
184
- const dts = existsSync(distDir) ? readdirSync(distDir).filter((f) => f.endsWith(".d.ts")).sort() : [];
185
- for (const f of dts) scan(`dist/${f}`, readFileSync(join(distDir, f), "utf8"));
186
- for (const f of tokenFiles(d.root)) scan(`src/tokens/${f}`, readFileSync(join(d.root, "src/tokens", f), "utf8"));
187
- const out = [];
188
- let shown = 0;
189
- let total = 0;
190
- for (const [, lines] of hits) total += lines.length;
191
- for (const [label, lines] of hits) {
192
- if (shown >= 60) break;
193
- out.push(`## ${label}`);
194
- for (const l of lines) {
195
- if (shown >= 60) break;
196
- out.push(l);
197
- shown++;
286
+ const full = hits.filter((h) => h.matched.size === words.length);
287
+ const ranked = (full.length ? full : hits).sort((a, b) => b.score - a.score).slice(0, 8);
288
+ const tokenHits = [];
289
+ for (const f of tokenFiles(d.root)) {
290
+ for (const line of readFileSync2(join2(d.root, "src/tokens", f), "utf8").split("\n")) {
291
+ const lower = line.toLowerCase();
292
+ if (words.some((w) => lower.includes(w)) && tokenHits.length < 12) tokenHits.push(`${f}: ${line.trim()}`);
198
293
  }
199
294
  }
200
- if (!total) return `No matches for "${query}". Try a shorter keyword, or list_components for the full index.`;
201
- if (total > shown) out.push(`... +${total - shown} more matching lines - narrow the query.`);
202
- if (!dts.length) out.push("(note: dist/ is not built, so type definitions were not searched)");
203
- out.push("", "Follow up with get_component(<name>) for the full picture.");
295
+ if (!ranked.length && !tokenHits.length) {
296
+ return `No matches for "${query}". The catalog:
297
+
298
+ ${d.index}`;
299
+ }
300
+ const out = [];
301
+ if (!full.length && ranked.length) out.push(`No component matches every word of "${query}"; closest by keyword:`, "");
302
+ for (const h of ranked) {
303
+ out.push(`## ${h.module.usage?.title ?? h.module.subpath} - @zyncat/ui/${h.module.subpath}`);
304
+ if (h.module.usage) out.push(h.module.usage.summary);
305
+ for (const line of h.lines) out.push(` ${line}`);
306
+ out.push("");
307
+ }
308
+ if (tokenHits.length) out.push("## Design tokens", ...tokenHits.map((l) => ` ${l}`), "");
309
+ out.push(`Follow up with get_component([...names]) for complete APIs.`);
204
310
  return out.join("\n");
205
311
  }
206
312
  function getTokens(group) {
@@ -222,36 +328,74 @@ function getTokens(group) {
222
328
  }
223
329
  const out = picked.map(
224
330
  (f) => `/* ==== src/tokens/${f} ==== */
225
- ${readFileSync(join(d.root, "src/tokens", f), "utf8").trimEnd()}`
331
+ ${readFileSync2(join2(d.root, "src/tokens", f), "utf8").trimEnd()}`
226
332
  );
227
- const theming = d.sections.find((s) => s.title.includes("THEMING"));
228
- if (theming?.body.length) out.push(["/* ==== theming ==== */", ...theming.body].join("\n"));
333
+ const theming = join2(d.root, "skills/zyncat-ui/references/theming.md");
334
+ if (!group && existsSync2(theming))
335
+ out.push(`/* ==== theming & overrides ==== */
336
+ ${readFileSync2(theming, "utf8").trimEnd()}`);
229
337
  return out.join("\n\n");
230
338
  }
231
- var TOOLS = [
232
- {
233
- name: "list_components",
234
- description: "Every Zyncat UI component: name, import subpath and one-line purpose, grouped by category, plus package setup and usage conventions. Start here instead of exploring node_modules.",
235
- inputSchema: { type: "object", properties: {}, additionalProperties: false }
236
- },
339
+ var GUIDES = { motion: "motion.md", design: "design-system.md", authoring: "authoring.md" };
340
+ var inRepo = (root) => existsSync2(join2(root, "tsup.config.ts"));
341
+ function contributorRoot(tool) {
342
+ const root = findRoot();
343
+ if (!inRepo(root)) {
344
+ throw new Error(
345
+ `${tool} is a contributor tool and is only available inside the zyncat-ui repository. In a consumer install use get_component / search_api / get_tokens.`
346
+ );
347
+ }
348
+ return root;
349
+ }
350
+ function guideSections(root, file) {
351
+ const path = join2(root, "docs/authoring", file);
352
+ if (!existsSync2(path)) throw new Error(`docs/authoring/${file} is missing from the repository.`);
353
+ const sections = [{ title: "", subtitles: [], lines: [] }];
354
+ for (const line of readFileSync2(path, "utf8").split("\n")) {
355
+ const head = line.match(/^##\s+(.+?)\s*$/);
356
+ const sub = line.match(/^###\s+(.+?)\s*$/);
357
+ if (head) sections.push({ title: head[1], subtitles: [], lines: [line] });
358
+ else {
359
+ const current = sections[sections.length - 1];
360
+ if (sub) current.subtitles.push(sub[1]);
361
+ current.lines.push(line);
362
+ }
363
+ }
364
+ return sections;
365
+ }
366
+ function guide(tool, file, topic) {
367
+ const sections = guideSections(contributorRoot(tool), file);
368
+ const text = (picked) => picked.flatMap((s) => s.lines).join("\n").trim();
369
+ if (!topic) return text(sections);
370
+ const q = norm(topic);
371
+ const matches = (title) => norm(title).includes(q) || q.includes(norm(title));
372
+ const named = sections.filter((s) => s.title);
373
+ const hits = named.filter((s) => matches(s.title) || s.subtitles.some(matches));
374
+ if (!hits.length) {
375
+ const titles = named.flatMap((s) => [s.title, ...s.subtitles]);
376
+ throw new Error(`No section of ${file} matches "${topic}". Sections: ${titles.join(", ")}.`);
377
+ }
378
+ return text(hits);
379
+ }
380
+ var CONSUMER_TOOLS = [
237
381
  {
238
382
  name: "get_component",
239
- description: "Full API for one component: the maintainers' usage notes and example plus the complete TypeScript prop types with doc comments (shared type chunks inlined). Cheaper and more accurate than reading node_modules/@zyncat/ui yourself.",
383
+ description: "Full current API for one or more components: the maintainers\u2019 usage doc (purpose, when to pick it over its neighbours, example, live docs page URL) plus the complete TypeScript prop types with doc comments, shared type chunks inlined. Accepts a list - pass every component the change touches in ONE call. This is the only reliable source for props: call it before writing any Zyncat UI JSX. An unknown name returns the full component catalog, so a wrong guess still orients you.",
240
384
  inputSchema: {
241
385
  type: "object",
242
386
  properties: {
243
- component: {
244
- type: "string",
245
- description: 'Component name or subpath - "Button", "TextField", "text-field", "@zyncat/ui/select".'
387
+ components: {
388
+ description: 'Component names or subpaths - ["select", "text-field", "dialog"], "Button", "@zyncat/ui/sheet".',
389
+ anyOf: [{ type: "string" }, { type: "array", items: { type: "string" }, minItems: 1 }]
246
390
  }
247
391
  },
248
- required: ["component"],
392
+ required: ["components"],
249
393
  additionalProperties: false
250
394
  }
251
395
  },
252
396
  {
253
397
  name: "search_api",
254
- description: 'Keyword search across all component docs, type definitions and design-token CSS. Finds which component owns a prop, type, token or behavior (e.g. "searchable", "DurationToken", "drag dismiss", "--accent"). Every word must match a line; follow up with get_component.',
398
+ description: 'Ranked keyword search across every component\u2019s usage doc, prop types and the design-token CSS. Finds which component owns a prop, behavior or token (e.g. "drag dismiss", "searchable", "DurationToken", "--accent"). Zero matches returns the whole catalog instead, so a miss still orients you. Follow up with get_component.',
255
399
  inputSchema: {
256
400
  type: "object",
257
401
  properties: { query: { type: "string", description: "One or more keywords." } },
@@ -261,7 +405,7 @@ var TOOLS = [
261
405
  },
262
406
  {
263
407
  name: "get_tokens",
264
- description: "The design-token vocabulary as CSS custom properties with their real values - color, semantic, spacing, typography, radius, elevation, motion, icons, layers, glass, avatar, fonts. Optionally pass one group name; omit for all. Use for theming/overrides and for reading exact values.",
408
+ description: "The design-token vocabulary as CSS custom properties with their real values - color, semantic, spacing, typography, radius, elevation, motion, icons, layers, glass, avatar, fonts - plus the theming/override levels. Optionally pass one group name; omit for all. Use for theming and for reading exact values.",
265
409
  inputSchema: {
266
410
  type: "object",
267
411
  properties: {
@@ -271,17 +415,62 @@ var TOOLS = [
271
415
  }
272
416
  }
273
417
  ];
274
- var INSTRUCTIONS = "Zyncat UI design-system API. Before writing Zyncat UI code, use these tools instead of reading node_modules or guessing props: list_components (what exists + setup and conventions), get_component (one component: usage docs + complete prop types), search_api (find the component/prop/token for a keyword), get_tokens (CSS custom-property vocabulary with real values, for theming). Imports are per-subpath (@zyncat/ui/button - no barrel); link @zyncat/ui/styles.css once at the root.";
418
+ var CONTRIBUTOR_TOOLS = [
419
+ {
420
+ name: "motion_guide",
421
+ description: "How to animate inside this repo: the transitions-vs-simulations boundary, which layer to reach for (CSS transition vs the engine vs Presence vs FLIP vs glide), the complete Layer keyframe vocabulary, [to] vs [from,to] semantics, timing, the one-writer-per-property ownership rules, sequencing, global reduced motion, and the canonical enter/exit recipes. Read this before writing any motion code - most of it is not guessable from the source.",
422
+ inputSchema: {
423
+ type: "object",
424
+ properties: {
425
+ topic: {
426
+ type: "string",
427
+ description: 'One section, e.g. "ownership", "timing", "simulations", "recipes". Omit for all.'
428
+ }
429
+ },
430
+ additionalProperties: false
431
+ }
432
+ },
433
+ {
434
+ name: "design_rules",
435
+ description: "The design-system rules for this repo: what the library is for, the system / expressive / replica contracts and the invariants that bind every tier, the token vocabulary and when to add a token rather than use an existing one, the consumer override levels, compose vs build a new component, which tier a component belongs in, and the internal machinery to reuse instead of hand-rolling.",
436
+ inputSchema: {
437
+ type: "object",
438
+ properties: {
439
+ topic: {
440
+ type: "string",
441
+ description: 'One section, e.g. "tokens", "contracts", "overrides", "compose", "tier". Omit for all.'
442
+ }
443
+ },
444
+ additionalProperties: false
445
+ }
446
+ },
447
+ {
448
+ name: "authoring_checklist",
449
+ description: "The complete checklist to add a component to this repo: file placement and tsup auto-discovery, the exports-map entry that fails silently when skipped, the per-component stylesheet and CSS-graph rule, the usage doc, which tests to write, and the checks to run.",
450
+ inputSchema: { type: "object", properties: {}, additionalProperties: false }
451
+ }
452
+ ];
453
+ function tools() {
454
+ try {
455
+ return inRepo(findRoot()) ? [...CONSUMER_TOOLS, ...CONTRIBUTOR_TOOLS] : CONSUMER_TOOLS;
456
+ } catch {
457
+ return CONSUMER_TOOLS;
458
+ }
459
+ }
460
+ var CONSUMER_INSTRUCTIONS = "Zyncat UI design-system API - the live truth for the installed version. Before writing any JSX that renders a Zyncat UI component, call get_component with every component the change touches (it accepts a list); prop lists remembered from training, a skill index or old code are not the API. search_api finds which component owns a keyword or behavior; get_tokens prints the token vocabulary with real values plus the theming levels. Imports are per-subpath (@zyncat/ui/button - no barrel); link @zyncat/ui/styles.css once at the root. The zyncat-ui skill (installed by `npx zyncat-ui init`) carries the component map, the recipes and the conventions.";
461
+ var CONTRIBUTOR_INSTRUCTIONS = " You are inside the zyncat-ui repository, so the contributor tools are also available and you are expected to use them before writing library code: motion_guide (call it before any motion code - the keyframe vocabulary and the ownership rules are not guessable from the source), design_rules (tokens, compose vs build, the internals to reuse), authoring_checklist (adding a component end to end).";
462
+ function instructions() {
463
+ try {
464
+ return inRepo(findRoot()) ? CONSUMER_INSTRUCTIONS + CONTRIBUTOR_INSTRUCTIONS : CONSUMER_INSTRUCTIONS;
465
+ } catch {
466
+ return CONSUMER_INSTRUCTIONS;
467
+ }
468
+ }
275
469
  function callTool(name, args) {
276
470
  const str = (k) => typeof args[k] === "string" ? args[k] : void 0;
277
471
  switch (name) {
278
- case "list_components":
279
- return listComponents();
280
- case "get_component": {
281
- const component = str("component");
282
- if (!component) throw new Error('Missing required argument "component".');
283
- return getComponent(component);
284
- }
472
+ case "get_component":
473
+ return getComponent(args.components ?? args.component);
285
474
  case "search_api": {
286
475
  const query = str("query");
287
476
  if (!query) throw new Error('Missing required argument "query".');
@@ -289,6 +478,12 @@ function callTool(name, args) {
289
478
  }
290
479
  case "get_tokens":
291
480
  return getTokens(str("group"));
481
+ case "motion_guide":
482
+ return guide(name, GUIDES.motion, str("topic"));
483
+ case "design_rules":
484
+ return guide(name, GUIDES.design, str("topic"));
485
+ case "authoring_checklist":
486
+ return guide(name, GUIDES.authoring);
292
487
  default:
293
488
  throw new Error(`Unknown tool: ${name}`);
294
489
  }
@@ -317,13 +512,13 @@ function handle(req) {
317
512
  protocolVersion: typeof params?.protocolVersion === "string" ? params.protocolVersion : "2025-06-18",
318
513
  capabilities: { tools: {} },
319
514
  serverInfo: { name: "zyncat-ui", version },
320
- instructions: INSTRUCTIONS
515
+ instructions: instructions()
321
516
  });
322
517
  }
323
518
  case "ping":
324
519
  return reply(id, {});
325
520
  case "tools/list":
326
- return reply(id, { tools: TOOLS });
521
+ return reply(id, { tools: tools() });
327
522
  case "tools/call": {
328
523
  try {
329
524
  const name = typeof params?.name === "string" ? params.name : "";