@maz-ui/mcp 5.0.1-beta.0 → 5.1.0-beta.1

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 (343) hide show
  1. package/README.md +61 -228
  2. package/bin/maz-ui-mcp.mjs +2 -5
  3. package/dist/cli.d.mts +7 -0
  4. package/dist/cli.d.ts +7 -0
  5. package/dist/cli.mjs +16 -0
  6. package/dist/index.d.mts +345 -0
  7. package/dist/index.d.ts +345 -0
  8. package/dist/index.mjs +16 -0
  9. package/dist/shared/mcp.DseFuKdl.mjs +2968 -0
  10. package/docs/README.md +207 -0
  11. package/docs/agents/agents-md.md +52 -0
  12. package/docs/agents/claude-rule.md +52 -0
  13. package/docs/components/maz-accordion.md +78 -0
  14. package/docs/{src/components → components}/maz-alert.md +31 -164
  15. package/docs/components/maz-animated-counter.md +87 -0
  16. package/docs/components/maz-animated-element.md +46 -0
  17. package/docs/components/maz-animated-text.md +53 -0
  18. package/docs/components/maz-avatar.md +193 -0
  19. package/docs/components/maz-backdrop.md +178 -0
  20. package/docs/{src/components → components}/maz-badge.md +26 -67
  21. package/docs/components/maz-bottom-sheet.md +257 -0
  22. package/docs/{src/components → components}/maz-btn-group.md +27 -189
  23. package/docs/{src/components → components}/maz-btn.md +62 -245
  24. package/docs/components/maz-card-spotlight.md +84 -0
  25. package/docs/{src/components → components}/maz-card.md +67 -192
  26. package/docs/components/maz-carousel.md +153 -0
  27. package/docs/{src/components → components}/maz-chart.md +17 -161
  28. package/docs/components/maz-checkbox.md +138 -0
  29. package/docs/components/maz-checklist.md +251 -0
  30. package/docs/components/maz-circular-progress-bar.md +109 -0
  31. package/docs/{src/components → components}/maz-code-highlight.md +15 -93
  32. package/docs/components/maz-container.md +241 -0
  33. package/docs/{src/components → components}/maz-date-picker.md +85 -454
  34. package/docs/components/maz-dialog-confirm.md +215 -0
  35. package/docs/components/maz-dialog.md +143 -0
  36. package/docs/components/maz-drawer.md +107 -0
  37. package/docs/components/maz-dropdown.md +419 -0
  38. package/docs/{src/components → components}/maz-dropzone.md +80 -221
  39. package/docs/components/maz-expand-animation.md +82 -0
  40. package/docs/components/maz-fullscreen-loader.md +58 -0
  41. package/docs/components/maz-gallery.md +79 -0
  42. package/docs/{src/components → components}/maz-icon.md +32 -83
  43. package/docs/components/maz-input-code.md +73 -0
  44. package/docs/components/maz-input-number.md +79 -0
  45. package/docs/components/maz-input-phone-number.md +536 -0
  46. package/docs/components/maz-input-price.md +68 -0
  47. package/docs/components/maz-input-tags.md +112 -0
  48. package/docs/{src/components → components}/maz-input.md +74 -221
  49. package/docs/components/maz-lazy-img.md +113 -0
  50. package/docs/components/maz-link.md +146 -0
  51. package/docs/components/maz-loading-bar.md +38 -0
  52. package/docs/{src/components → components}/maz-markdown-editor.md +72 -125
  53. package/docs/components/maz-pagination.md +82 -0
  54. package/docs/components/maz-popover.md +794 -0
  55. package/docs/{src/components → components}/maz-pull-to-refresh.md +59 -45
  56. package/docs/components/maz-radio-buttons.md +313 -0
  57. package/docs/components/maz-radio.md +119 -0
  58. package/docs/{src/components → components}/maz-read-more.md +31 -122
  59. package/docs/components/maz-reading-progress-bar.md +96 -0
  60. package/docs/{src/components → components}/maz-select-country.md +80 -340
  61. package/docs/{src/components → components}/maz-select.md +76 -206
  62. package/docs/components/maz-sidebar-content.md +25 -0
  63. package/docs/components/maz-sidebar-footer.md +25 -0
  64. package/docs/components/maz-sidebar-group.md +27 -0
  65. package/docs/components/maz-sidebar-header.md +25 -0
  66. package/docs/components/maz-sidebar-menu-button.md +41 -0
  67. package/docs/components/maz-sidebar-menu-item.md +25 -0
  68. package/docs/components/maz-sidebar-menu-sub.md +32 -0
  69. package/docs/components/maz-sidebar-menu.md +25 -0
  70. package/docs/components/maz-sidebar-separator.md +21 -0
  71. package/docs/components/maz-sidebar-trigger.md +25 -0
  72. package/docs/{src/components → components}/maz-sidebar.md +117 -329
  73. package/docs/{src/components → components}/maz-skeleton.md +27 -156
  74. package/docs/{src/components → components}/maz-slider.md +33 -66
  75. package/docs/components/maz-spinner.md +84 -0
  76. package/docs/{src/components → components}/maz-stepper.md +48 -185
  77. package/docs/components/maz-switch.md +86 -0
  78. package/docs/components/maz-table-cell.md +27 -0
  79. package/docs/components/maz-table-row.md +28 -0
  80. package/docs/components/maz-table-title.md +27 -0
  81. package/docs/components/maz-table-virtualizer.md +31 -0
  82. package/docs/components/maz-table.md +426 -0
  83. package/docs/components/maz-tabs-bar.md +43 -0
  84. package/docs/components/maz-tabs-content-item.md +27 -0
  85. package/docs/components/maz-tabs-content.md +27 -0
  86. package/docs/{src/components → components}/maz-tabs.md +89 -126
  87. package/docs/components/maz-textarea.md +255 -0
  88. package/docs/components/maz-ticker.md +427 -0
  89. package/docs/components/maz-timeline.md +304 -0
  90. package/docs/components/maz-ui-provider.md +26 -0
  91. package/docs/{src/components → components}/maz-window-mockup.md +38 -105
  92. package/docs/composables/use-aos.md +41 -0
  93. package/docs/composables/use-breakpoints.md +42 -0
  94. package/docs/composables/use-dialog.md +58 -0
  95. package/docs/{src/composables → composables}/use-display-names.md +12 -59
  96. package/docs/{src/composables → composables}/use-drag.md +14 -68
  97. package/docs/{src/composables → composables}/use-form-validator.md +22 -696
  98. package/docs/{src/composables → composables}/use-idle-timeout.md +13 -97
  99. package/docs/{src/composables → composables}/use-pull-to-refresh.md +14 -7
  100. package/docs/{src/composables → composables}/use-reading-time.md +20 -56
  101. package/docs/composables/use-string-matching.md +41 -0
  102. package/docs/{src/composables → composables}/use-swipe.md +14 -81
  103. package/docs/{src/composables → composables}/use-timer.md +12 -38
  104. package/docs/composables/use-toast.md +50 -0
  105. package/docs/{src/composables → composables}/use-user-visibility.md +14 -56
  106. package/docs/composables/use-wait.md +50 -0
  107. package/docs/composables/use-window-size.md +25 -0
  108. package/docs/{src/directives → directives}/click-outside.md +13 -99
  109. package/docs/{src/directives → directives}/fullscreen-img.md +10 -28
  110. package/docs/{src/directives → directives}/lazy-img.md +14 -49
  111. package/docs/{src/directives → directives}/tooltip.md +12 -217
  112. package/docs/{src/directives → directives}/zoom-img.md +11 -38
  113. package/docs/{src/ecosystem → ecosystem}/eslint-config.md +37 -29
  114. package/docs/ecosystem/icons/icon-set.md +25 -0
  115. package/docs/{src/ecosystem → ecosystem}/icons/index.md +21 -15
  116. package/docs/ecosystem/mcp.md +165 -0
  117. package/docs/{src/ecosystem → ecosystem}/node/exec-promise.md +12 -6
  118. package/docs/ecosystem/node/index.md +53 -0
  119. package/docs/{src/ecosystem → ecosystem}/node/logger.md +12 -6
  120. package/docs/{src/ecosystem → ecosystem}/node/print-banner.md +12 -4
  121. package/docs/ecosystem/node/setup-agents.md +102 -0
  122. package/docs/{src/ecosystem → ecosystem}/nuxt.md +50 -19
  123. package/docs/{src/ecosystem → ecosystem}/stylelint-config.md +33 -25
  124. package/docs/{src/ecosystem → ecosystem}/themes.md +72 -235
  125. package/docs/{src/ecosystem → ecosystem}/translations.md +25 -23
  126. package/docs/ecosystem/utils/camel-case.md +37 -0
  127. package/docs/ecosystem/utils/capitalize.md +37 -0
  128. package/docs/{src/ecosystem → ecosystem}/utils/check-availability.md +14 -8
  129. package/docs/{src/ecosystem → ecosystem}/utils/cookie.md +18 -12
  130. package/docs/ecosystem/utils/country-code-to-unicode-flag.md +128 -0
  131. package/docs/{src/ecosystem → ecosystem}/utils/currency.md +12 -26
  132. package/docs/{src/ecosystem → ecosystem}/utils/date.md +10 -24
  133. package/docs/ecosystem/utils/debounce-callback.md +44 -0
  134. package/docs/{src/ecosystem → ecosystem}/utils/debounce-id.md +14 -8
  135. package/docs/{src/ecosystem → ecosystem}/utils/debounce.md +14 -8
  136. package/docs/ecosystem/utils/fetch-locale-ip.md +39 -0
  137. package/docs/{src/ecosystem → ecosystem}/utils/format-json.md +11 -5
  138. package/docs/{src/ecosystem → ecosystem}/utils/format-phone-number.md +12 -6
  139. package/docs/ecosystem/utils/get-browser-locale.md +35 -0
  140. package/docs/ecosystem/utils/get-country-flag-url.md +67 -0
  141. package/docs/{src/ecosystem → ecosystem}/utils/get-error-message.md +10 -4
  142. package/docs/{src/ecosystem → ecosystem}/utils/idle-timeout.md +15 -9
  143. package/docs/{src/ecosystem → ecosystem}/utils/index.md +10 -13
  144. package/docs/{src/ecosystem → ecosystem}/utils/is-client.md +11 -5
  145. package/docs/{src/ecosystem → ecosystem}/utils/is-equal.md +14 -8
  146. package/docs/{src/ecosystem → ecosystem}/utils/is-ios.md +12 -6
  147. package/docs/ecosystem/utils/is-server.md +37 -0
  148. package/docs/ecosystem/utils/is-standalone-mode.md +49 -0
  149. package/docs/{src/ecosystem → ecosystem}/utils/kebab-case.md +10 -4
  150. package/docs/{src/ecosystem → ecosystem}/utils/normalize-string.md +10 -4
  151. package/docs/{src/ecosystem → ecosystem}/utils/number.md +10 -24
  152. package/docs/{src/ecosystem → ecosystem}/utils/pascal-case.md +11 -5
  153. package/docs/{src/ecosystem → ecosystem}/utils/prevent-ios-input-zoom.md +14 -8
  154. package/docs/{src/ecosystem → ecosystem}/utils/script-loader.md +16 -8
  155. package/docs/{src/ecosystem → ecosystem}/utils/sleep.md +10 -4
  156. package/docs/{src/ecosystem → ecosystem}/utils/snake-case.md +10 -4
  157. package/docs/{src/ecosystem → ecosystem}/utils/swipe-handler.md +14 -8
  158. package/docs/{src/ecosystem → ecosystem}/utils/textarea-autogrow.md +12 -6
  159. package/docs/{src/ecosystem → ecosystem}/utils/throttle-id.md +13 -7
  160. package/docs/{src/ecosystem → ecosystem}/utils/throttle.md +14 -8
  161. package/docs/ecosystem/utils/truthy-filter.md +37 -0
  162. package/docs/{src/ecosystem → ecosystem}/utils/types/deep-key-of.md +11 -5
  163. package/docs/{src/ecosystem → ecosystem}/utils/types/deep-partial.md +10 -4
  164. package/docs/ecosystem/utils/types/deep-required.md +45 -0
  165. package/docs/ecosystem/utils/types/flatten-object-keys.md +50 -0
  166. package/docs/{src/ecosystem → ecosystem}/utils/types/generic-instance-type.md +10 -4
  167. package/docs/{src/ecosystem → ecosystem}/utils/types/infer-maybe-ref.md +10 -4
  168. package/docs/ecosystem/utils/upper-first.md +38 -0
  169. package/docs/{src/ecosystem → ecosystem}/utils/user-visibility.md +12 -6
  170. package/docs/guide/ai-agents.md +239 -0
  171. package/docs/{src/guide → guide}/browser-support.md +22 -15
  172. package/docs/{src/guide → guide}/getting-started.md +34 -139
  173. package/docs/{src/guide → guide}/global-defaults.md +12 -11
  174. package/docs/{src/guide → guide}/maz-ui-provider.md +17 -16
  175. package/docs/{src/guide → guide}/migration-v5.md +95 -88
  176. package/docs/{src/guide → guide}/resolvers.md +33 -100
  177. package/docs/guide/tailwind.md +507 -0
  178. package/docs/{src/guide → guide}/vue.md +33 -39
  179. package/docs/manifest.json +1 -0
  180. package/docs/{src/plugins → plugins}/aos.md +20 -55
  181. package/docs/{src/plugins → plugins}/dialog.md +14 -161
  182. package/docs/plugins/toast.md +221 -0
  183. package/docs/plugins/wait.md +78 -0
  184. package/docs/reference/icons.md +46 -0
  185. package/docs/reference/tailwind-tokens.md +191 -0
  186. package/docs/rules.md +59 -0
  187. package/package.json +86 -22
  188. package/dist/mcp.d.mts +0 -153
  189. package/dist/mcp.d.ts +0 -153
  190. package/dist/mcp.mjs +0 -1511
  191. package/docs/generated-docs/maz-accordion.doc.md +0 -21
  192. package/docs/generated-docs/maz-alert.doc.md +0 -20
  193. package/docs/generated-docs/maz-animated-counter.doc.md +0 -17
  194. package/docs/generated-docs/maz-animated-element.doc.md +0 -14
  195. package/docs/generated-docs/maz-animated-text.doc.md +0 -17
  196. package/docs/generated-docs/maz-avatar.doc.md +0 -45
  197. package/docs/generated-docs/maz-backdrop.doc.md +0 -55
  198. package/docs/generated-docs/maz-badge.doc.md +0 -16
  199. package/docs/generated-docs/maz-bottom-sheet.doc.md +0 -24
  200. package/docs/generated-docs/maz-btn-group.doc.md +0 -20
  201. package/docs/generated-docs/maz-btn.doc.md +0 -33
  202. package/docs/generated-docs/maz-card-spotlight.doc.md +0 -16
  203. package/docs/generated-docs/maz-card.doc.md +0 -39
  204. package/docs/generated-docs/maz-carousel.doc.md +0 -17
  205. package/docs/generated-docs/maz-chart.doc.md +0 -10
  206. package/docs/generated-docs/maz-checkbox.doc.md +0 -33
  207. package/docs/generated-docs/maz-checklist.doc.md +0 -30
  208. package/docs/generated-docs/maz-circular-progress-bar.doc.md +0 -27
  209. package/docs/generated-docs/maz-code-highlight.doc.md +0 -11
  210. package/docs/generated-docs/maz-container.doc.md +0 -26
  211. package/docs/generated-docs/maz-date-picker.doc.md +0 -56
  212. package/docs/generated-docs/maz-dialog-confirm.doc.md +0 -24
  213. package/docs/generated-docs/maz-dialog.doc.md +0 -22
  214. package/docs/generated-docs/maz-drawer.doc.md +0 -25
  215. package/docs/generated-docs/maz-dropdown.doc.md +0 -45
  216. package/docs/generated-docs/maz-dropzone.doc.md +0 -82
  217. package/docs/generated-docs/maz-expand-animation.doc.md +0 -12
  218. package/docs/generated-docs/maz-fullscreen-loader.doc.md +0 -13
  219. package/docs/generated-docs/maz-gallery.doc.md +0 -17
  220. package/docs/generated-docs/maz-icon.doc.md +0 -16
  221. package/docs/generated-docs/maz-input-code.doc.md +0 -25
  222. package/docs/generated-docs/maz-input-number.doc.md +0 -33
  223. package/docs/generated-docs/maz-input-phone-number.doc.md +0 -62
  224. package/docs/generated-docs/maz-input-price.doc.md +0 -26
  225. package/docs/generated-docs/maz-input-tags.doc.md +0 -24
  226. package/docs/generated-docs/maz-input.doc.md +0 -54
  227. package/docs/generated-docs/maz-lazy-img.doc.md +0 -49
  228. package/docs/generated-docs/maz-link.doc.md +0 -31
  229. package/docs/generated-docs/maz-loading-bar.doc.md +0 -6
  230. package/docs/generated-docs/maz-markdown-editor.doc.md +0 -65
  231. package/docs/generated-docs/maz-pagination.doc.md +0 -21
  232. package/docs/generated-docs/maz-popover.doc.md +0 -79
  233. package/docs/generated-docs/maz-pull-to-refresh.doc.md +0 -50
  234. package/docs/generated-docs/maz-radio-buttons.doc.md +0 -34
  235. package/docs/generated-docs/maz-radio.doc.md +0 -33
  236. package/docs/generated-docs/maz-read-more.doc.md +0 -18
  237. package/docs/generated-docs/maz-reading-progress-bar.doc.md +0 -18
  238. package/docs/generated-docs/maz-select-country.doc.md +0 -45
  239. package/docs/generated-docs/maz-select.doc.md +0 -32
  240. package/docs/generated-docs/maz-sidebar-content.doc.md +0 -5
  241. package/docs/generated-docs/maz-sidebar-footer.doc.md +0 -5
  242. package/docs/generated-docs/maz-sidebar-group.doc.md +0 -11
  243. package/docs/generated-docs/maz-sidebar-header.doc.md +0 -5
  244. package/docs/generated-docs/maz-sidebar-menu-button.doc.md +0 -27
  245. package/docs/generated-docs/maz-sidebar-menu-item.doc.md +0 -5
  246. package/docs/generated-docs/maz-sidebar-menu-sub.doc.md +0 -16
  247. package/docs/generated-docs/maz-sidebar-menu.doc.md +0 -5
  248. package/docs/generated-docs/maz-sidebar-separator.doc.md +0 -0
  249. package/docs/generated-docs/maz-sidebar-trigger.doc.md +0 -5
  250. package/docs/generated-docs/maz-sidebar.doc.md +0 -36
  251. package/docs/generated-docs/maz-skeleton.doc.md +0 -12
  252. package/docs/generated-docs/maz-slider.doc.md +0 -20
  253. package/docs/generated-docs/maz-spinner.doc.md +0 -6
  254. package/docs/generated-docs/maz-stepper.doc.md +0 -30
  255. package/docs/generated-docs/maz-switch.doc.md +0 -31
  256. package/docs/generated-docs/maz-table-cell.doc.md +0 -5
  257. package/docs/generated-docs/maz-table-row.doc.md +0 -12
  258. package/docs/generated-docs/maz-table-title.doc.md +0 -5
  259. package/docs/generated-docs/maz-table-virtualizer.doc.md +0 -20
  260. package/docs/generated-docs/maz-table.doc.md +0 -72
  261. package/docs/generated-docs/maz-tabs-bar.doc.md +0 -29
  262. package/docs/generated-docs/maz-tabs-content-item.doc.md +0 -11
  263. package/docs/generated-docs/maz-tabs-content.doc.md +0 -5
  264. package/docs/generated-docs/maz-tabs.doc.md +0 -20
  265. package/docs/generated-docs/maz-textarea.doc.md +0 -46
  266. package/docs/generated-docs/maz-ticker.doc.md +0 -25
  267. package/docs/generated-docs/maz-timeline.doc.md +0 -32
  268. package/docs/generated-docs/maz-ui-provider.doc.md +0 -12
  269. package/docs/generated-docs/maz-window-mockup.doc.md +0 -23
  270. package/docs/src/blog/v4.md +0 -276
  271. package/docs/src/blog/v5.md +0 -184
  272. package/docs/src/changelog.md +0 -7
  273. package/docs/src/components/index.md +0 -8
  274. package/docs/src/components/maz-accordion.md +0 -80
  275. package/docs/src/components/maz-animated-counter.md +0 -124
  276. package/docs/src/components/maz-animated-element.md +0 -36
  277. package/docs/src/components/maz-animated-text.md +0 -36
  278. package/docs/src/components/maz-avatar.md +0 -227
  279. package/docs/src/components/maz-backdrop.md +0 -250
  280. package/docs/src/components/maz-bottom-sheet.md +0 -533
  281. package/docs/src/components/maz-card-spotlight.md +0 -163
  282. package/docs/src/components/maz-carousel.md +0 -231
  283. package/docs/src/components/maz-checkbox.md +0 -168
  284. package/docs/src/components/maz-checklist.md +0 -414
  285. package/docs/src/components/maz-circular-progress-bar.md +0 -145
  286. package/docs/src/components/maz-container.md +0 -363
  287. package/docs/src/components/maz-dialog-confirm.md +0 -240
  288. package/docs/src/components/maz-dialog.md +0 -164
  289. package/docs/src/components/maz-drawer.md +0 -181
  290. package/docs/src/components/maz-dropdown.md +0 -691
  291. package/docs/src/components/maz-expand-animation.md +0 -99
  292. package/docs/src/components/maz-fullscreen-loader.md +0 -58
  293. package/docs/src/components/maz-gallery.md +0 -85
  294. package/docs/src/components/maz-input-code.md +0 -61
  295. package/docs/src/components/maz-input-number.md +0 -81
  296. package/docs/src/components/maz-input-phone-number.md +0 -942
  297. package/docs/src/components/maz-input-price.md +0 -67
  298. package/docs/src/components/maz-input-tags.md +0 -114
  299. package/docs/src/components/maz-lazy-img.md +0 -88
  300. package/docs/src/components/maz-link.md +0 -178
  301. package/docs/src/components/maz-loading-bar.md +0 -26
  302. package/docs/src/components/maz-pagination.md +0 -79
  303. package/docs/src/components/maz-popover.md +0 -1416
  304. package/docs/src/components/maz-radio-buttons.md +0 -462
  305. package/docs/src/components/maz-radio.md +0 -142
  306. package/docs/src/components/maz-reading-progress-bar.md +0 -74
  307. package/docs/src/components/maz-spinner.md +0 -93
  308. package/docs/src/components/maz-switch.md +0 -92
  309. package/docs/src/components/maz-table.md +0 -732
  310. package/docs/src/components/maz-textarea.md +0 -400
  311. package/docs/src/components/maz-ticker.md +0 -692
  312. package/docs/src/components/maz-timeline.md +0 -478
  313. package/docs/src/composables/use-aos.md +0 -34
  314. package/docs/src/composables/use-breakpoints.md +0 -35
  315. package/docs/src/composables/use-dialog.md +0 -88
  316. package/docs/src/composables/use-string-matching.md +0 -63
  317. package/docs/src/composables/use-toast.md +0 -71
  318. package/docs/src/composables/use-wait.md +0 -62
  319. package/docs/src/composables/use-window-size.md +0 -18
  320. package/docs/src/ecosystem/icons/icon-set.md +0 -123
  321. package/docs/src/ecosystem/mcp.md +0 -210
  322. package/docs/src/ecosystem/node/index.md +0 -53
  323. package/docs/src/ecosystem/utils/camel-case.md +0 -31
  324. package/docs/src/ecosystem/utils/capitalize.md +0 -50
  325. package/docs/src/ecosystem/utils/country-code-to-unicode-flag.md +0 -213
  326. package/docs/src/ecosystem/utils/debounce-callback.md +0 -38
  327. package/docs/src/ecosystem/utils/fetch-locale-ip.md +0 -33
  328. package/docs/src/ecosystem/utils/get-browser-locale.md +0 -29
  329. package/docs/src/ecosystem/utils/get-country-flag-url.md +0 -156
  330. package/docs/src/ecosystem/utils/is-server.md +0 -31
  331. package/docs/src/ecosystem/utils/is-standalone-mode.md +0 -43
  332. package/docs/src/ecosystem/utils/truthy-filter.md +0 -31
  333. package/docs/src/ecosystem/utils/types/deep-required.md +0 -39
  334. package/docs/src/ecosystem/utils/types/flatten-object-keys.md +0 -44
  335. package/docs/src/ecosystem/utils/upper-first.md +0 -32
  336. package/docs/src/guide/cli.md +0 -144
  337. package/docs/src/guide/migration-v4.md +0 -925
  338. package/docs/src/guide/tailwind.md +0 -158
  339. package/docs/src/index.md +0 -603
  340. package/docs/src/made-with-maz-ui.md +0 -58
  341. package/docs/src/plugins/toast.md +0 -349
  342. package/docs/src/plugins/wait.md +0 -109
  343. package/docs/src/theme-editor.md +0 -21
package/dist/mcp.mjs DELETED
@@ -1,1511 +0,0 @@
1
- #!/usr/bin/env node
2
- import { getErrorMessage } from '@maz-ui/utils/helpers/getErrorMessage';
3
- import { Server } from '@modelcontextprotocol/sdk/server/index.js';
4
- import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
5
- import { ListResourcesRequestSchema, ReadResourceRequestSchema, ListToolsRequestSchema, CallToolRequestSchema } from '@modelcontextprotocol/sdk/types.js';
6
- import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
7
- import { resolve, join, dirname } from 'node:path';
8
- import { fileURLToPath } from 'node:url';
9
-
10
- const version = "5.0.0";
11
-
12
- class MetadataExtractor {
13
- extract(name, type, content, manualTags = []) {
14
- const frontmatter = this.extractFrontmatter(content);
15
- const sections = this.extractSections(content);
16
- const props = this.extractProps(content);
17
- const slots = this.extractSlots(content);
18
- const events = this.extractEvents(content);
19
- const displayName = frontmatter.title ?? this.nameToDisplayName(name);
20
- const description = frontmatter.description ?? this.extractFirstParagraph(content);
21
- const extractedTags = this.buildTags(name, displayName, props, slots, events);
22
- const tags = this.mergeTags(manualTags, extractedTags);
23
- return {
24
- name,
25
- displayName,
26
- type,
27
- description,
28
- tags,
29
- ...props.length > 0 && { props },
30
- ...slots.length > 0 && { slots },
31
- ...events.length > 0 && { events },
32
- sections
33
- };
34
- }
35
- extractFrontmatter(content) {
36
- const match = content.match(/^---\n([\s\S]*?)\n---/);
37
- if (!match) {
38
- return {};
39
- }
40
- const result = {};
41
- const yaml = match[1];
42
- for (const line of yaml.split("\n")) {
43
- const trimmed = line.trim();
44
- if (trimmed.startsWith("title:")) {
45
- result.title = trimmed.slice("title:".length).trim();
46
- } else if (trimmed.startsWith("description:")) {
47
- result.description = trimmed.slice("description:".length).trim();
48
- }
49
- }
50
- return result;
51
- }
52
- extractSections(content) {
53
- const sections = [];
54
- const contentWithoutFrontmatter = this.stripFrontmatter(content);
55
- const lines = contentWithoutFrontmatter.split("\n");
56
- let currentSection;
57
- const flushSection = () => {
58
- if (currentSection) {
59
- const sectionContent = currentSection.contentLines.join("\n").trim();
60
- sections.push({
61
- title: currentSection.title,
62
- level: currentSection.level,
63
- content: this.extractSectionLeadText(sectionContent)
64
- });
65
- }
66
- };
67
- for (const line of lines) {
68
- const headingMatch = line.match(/^(#{2,3}) +(\S.*)$/);
69
- if (headingMatch) {
70
- flushSection();
71
- currentSection = {
72
- level: headingMatch[1].length,
73
- title: this.cleanHeadingText(headingMatch[2]),
74
- contentLines: []
75
- };
76
- } else if (currentSection) {
77
- currentSection.contentLines.push(line);
78
- }
79
- }
80
- flushSection();
81
- return sections;
82
- }
83
- extractProps(content) {
84
- return this.extractTableColumn(content, "Props", "Name");
85
- }
86
- extractSlots(content) {
87
- return this.extractTableColumn(content, "Slots", "Name");
88
- }
89
- extractEvents(content) {
90
- return this.extractTableColumn(content, "Events", "Event name");
91
- }
92
- mergeTags(manualTags, extractedTags) {
93
- const tagSet = /* @__PURE__ */ new Set();
94
- for (const tag of manualTags) {
95
- tagSet.add(tag.toLowerCase());
96
- }
97
- for (const tag of extractedTags) {
98
- tagSet.add(tag.toLowerCase());
99
- }
100
- return Array.from(tagSet);
101
- }
102
- extractTableColumn(content, sectionName, columnName) {
103
- const sectionRegex = new RegExp(`## ${sectionName} *\\n`, "i");
104
- const sectionMatch = content.match(sectionRegex);
105
- if (!sectionMatch || sectionMatch.index === void 0) {
106
- return [];
107
- }
108
- const afterSection = content.slice(sectionMatch.index + sectionMatch[0].length);
109
- const lines = afterSection.split("\n");
110
- const headerLine = lines.find((l) => l.includes("|") && l.toLowerCase().includes(columnName.toLowerCase()));
111
- if (!headerLine) {
112
- return [];
113
- }
114
- const headerIndex = lines.indexOf(headerLine);
115
- const columns = headerLine.split("|").map((c) => c.trim()).filter(Boolean);
116
- const nameColumnIndex = columns.findIndex((c) => c.toLowerCase().includes(columnName.toLowerCase()));
117
- if (nameColumnIndex === -1) {
118
- return [];
119
- }
120
- const results = [];
121
- for (let i = headerIndex + 2; i < lines.length; i++) {
122
- const line = lines[i];
123
- if (!line.includes("|") || line.match(/^#{1,6}\s/)) {
124
- break;
125
- }
126
- if (line.match(/^ *\|[-\s|]+\| *$/)) {
127
- continue;
128
- }
129
- const cells = line.split("|").map((c) => c.trim()).filter(Boolean);
130
- if (cells[nameColumnIndex]) {
131
- const name = cells[nameColumnIndex].replace(/\*\*/g, "").trim();
132
- if (name) {
133
- results.push(name);
134
- }
135
- }
136
- }
137
- return results;
138
- }
139
- stripFrontmatter(content) {
140
- return content.replace(/^---\n[\s\S]*?\n---\n?/, "");
141
- }
142
- cleanHeadingText(text) {
143
- let result = this.removeTemplateTags(text);
144
- result = this.resolveMarkdownLinks(result);
145
- return result.trim();
146
- }
147
- removeTemplateTags(text) {
148
- let result = "";
149
- let i = 0;
150
- while (i < text.length) {
151
- if (text[i] === "{" && text[i + 1] === "{") {
152
- const end = text.indexOf("}}", i + 2);
153
- i = end === -1 ? text.length : end + 2;
154
- } else {
155
- result += text[i];
156
- i++;
157
- }
158
- }
159
- return result;
160
- }
161
- resolveMarkdownLinks(text) {
162
- let result = "";
163
- let i = 0;
164
- while (i < text.length) {
165
- if (text[i] === "[") {
166
- const closeBracket = text.indexOf("]", i + 1);
167
- if (closeBracket !== -1 && text[closeBracket + 1] === "(") {
168
- const closeParen = text.indexOf(")", closeBracket + 2);
169
- if (closeParen !== -1) {
170
- result += text.slice(i + 1, closeBracket);
171
- i = closeParen + 1;
172
- continue;
173
- }
174
- }
175
- }
176
- result += text[i];
177
- i++;
178
- }
179
- return result;
180
- }
181
- extractSectionLeadText(content) {
182
- const lines = content.split("\n");
183
- const paragraphLines = [];
184
- for (const line of lines) {
185
- const trimmed = line.trim();
186
- if (!trimmed) {
187
- if (paragraphLines.length > 0) {
188
- break;
189
- }
190
- continue;
191
- }
192
- if (trimmed.startsWith("#") || trimmed.startsWith("<") || trimmed.startsWith("```") || trimmed.startsWith(":::") || trimmed.startsWith("|")) {
193
- if (paragraphLines.length > 0) {
194
- break;
195
- }
196
- continue;
197
- }
198
- paragraphLines.push(trimmed);
199
- }
200
- return paragraphLines.join(" ");
201
- }
202
- extractFirstParagraph(content) {
203
- const stripped = this.stripFrontmatter(content);
204
- const lines = stripped.split("\n");
205
- const paragraphLines = [];
206
- for (const line of lines) {
207
- const trimmed = line.trim();
208
- if (!trimmed) {
209
- if (paragraphLines.length > 0) {
210
- break;
211
- }
212
- continue;
213
- }
214
- if (trimmed.startsWith("#") || trimmed.startsWith("<") || trimmed.startsWith("```") || trimmed.startsWith(":::") || trimmed.startsWith("|") || trimmed.startsWith("{{")) {
215
- if (paragraphLines.length > 0) {
216
- break;
217
- }
218
- continue;
219
- }
220
- paragraphLines.push(trimmed);
221
- }
222
- return paragraphLines.join(" ");
223
- }
224
- nameToDisplayName(name) {
225
- return name.split("-").map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("");
226
- }
227
- buildTags(name, displayName, props, slots, events) {
228
- const tags = [name, displayName.toLowerCase()];
229
- for (const prop of props.slice(0, 10)) {
230
- tags.push(`prop:${prop}`);
231
- }
232
- for (const slot of slots.slice(0, 10)) {
233
- tags.push(`slot:${slot}`);
234
- }
235
- for (const event of events.slice(0, 10)) {
236
- tags.push(`event:${event}`);
237
- }
238
- return tags;
239
- }
240
- }
241
-
242
- const _dirname = dirname(fileURLToPath(import.meta.url));
243
- class DocumentationService {
244
- docsRoot;
245
- componentsDir;
246
- generatedDocsDir;
247
- guidesDir;
248
- composablesDir;
249
- directivesDir;
250
- pluginsDir;
251
- ecosystemDir;
252
- utilsDir;
253
- utilsTypesDir;
254
- nodeDir;
255
- iconsDir;
256
- metadataExtractor = new MetadataExtractor();
257
- constructor() {
258
- const localDocsRoot = resolve(_dirname, "../docs/src");
259
- const localGeneratedDocsDir = resolve(_dirname, "../docs/generated-docs");
260
- this.docsRoot = localDocsRoot;
261
- this.generatedDocsDir = localGeneratedDocsDir;
262
- this.componentsDir = join(this.docsRoot, "components");
263
- this.guidesDir = join(this.docsRoot, "guide");
264
- this.composablesDir = join(this.docsRoot, "composables");
265
- this.directivesDir = join(this.docsRoot, "directives");
266
- this.pluginsDir = join(this.docsRoot, "plugins");
267
- this.ecosystemDir = join(this.docsRoot, "ecosystem");
268
- this.utilsDir = join(this.ecosystemDir, "utils");
269
- this.utilsTypesDir = join(this.utilsDir, "types");
270
- this.nodeDir = join(this.ecosystemDir, "node");
271
- this.iconsDir = join(this.ecosystemDir, "icons");
272
- }
273
- pascalToKebabCase(pascalName) {
274
- return pascalName.replace(/([A-Z])/g, "-$1").toLowerCase().replace(/^-/, "");
275
- }
276
- readMarkdownFile(filePath) {
277
- try {
278
- if (!existsSync(filePath)) {
279
- return "";
280
- }
281
- return readFileSync(filePath, "utf-8");
282
- } catch {
283
- return "";
284
- }
285
- }
286
- listMarkdownFiles(dirPath, options = {}) {
287
- try {
288
- if (!existsSync(dirPath)) {
289
- return [];
290
- }
291
- const entries = readdirSync(dirPath);
292
- return entries.filter((entry) => {
293
- if (!entry.endsWith(".md"))
294
- return false;
295
- if (!options.keepIndex && entry === "index.md")
296
- return false;
297
- const fullPath = join(dirPath, entry);
298
- return statSync(fullPath).isFile();
299
- }).map((file) => file.replace(".md", "")).sort();
300
- } catch {
301
- return [];
302
- }
303
- }
304
- // ========== COMPONENTS ==========
305
- getComponentDocumentation(componentName) {
306
- const kebabName = componentName.startsWith("Maz") ? this.pascalToKebabCase(componentName) : componentName;
307
- const manualDocPath = join(this.componentsDir, `${kebabName}.md`);
308
- const generatedDocPath = join(this.generatedDocsDir, `${kebabName}.doc.md`);
309
- const [manualDoc, generatedDoc] = [
310
- this.readMarkdownFile(manualDocPath),
311
- this.readMarkdownFile(generatedDocPath)
312
- ];
313
- if (!manualDoc && !generatedDoc) {
314
- return "";
315
- }
316
- let combinedDoc = "";
317
- if (manualDoc) {
318
- combinedDoc += `${manualDoc}
319
-
320
- `;
321
- }
322
- if (generatedDoc) {
323
- combinedDoc += `---
324
-
325
- # API Reference
326
-
327
- ${generatedDoc}`;
328
- }
329
- return combinedDoc.trim();
330
- }
331
- getAllComponents() {
332
- const [manualFiles, generatedFiles] = [
333
- this.listMarkdownFiles(this.componentsDir),
334
- this.listMarkdownFiles(this.generatedDocsDir).map((file) => file.replace(".doc", ""))
335
- ];
336
- const allComponents = /* @__PURE__ */ new Set([...manualFiles, ...generatedFiles]);
337
- return Array.from(allComponents).sort();
338
- }
339
- // ========== GUIDES ==========
340
- // Aggregates: guide/*.md + ecosystem/*.md (standalone) + ecosystem/icons/*.md (index.md → 'icons')
341
- getGuideDocumentation(guideName) {
342
- const candidates = [
343
- join(this.guidesDir, `${guideName}.md`),
344
- join(this.ecosystemDir, `${guideName}.md`),
345
- join(this.iconsDir, `${guideName}.md`)
346
- ];
347
- if (guideName === "icons") {
348
- candidates.push(join(this.iconsDir, "index.md"));
349
- }
350
- for (const path of candidates) {
351
- const content = this.readMarkdownFile(path);
352
- if (content)
353
- return content;
354
- }
355
- return "";
356
- }
357
- getAllGuides() {
358
- const guides = /* @__PURE__ */ new Set();
359
- for (const name of this.listMarkdownFiles(this.guidesDir)) {
360
- guides.add(name);
361
- }
362
- for (const name of this.listMarkdownFiles(this.ecosystemDir)) {
363
- guides.add(name);
364
- }
365
- for (const name of this.listMarkdownFiles(this.iconsDir)) {
366
- guides.add(name);
367
- }
368
- if (existsSync(join(this.iconsDir, "index.md"))) {
369
- guides.add("icons");
370
- }
371
- return Array.from(guides).sort();
372
- }
373
- // ========== COMPOSABLES ==========
374
- getComposableDocumentation(composableName) {
375
- const composablePath = join(this.composablesDir, `${composableName}.md`);
376
- return this.readMarkdownFile(composablePath);
377
- }
378
- getAllComposables() {
379
- return this.listMarkdownFiles(this.composablesDir);
380
- }
381
- // ========== DIRECTIVES ==========
382
- getDirectiveDocumentation(directiveName) {
383
- const directivePath = join(this.directivesDir, `${directiveName}.md`);
384
- return this.readMarkdownFile(directivePath);
385
- }
386
- getAllDirectives() {
387
- return this.listMarkdownFiles(this.directivesDir);
388
- }
389
- // ========== PLUGINS ==========
390
- getPluginDocumentation(pluginName) {
391
- const pluginPath = join(this.pluginsDir, `${pluginName}.md`);
392
- return this.readMarkdownFile(pluginPath);
393
- }
394
- getAllPlugins() {
395
- return this.listMarkdownFiles(this.pluginsDir);
396
- }
397
- // ========== UTILS ==========
398
- // Aggregates: ecosystem/utils/*.md + ecosystem/utils/types/*.md
399
- getUtilDocumentation(utilName) {
400
- const candidates = [
401
- join(this.utilsDir, `${utilName}.md`),
402
- join(this.utilsTypesDir, `${utilName}.md`)
403
- ];
404
- for (const path of candidates) {
405
- const content = this.readMarkdownFile(path);
406
- if (content)
407
- return content;
408
- }
409
- return "";
410
- }
411
- getAllUtils() {
412
- const utils = /* @__PURE__ */ new Set([
413
- ...this.listMarkdownFiles(this.utilsDir),
414
- ...this.listMarkdownFiles(this.utilsTypesDir)
415
- ]);
416
- return Array.from(utils).sort();
417
- }
418
- // ========== NODE ==========
419
- getNodeDocumentation(nodeName) {
420
- const nodePath = join(this.nodeDir, `${nodeName}.md`);
421
- return this.readMarkdownFile(nodePath);
422
- }
423
- getAllNode() {
424
- return this.listMarkdownFiles(this.nodeDir);
425
- }
426
- // ========== UNIFIED LOADING ==========
427
- getAllDocuments() {
428
- const documents = [];
429
- for (const name of this.getAllComponents()) {
430
- const content = this.getComponentDocumentation(name);
431
- if (content) {
432
- documents.push(this.buildDocument(name, "component", content));
433
- }
434
- }
435
- const categories = [
436
- { type: "guide", names: this.getAllGuides(), getContent: (name) => this.getGuideDocumentation(name) },
437
- { type: "composable", names: this.getAllComposables(), getContent: (name) => this.getComposableDocumentation(name) },
438
- { type: "directive", names: this.getAllDirectives(), getContent: (name) => this.getDirectiveDocumentation(name) },
439
- { type: "plugin", names: this.getAllPlugins(), getContent: (name) => this.getPluginDocumentation(name) },
440
- { type: "util", names: this.getAllUtils(), getContent: (name) => this.getUtilDocumentation(name) },
441
- { type: "node", names: this.getAllNode(), getContent: (name) => this.getNodeDocumentation(name) }
442
- ];
443
- for (const category of categories) {
444
- for (const name of category.names) {
445
- const content = category.getContent(name);
446
- if (content) {
447
- documents.push(this.buildDocument(name, category.type, content));
448
- }
449
- }
450
- }
451
- return documents;
452
- }
453
- buildDocument(name, type, content) {
454
- return {
455
- name,
456
- type,
457
- content,
458
- metadata: this.metadataExtractor.extract(name, type, content)
459
- };
460
- }
461
- // ========== UTILITAIRES ==========
462
- getOverview() {
463
- const overviewPath = join(this.docsRoot, "index.md");
464
- return this.readMarkdownFile(overviewPath);
465
- }
466
- searchDocumentation(query) {
467
- const searchTerm = query.toLowerCase();
468
- const results = [];
469
- const buckets = [
470
- { type: "component", names: this.getAllComponents() },
471
- { type: "guide", names: this.getAllGuides() },
472
- { type: "composable", names: this.getAllComposables() },
473
- { type: "directive", names: this.getAllDirectives() },
474
- { type: "plugin", names: this.getAllPlugins() },
475
- { type: "util", names: this.getAllUtils() },
476
- { type: "node", names: this.getAllNode() }
477
- ];
478
- for (const { type, names } of buckets) {
479
- for (const name of names) {
480
- if (name.toLowerCase().includes(searchTerm)) {
481
- results.push(`${type}:${name}`);
482
- }
483
- }
484
- }
485
- return results;
486
- }
487
- getDiagnostics() {
488
- const [components, guides, composables, directives, plugins, utils, nodeItems] = [
489
- this.getAllComponents(),
490
- this.getAllGuides(),
491
- this.getAllComposables(),
492
- this.getAllDirectives(),
493
- this.getAllPlugins(),
494
- this.getAllUtils(),
495
- this.getAllNode()
496
- ];
497
- let withManualDoc = 0;
498
- let withGeneratedDoc = 0;
499
- let withBothDocs = 0;
500
- for (const component of components) {
501
- const manualExists = existsSync(join(this.componentsDir, `${component}.md`));
502
- const generatedExists = existsSync(join(this.generatedDocsDir, `${component}.doc.md`));
503
- if (manualExists)
504
- withManualDoc++;
505
- if (generatedExists)
506
- withGeneratedDoc++;
507
- if (manualExists && generatedExists)
508
- withBothDocs++;
509
- }
510
- return {
511
- components: {
512
- total: components.length,
513
- withManualDoc,
514
- withGeneratedDoc,
515
- withBothDocs
516
- },
517
- guides: {
518
- total: guides.length,
519
- list: guides
520
- },
521
- composables: {
522
- total: composables.length,
523
- list: composables
524
- },
525
- directives: {
526
- total: directives.length,
527
- list: directives
528
- },
529
- plugins: {
530
- total: plugins.length,
531
- list: plugins
532
- },
533
- utils: {
534
- total: utils.length,
535
- list: utils
536
- },
537
- node: {
538
- total: nodeItems.length,
539
- list: nodeItems
540
- },
541
- paths: {
542
- docsRoot: this.docsRoot,
543
- componentsDir: this.componentsDir,
544
- generatedDocsDir: this.generatedDocsDir,
545
- guidesDir: this.guidesDir,
546
- composablesDir: this.composablesDir,
547
- directivesDir: this.directivesDir,
548
- pluginsDir: this.pluginsDir,
549
- ecosystemDir: this.ecosystemDir,
550
- utilsDir: this.utilsDir,
551
- nodeDir: this.nodeDir,
552
- iconsDir: this.iconsDir
553
- }
554
- };
555
- }
556
- }
557
-
558
- const SNIPPET_LENGTH = 150;
559
- class SearchEngine {
560
- documents = [];
561
- invertedIndex = /* @__PURE__ */ new Map();
562
- documentLengths = [];
563
- buildIndex(documents) {
564
- this.documents = documents;
565
- this.invertedIndex.clear();
566
- this.documentLengths = [];
567
- for (let docIndex = 0; docIndex < documents.length; docIndex++) {
568
- const tokens = this.tokenize(documents[docIndex].content);
569
- this.documentLengths.push(tokens.length);
570
- const termFrequencies = /* @__PURE__ */ new Map();
571
- for (let pos = 0; pos < tokens.length; pos++) {
572
- const token = tokens[pos];
573
- const entry = termFrequencies.get(token);
574
- if (entry) {
575
- entry.count++;
576
- entry.positions.push(pos);
577
- } else {
578
- termFrequencies.set(token, { count: 1, positions: [pos] });
579
- }
580
- }
581
- for (const [term, { count, positions }] of termFrequencies) {
582
- let postings = this.invertedIndex.get(term);
583
- if (!postings) {
584
- postings = [];
585
- this.invertedIndex.set(term, postings);
586
- }
587
- postings.push({ docIndex, frequency: count, positions });
588
- }
589
- }
590
- }
591
- search(query, maxResults = 20) {
592
- if (this.documents.length === 0 || !query.trim()) {
593
- return [];
594
- }
595
- const exactPhrases = this.extractExactPhrases(query);
596
- const remainingQuery = query.replace(/"[^"]*"/g, "").trim();
597
- const singleTerms = remainingQuery ? this.tokenize(remainingQuery) : [];
598
- const scores = /* @__PURE__ */ new Map();
599
- const matchPositions = /* @__PURE__ */ new Map();
600
- for (const term of singleTerms) {
601
- this.scoreTerm(term, scores, matchPositions);
602
- }
603
- for (const phrase of exactPhrases) {
604
- this.scorePhrase(phrase, scores, matchPositions);
605
- }
606
- return Array.from(scores.entries()).filter(([, score]) => score > 0).sort(([, a], [, b]) => b - a).slice(0, maxResults).map(([docIndex, score]) => {
607
- const doc = this.documents[docIndex];
608
- const positions = matchPositions.get(docIndex) ?? [];
609
- return {
610
- id: doc.id,
611
- type: doc.type,
612
- name: doc.name,
613
- score: Math.round(score * 1e4) / 1e4,
614
- snippet: this.extractSnippet(doc.content, positions)
615
- };
616
- });
617
- }
618
- getIndexedTermCount() {
619
- return this.invertedIndex.size;
620
- }
621
- getDocumentCount() {
622
- return this.documents.length;
623
- }
624
- scoreTerm(term, scores, matchPositions) {
625
- const postings = this.invertedIndex.get(term);
626
- if (!postings) {
627
- return;
628
- }
629
- const totalDocs = this.documents.length;
630
- const df = postings.length;
631
- const idf = Math.log(1 + totalDocs / df);
632
- for (const posting of postings) {
633
- const docLength = this.documentLengths[posting.docIndex];
634
- const tf = docLength > 0 ? posting.frequency / docLength : 0;
635
- const tfidf = tf * idf;
636
- scores.set(posting.docIndex, (scores.get(posting.docIndex) ?? 0) + tfidf);
637
- const existing = matchPositions.get(posting.docIndex) ?? [];
638
- existing.push(posting.positions[0]);
639
- matchPositions.set(posting.docIndex, existing);
640
- }
641
- }
642
- scorePhrase(phrase, scores, matchPositions) {
643
- const phraseTokens = this.tokenize(phrase);
644
- if (phraseTokens.length === 0) {
645
- return;
646
- }
647
- const phraseMatches = this.findPhraseMatches(phraseTokens);
648
- const matchedDocs = new Set(phraseMatches.map((m) => m.docIndex));
649
- if (matchedDocs.size === 0) {
650
- return;
651
- }
652
- const totalDocs = this.documents.length;
653
- const idf = Math.log(1 + totalDocs / matchedDocs.size);
654
- for (const docIndex of matchedDocs) {
655
- const docMatches = phraseMatches.filter((m) => m.docIndex === docIndex);
656
- const docLength = this.documentLengths[docIndex];
657
- const tf = docLength > 0 ? docMatches.length / docLength : 0;
658
- const tfidf = tf * idf * phraseTokens.length;
659
- scores.set(docIndex, (scores.get(docIndex) ?? 0) + tfidf);
660
- const existing = matchPositions.get(docIndex) ?? [];
661
- existing.push(docMatches[0].position);
662
- matchPositions.set(docIndex, existing);
663
- }
664
- }
665
- findPhraseMatches(phraseTokens) {
666
- const firstTermPostings = this.invertedIndex.get(phraseTokens[0]);
667
- if (!firstTermPostings) {
668
- return [];
669
- }
670
- const matches = [];
671
- for (const posting of firstTermPostings) {
672
- for (const startPos of posting.positions) {
673
- if (this.isPhraseAtPosition(phraseTokens, posting.docIndex, startPos)) {
674
- matches.push({ docIndex: posting.docIndex, position: startPos });
675
- }
676
- }
677
- }
678
- return matches;
679
- }
680
- isPhraseAtPosition(phraseTokens, docIndex, startPos) {
681
- for (let i = 1; i < phraseTokens.length; i++) {
682
- const nextPostings = this.invertedIndex.get(phraseTokens[i]);
683
- if (!nextPostings) {
684
- return false;
685
- }
686
- const nextPosting = nextPostings.find((p) => p.docIndex === docIndex);
687
- if (!nextPosting || !nextPosting.positions.includes(startPos + i)) {
688
- return false;
689
- }
690
- }
691
- return true;
692
- }
693
- extractExactPhrases(query) {
694
- const phrases = [];
695
- const regex = /"([^"]+)"/g;
696
- for (const match of query.matchAll(regex)) {
697
- if (match[1].trim()) {
698
- phrases.push(match[1].trim());
699
- }
700
- }
701
- return phrases;
702
- }
703
- tokenize(text) {
704
- return text.toLowerCase().replace(/[#*`|[\](){}!@$%^&+=~<>/\\,;:.?'"_-]+/g, " ").split(/\s+/).filter((token) => token.length > 1);
705
- }
706
- extractSnippet(content, tokenPositions) {
707
- if (!content || tokenPositions.length === 0) {
708
- return content.slice(0, SNIPPET_LENGTH).trim();
709
- }
710
- const tokens = this.tokenize(content);
711
- if (tokens.length === 0) {
712
- return content.slice(0, SNIPPET_LENGTH).trim();
713
- }
714
- const bestPosition = tokenPositions[0];
715
- const targetToken = tokens[Math.min(bestPosition, tokens.length - 1)];
716
- const contentLower = content.toLowerCase();
717
- const charIndex = contentLower.indexOf(targetToken);
718
- if (charIndex === -1) {
719
- return content.slice(0, SNIPPET_LENGTH).trim();
720
- }
721
- const halfSnippet = Math.floor(SNIPPET_LENGTH / 2);
722
- let start = Math.max(0, charIndex - halfSnippet);
723
- let end = Math.min(content.length, start + SNIPPET_LENGTH);
724
- if (end === content.length) {
725
- start = Math.max(0, end - SNIPPET_LENGTH);
726
- }
727
- if (start > 0) {
728
- const spaceIndex = content.indexOf(" ", start);
729
- if (spaceIndex !== -1 && spaceIndex < start + 20) {
730
- start = spaceIndex + 1;
731
- }
732
- }
733
- if (end < content.length) {
734
- const spaceIndex = content.lastIndexOf(" ", end);
735
- if (spaceIndex !== -1 && spaceIndex > end - 20) {
736
- end = spaceIndex;
737
- }
738
- }
739
- let snippet = content.slice(start, end).trim();
740
- if (start > 0) {
741
- snippet = `...${snippet}`;
742
- }
743
- if (end < content.length) {
744
- snippet = `${snippet}...`;
745
- }
746
- return snippet;
747
- }
748
- }
749
-
750
- const NAME_BOOST = 3;
751
- const TAG_BOOST = 2;
752
- const CONTENT_BOOST = 1;
753
- const DEFAULT_MAX_RESULTS = 10;
754
- class UnifiedSearchService {
755
- searchEngine = new SearchEngine();
756
- documents = [];
757
- initialize(documents) {
758
- this.documents = documents;
759
- this.searchEngine.buildIndex(
760
- documents.map((doc) => ({
761
- id: doc.name,
762
- type: doc.type,
763
- name: doc.name,
764
- content: doc.content
765
- }))
766
- );
767
- }
768
- search(query, options = {}) {
769
- const { category, maxResults = DEFAULT_MAX_RESULTS } = options;
770
- if (!query.trim()) {
771
- return [];
772
- }
773
- const normalizedQuery = query.toLowerCase().trim();
774
- const queryTokens = this.searchEngine.tokenize(query);
775
- let candidates = this.documents;
776
- if (category) {
777
- candidates = candidates.filter((doc) => doc.type === category);
778
- }
779
- const tfidfResults = this.searchEngine.search(query, candidates.length || this.documents.length);
780
- const tfidfScoreMap = /* @__PURE__ */ new Map();
781
- for (const result of tfidfResults) {
782
- tfidfScoreMap.set(result.id, { score: result.score, snippet: result.snippet });
783
- }
784
- const scored = [];
785
- for (const doc of candidates) {
786
- const nameScore = this.scoreNameMatch(normalizedQuery, doc) * NAME_BOOST;
787
- const tagScore = this.scoreTagMatch(normalizedQuery, queryTokens, doc) * TAG_BOOST;
788
- const tfidfEntry = tfidfScoreMap.get(doc.name);
789
- const contentScore = (tfidfEntry?.score ?? 0) * CONTENT_BOOST;
790
- const totalScore = nameScore + tagScore + contentScore;
791
- if (totalScore > 0) {
792
- scored.push({
793
- name: doc.name,
794
- displayName: doc.metadata.displayName,
795
- type: doc.type,
796
- description: doc.metadata.description,
797
- score: Math.round(totalScore * 1e4) / 1e4,
798
- snippet: tfidfEntry?.snippet ?? doc.content.slice(0, 150).trim()
799
- });
800
- }
801
- }
802
- return scored.sort((a, b) => b.score - a.score).slice(0, maxResults);
803
- }
804
- scoreNameMatch(normalizedQuery, doc) {
805
- const name = doc.name.toLowerCase();
806
- const displayName = doc.metadata.displayName.toLowerCase();
807
- if (name === normalizedQuery || displayName === normalizedQuery) {
808
- return 1;
809
- }
810
- if (name.includes(normalizedQuery) || displayName.includes(normalizedQuery)) {
811
- return 0.7;
812
- }
813
- if (normalizedQuery.includes(name)) {
814
- return 0.5;
815
- }
816
- return 0;
817
- }
818
- scoreTagMatch(normalizedQuery, queryTokens, doc) {
819
- const tags = doc.metadata.tags;
820
- for (const tag of tags) {
821
- if (tag === normalizedQuery) {
822
- return 1;
823
- }
824
- }
825
- if (queryTokens.length === 0) {
826
- return 0;
827
- }
828
- let matchedTokens = 0;
829
- for (const token of queryTokens) {
830
- for (const tag of tags) {
831
- if (tag.includes(token) || token.includes(tag)) {
832
- matchedTokens++;
833
- break;
834
- }
835
- }
836
- }
837
- return matchedTokens / queryTokens.length * 0.8;
838
- }
839
- }
840
-
841
- class MazUiMcpServer {
842
- server;
843
- documentationService = new DocumentationService();
844
- unifiedSearchService = new UnifiedSearchService();
845
- documentationIndex = [];
846
- constructor() {
847
- this.server = new Server(
848
- {
849
- name: "maz-ui-mcp",
850
- version
851
- },
852
- {
853
- capabilities: {
854
- resources: {},
855
- tools: {}
856
- }
857
- }
858
- );
859
- this.buildDocumentationIndex();
860
- this.setupHandlers();
861
- }
862
- getDocumentationService() {
863
- return this.documentationService;
864
- }
865
- /**
866
- * Build a comprehensive index of all available documentation
867
- * This helps the AI understand what's available and how to access it
868
- */
869
- buildDocumentationIndex() {
870
- const index = [];
871
- index.push({
872
- type: "guide",
873
- name: "overview",
874
- displayName: "Library Overview",
875
- description: "Complete overview and introduction to Maz-UI Vue.js component library",
876
- tags: ["overview", "introduction", "getting-started", "maz-ui"],
877
- uri: "overview://"
878
- });
879
- const components = this.documentationService.getAllComponents();
880
- for (const component of components) {
881
- const pascalName = component.split("-").map(
882
- (part) => part.charAt(0).toUpperCase() + part.slice(1)
883
- ).join("");
884
- const componentType = this.getComponentType(component);
885
- const tags = [
886
- "component",
887
- "vue",
888
- component,
889
- pascalName.toLowerCase(),
890
- componentType,
891
- ...this.generateSearchTags(component)
892
- ];
893
- index.push({
894
- type: "component",
895
- name: component,
896
- displayName: `${pascalName} Component`,
897
- description: `Vue.js ${componentType} component: ${pascalName} - Interactive UI element with props, events, slots and styling options`,
898
- tags,
899
- uri: `component://${component}`
900
- });
901
- }
902
- const guides = this.documentationService.getAllGuides();
903
- for (const guide of guides) {
904
- const displayName = guide.split("-").map(
905
- (part) => part.charAt(0).toUpperCase() + part.slice(1)
906
- ).join(" ");
907
- const tags = [
908
- "guide",
909
- "documentation",
910
- guide,
911
- displayName.toLowerCase(),
912
- ...this.generateSearchTags(guide)
913
- ];
914
- index.push({
915
- type: "guide",
916
- name: guide,
917
- displayName: `Guide: ${displayName}`,
918
- description: `Documentation guide: ${displayName} - Setup instructions, configuration options, and best practices`,
919
- tags,
920
- uri: `guide://${guide}`
921
- });
922
- }
923
- const composables = this.documentationService.getAllComposables();
924
- for (const composable of composables) {
925
- const tags = [
926
- "composable",
927
- "vue3",
928
- "composition-api",
929
- composable,
930
- composable.replace("use", "").toLowerCase(),
931
- ...this.generateSearchTags(composable)
932
- ];
933
- index.push({
934
- type: "composable",
935
- name: composable,
936
- displayName: `${composable} Composable`,
937
- description: `Vue 3 Composition API composable: ${composable} - Reactive state management and reusable logic`,
938
- tags,
939
- uri: `composable://${composable}`
940
- });
941
- }
942
- const directives = this.documentationService.getAllDirectives();
943
- for (const directive of directives) {
944
- const tags = [
945
- "directive",
946
- "vue",
947
- "dom",
948
- directive,
949
- `v-${directive}`,
950
- ...this.generateSearchTags(directive)
951
- ];
952
- index.push({
953
- type: "directive",
954
- name: directive,
955
- displayName: `v-${directive} Directive`,
956
- description: `Vue directive: v-${directive} - DOM manipulation and behavioral enhancement for elements`,
957
- tags,
958
- uri: `directive://${directive}`
959
- });
960
- }
961
- const plugins = this.documentationService.getAllPlugins();
962
- for (const plugin of plugins) {
963
- const tags = [
964
- "plugin",
965
- "vue",
966
- "global",
967
- plugin,
968
- plugin.toLowerCase(),
969
- ...this.generateSearchTags(plugin)
970
- ];
971
- index.push({
972
- type: "plugin",
973
- name: plugin,
974
- displayName: `${plugin} Plugin`,
975
- description: `Vue plugin: ${plugin} - Application-wide functionality and global services integration`,
976
- tags,
977
- uri: `plugin://${plugin}`
978
- });
979
- }
980
- const utils = this.documentationService.getAllUtils();
981
- for (const util of utils) {
982
- const utilType = this.getUtilType(util);
983
- const tags = [
984
- "util",
985
- "utility",
986
- "function",
987
- "maz-ui-utils",
988
- util,
989
- utilType,
990
- ...this.generateSearchTags(util)
991
- ];
992
- index.push({
993
- type: "util",
994
- name: util,
995
- displayName: `${util} Util`,
996
- description: `Utility from @maz-ui/utils: ${util} - ${utilType} utility for data processing and manipulation`,
997
- tags,
998
- uri: `util://${util}`
999
- });
1000
- }
1001
- const nodeItems = this.documentationService.getAllNode();
1002
- for (const nodeItem of nodeItems) {
1003
- const tags = [
1004
- "node",
1005
- "server",
1006
- "cli",
1007
- "maz-ui-node",
1008
- nodeItem,
1009
- ...this.generateSearchTags(nodeItem)
1010
- ];
1011
- index.push({
1012
- type: "node",
1013
- name: nodeItem,
1014
- displayName: `${nodeItem} Node Utility`,
1015
- description: `Node.js utility from @maz-ui/node: ${nodeItem} - server-side helper for scripts, CLI and SSR runtimes`,
1016
- tags,
1017
- uri: `node://${nodeItem}`
1018
- });
1019
- }
1020
- this.documentationIndex = index;
1021
- this.unifiedSearchService.initialize(this.documentationService.getAllDocuments());
1022
- }
1023
- /**
1024
- * Generate additional search tags based on common patterns
1025
- */
1026
- generateSearchTags(name) {
1027
- const tags = [];
1028
- const commonMappings = {
1029
- btn: ["button"],
1030
- input: ["form", "field"],
1031
- select: ["dropdown", "option"],
1032
- dialog: ["modal", "popup"],
1033
- tooltip: ["hint", "tip"],
1034
- toast: ["notification", "snackbar"],
1035
- card: ["panel"],
1036
- avatar: ["profile", "image"],
1037
- badge: ["label", "tag"],
1038
- spinner: ["loader", "loading"],
1039
- divider: ["separator"],
1040
- drawer: ["sidebar", "panel"],
1041
- tabs: ["tab", "navigation"],
1042
- accordion: ["collapse", "expand"],
1043
- carousel: ["slider", "slideshow"],
1044
- gallery: ["images", "photos"],
1045
- stepper: ["steps", "wizard"],
1046
- table: ["grid", "data"],
1047
- chart: ["graph", "visualization"],
1048
- date: ["calendar", "picker"],
1049
- time: ["clock", "picker"]
1050
- };
1051
- for (const [key, aliases] of Object.entries(commonMappings)) {
1052
- if (name.toLowerCase().includes(key)) {
1053
- tags.push(...aliases);
1054
- }
1055
- }
1056
- return tags;
1057
- }
1058
- /**
1059
- * Determine component type for better categorization
1060
- */
1061
- getComponentType(componentName) {
1062
- const formComponents = ["btn", "checkbox", "checklist", "date", "input", "radio", "select", "slider", "switch", "textarea"];
1063
- const layoutComponents = ["accordion", "card"];
1064
- const navigationComponents = ["tabs", "stepper", "pagination", "link", "pull", "reading"];
1065
- const overlayComponents = ["dialog", "drawer", "sheet", "popover", "dropdown", "backdrop"];
1066
- const dataComponents = ["chart", "table", "dropzone"];
1067
- const feedbackComponents = ["spinner", "loading", "progress", "badge"];
1068
- const displayComponents = ["avatar", "gallery", "lazy", "carousel", "icon"];
1069
- const animationComponents = ["animated", "expand"];
1070
- const lowerName = componentName.toLowerCase();
1071
- if (formComponents.some((type) => lowerName.includes(type)))
1072
- return "form";
1073
- if (layoutComponents.some((type) => lowerName.includes(type)))
1074
- return "layout";
1075
- if (navigationComponents.some((type) => lowerName.includes(type)))
1076
- return "navigation";
1077
- if (overlayComponents.some((type) => lowerName.includes(type)))
1078
- return "overlay";
1079
- if (dataComponents.some((type) => lowerName.includes(type)))
1080
- return "data";
1081
- if (feedbackComponents.some((type) => lowerName.includes(type)))
1082
- return "feedback";
1083
- if (displayComponents.some((type) => lowerName.includes(type)))
1084
- return "display";
1085
- if (animationComponents.some((type) => lowerName.includes(type)))
1086
- return "animation";
1087
- return "general";
1088
- }
1089
- /**
1090
- * Determine util type for better categorization
1091
- */
1092
- getUtilType(utilName) {
1093
- const lowerName = utilName.toLowerCase();
1094
- if (lowerName.includes("string") || lowerName.includes("text"))
1095
- return "string";
1096
- if (lowerName.includes("date") || lowerName.includes("time"))
1097
- return "date";
1098
- if (lowerName.includes("number") || lowerName.includes("currency"))
1099
- return "number";
1100
- if (lowerName.includes("color") || lowerName.includes("theme"))
1101
- return "color";
1102
- if (lowerName.includes("format") || lowerName.includes("parse"))
1103
- return "formatting";
1104
- if (lowerName.includes("valid") || lowerName.includes("check"))
1105
- return "validation";
1106
- return "general";
1107
- }
1108
- /**
1109
- * Resolve a document name using intelligent matching:
1110
- * PascalCase (MazBtn), kebab-case (maz-btn), short name (btn), aliases
1111
- */
1112
- resolveDocumentName(name, type) {
1113
- const normalizedName = name.toLowerCase().trim();
1114
- const candidates = type && type !== "auto" ? this.documentationIndex.filter((item) => item.type === type) : this.documentationIndex;
1115
- const exactMatch = candidates.find((item) => item.name.toLowerCase() === normalizedName);
1116
- if (exactMatch) {
1117
- return exactMatch;
1118
- }
1119
- if (/[A-Z]/.test(name)) {
1120
- const kebabName = name.replace(/([A-Z])/g, "-$1").toLowerCase().replace(/^-/, "");
1121
- const kebabMatch = candidates.find((item) => item.name.toLowerCase() === kebabName);
1122
- if (kebabMatch) {
1123
- return kebabMatch;
1124
- }
1125
- }
1126
- if (!normalizedName.startsWith("maz-")) {
1127
- const prefixedName = `maz-${normalizedName}`;
1128
- const prefixMatch = candidates.find((item) => item.name.toLowerCase() === prefixedName);
1129
- if (prefixMatch) {
1130
- return prefixMatch;
1131
- }
1132
- }
1133
- const displayMatch = candidates.find(
1134
- (item) => item.displayName.toLowerCase() === normalizedName
1135
- );
1136
- if (displayMatch) {
1137
- return displayMatch;
1138
- }
1139
- const tagMatch = candidates.find(
1140
- (item) => item.tags.some((tag) => tag.toLowerCase() === normalizedName)
1141
- );
1142
- if (tagMatch) {
1143
- return tagMatch;
1144
- }
1145
- const partialMatch = candidates.find(
1146
- (item) => item.name.toLowerCase().includes(normalizedName) || item.displayName.toLowerCase().includes(normalizedName)
1147
- );
1148
- if (partialMatch) {
1149
- return partialMatch;
1150
- }
1151
- return void 0;
1152
- }
1153
- handleSearch(args) {
1154
- const query = args?.query;
1155
- const category = args?.category;
1156
- const maxResults = args?.maxResults || 10;
1157
- if (!query) {
1158
- throw new Error("Search query is required. Provide a component name, description, prop name, or use case.");
1159
- }
1160
- const results = this.unifiedSearchService.search(query, {
1161
- category,
1162
- maxResults
1163
- });
1164
- if (results.length === 0) {
1165
- return {
1166
- content: [{
1167
- type: "text",
1168
- text: `No results found for "${query}".${category ? ` (filtered by category: ${category})` : ""}
1169
-
1170
- **Suggestions:**
1171
- - Try broader or different terms (e.g. "button" instead of "btn")
1172
- - Remove the category filter to search all documentation
1173
- - Use \`list\` to browse all available documentation`
1174
- }]
1175
- };
1176
- }
1177
- let resultText = `# Search Results for "${query}" (${results.length} found)
1178
-
1179
- `;
1180
- for (const item of results) {
1181
- resultText += `## ${item.displayName}
1182
- `;
1183
- resultText += `- **Name**: \`${item.name}\`
1184
- `;
1185
- resultText += `- **Type**: ${item.type}
1186
- `;
1187
- resultText += `- **Description**: ${item.description}
1188
- `;
1189
- resultText += `- **Score**: ${item.score}
1190
- `;
1191
- resultText += `- **Snippet**: ${item.snippet}
1192
- `;
1193
- resultText += `- **Get full doc**: Use \`get_doc\` with name \`${item.name}\`
1194
-
1195
- `;
1196
- }
1197
- return {
1198
- content: [{
1199
- type: "text",
1200
- text: resultText
1201
- }]
1202
- };
1203
- }
1204
- handleList(args) {
1205
- const category = args?.category || "all";
1206
- const filteredIndex = category === "all" ? this.documentationIndex : this.documentationIndex.filter((item) => item.type === category);
1207
- const groupedDocs = filteredIndex.reduce((acc, item) => {
1208
- if (!acc[item.type])
1209
- acc[item.type] = [];
1210
- acc[item.type].push(item);
1211
- return acc;
1212
- }, {});
1213
- const typeLabels = {
1214
- component: "Components",
1215
- guide: "Guides",
1216
- composable: "Composables",
1217
- directive: "Directives",
1218
- plugin: "Plugins",
1219
- util: "Utils",
1220
- node: "Node Utilities"
1221
- };
1222
- const typeOrder = ["component", "guide", "composable", "directive", "plugin", "util", "node"];
1223
- let result = `# Maz-UI Documentation (${filteredIndex.length} items)
1224
-
1225
- `;
1226
- for (const type of typeOrder) {
1227
- if (!groupedDocs[type])
1228
- continue;
1229
- const items = groupedDocs[type].sort((a, b) => a.name.localeCompare(b.name));
1230
- result += `## ${typeLabels[type]} (${items.length})
1231
-
1232
- `;
1233
- for (const item of items) {
1234
- result += `- **${item.displayName}** (\`${item.name}\`) \u2014 ${item.description}
1235
- `;
1236
- }
1237
- result += "\n";
1238
- }
1239
- return {
1240
- content: [{
1241
- type: "text",
1242
- text: result.trim()
1243
- }]
1244
- };
1245
- }
1246
- handleGetDoc(args) {
1247
- const docName = args?.name;
1248
- const docType = args?.type || "auto";
1249
- if (!docName) {
1250
- throw new Error("Name is required");
1251
- }
1252
- const found = this.resolveDocumentName(docName, docType);
1253
- if (!found) {
1254
- return this.handleDocNotFound(docName);
1255
- }
1256
- const content = this.getDocumentContent(found);
1257
- if (!content) {
1258
- return {
1259
- content: [{
1260
- type: "text",
1261
- text: `Found "${found.displayName}" but documentation content is not available. This might be a documentation file that needs to be created.`
1262
- }]
1263
- };
1264
- }
1265
- return {
1266
- content: [{
1267
- type: "text",
1268
- text: content
1269
- }]
1270
- };
1271
- }
1272
- handleDocNotFound(docName) {
1273
- const searchResults = this.unifiedSearchService.search(docName, { maxResults: 3 });
1274
- if (searchResults.length === 0) {
1275
- return {
1276
- content: [{
1277
- type: "text",
1278
- text: `Documentation not found for "${docName}".
1279
-
1280
- **Available options:**
1281
- - Use \`search\` to find similar items
1282
- - Use \`list\` to see all available documentation`
1283
- }]
1284
- };
1285
- }
1286
- const suggestions = searchResults.map((item) => `- **${item.displayName}** (\`${item.name}\`) - ${item.description}`).join("\n");
1287
- return {
1288
- content: [{
1289
- type: "text",
1290
- text: `Exact match not found for "${docName}". Did you mean:
1291
-
1292
- ${suggestions}
1293
-
1294
- **Use \`get_doc\` with the exact name from above.**`
1295
- }]
1296
- };
1297
- }
1298
- getDocumentContent(doc) {
1299
- const contentMethods = {
1300
- component: (name) => this.documentationService.getComponentDocumentation(name),
1301
- guide: (name) => this.documentationService.getGuideDocumentation(name),
1302
- composable: (name) => this.documentationService.getComposableDocumentation(name),
1303
- directive: (name) => this.documentationService.getDirectiveDocumentation(name),
1304
- plugin: (name) => this.documentationService.getPluginDocumentation(name),
1305
- util: (name) => this.documentationService.getUtilDocumentation(name),
1306
- node: (name) => this.documentationService.getNodeDocumentation(name)
1307
- };
1308
- const getContent = contentMethods[doc.type];
1309
- return getContent ? getContent(doc.name) : "";
1310
- }
1311
- setupHandlers() {
1312
- this.server.setRequestHandler(ListResourcesRequestSchema, () => {
1313
- return {
1314
- resources: this.documentationIndex.map((item) => ({
1315
- uri: item.uri,
1316
- name: item.displayName,
1317
- description: item.description,
1318
- mimeType: "text/markdown"
1319
- }))
1320
- };
1321
- });
1322
- this.server.setRequestHandler(ReadResourceRequestSchema, (request) => {
1323
- const { uri } = request.params;
1324
- if (!uri) {
1325
- throw new Error("URI is required");
1326
- }
1327
- let type, name;
1328
- if (uri === "overview://") {
1329
- type = "overview";
1330
- name = "";
1331
- } else if (uri.includes("://")) {
1332
- [type, name] = uri.split("://");
1333
- } else {
1334
- throw new Error("Invalid URI format. Expected format: type://name");
1335
- }
1336
- if (!name && type !== "overview") {
1337
- throw new Error("Resource name is required");
1338
- }
1339
- let content;
1340
- try {
1341
- switch (type) {
1342
- case "overview":
1343
- content = this.documentationService.getOverview();
1344
- if (!content) {
1345
- const diagnostics = this.documentationService.getDiagnostics();
1346
- content = `# Maz-UI Vue.js Component Library
1347
-
1348
- ## Quick Stats
1349
- - **${diagnostics.components.total} Components** - Ready-to-use Vue components
1350
- - **${diagnostics.composables.total} Composables** - Vue 3 reactive utilities
1351
- - **${diagnostics.directives.total} Directives** - DOM helpers
1352
- - **${diagnostics.plugins.total} Plugins** - App-wide services
1353
- - **${diagnostics.utils.total} Utils** - Utility functions from @maz-ui/utils
1354
- - **${diagnostics.node.total} Node Utilities** - Server-side helpers from @maz-ui/node
1355
- - **${diagnostics.guides.total} Guides** - Documentation
1356
-
1357
- ## Getting Started
1358
- Use the MCP tools to explore components and features:
1359
- - \`list\` - See everything available
1360
- - \`search\` - Find specific features
1361
- - \`get_doc\` - Get detailed documentation`;
1362
- }
1363
- break;
1364
- case "component":
1365
- content = this.documentationService.getComponentDocumentation(name);
1366
- break;
1367
- case "guide":
1368
- content = this.documentationService.getGuideDocumentation(name);
1369
- break;
1370
- case "composable":
1371
- content = this.documentationService.getComposableDocumentation(name);
1372
- break;
1373
- case "directive":
1374
- content = this.documentationService.getDirectiveDocumentation(name);
1375
- break;
1376
- case "plugin":
1377
- content = this.documentationService.getPluginDocumentation(name);
1378
- break;
1379
- case "util":
1380
- content = this.documentationService.getUtilDocumentation(name);
1381
- break;
1382
- case "node":
1383
- content = this.documentationService.getNodeDocumentation(name);
1384
- break;
1385
- default:
1386
- throw new Error(`Unknown resource type: ${type}. Valid types: overview, component, guide, composable, directive, plugin, util, node`);
1387
- }
1388
- if (!content) {
1389
- throw new Error(`Documentation not found for ${type}: ${name}`);
1390
- }
1391
- return {
1392
- contents: [{
1393
- uri,
1394
- mimeType: "text/markdown",
1395
- text: content
1396
- }]
1397
- };
1398
- } catch (error) {
1399
- throw new Error(`Failed to read ${type} documentation for "${name}": ${getErrorMessage(error)}`, { cause: error });
1400
- }
1401
- });
1402
- this.server.setRequestHandler(ListToolsRequestSchema, () => {
1403
- return {
1404
- tools: [
1405
- {
1406
- name: "search",
1407
- description: 'Search across ALL Maz-UI documentation using a powerful unified search engine. Combines exact name matching, tag/alias matching, and full-text content search with TF-IDF scoring. Use this tool for any search query: component names (e.g. "MazBtn"), functional descriptions (e.g. "date picker"), prop names (e.g. "model-value"), use cases (e.g. "form validation"), or aliases (e.g. "modal" for dialog). Returns ranked results with contextual snippets.',
1408
- inputSchema: {
1409
- type: "object",
1410
- properties: {
1411
- query: {
1412
- type: "string",
1413
- description: 'Search query \u2014 can be a component name, description, prop name, use case, or alias. Examples: "button", "MazDialog", "model-value", "phone number input", "lazy loading"'
1414
- },
1415
- category: {
1416
- type: "string",
1417
- enum: ["component", "guide", "composable", "directive", "plugin", "util", "node"],
1418
- description: "Optional filter to restrict results to a specific documentation category"
1419
- },
1420
- maxResults: {
1421
- type: "number",
1422
- description: "Maximum number of results to return (default: 10)",
1423
- default: 10,
1424
- minimum: 1,
1425
- maximum: 50
1426
- }
1427
- },
1428
- required: ["query"]
1429
- }
1430
- },
1431
- {
1432
- name: "get_doc",
1433
- description: "Get the complete documentation for a specific item. Supports exact names and common aliases. If the exact name isn't found, provides intelligent suggestions based on fuzzy matching.",
1434
- inputSchema: {
1435
- type: "object",
1436
- properties: {
1437
- name: {
1438
- type: "string",
1439
- description: 'Exact name or common alias. Examples: "maz-btn" or "MazBtn" for components, "useToast" for composables, "tooltip" for directives'
1440
- },
1441
- type: {
1442
- type: "string",
1443
- enum: ["auto", "component", "guide", "composable", "directive", "plugin", "util", "node"],
1444
- description: 'Type hint to improve search accuracy (optional). Use "auto" to search all types.',
1445
- default: "auto"
1446
- }
1447
- },
1448
- required: ["name"]
1449
- }
1450
- },
1451
- {
1452
- name: "list",
1453
- description: "Browse all available Maz-UI documentation grouped by category. Returns a structured list with counters per category and for each item: name, displayName, description. Use this tool to discover what components, composables, directives, plugins, utils, node utilities and guides are available. Examples: list all docs, list only components, list composables.",
1454
- inputSchema: {
1455
- type: "object",
1456
- properties: {
1457
- category: {
1458
- type: "string",
1459
- enum: ["all", "component", "guide", "composable", "directive", "plugin", "util", "node"],
1460
- description: 'Filter by documentation category. Use "all" or omit to see everything.',
1461
- default: "all"
1462
- }
1463
- }
1464
- }
1465
- }
1466
- ]
1467
- };
1468
- });
1469
- this.server.setRequestHandler(CallToolRequestSchema, (request) => {
1470
- const { name, arguments: args } = request.params;
1471
- try {
1472
- switch (name) {
1473
- case "search":
1474
- return this.handleSearch(args);
1475
- case "list":
1476
- return this.handleList(args);
1477
- case "get_doc":
1478
- return this.handleGetDoc(args);
1479
- default:
1480
- throw new Error(`Unknown tool: ${name}. Available tools: search, get_doc, list`);
1481
- }
1482
- } catch (error) {
1483
- return {
1484
- content: [{
1485
- type: "text",
1486
- text: `Error: ${getErrorMessage(error)}
1487
-
1488
- **Available tools:**
1489
- - \`search\` - Search across all documentation
1490
- - \`get_doc\` - Get specific documentation
1491
- - \`list\` - Browse all available documentation`
1492
- }],
1493
- isError: true
1494
- };
1495
- }
1496
- });
1497
- }
1498
- async run() {
1499
- const transport = new StdioServerTransport();
1500
- await this.server.connect(transport);
1501
- }
1502
- }
1503
- if (import.meta.url === `file://${process.argv[1]}`) {
1504
- const server = new MazUiMcpServer();
1505
- server.run().catch((error) => {
1506
- console.error("Failed to start MCP server:", getErrorMessage(error));
1507
- process.exit(1);
1508
- });
1509
- }
1510
-
1511
- export { MazUiMcpServer };