@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/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,75 +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
- let cached: Db | null = null;
43
29
  function db(): Db {
44
- if (cached) return cached;
45
30
  const root = findRoot();
46
- const pkg = JSON.parse(readFileSync(join(root, 'package.json'), 'utf8'));
47
- const subpaths = Object.entries(pkg.exports ?? {})
48
- .filter(([, v]) => typeof v === 'object' && v !== null && 'types' in (v as object))
49
- .map(([k]) => k.replace(/^\.\//, ''));
50
-
51
- const preamble: string[] = [];
52
- const sections: LlmsSection[] = [];
53
- const entries: LlmsEntry[] = [];
54
- let section: LlmsSection | null = null;
55
- let entry: LlmsEntry | null = null;
56
- const close = (e: LlmsEntry | null) => {
57
- if (!e) return;
58
- while (e.lines.length && !e.lines[e.lines.length - 1].trim()) e.lines.pop();
59
- entries.push(e);
60
- };
61
- for (const line of readFileSync(join(root, 'llms.txt'), 'utf8').split('\n')) {
62
- const sec = line.match(SECTION_RE);
63
- const head = line.match(HEADING_RE);
64
- if (sec) {
65
- close(entry);
66
- entry = null;
67
- section = { title: sec[1], body: [] };
68
- sections.push(section);
69
- } else if (head) {
70
- close(entry);
71
- entry = { title: head[1].trim(), subpath: head[2], section: section?.title ?? '', lines: [line] };
72
- } else if (entry) {
73
- entry.lines.push(line);
74
- } else if (section) {
75
- section.body.push(line);
76
- } else {
77
- preamble.push(line);
78
- }
79
- }
80
- close(entry);
81
- for (const s of sections) {
82
- while (s.body.length && !s.body[s.body.length - 1].trim()) s.body.pop();
83
- while (s.body.length && !s.body[0].trim()) s.body.shift();
84
- }
85
- while (preamble.length && !preamble[preamble.length - 1].trim()) preamble.pop();
86
-
87
- cached = { root, version: String(pkg.version ?? '0'), subpaths, preamble, sections, entries };
88
- return cached;
31
+ const { version, modules } = loadModules(root);
32
+ return { root, version, modules, index: buildIndex(modules) };
89
33
  }
90
34
 
91
35
  const norm = (s: string) =>
@@ -94,47 +38,99 @@ const norm = (s: string) =>
94
38
  .replace(/^@zyncat\/ui\//, '')
95
39
  .replace(/[^a-z0-9]/g, '');
96
40
 
97
- function resolveSubpath(input: string): string {
98
- const d = db();
99
- const q = norm(input);
100
- if (!q) throw new Error('Pass a component name or subpath, e.g. "Button" or "text-field".');
101
- const candidates = new Map<string, string>();
102
- for (const sub of d.subpaths) candidates.set(norm(sub), sub);
103
- for (const e of d.entries) for (const part of e.title.split('/')) candidates.set(norm(part), e.subpath);
104
- const exact = candidates.get(q);
105
- if (exact) return exact;
106
- const loose = new Set<string>();
107
- for (const [name, sub] of candidates) if (name.includes(q) || q.includes(name)) loose.add(sub);
108
- if (loose.size === 1) return [...loose][0];
109
- const all = d.entries.map((e) => `${e.title} (${e.subpath})`).join(', ');
110
- const extras = d.subpaths.filter((s) => !d.entries.some((e) => e.subpath === s)).join(', ');
111
- throw new Error(
112
- (loose.size ? `"${input}" is ambiguous: ${[...loose].join(', ')}. ` : `No component matches "${input}". `) +
113
- `Available: ${all}${extras ? `; types-only modules: ${extras}` : ''}.`,
114
- );
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)];
115
76
  }
116
77
 
117
- 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 {
118
81
  const out: string[] = [];
119
82
  const seen = new Set<string>();
120
- const walk = (base: string) => {
121
- if (seen.has(base)) return;
122
- seen.add(base);
123
- const p = join(root, 'dist', `${base}.d.ts`);
124
- if (!existsSync(p)) return;
125
- const text = readFileSync(p, 'utf8');
126
- out.push(`--- dist/${base}.d.ts ---\n${text.trimEnd()}`);
127
- 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
+ }
128
98
  };
129
- walk(subpath);
99
+ walk(typesPath);
130
100
  if (!out.length) {
131
101
  throw new Error(
132
- `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.`,
133
103
  );
134
104
  }
135
105
  return out.join('\n\n');
136
106
  }
137
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
+
138
134
  const tokenFiles = (root: string): string[] =>
139
135
  existsSync(join(root, 'src/tokens'))
140
136
  ? readdirSync(join(root, 'src/tokens'))
@@ -142,112 +138,85 @@ const tokenFiles = (root: string): string[] =>
142
138
  .sort()
143
139
  : [];
144
140
 
145
- const CODE_LINE_RE = /^(?:[<{]|import\s|const\s|let\s|function\s)/;
146
-
147
- function entryTeaser(e: LlmsEntry): string {
148
- const parts: string[] = [];
149
- for (let i = 1; i < e.lines.length; i++) {
150
- const line = e.lines[i].trim();
151
- if (!line) break;
152
- if (i > 1 && CODE_LINE_RE.test(line)) break;
153
- parts.push(line);
154
- }
155
- return parts.join(' ');
141
+ interface Hit {
142
+ module: UsageModule;
143
+ score: number;
144
+ matched: Set<string>;
145
+ lines: string[];
156
146
  }
157
147
 
158
- function listComponents(): string {
159
- const d = db();
160
- const out: string[] = [...d.preamble, ''];
161
- for (const s of d.sections) {
162
- const inSection = d.entries.filter((e) => e.section === s.title);
163
- if (!inSection.length && !s.body.length) continue;
164
- out.push(`== ${s.title} ==`);
165
- out.push(...s.body);
166
- for (const e of inSection) {
167
- const first = entryTeaser(e);
168
- out.push(`${e.title} - @zyncat/ui/${e.subpath}${first ? ` - ${first}` : ''}`);
169
- }
170
- 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') });
171
152
  }
172
- const extras = d.subpaths.filter((sub) => !d.entries.some((e) => e.subpath === sub));
173
- if (extras.length) {
174
- out.push('== SUPPORTING MODULES (no llms.txt entry - full docs live in their types) ==');
175
- for (const sub of extras) out.push(`@zyncat/ui/${sub} - call get_component("${sub}")`);
176
- }
177
- return out.join('\n').trim();
178
- }
179
-
180
- function getComponent(input: string): string {
181
- const d = db();
182
- const sub = resolveSubpath(input);
183
- const entry = d.entries.find((e) => e.subpath === sub);
184
-
185
- const out: string[] = [`# ${entry ? entry.title : sub} - @zyncat/ui/${sub}`, ''];
186
- if (entry) {
187
- const note = d.sections.find((s) => s.title === entry.section)?.body ?? [];
188
- if (note.length) out.push(`Applies to every ${entry.section} component:`, ...note, '');
189
- out.push('## Usage (llms.txt)', ...entry.lines, '');
190
- } else {
191
- out.push('No llms.txt entry - this module is documented by its types below.', '');
192
- }
193
- out.push('## Types (entry .d.ts + the shared chunks it imports)', readTypes(d.root, sub));
194
- return out.join('\n');
153
+ try {
154
+ parts.push({ label: 'types', text: readTypes(d.root, m.typesPath) });
155
+ } catch {}
156
+ return parts;
195
157
  }
196
158
 
197
159
  function searchApi(query: string): string {
198
- const d = db();
199
160
  const words = query.toLowerCase().split(/\s+/).filter(Boolean);
200
161
  if (!words.length) throw new Error('Pass one or more keywords, e.g. "searchable" or "drag dismiss".');
201
- const hits = new Map<string, string[]>();
202
- const scan = (label: string, text: string, lineLabel?: (line: string, i: number) => string) => {
203
- text.split('\n').forEach((line, i) => {
204
- const l = line.toLowerCase();
205
- if (!words.every((w) => l.includes(w))) return;
206
- const key = lineLabel ? lineLabel(line, i) : label;
207
- if (!hits.has(key)) hits.set(key, []);
208
- hits.get(key)!.push(` L${i + 1}: ${line.trim()}`);
209
- });
210
- };
162
+ const d = db();
211
163
 
212
- {
213
- const raw = readFileSync(join(d.root, 'llms.txt'), 'utf8');
214
- const labels: string[] = [];
215
- let current = 'llms.txt';
216
- for (const line of raw.split('\n')) {
217
- const sec = line.match(SECTION_RE);
218
- const head = line.match(HEADING_RE);
219
- if (sec) current = `llms.txt » ${sec[1]}`;
220
- else if (head) current = `llms.txt » ${head[1].trim()}`;
221
- 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
+ }
222
191
  }
223
- scan('llms.txt', raw, (_line, i) => labels[i]);
192
+ if (hit.matched.size) hits.push(hit);
224
193
  }
225
- const distDir = join(d.root, 'dist');
226
- const dts = existsSync(distDir)
227
- ? readdirSync(distDir)
228
- .filter((f) => f.endsWith('.d.ts'))
229
- .sort()
230
- : [];
231
- for (const f of dts) scan(`dist/${f}`, readFileSync(join(distDir, f), 'utf8'));
232
- for (const f of tokenFiles(d.root)) scan(`src/tokens/${f}`, readFileSync(join(d.root, 'src/tokens', f), 'utf8'));
233
194
 
234
- const out: string[] = [];
235
- let shown = 0;
236
- let total = 0;
237
- for (const [, lines] of hits) total += lines.length;
238
- for (const [label, lines] of hits) {
239
- if (shown >= 60) break;
240
- out.push(`## ${label}`);
241
- for (const l of lines) {
242
- if (shown >= 60) break;
243
- out.push(l);
244
- 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()}`);
245
203
  }
246
204
  }
247
- if (!total) return `No matches for "${query}". Try a shorter keyword, or list_components for the full index.`;
248
- if (total > shown) out.push(`... +${total - shown} more matching lines - narrow the query.`);
249
- if (!dts.length) out.push('(note: dist/ is not built, so type definitions were not searched)');
250
- 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.`);
251
220
  return out.join('\n');
252
221
  }
253
222
 
@@ -271,38 +240,98 @@ function getTokens(group?: string): string {
271
240
  const out = picked.map(
272
241
  (f) => `/* ==== src/tokens/${f} ==== */\n${readFileSync(join(d.root, 'src/tokens', f), 'utf8').trimEnd()}`,
273
242
  );
274
- const theming = d.sections.find((s) => s.title.includes('THEMING'));
275
- 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()}`);
276
246
  return out.join('\n\n');
277
247
  }
278
248
 
279
- const TOOLS = [
280
- {
281
- name: 'list_components',
282
- description:
283
- '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.',
284
- inputSchema: { type: 'object', properties: {}, additionalProperties: false },
285
- },
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 = [
286
307
  {
287
308
  name: 'get_component',
288
309
  description:
289
- "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.',
290
315
  inputSchema: {
291
316
  type: 'object',
292
317
  properties: {
293
- component: {
294
- type: 'string',
295
- 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 }],
296
322
  },
297
323
  },
298
- required: ['component'],
324
+ required: ['components'],
299
325
  additionalProperties: false,
300
326
  },
301
327
  },
302
328
  {
303
329
  name: 'search_api',
304
330
  description:
305
- '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.',
306
335
  inputSchema: {
307
336
  type: 'object',
308
337
  properties: { query: { type: 'string', description: 'One or more keywords.' } },
@@ -313,7 +342,9 @@ const TOOLS = [
313
342
  {
314
343
  name: 'get_tokens',
315
344
  description:
316
- '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.',
317
348
  inputSchema: {
318
349
  type: 'object',
319
350
  properties: {
@@ -324,23 +355,80 @@ const TOOLS = [
324
355
  },
325
356
  ];
326
357
 
327
- const INSTRUCTIONS =
328
- 'Zyncat UI design-system API. Before writing Zyncat UI code, use these tools instead of reading ' +
329
- 'node_modules or guessing props: list_components (what exists + setup and conventions), get_component ' +
330
- '(one component: usage docs + complete prop types), search_api (find the component/prop/token for a ' +
331
- 'keyword), get_tokens (CSS custom-property vocabulary with real values, for theming). Imports are ' +
332
- '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
+ }
333
426
 
334
427
  function callTool(name: string, args: Record<string, unknown>): string {
335
428
  const str = (k: string) => (typeof args[k] === 'string' ? (args[k] as string) : undefined);
336
429
  switch (name) {
337
- case 'list_components':
338
- return listComponents();
339
- case 'get_component': {
340
- const component = str('component');
341
- if (!component) throw new Error('Missing required argument "component".');
342
- return getComponent(component);
343
- }
430
+ case 'get_component':
431
+ return getComponent(args.components ?? args.component);
344
432
  case 'search_api': {
345
433
  const query = str('query');
346
434
  if (!query) throw new Error('Missing required argument "query".');
@@ -348,6 +436,12 @@ function callTool(name: string, args: Record<string, unknown>): string {
348
436
  }
349
437
  case 'get_tokens':
350
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);
351
445
  default:
352
446
  throw new Error(`Unknown tool: ${name}`);
353
447
  }
@@ -377,13 +471,13 @@ function handle(req: { id?: RpcId; method?: string; params?: Record<string, unkn
377
471
  protocolVersion: typeof params?.protocolVersion === 'string' ? params.protocolVersion : '2025-06-18',
378
472
  capabilities: { tools: {} },
379
473
  serverInfo: { name: 'zyncat-ui', version },
380
- instructions: INSTRUCTIONS,
474
+ instructions: instructions(),
381
475
  });
382
476
  }
383
477
  case 'ping':
384
478
  return reply(id!, {});
385
479
  case 'tools/list':
386
- return reply(id!, { tools: TOOLS });
480
+ return reply(id!, { tools: tools() });
387
481
  case 'tools/call': {
388
482
  try {
389
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