@zyncat/ui 0.11.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-AMFGY56I.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-AIQXS2XY.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-DKVUPFQR.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-XJQQQJAO.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-NGTA34V2.js → chunk-DDRSMHN4.js} +16 -10
  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-WFHRAKN3.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-U4MHX3KH.js → chunk-VAXCXZ53.js} +33 -12
  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 -181
  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 -9
  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 -218
  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 +12 -5
  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-62P3KD57.js.map +0 -1
  567. package/dist/chunk-7SZCJ7WI.js.map +0 -1
  568. package/dist/chunk-AIQXS2XY.js.map +0 -1
  569. package/dist/chunk-AMFGY56I.js.map +0 -1
  570. package/dist/chunk-CONSWNIV.js.map +0 -1
  571. package/dist/chunk-DKVUPFQR.js.map +0 -1
  572. package/dist/chunk-I4XQ4PV2.js.map +0 -1
  573. package/dist/chunk-NEF5XAHG.js.map +0 -1
  574. package/dist/chunk-NGTA34V2.js.map +0 -1
  575. package/dist/chunk-NNXJCLTV.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-S5ZTZANS.js.map +0 -1
  579. package/dist/chunk-U4MHX3KH.js.map +0 -1
  580. package/dist/chunk-VTJTGVZZ.js.map +0 -1
  581. package/dist/chunk-WFHRAKN3.js.map +0 -1
  582. package/dist/chunk-WM5J5TDI.js.map +0 -1
  583. package/dist/chunk-XJQQQJAO.js.map +0 -1
  584. package/dist/chunk-XWUWYSCT.js.map +0 -1
  585. package/dist/chunk-Y7AJQVWJ.js.map +0 -1
  586. package/dist/chunk-YGCVWGUG.js.map +0 -1
  587. package/dist/chunk-YGGCQNNU.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/src/mcp/server.ts CHANGED
@@ -1,7 +1,16 @@
1
- import { existsSync, readFileSync, readdirSync } from 'node:fs';
2
- import { dirname, join } from 'node:path';
1
+ import { existsSync, readdirSync, readFileSync } from 'node:fs';
2
+ import { dirname, join, relative, resolve } from 'node:path';
3
3
  import { fileURLToPath } from 'node:url';
4
4
 
5
+ import { buildIndex, GROUPS, loadModules, type UsageModule } from '../../scripts/lib/usage-format.mjs';
6
+
7
+ interface Db {
8
+ root: string;
9
+ version: string;
10
+ modules: UsageModule[];
11
+ index: string;
12
+ }
13
+
5
14
  function findRoot(): string {
6
15
  let dir = dirname(fileURLToPath(import.meta.url));
7
16
  for (;;) {
@@ -17,72 +26,10 @@ function findRoot(): string {
17
26
  }
18
27
  }
19
28
 
20
- interface LlmsEntry {
21
- title: string;
22
- subpath: string;
23
- section: string;
24
- lines: string[];
25
- }
26
- interface LlmsSection {
27
- title: string;
28
- body: string[];
29
- }
30
- interface Db {
31
- root: string;
32
- version: string;
33
- subpaths: string[];
34
- preamble: string[];
35
- sections: LlmsSection[];
36
- entries: LlmsEntry[];
37
- }
38
-
39
- const SECTION_RE = /^=+\s+(.+?)\s*$/;
40
- const HEADING_RE = /^([A-Za-z][\w /]*?) - @zyncat\/ui\/([a-z][a-z0-9-]*)\b.*$/;
41
-
42
29
  function db(): Db {
43
30
  const root = findRoot();
44
- const pkg = JSON.parse(readFileSync(join(root, 'package.json'), 'utf8'));
45
- const subpaths = Object.entries(pkg.exports ?? {})
46
- .filter(([, v]) => typeof v === 'object' && v !== null && 'types' in (v as object))
47
- .map(([k]) => k.replace(/^\.\//, ''));
48
-
49
- const preamble: string[] = [];
50
- const sections: LlmsSection[] = [];
51
- const entries: LlmsEntry[] = [];
52
- let section: LlmsSection | null = null;
53
- let entry: LlmsEntry | null = null;
54
- const close = (e: LlmsEntry | null) => {
55
- if (!e) return;
56
- while (e.lines.length && !e.lines[e.lines.length - 1].trim()) e.lines.pop();
57
- entries.push(e);
58
- };
59
- for (const line of readFileSync(join(root, 'llms.txt'), 'utf8').split('\n')) {
60
- const sec = line.match(SECTION_RE);
61
- const head = line.match(HEADING_RE);
62
- if (sec) {
63
- close(entry);
64
- entry = null;
65
- section = { title: sec[1], body: [] };
66
- sections.push(section);
67
- } else if (head) {
68
- close(entry);
69
- entry = { title: head[1].trim(), subpath: head[2], section: section?.title ?? '', lines: [line] };
70
- } else if (entry) {
71
- entry.lines.push(line);
72
- } else if (section) {
73
- section.body.push(line);
74
- } else {
75
- preamble.push(line);
76
- }
77
- }
78
- close(entry);
79
- for (const s of sections) {
80
- while (s.body.length && !s.body[s.body.length - 1].trim()) s.body.pop();
81
- while (s.body.length && !s.body[0].trim()) s.body.shift();
82
- }
83
- while (preamble.length && !preamble[preamble.length - 1].trim()) preamble.pop();
84
-
85
- return { root, version: String(pkg.version ?? '0'), subpaths, preamble, sections, entries };
31
+ const { version, modules } = loadModules(root);
32
+ return { root, version, modules, index: buildIndex(modules) };
86
33
  }
87
34
 
88
35
  const norm = (s: string) =>
@@ -91,47 +38,99 @@ const norm = (s: string) =>
91
38
  .replace(/^@zyncat\/ui\//, '')
92
39
  .replace(/[^a-z0-9]/g, '');
93
40
 
94
- function resolveSubpath(input: string): string {
95
- const d = db();
96
- const q = norm(input);
97
- if (!q) throw new Error('Pass a component name or subpath, e.g. "Button" or "text-field".');
98
- const candidates = new Map<string, string>();
99
- for (const sub of d.subpaths) candidates.set(norm(sub), sub);
100
- for (const e of d.entries) for (const part of e.title.split('/')) candidates.set(norm(part), e.subpath);
101
- const exact = candidates.get(q);
102
- if (exact) return exact;
103
- const loose = new Set<string>();
104
- for (const [name, sub] of candidates) if (name.includes(q) || q.includes(name)) loose.add(sub);
105
- if (loose.size === 1) return [...loose][0];
106
- const all = d.entries.map((e) => `${e.title} (${e.subpath})`).join(', ');
107
- const extras = d.subpaths.filter((s) => !d.entries.some((e) => e.subpath === s)).join(', ');
108
- throw new Error(
109
- (loose.size ? `"${input}" is ambiguous: ${[...loose].join(', ')}. ` : `No component matches "${input}". `) +
110
- `Available: ${all}${extras ? `; types-only modules: ${extras}` : ''}.`,
111
- );
41
+ function resolveModules(d: Db, inputs: string[]): UsageModule[] {
42
+ const bySubpath = new Map(d.modules.map((m) => [m.subpath, m]));
43
+ const candidates = new Map<string, UsageModule>();
44
+ for (const m of d.modules) {
45
+ candidates.set(norm(m.subpath), m);
46
+ if (m.usage) {
47
+ for (const part of m.usage.title.split('/')) {
48
+ const key = norm(part);
49
+ if (key) candidates.set(key, m);
50
+ }
51
+ }
52
+ }
53
+ const misses: string[] = [];
54
+ const found: UsageModule[] = [];
55
+ for (const input of inputs) {
56
+ const q = norm(input);
57
+ if (!q) {
58
+ misses.push(`"${input}"`);
59
+ continue;
60
+ }
61
+ const exact = candidates.get(q) ?? bySubpath.get(q);
62
+ if (exact) {
63
+ found.push(exact);
64
+ continue;
65
+ }
66
+ const loose = new Set<UsageModule>();
67
+ for (const [name, m] of candidates) if (name.includes(q) || q.includes(name)) loose.add(m);
68
+ if (loose.size === 1) found.push([...loose][0]);
69
+ else if (loose.size > 1) misses.push(`"${input}" (ambiguous: ${[...loose].map((m) => m.subpath).join(', ')})`);
70
+ else misses.push(`"${input}"`);
71
+ }
72
+ if (misses.length) {
73
+ throw new Error(`No component matches ${misses.join(', ')}. The catalog:\n\n${d.index}`);
74
+ }
75
+ return [...new Set(found)];
112
76
  }
113
77
 
114
- function readTypes(root: string, subpath: string): string {
78
+ const RELATIVE_SPEC_RE = /(?:from\s+['"]|import\(['"])(\.[^'"]+)['"]/g;
79
+
80
+ function readTypes(root: string, typesPath: string): string {
115
81
  const out: string[] = [];
116
82
  const seen = new Set<string>();
117
- const walk = (base: string) => {
118
- if (seen.has(base)) return;
119
- seen.add(base);
120
- const p = join(root, 'dist', `${base}.d.ts`);
121
- if (!existsSync(p)) return;
122
- const text = readFileSync(p, 'utf8');
123
- out.push(`--- dist/${base}.d.ts ---\n${text.trimEnd()}`);
124
- for (const m of text.matchAll(/from\s+['"]\.\/([\w.-]+)\.js['"]/g)) walk(m[1]);
83
+ const walk = (path: string) => {
84
+ const full = resolve(root, path);
85
+ if (seen.has(full) || !existsSync(full)) return;
86
+ seen.add(full);
87
+ const text = readFileSync(full, 'utf8');
88
+ out.push(`--- ${relative(root, full)} ---\n${text.trimEnd()}`);
89
+ for (const m of text.matchAll(RELATIVE_SPEC_RE)) {
90
+ const base = join(dirname(full), m[1].replace(/\.js$/, ''));
91
+ for (const candidate of [`${base}.d.ts`, `${base}.d.mts`, join(base, 'index.d.ts')]) {
92
+ if (existsSync(candidate)) {
93
+ walk(relative(root, candidate));
94
+ break;
95
+ }
96
+ }
97
+ }
125
98
  };
126
- walk(subpath);
99
+ walk(typesPath);
127
100
  if (!out.length) {
128
101
  throw new Error(
129
- `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.`,
102
+ `${typesPath} not found in the installed package - reinstall @zyncat/ui; in the zyncat-ui repo, run "pnpm build" first.`,
130
103
  );
131
104
  }
132
105
  return out.join('\n\n');
133
106
  }
134
107
 
108
+ function renderModule(d: Db, m: UsageModule): string {
109
+ const out: string[] = [];
110
+ if (m.usage) {
111
+ out.push(`# ${m.usage.title} - @zyncat/ui/${m.subpath}`, '');
112
+ if (m.usage.docs) out.push(`Live docs page (see it rendered): ${m.usage.docs}`, '');
113
+ out.push(m.usage.summary, '');
114
+ const note = GROUPS.find((g) => g.id === m.usage!.group)?.note;
115
+ if (note) out.push(`Applies to the whole ${m.usage.group} group: ${note}`, '');
116
+ const prose = m.usage.prose.map((l) => l.text);
117
+ if (prose.length) out.push(...prose, '');
118
+ for (const example of m.usage.examples) out.push('## Example', '', '```' + example.lang, example.code, '```', '');
119
+ } else {
120
+ out.push(`# @zyncat/ui/${m.subpath}`, '', 'No usage doc - this module is documented by its types below.', '');
121
+ }
122
+ out.push('## Complete prop types (entry .d.ts + the shared chunks it imports)', '', readTypes(d.root, m.typesPath));
123
+ return out.join('\n');
124
+ }
125
+
126
+ function getComponent(raw: unknown): string {
127
+ const inputs = (Array.isArray(raw) ? raw : [raw]).filter((v): v is string => typeof v === 'string');
128
+ if (!inputs.length) throw new Error('Pass one or more component names, e.g. ["select", "text-field"].');
129
+ const d = db();
130
+ const modules = resolveModules(d, inputs);
131
+ return modules.map((m) => renderModule(d, m)).join('\n\n');
132
+ }
133
+
135
134
  const tokenFiles = (root: string): string[] =>
136
135
  existsSync(join(root, 'src/tokens'))
137
136
  ? readdirSync(join(root, 'src/tokens'))
@@ -139,112 +138,85 @@ const tokenFiles = (root: string): string[] =>
139
138
  .sort()
140
139
  : [];
141
140
 
142
- const CODE_LINE_RE = /^(?:[<{]|import\s|const\s|let\s|function\s)/;
143
-
144
- function entryTeaser(e: LlmsEntry): string {
145
- const parts: string[] = [];
146
- for (let i = 1; i < e.lines.length; i++) {
147
- const line = e.lines[i].trim();
148
- if (!line) break;
149
- if (i > 1 && CODE_LINE_RE.test(line)) break;
150
- parts.push(line);
151
- }
152
- return parts.join(' ');
141
+ interface Hit {
142
+ module: UsageModule;
143
+ score: number;
144
+ matched: Set<string>;
145
+ lines: string[];
153
146
  }
154
147
 
155
- function listComponents(): string {
156
- const d = db();
157
- const out: string[] = [...d.preamble, ''];
158
- for (const s of d.sections) {
159
- const inSection = d.entries.filter((e) => e.section === s.title);
160
- if (!inSection.length && !s.body.length) continue;
161
- out.push(`== ${s.title} ==`);
162
- out.push(...s.body);
163
- for (const e of inSection) {
164
- const first = entryTeaser(e);
165
- out.push(`${e.title} - @zyncat/ui/${e.subpath}${first ? ` - ${first}` : ''}`);
166
- }
167
- out.push('');
148
+ function corpusFor(d: Db, m: UsageModule): { label: string; text: string }[] {
149
+ const parts: { label: string; text: string }[] = [];
150
+ if (m.usagePath && existsSync(join(d.root, m.usagePath))) {
151
+ parts.push({ label: 'usage', text: readFileSync(join(d.root, m.usagePath), 'utf8') });
168
152
  }
169
- const extras = d.subpaths.filter((sub) => !d.entries.some((e) => e.subpath === sub));
170
- if (extras.length) {
171
- out.push('== SUPPORTING MODULES (no llms.txt entry - full docs live in their types) ==');
172
- for (const sub of extras) out.push(`@zyncat/ui/${sub} - call get_component("${sub}")`);
173
- }
174
- return out.join('\n').trim();
175
- }
176
-
177
- function getComponent(input: string): string {
178
- const d = db();
179
- const sub = resolveSubpath(input);
180
- const entry = d.entries.find((e) => e.subpath === sub);
181
-
182
- const out: string[] = [`# ${entry ? entry.title : sub} - @zyncat/ui/${sub}`, ''];
183
- if (entry) {
184
- const note = d.sections.find((s) => s.title === entry.section)?.body ?? [];
185
- if (note.length) out.push(`Applies to every ${entry.section} component:`, ...note, '');
186
- out.push('## Usage (llms.txt)', ...entry.lines, '');
187
- } else {
188
- out.push('No llms.txt entry - this module is documented by its types below.', '');
189
- }
190
- out.push('## Types (entry .d.ts + the shared chunks it imports)', readTypes(d.root, sub));
191
- return out.join('\n');
153
+ try {
154
+ parts.push({ label: 'types', text: readTypes(d.root, m.typesPath) });
155
+ } catch {}
156
+ return parts;
192
157
  }
193
158
 
194
159
  function searchApi(query: string): string {
195
- const d = db();
196
160
  const words = query.toLowerCase().split(/\s+/).filter(Boolean);
197
161
  if (!words.length) throw new Error('Pass one or more keywords, e.g. "searchable" or "drag dismiss".');
198
- const hits = new Map<string, string[]>();
199
- const scan = (label: string, text: string, lineLabel?: (line: string, i: number) => string) => {
200
- text.split('\n').forEach((line, i) => {
201
- const l = line.toLowerCase();
202
- if (!words.every((w) => l.includes(w))) return;
203
- const key = lineLabel ? lineLabel(line, i) : label;
204
- if (!hits.has(key)) hits.set(key, []);
205
- hits.get(key)!.push(` L${i + 1}: ${line.trim()}`);
206
- });
207
- };
162
+ const d = db();
208
163
 
209
- {
210
- const raw = readFileSync(join(d.root, 'llms.txt'), 'utf8');
211
- const labels: string[] = [];
212
- let current = 'llms.txt';
213
- for (const line of raw.split('\n')) {
214
- const sec = line.match(SECTION_RE);
215
- const head = line.match(HEADING_RE);
216
- if (sec) current = `llms.txt » ${sec[1]}`;
217
- else if (head) current = `llms.txt » ${head[1].trim()}`;
218
- labels.push(current);
164
+ const hits: Hit[] = [];
165
+ for (const m of d.modules) {
166
+ const hit: Hit = { module: m, score: 0, matched: new Set(), lines: [] };
167
+ const head = `${m.usage?.title ?? ''} ${m.subpath} ${m.usage?.summary ?? ''}`.toLowerCase();
168
+ for (const w of words) {
169
+ if (head.includes(w)) {
170
+ hit.score += 4;
171
+ hit.matched.add(w);
172
+ }
173
+ }
174
+ for (const { label, text } of corpusFor(d, m)) {
175
+ for (const line of text.split('\n')) {
176
+ const lower = line.toLowerCase();
177
+ const inLine = words.filter((w) => lower.includes(w));
178
+ if (!inLine.length) continue;
179
+ for (const w of inLine) hit.matched.add(w);
180
+ hit.score += inLine.length * (label === 'usage' ? 2 : 1);
181
+ const shown = line.trim();
182
+ if (
183
+ hit.lines.length < 4 &&
184
+ shown &&
185
+ !line.startsWith('---') &&
186
+ shown !== m.usage?.summary &&
187
+ !shown.startsWith('# ')
188
+ )
189
+ hit.lines.push(shown);
190
+ }
219
191
  }
220
- scan('llms.txt', raw, (_line, i) => labels[i]);
192
+ if (hit.matched.size) hits.push(hit);
221
193
  }
222
- const distDir = join(d.root, 'dist');
223
- const dts = existsSync(distDir)
224
- ? readdirSync(distDir)
225
- .filter((f) => f.endsWith('.d.ts'))
226
- .sort()
227
- : [];
228
- for (const f of dts) scan(`dist/${f}`, readFileSync(join(distDir, f), 'utf8'));
229
- for (const f of tokenFiles(d.root)) scan(`src/tokens/${f}`, readFileSync(join(d.root, 'src/tokens', f), 'utf8'));
230
194
 
231
- const out: string[] = [];
232
- let shown = 0;
233
- let total = 0;
234
- for (const [, lines] of hits) total += lines.length;
235
- for (const [label, lines] of hits) {
236
- if (shown >= 60) break;
237
- out.push(`## ${label}`);
238
- for (const l of lines) {
239
- if (shown >= 60) break;
240
- out.push(l);
241
- shown++;
195
+ const full = hits.filter((h) => h.matched.size === words.length);
196
+ const ranked = (full.length ? full : hits).sort((a, b) => b.score - a.score).slice(0, 8);
197
+
198
+ const tokenHits: string[] = [];
199
+ for (const f of tokenFiles(d.root)) {
200
+ for (const line of readFileSync(join(d.root, 'src/tokens', f), 'utf8').split('\n')) {
201
+ const lower = line.toLowerCase();
202
+ if (words.some((w) => lower.includes(w)) && tokenHits.length < 12) tokenHits.push(`${f}: ${line.trim()}`);
242
203
  }
243
204
  }
244
- if (!total) return `No matches for "${query}". Try a shorter keyword, or list_components for the full index.`;
245
- if (total > shown) out.push(`... +${total - shown} more matching lines - narrow the query.`);
246
- if (!dts.length) out.push('(note: dist/ is not built, so type definitions were not searched)');
247
- out.push('', 'Follow up with get_component(<name>) for the full picture.');
205
+
206
+ if (!ranked.length && !tokenHits.length) {
207
+ return `No matches for "${query}". The catalog:\n\n${d.index}`;
208
+ }
209
+
210
+ const out: string[] = [];
211
+ if (!full.length && ranked.length) out.push(`No component matches every word of "${query}"; closest by keyword:`, '');
212
+ for (const h of ranked) {
213
+ out.push(`## ${h.module.usage?.title ?? h.module.subpath} - @zyncat/ui/${h.module.subpath}`);
214
+ if (h.module.usage) out.push(h.module.usage.summary);
215
+ for (const line of h.lines) out.push(` ${line}`);
216
+ out.push('');
217
+ }
218
+ if (tokenHits.length) out.push('## Design tokens', ...tokenHits.map((l) => ` ${l}`), '');
219
+ out.push(`Follow up with get_component([...names]) for complete APIs.`);
248
220
  return out.join('\n');
249
221
  }
250
222
 
@@ -268,38 +240,98 @@ function getTokens(group?: string): string {
268
240
  const out = picked.map(
269
241
  (f) => `/* ==== src/tokens/${f} ==== */\n${readFileSync(join(d.root, 'src/tokens', f), 'utf8').trimEnd()}`,
270
242
  );
271
- const theming = d.sections.find((s) => s.title.includes('THEMING'));
272
- if (theming?.body.length) out.push(['/* ==== theming ==== */', ...theming.body].join('\n'));
243
+ const theming = join(d.root, 'skills/zyncat-ui/references/theming.md');
244
+ if (!group && existsSync(theming))
245
+ out.push(`/* ==== theming & overrides ==== */\n${readFileSync(theming, 'utf8').trimEnd()}`);
273
246
  return out.join('\n\n');
274
247
  }
275
248
 
276
- const TOOLS = [
277
- {
278
- name: 'list_components',
279
- description:
280
- '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.',
281
- inputSchema: { type: 'object', properties: {}, additionalProperties: false },
282
- },
249
+ const GUIDES = { motion: 'motion.md', design: 'design-system.md', authoring: 'authoring.md' } as const;
250
+
251
+ const inRepo = (root: string): boolean => existsSync(join(root, 'tsup.config.ts'));
252
+
253
+ function contributorRoot(tool: string): string {
254
+ const root = findRoot();
255
+ if (!inRepo(root)) {
256
+ throw new Error(
257
+ `${tool} is a contributor tool and is only available inside the zyncat-ui repository. ` +
258
+ 'In a consumer install use get_component / search_api / get_tokens.',
259
+ );
260
+ }
261
+ return root;
262
+ }
263
+
264
+ interface GuideSection {
265
+ title: string;
266
+ subtitles: string[];
267
+ lines: string[];
268
+ }
269
+
270
+ function guideSections(root: string, file: string): GuideSection[] {
271
+ const path = join(root, 'docs/authoring', file);
272
+ if (!existsSync(path)) throw new Error(`docs/authoring/${file} is missing from the repository.`);
273
+ const sections: GuideSection[] = [{ title: '', subtitles: [], lines: [] }];
274
+ for (const line of readFileSync(path, 'utf8').split('\n')) {
275
+ const head = line.match(/^##\s+(.+?)\s*$/);
276
+ const sub = line.match(/^###\s+(.+?)\s*$/);
277
+ if (head) sections.push({ title: head[1], subtitles: [], lines: [line] });
278
+ else {
279
+ const current = sections[sections.length - 1];
280
+ if (sub) current.subtitles.push(sub[1]);
281
+ current.lines.push(line);
282
+ }
283
+ }
284
+ return sections;
285
+ }
286
+
287
+ function guide(tool: string, file: string, topic?: string): string {
288
+ const sections = guideSections(contributorRoot(tool), file);
289
+ const text = (picked: GuideSection[]) =>
290
+ picked
291
+ .flatMap((s) => s.lines)
292
+ .join('\n')
293
+ .trim();
294
+ if (!topic) return text(sections);
295
+ const q = norm(topic);
296
+ const matches = (title: string) => norm(title).includes(q) || q.includes(norm(title));
297
+ const named = sections.filter((s) => s.title);
298
+ const hits = named.filter((s) => matches(s.title) || s.subtitles.some(matches));
299
+ if (!hits.length) {
300
+ const titles = named.flatMap((s) => [s.title, ...s.subtitles]);
301
+ throw new Error(`No section of ${file} matches "${topic}". Sections: ${titles.join(', ')}.`);
302
+ }
303
+ return text(hits);
304
+ }
305
+
306
+ const CONSUMER_TOOLS = [
283
307
  {
284
308
  name: 'get_component',
285
309
  description:
286
- "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.",
310
+ 'Full current API for one or more components: the maintainers usage doc (purpose, when to pick it over ' +
311
+ 'its neighbours, example, live docs page URL) plus the complete TypeScript prop types with doc comments, ' +
312
+ 'shared type chunks inlined. Accepts a list - pass every component the change touches in ONE call. This is ' +
313
+ 'the only reliable source for props: call it before writing any Zyncat UI JSX. An unknown name returns the ' +
314
+ 'full component catalog, so a wrong guess still orients you.',
287
315
  inputSchema: {
288
316
  type: 'object',
289
317
  properties: {
290
- component: {
291
- type: 'string',
292
- description: 'Component name or subpath - "Button", "TextField", "text-field", "@zyncat/ui/select".',
318
+ components: {
319
+ description:
320
+ 'Component names or subpaths - ["select", "text-field", "dialog"], "Button", "@zyncat/ui/sheet".',
321
+ anyOf: [{ type: 'string' }, { type: 'array', items: { type: 'string' }, minItems: 1 }],
293
322
  },
294
323
  },
295
- required: ['component'],
324
+ required: ['components'],
296
325
  additionalProperties: false,
297
326
  },
298
327
  },
299
328
  {
300
329
  name: 'search_api',
301
330
  description:
302
- '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.',
331
+ 'Ranked keyword search across every component’s usage doc, prop types and the design-token CSS. Finds ' +
332
+ 'which component owns a prop, behavior or token (e.g. "drag dismiss", "searchable", "DurationToken", ' +
333
+ '"--accent"). Zero matches returns the whole catalog instead, so a miss still orients you. Follow up with ' +
334
+ 'get_component.',
303
335
  inputSchema: {
304
336
  type: 'object',
305
337
  properties: { query: { type: 'string', description: 'One or more keywords.' } },
@@ -310,7 +342,9 @@ const TOOLS = [
310
342
  {
311
343
  name: 'get_tokens',
312
344
  description:
313
- '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.',
345
+ 'The design-token vocabulary as CSS custom properties with their real values - color, semantic, spacing, ' +
346
+ 'typography, radius, elevation, motion, icons, layers, glass, avatar, fonts - plus the theming/override ' +
347
+ 'levels. Optionally pass one group name; omit for all. Use for theming and for reading exact values.',
314
348
  inputSchema: {
315
349
  type: 'object',
316
350
  properties: {
@@ -321,23 +355,80 @@ const TOOLS = [
321
355
  },
322
356
  ];
323
357
 
324
- const INSTRUCTIONS =
325
- 'Zyncat UI design-system API. Before writing Zyncat UI code, use these tools instead of reading ' +
326
- 'node_modules or guessing props: list_components (what exists + setup and conventions), get_component ' +
327
- '(one component: usage docs + complete prop types), search_api (find the component/prop/token for a ' +
328
- 'keyword), get_tokens (CSS custom-property vocabulary with real values, for theming). Imports are ' +
329
- 'per-subpath (@zyncat/ui/button - no barrel); link @zyncat/ui/styles.css once at the root.';
358
+ const CONTRIBUTOR_TOOLS = [
359
+ {
360
+ name: 'motion_guide',
361
+ description:
362
+ '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.',
363
+ inputSchema: {
364
+ type: 'object',
365
+ properties: {
366
+ topic: {
367
+ type: 'string',
368
+ description: 'One section, e.g. "ownership", "timing", "simulations", "recipes". Omit for all.',
369
+ },
370
+ },
371
+ additionalProperties: false,
372
+ },
373
+ },
374
+ {
375
+ name: 'design_rules',
376
+ description:
377
+ '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.',
378
+ inputSchema: {
379
+ type: 'object',
380
+ properties: {
381
+ topic: {
382
+ type: 'string',
383
+ description: 'One section, e.g. "tokens", "contracts", "overrides", "compose", "tier". Omit for all.',
384
+ },
385
+ },
386
+ additionalProperties: false,
387
+ },
388
+ },
389
+ {
390
+ name: 'authoring_checklist',
391
+ description:
392
+ '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.',
393
+ inputSchema: { type: 'object', properties: {}, additionalProperties: false },
394
+ },
395
+ ];
396
+
397
+ function tools() {
398
+ try {
399
+ return inRepo(findRoot()) ? [...CONSUMER_TOOLS, ...CONTRIBUTOR_TOOLS] : CONSUMER_TOOLS;
400
+ } catch {
401
+ return CONSUMER_TOOLS;
402
+ }
403
+ }
404
+
405
+ const CONSUMER_INSTRUCTIONS =
406
+ 'Zyncat UI design-system API - the live truth for the installed version. Before writing any JSX that renders a ' +
407
+ 'Zyncat UI component, call get_component with every component the change touches (it accepts a list); prop lists ' +
408
+ 'remembered from training, a skill index or old code are not the API. search_api finds which component owns a ' +
409
+ 'keyword or behavior; get_tokens prints the token vocabulary with real values plus the theming levels. Imports ' +
410
+ 'are per-subpath (@zyncat/ui/button - no barrel); link @zyncat/ui/styles.css once at the root. The zyncat-ui ' +
411
+ 'skill (installed by `npx zyncat-ui init`) carries the component map, the recipes and the conventions.';
412
+
413
+ const CONTRIBUTOR_INSTRUCTIONS =
414
+ ' You are inside the zyncat-ui repository, so the contributor tools are also available and you are ' +
415
+ 'expected to use them before writing library code: motion_guide (call it before any motion code - the ' +
416
+ 'keyframe vocabulary and the ownership rules are not guessable from the source), design_rules (tokens, ' +
417
+ 'compose vs build, the internals to reuse), authoring_checklist (adding a component end to end).';
418
+
419
+ function instructions(): string {
420
+ try {
421
+ return inRepo(findRoot()) ? CONSUMER_INSTRUCTIONS + CONTRIBUTOR_INSTRUCTIONS : CONSUMER_INSTRUCTIONS;
422
+ } catch {
423
+ return CONSUMER_INSTRUCTIONS;
424
+ }
425
+ }
330
426
 
331
427
  function callTool(name: string, args: Record<string, unknown>): string {
332
428
  const str = (k: string) => (typeof args[k] === 'string' ? (args[k] as string) : undefined);
333
429
  switch (name) {
334
- case 'list_components':
335
- return listComponents();
336
- case 'get_component': {
337
- const component = str('component');
338
- if (!component) throw new Error('Missing required argument "component".');
339
- return getComponent(component);
340
- }
430
+ case 'get_component':
431
+ return getComponent(args.components ?? args.component);
341
432
  case 'search_api': {
342
433
  const query = str('query');
343
434
  if (!query) throw new Error('Missing required argument "query".');
@@ -345,6 +436,12 @@ function callTool(name: string, args: Record<string, unknown>): string {
345
436
  }
346
437
  case 'get_tokens':
347
438
  return getTokens(str('group'));
439
+ case 'motion_guide':
440
+ return guide(name, GUIDES.motion, str('topic'));
441
+ case 'design_rules':
442
+ return guide(name, GUIDES.design, str('topic'));
443
+ case 'authoring_checklist':
444
+ return guide(name, GUIDES.authoring);
348
445
  default:
349
446
  throw new Error(`Unknown tool: ${name}`);
350
447
  }
@@ -374,13 +471,13 @@ function handle(req: { id?: RpcId; method?: string; params?: Record<string, unkn
374
471
  protocolVersion: typeof params?.protocolVersion === 'string' ? params.protocolVersion : '2025-06-18',
375
472
  capabilities: { tools: {} },
376
473
  serverInfo: { name: 'zyncat-ui', version },
377
- instructions: INSTRUCTIONS,
474
+ instructions: instructions(),
378
475
  });
379
476
  }
380
477
  case 'ping':
381
478
  return reply(id!, {});
382
479
  case 'tools/list':
383
- return reply(id!, { tools: TOOLS });
480
+ return reply(id!, { tools: tools() });
384
481
  case 'tools/call': {
385
482
  try {
386
483
  const name = typeof params?.name === 'string' ? params.name : '';
@@ -1,6 +1,7 @@
1
1
  'use client';
2
2
 
3
3
  import { createElement, useCallback, useRef, type ReactNode, type Ref } from 'react';
4
+
4
5
  import { useFlip, type FlipTuning } from './flip';
5
6
  import { useMotion, type MotionSpecs } from './use-motion';
6
7