@hanzo/ui 4.9.0 → 5.0.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.
- package/README.md +192 -185
- package/assets/ai-icons.tsx +207 -0
- package/assets/crypto.tsx +33 -0
- package/assets/file-type-icon.tsx +66 -0
- package/assets/file.tsx +45 -0
- package/assets/general.tsx +2318 -0
- package/assets/hanzo-logo.svg +9 -0
- package/assets/hanzo-logo.tsx +17 -0
- package/assets/index.ts +122 -0
- package/assets/index.tsx +4 -0
- package/assets/llm-provider.tsx +1094 -0
- package/bin/cli.js +100 -0
- package/bin/create-registry.js +108 -0
- package/bin/mcp.js +403 -0
- package/bin/npx-registry-mcp.js +15 -0
- package/bin/registry-mcp-wrapper.sh +19 -0
- package/bin/registry-mcp.js +100 -0
- package/bin/start-mcp-server.sh +22 -0
- package/bin/test-mcp.sh +52 -0
- package/bin/update-registry.js +196 -0
- package/blocks/auth/index.ts +6 -0
- package/blocks/auth/login-2fa.tsx +165 -0
- package/blocks/auth/login-basic.tsx +94 -0
- package/blocks/auth/login-social.tsx +148 -0
- package/blocks/auth/magic-link.tsx +129 -0
- package/blocks/auth/password-reset.tsx +97 -0
- package/blocks/auth/signup.tsx +157 -0
- package/blocks/components/accordian-block.tsx +48 -0
- package/blocks/components/block-component-props.ts +11 -0
- package/blocks/components/bullet-cards-block.tsx +46 -0
- package/blocks/components/card-block/index.tsx +171 -0
- package/blocks/components/card-block/link-out-button.tsx +20 -0
- package/blocks/components/card-block/util.ts +28 -0
- package/blocks/components/carte-blanche-block/index.tsx +127 -0
- package/blocks/components/carte-blanche-block/variant-content-left.tsx +49 -0
- package/blocks/components/content.tsx +70 -0
- package/blocks/components/cta-block.tsx +115 -0
- package/blocks/components/enh-heading-block.tsx +204 -0
- package/blocks/components/grid-block/grid-block-mutator.ts +12 -0
- package/blocks/components/grid-block/index.tsx +83 -0
- package/blocks/components/grid-block/mutator-registry.ts +10 -0
- package/blocks/components/grid-block/table-borders.mutator.ts +47 -0
- package/blocks/components/group-block.tsx +83 -0
- package/blocks/components/heading-block.tsx +88 -0
- package/blocks/components/image-block.tsx +111 -0
- package/blocks/components/index.ts +30 -0
- package/blocks/components/screenful-block/content.tsx +123 -0
- package/blocks/components/screenful-block/index.tsx +107 -0
- package/blocks/components/screenful-block/poster-background.tsx +34 -0
- package/blocks/components/screenful-block/video-background.tsx +45 -0
- package/blocks/components/space-block.tsx +66 -0
- package/blocks/components/video-block.tsx +138 -0
- package/blocks/data-display/activity-feed.tsx +242 -0
- package/blocks/data-display/data-table.tsx +235 -0
- package/blocks/data-display/stats-grid.tsx +194 -0
- package/blocks/def/accordian-block.ts +14 -0
- package/blocks/def/block.ts +7 -0
- package/blocks/def/bullet-cards-block.ts +22 -0
- package/blocks/def/card-block.ts +22 -0
- package/blocks/def/carte-blanche-block.ts +21 -0
- package/blocks/def/cta-block.ts +19 -0
- package/blocks/def/element-block.ts +11 -0
- package/blocks/def/enh-heading-block.ts +44 -0
- package/blocks/def/grid-block.ts +16 -0
- package/blocks/def/group-block.ts +11 -0
- package/blocks/def/heading-block.ts +15 -0
- package/blocks/def/image-block.ts +31 -0
- package/blocks/def/index.ts +35 -0
- package/blocks/def/screenful-block.ts +54 -0
- package/blocks/def/space-block.ts +64 -0
- package/blocks/def/video-block.ts +9 -0
- package/blocks/ecommerce/checkout.tsx +242 -0
- package/blocks/ecommerce/index.ts +7 -0
- package/blocks/ecommerce/product-detail.tsx +257 -0
- package/blocks/ecommerce/product-grid.tsx +148 -0
- package/blocks/ecommerce/shopping-cart.tsx +181 -0
- package/blocks/index.ts +2 -0
- package/blocks/marketing/cta-section.tsx +207 -0
- package/blocks/marketing/faq.tsx +159 -0
- package/blocks/marketing/features-grid.tsx +156 -0
- package/blocks/marketing/hero-section.tsx +192 -0
- package/blocks/marketing/index.ts +6 -0
- package/blocks/marketing/pricing-table.tsx +121 -0
- package/blocks/marketing/testimonials.tsx +196 -0
- package/components/index.ts +9 -0
- package/dist/index.js +9070 -1089
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +8695 -45
- package/dist/index.mjs.map +1 -1
- package/dist/tailwind.js +2025 -0
- package/dist/tailwind.js.map +1 -0
- package/dist/tailwind.mjs +2013 -0
- package/dist/tailwind.mjs.map +1 -0
- package/dist/types.js +59 -0
- package/dist/types.js.map +1 -0
- package/dist/types.mjs +53 -0
- package/dist/types.mjs.map +1 -0
- package/dist/utils.js +30 -0
- package/dist/utils.js.map +1 -0
- package/dist/utils.mjs +26 -0
- package/dist/utils.mjs.map +1 -0
- package/frameworks/core/index.ts +6 -0
- package/frameworks/core/utils/index.ts +64 -0
- package/frameworks/react/components/button.tsx +26 -0
- package/frameworks/react/components/index.ts +5 -0
- package/frameworks/react/hooks/index.ts +5 -0
- package/frameworks/react/index.ts +9 -0
- package/frameworks/react/package.json +8 -0
- package/frameworks/react/utils/index.ts +2 -0
- package/frameworks/react-native/index.ts +9 -0
- package/frameworks/react-native/package.json +8 -0
- package/frameworks/registry.json +371 -0
- package/frameworks/setup.sh +69 -0
- package/frameworks/svelte/index.ts +9 -0
- package/frameworks/svelte/package.json +8 -0
- package/frameworks/tracker.json +1854 -0
- package/frameworks/vue/index.ts +9 -0
- package/frameworks/vue/package.json +8 -0
- package/helpers/file.ts +33 -0
- package/helpers/memoization.ts +40 -0
- package/package.json +272 -153
- package/primitives/accordion.tsx +74 -0
- package/primitives/action-button.tsx +42 -0
- package/primitives/alert-dialog.tsx +185 -0
- package/primitives/alert.tsx +74 -0
- package/primitives/apply-typography.tsx +55 -0
- package/primitives/aspect-ratio.tsx +5 -0
- package/primitives/avatar.tsx +57 -0
- package/primitives/background-beams.tsx +142 -0
- package/primitives/badge.tsx +45 -0
- package/primitives/breadcrumb.tsx +130 -0
- package/primitives/breakpoint-indicator.tsx +19 -0
- package/primitives/button.tsx +72 -0
- package/primitives/calendar.tsx +72 -0
- package/primitives/card.tsx +97 -0
- package/primitives/carousel.tsx +238 -0
- package/primitives/chat/chat-input-area.tsx +88 -0
- package/primitives/chat/chat-input.tsx +71 -0
- package/primitives/chat/files-preview.tsx +331 -0
- package/primitives/chat/index.ts +6 -0
- package/primitives/chat/json-form.tsx +8 -0
- package/primitives/chat/message-list.tsx +308 -0
- package/primitives/chat/message.tsx +569 -0
- package/primitives/chat/sqlite-preview.tsx +215 -0
- package/primitives/checkbox.tsx +32 -0
- package/primitives/collapsible.tsx +9 -0
- package/primitives/combobox.tsx +239 -0
- package/primitives/command.tsx +151 -0
- package/primitives/context-menu.tsx +206 -0
- package/primitives/copy-to-clipboard-icon.tsx +60 -0
- package/primitives/dialog-video-controller.tsx +38 -0
- package/primitives/dialog.tsx +128 -0
- package/primitives/dot-pattern.tsx +57 -0
- package/primitives/dots-loader.tsx +13 -0
- package/primitives/drawer.tsx +113 -0
- package/primitives/dropdown-menu.tsx +199 -0
- package/primitives/error-message.tsx +19 -0
- package/primitives/file-uploader.tsx +203 -0
- package/primitives/form.tsx +185 -0
- package/primitives/hover-card.tsx +28 -0
- package/primitives/icons/github.tsx +14 -0
- package/primitives/icons/index.ts +18 -0
- package/primitives/icons/youtube-logo.tsx +59 -0
- package/primitives/index-client.ts +4 -0
- package/primitives/index-common.ts +304 -0
- package/primitives/index-next.ts +4 -0
- package/primitives/input-otp.tsx +65 -0
- package/primitives/input.tsx +128 -0
- package/primitives/label.tsx +21 -0
- package/primitives/list-adaptor.ts +12 -0
- package/primitives/list-box.tsx +74 -0
- package/primitives/loading-spinner.tsx +33 -0
- package/primitives/markdown-preview.tsx +612 -0
- package/primitives/mermaid.tsx +191 -0
- package/primitives/navigation-menu.tsx +147 -0
- package/primitives/next/image.tsx +91 -0
- package/primitives/next/index.ts +7 -0
- package/primitives/next/inline-icon.tsx +36 -0
- package/primitives/next/link-element.tsx +109 -0
- package/primitives/next/mdx-link.tsx +22 -0
- package/primitives/next/media-stack.tsx +52 -0
- package/primitives/next/nav-items.tsx +45 -0
- package/primitives/next/youtube-embed.tsx +83 -0
- package/primitives/pagination.tsx +117 -0
- package/primitives/popover.tsx +34 -0
- package/primitives/pretty-json-print.tsx +28 -0
- package/primitives/progress.tsx +27 -0
- package/primitives/prompt-textarea.tsx +72 -0
- package/primitives/qr-code.tsx +112 -0
- package/primitives/radio-group.tsx +42 -0
- package/primitives/resizable.tsx +47 -0
- package/primitives/scroll-area.tsx +57 -0
- package/primitives/search-input.tsx +66 -0
- package/primitives/select.tsx +122 -0
- package/primitives/separator.tsx +26 -0
- package/primitives/sheet.tsx +139 -0
- package/primitives/skeleton.tsx +18 -0
- package/primitives/slider.tsx +63 -0
- package/primitives/sonner.tsx +35 -0
- package/primitives/step-indicator.tsx +69 -0
- package/primitives/stepper.tsx +272 -0
- package/primitives/switch.tsx +27 -0
- package/primitives/table.tsx +105 -0
- package/primitives/tabs.tsx +50 -0
- package/primitives/text-area.tsx +26 -0
- package/primitives/text-link.tsx +27 -0
- package/primitives/textarea.tsx +64 -0
- package/primitives/textfield.tsx +78 -0
- package/primitives/toast.tsx +30 -0
- package/primitives/toggle-group.tsx +63 -0
- package/primitives/toggle.tsx +44 -0
- package/primitives/tooltip.tsx +47 -0
- package/primitives/video-player.tsx +23 -0
- package/src/button.ts +1 -0
- package/src/hooks/index.ts +7 -0
- package/src/hooks/use-click-away.ts +31 -0
- package/src/hooks/use-combined-refs.ts +22 -0
- package/src/hooks/use-copy-clipboard.ts +30 -0
- package/src/hooks/use-debounce.ts +17 -0
- package/src/hooks/use-fill-ids.ts +25 -0
- package/src/hooks/use-map.ts +26 -0
- package/src/hooks/use-measure.ts +42 -0
- package/src/hooks/use-reverse-video-playback.ts +43 -0
- package/src/hooks/use-scroll-restoration.ts +50 -0
- package/src/index-lean.ts +87 -0
- package/src/index.ts +54 -0
- package/src/mcp/README.md +141 -0
- package/src/mcp/enhanced-server.ts +1208 -0
- package/src/mcp/index.ts +518 -0
- package/src/mcp/package.json +10 -0
- package/src/registry/api.ts +164 -0
- package/src/registry/index.ts +60 -0
- package/src/registry/package.json +10 -0
- package/src/utils.ts +19 -0
- package/style/drawer.css +163 -0
- package/style/globals.css +13 -0
- package/style/hanzo-common.css +31 -0
- package/style/hanzo-default-colors.css +82 -0
- package/style/theme-provider.tsx +20 -0
- package/tailwind/colors.tailwind.js +53 -0
- package/tailwind/fontFamily.tailwind.ts +7 -0
- package/tailwind/fontSize.tailwind.ts +13 -0
- package/tailwind/index.ts +7 -0
- package/tailwind/safelist.tailwind.js +26 -0
- package/tailwind/screens.tailwind.js +8 -0
- package/tailwind/spacing.tailwind.js +65 -0
- package/tailwind/tailwind.config.hanzo-preset.d.ts +5 -0
- package/tailwind/tailwind.config.hanzo-preset.js +915 -0
- package/tailwind/tw-font-desc.ts +15 -0
- package/tailwind/typo-plugin/get-plugin-styles.js +679 -0
- package/tailwind/typo-plugin/index.d.ts +9 -0
- package/tailwind/typo-plugin/index.js +141 -0
- package/tailwind/typo-plugin/utils.js +60 -0
- package/tailwind/typography-test.mdx +35 -0
- package/tailwind/z-index.tailwind.js +71 -0
- package/types/animation-def.ts +3 -0
- package/types/breakpoints.ts +11 -0
- package/types/bullet-item.ts +10 -0
- package/types/button-def.ts +39 -0
- package/types/dimensions.ts +8 -0
- package/types/grid-def.ts +56 -0
- package/types/image-def.ts +32 -0
- package/types/index.ts +30 -0
- package/types/link-def.ts +56 -0
- package/types/media-stack-def.ts +31 -0
- package/types/t-shirt-size.ts +5 -0
- package/types/tshirt-dimensions.ts +20 -0
- package/types/video-def.ts +25 -0
- package/util/blob.ts +33 -0
- package/util/copy-to-clipboard.ts +17 -0
- package/util/create-shadow-root.ts +22 -0
- package/util/date.ts +84 -0
- package/util/debounce.ts +11 -0
- package/util/file.ts +15 -0
- package/util/format-and-abbreviate-as-currency.ts +125 -0
- package/util/format-text.ts +34 -0
- package/util/format-to-max-char.ts +68 -0
- package/util/index-client.ts +3 -0
- package/util/index.ts +112 -0
- package/util/number-abbreviate.ts +49 -0
- package/util/specifier.ts +43 -0
- package/util/spread-to-transform.ts +25 -0
- package/util/step-animation.ts +90 -0
- package/util/timing.ts +3 -0
- package/util/toasts.tsx +17 -0
- package/util/two-way-map.ts +19 -0
- package/CHANGELOG.md +0 -184
- package/LICENSE +0 -21
- package/dist/ai/index.js +0 -53
- package/dist/ai/index.js.map +0 -1
- package/dist/ai/index.mjs +0 -4
- package/dist/ai/index.mjs.map +0 -1
- package/dist/blocks/index.js +0 -983
- package/dist/blocks/index.js.map +0 -1
- package/dist/blocks/index.mjs +0 -945
- package/dist/blocks/index.mjs.map +0 -1
- package/dist/calendar/index.js +0 -14
- package/dist/calendar/index.js.map +0 -1
- package/dist/calendar/index.mjs +0 -5
- package/dist/calendar/index.mjs.map +0 -1
- package/dist/carousel/index.js +0 -220
- package/dist/carousel/index.js.map +0 -1
- package/dist/carousel/index.mjs +0 -191
- package/dist/carousel/index.mjs.map +0 -1
- package/dist/charts/index.js +0 -945
- package/dist/charts/index.js.map +0 -1
- package/dist/charts/index.mjs +0 -901
- package/dist/charts/index.mjs.map +0 -1
- package/dist/chunk-26T4V5QU.mjs +0 -111
- package/dist/chunk-26T4V5QU.mjs.map +0 -1
- package/dist/chunk-2A5KXDLJ.js +0 -22
- package/dist/chunk-2A5KXDLJ.js.map +0 -1
- package/dist/chunk-2CJ4HMF4.js +0 -79
- package/dist/chunk-2CJ4HMF4.js.map +0 -1
- package/dist/chunk-2OIQKC5E.js +0 -236
- package/dist/chunk-2OIQKC5E.js.map +0 -1
- package/dist/chunk-2X3KSYBN.js +0 -44
- package/dist/chunk-2X3KSYBN.js.map +0 -1
- package/dist/chunk-3PBQGYR7.mjs +0 -100
- package/dist/chunk-3PBQGYR7.mjs.map +0 -1
- package/dist/chunk-3POQQ6L7.js +0 -62
- package/dist/chunk-3POQQ6L7.js.map +0 -1
- package/dist/chunk-4B47GITH.mjs +0 -28
- package/dist/chunk-4B47GITH.mjs.map +0 -1
- package/dist/chunk-4BC2OH6B.js +0 -129
- package/dist/chunk-4BC2OH6B.js.map +0 -1
- package/dist/chunk-5AQSGH4R.js +0 -130
- package/dist/chunk-5AQSGH4R.js.map +0 -1
- package/dist/chunk-5IHRJFOO.mjs +0 -102
- package/dist/chunk-5IHRJFOO.mjs.map +0 -1
- package/dist/chunk-5LDGR7YN.mjs +0 -28
- package/dist/chunk-5LDGR7YN.mjs.map +0 -1
- package/dist/chunk-5MCN3VYM.mjs +0 -23
- package/dist/chunk-5MCN3VYM.mjs.map +0 -1
- package/dist/chunk-6AVAMRMB.mjs +0 -47
- package/dist/chunk-6AVAMRMB.mjs.map +0 -1
- package/dist/chunk-6H62JRNM.mjs +0 -120
- package/dist/chunk-6H62JRNM.mjs.map +0 -1
- package/dist/chunk-6KCII3F6.mjs +0 -126
- package/dist/chunk-6KCII3F6.mjs.map +0 -1
- package/dist/chunk-7EHB43BJ.js +0 -155
- package/dist/chunk-7EHB43BJ.js.map +0 -1
- package/dist/chunk-7LRD23Q5.js +0 -191
- package/dist/chunk-7LRD23Q5.js.map +0 -1
- package/dist/chunk-7SAHKOJG.mjs +0 -45
- package/dist/chunk-7SAHKOJG.mjs.map +0 -1
- package/dist/chunk-A3D2YZK3.js +0 -50
- package/dist/chunk-A3D2YZK3.js.map +0 -1
- package/dist/chunk-AL4QFH7V.js +0 -63
- package/dist/chunk-AL4QFH7V.js.map +0 -1
- package/dist/chunk-B3WFEG6U.js +0 -69
- package/dist/chunk-B3WFEG6U.js.map +0 -1
- package/dist/chunk-BDZQJ6GK.js +0 -242
- package/dist/chunk-BDZQJ6GK.js.map +0 -1
- package/dist/chunk-BRWFYRGX.js +0 -61
- package/dist/chunk-BRWFYRGX.js.map +0 -1
- package/dist/chunk-C5DNTLBO.js +0 -53
- package/dist/chunk-C5DNTLBO.js.map +0 -1
- package/dist/chunk-CRALRACO.js +0 -54
- package/dist/chunk-CRALRACO.js.map +0 -1
- package/dist/chunk-CVACQJRM.js +0 -149
- package/dist/chunk-CVACQJRM.js.map +0 -1
- package/dist/chunk-DEIUKFPZ.mjs +0 -63
- package/dist/chunk-DEIUKFPZ.mjs.map +0 -1
- package/dist/chunk-DN2AEEA2.js +0 -13
- package/dist/chunk-DN2AEEA2.js.map +0 -1
- package/dist/chunk-DTNRWU4B.mjs +0 -35
- package/dist/chunk-DTNRWU4B.mjs.map +0 -1
- package/dist/chunk-DXIUEWRJ.mjs +0 -31
- package/dist/chunk-DXIUEWRJ.mjs.map +0 -1
- package/dist/chunk-DYFV66JX.mjs +0 -54
- package/dist/chunk-DYFV66JX.mjs.map +0 -1
- package/dist/chunk-F3WMAHXV.mjs +0 -86
- package/dist/chunk-F3WMAHXV.mjs.map +0 -1
- package/dist/chunk-F4RWPBBB.js +0 -79
- package/dist/chunk-F4RWPBBB.js.map +0 -1
- package/dist/chunk-FEGAPM6U.js +0 -194
- package/dist/chunk-FEGAPM6U.js.map +0 -1
- package/dist/chunk-G5TS56PW.mjs +0 -160
- package/dist/chunk-G5TS56PW.mjs.map +0 -1
- package/dist/chunk-GG6VGOEN.mjs +0 -590
- package/dist/chunk-GG6VGOEN.mjs.map +0 -1
- package/dist/chunk-GLAMGK32.mjs +0 -54
- package/dist/chunk-GLAMGK32.mjs.map +0 -1
- package/dist/chunk-GNMMUJXD.mjs +0 -200
- package/dist/chunk-GNMMUJXD.mjs.map +0 -1
- package/dist/chunk-GNPBULLS.mjs +0 -600
- package/dist/chunk-GNPBULLS.mjs.map +0 -1
- package/dist/chunk-GTE2DELE.js +0 -65
- package/dist/chunk-GTE2DELE.js.map +0 -1
- package/dist/chunk-GUQAFFTH.js +0 -94
- package/dist/chunk-GUQAFFTH.js.map +0 -1
- package/dist/chunk-H5VOYZHT.mjs +0 -34
- package/dist/chunk-H5VOYZHT.mjs.map +0 -1
- package/dist/chunk-HR6PBOGG.mjs +0 -59
- package/dist/chunk-HR6PBOGG.mjs.map +0 -1
- package/dist/chunk-HROONQS3.js +0 -55
- package/dist/chunk-HROONQS3.js.map +0 -1
- package/dist/chunk-IAO7SOQ3.mjs +0 -56
- package/dist/chunk-IAO7SOQ3.mjs.map +0 -1
- package/dist/chunk-K2QKU3K6.mjs +0 -40
- package/dist/chunk-K2QKU3K6.mjs.map +0 -1
- package/dist/chunk-KEUZZCCP.js +0 -53
- package/dist/chunk-KEUZZCCP.js.map +0 -1
- package/dist/chunk-KJXSLTG7.mjs +0 -73
- package/dist/chunk-KJXSLTG7.mjs.map +0 -1
- package/dist/chunk-L5AFUCVH.mjs +0 -26
- package/dist/chunk-L5AFUCVH.mjs.map +0 -1
- package/dist/chunk-LB3I52KZ.mjs +0 -42
- package/dist/chunk-LB3I52KZ.mjs.map +0 -1
- package/dist/chunk-LN75MJQ2.js +0 -71
- package/dist/chunk-LN75MJQ2.js.map +0 -1
- package/dist/chunk-LRBOFJUV.js +0 -60
- package/dist/chunk-LRBOFJUV.js.map +0 -1
- package/dist/chunk-MMNYRBOU.js +0 -157
- package/dist/chunk-MMNYRBOU.js.map +0 -1
- package/dist/chunk-MO65YF6P.js +0 -236
- package/dist/chunk-MO65YF6P.js.map +0 -1
- package/dist/chunk-N4KHP5FC.mjs +0 -33
- package/dist/chunk-N4KHP5FC.mjs.map +0 -1
- package/dist/chunk-NP2J7AB7.mjs +0 -121
- package/dist/chunk-NP2J7AB7.mjs.map +0 -1
- package/dist/chunk-OLR6SGYO.js +0 -57
- package/dist/chunk-OLR6SGYO.js.map +0 -1
- package/dist/chunk-ON7NQ4DY.js +0 -21
- package/dist/chunk-ON7NQ4DY.js.map +0 -1
- package/dist/chunk-PE3VFRLV.mjs +0 -198
- package/dist/chunk-PE3VFRLV.mjs.map +0 -1
- package/dist/chunk-Q7LOOIE5.mjs +0 -8
- package/dist/chunk-Q7LOOIE5.mjs.map +0 -1
- package/dist/chunk-QFA6U75G.mjs +0 -51
- package/dist/chunk-QFA6U75G.mjs.map +0 -1
- package/dist/chunk-QJQPT4WX.js +0 -638
- package/dist/chunk-QJQPT4WX.js.map +0 -1
- package/dist/chunk-QKHQPBSR.mjs +0 -20
- package/dist/chunk-QKHQPBSR.mjs.map +0 -1
- package/dist/chunk-SJD4XRFJ.mjs +0 -141
- package/dist/chunk-SJD4XRFJ.mjs.map +0 -1
- package/dist/chunk-SOOJLU4C.mjs +0 -19
- package/dist/chunk-SOOJLU4C.mjs.map +0 -1
- package/dist/chunk-T66B5IM5.js +0 -51
- package/dist/chunk-T66B5IM5.js.map +0 -1
- package/dist/chunk-T7RPZDO4.js +0 -645
- package/dist/chunk-T7RPZDO4.js.map +0 -1
- package/dist/chunk-TGRMDGTV.mjs +0 -38
- package/dist/chunk-TGRMDGTV.mjs.map +0 -1
- package/dist/chunk-TH2UKMCO.mjs +0 -11
- package/dist/chunk-TH2UKMCO.mjs.map +0 -1
- package/dist/chunk-TMV45OKE.mjs +0 -113
- package/dist/chunk-TMV45OKE.mjs.map +0 -1
- package/dist/chunk-TUJ7EVEK.js +0 -171
- package/dist/chunk-TUJ7EVEK.js.map +0 -1
- package/dist/chunk-ULNWDOI7.js +0 -122
- package/dist/chunk-ULNWDOI7.js.map +0 -1
- package/dist/chunk-UNUTTHCH.mjs +0 -210
- package/dist/chunk-UNUTTHCH.mjs.map +0 -1
- package/dist/chunk-VJMI6BG4.mjs +0 -10
- package/dist/chunk-VJMI6BG4.mjs.map +0 -1
- package/dist/chunk-VZVOB5MG.mjs +0 -26
- package/dist/chunk-VZVOB5MG.mjs.map +0 -1
- package/dist/chunk-WD67O22C.js +0 -50
- package/dist/chunk-WD67O22C.js.map +0 -1
- package/dist/chunk-WYPMLIJN.js +0 -53
- package/dist/chunk-WYPMLIJN.js.map +0 -1
- package/dist/chunk-X32I34NH.js +0 -109
- package/dist/chunk-X32I34NH.js.map +0 -1
- package/dist/chunk-X5MOZ3YL.js +0 -65
- package/dist/chunk-X5MOZ3YL.js.map +0 -1
- package/dist/chunk-Y4JVIPQZ.mjs +0 -31
- package/dist/chunk-Y4JVIPQZ.mjs.map +0 -1
- package/dist/chunk-Y6WOV2LZ.js +0 -95
- package/dist/chunk-Y6WOV2LZ.js.map +0 -1
- package/dist/chunk-YAEN5SCU.mjs +0 -41
- package/dist/chunk-YAEN5SCU.mjs.map +0 -1
- package/dist/chunk-YH6XDF3N.js +0 -121
- package/dist/chunk-YH6XDF3N.js.map +0 -1
- package/dist/chunk-YJKA4D75.mjs +0 -124
- package/dist/chunk-YJKA4D75.mjs.map +0 -1
- package/dist/chunk-ZANAF7WB.js +0 -88
- package/dist/chunk-ZANAF7WB.js.map +0 -1
- package/dist/chunk-ZDBWNPLO.js +0 -30
- package/dist/chunk-ZDBWNPLO.js.map +0 -1
- package/dist/chunk-ZDT2IOK2.js +0 -56
- package/dist/chunk-ZDT2IOK2.js.map +0 -1
- package/dist/chunk-ZKGVLTSI.js +0 -25
- package/dist/chunk-ZKGVLTSI.js.map +0 -1
- package/dist/chunk-ZLELESO7.js +0 -34
- package/dist/chunk-ZLELESO7.js.map +0 -1
- package/dist/chunk-ZUFUEQTX.mjs +0 -157
- package/dist/chunk-ZUFUEQTX.mjs.map +0 -1
- package/dist/chunk-ZZZWRQQE.mjs +0 -42
- package/dist/chunk-ZZZWRQQE.mjs.map +0 -1
- package/dist/command/index.js +0 -138
- package/dist/command/index.js.map +0 -1
- package/dist/command/index.mjs +0 -128
- package/dist/command/index.mjs.map +0 -1
- package/dist/components/accordion.js +0 -25
- package/dist/components/accordion.js.map +0 -1
- package/dist/components/accordion.mjs +0 -4
- package/dist/components/accordion.mjs.map +0 -1
- package/dist/components/alert.js +0 -21
- package/dist/components/alert.js.map +0 -1
- package/dist/components/alert.mjs +0 -4
- package/dist/components/alert.mjs.map +0 -1
- package/dist/components/aspect-ratio.js +0 -12
- package/dist/components/aspect-ratio.js.map +0 -1
- package/dist/components/aspect-ratio.mjs +0 -3
- package/dist/components/aspect-ratio.mjs.map +0 -1
- package/dist/components/avatar.js +0 -21
- package/dist/components/avatar.js.map +0 -1
- package/dist/components/avatar.mjs +0 -4
- package/dist/components/avatar.mjs.map +0 -1
- package/dist/components/badge.js +0 -17
- package/dist/components/badge.js.map +0 -1
- package/dist/components/badge.mjs +0 -4
- package/dist/components/badge.mjs.map +0 -1
- package/dist/components/breadcrumb.js +0 -37
- package/dist/components/breadcrumb.js.map +0 -1
- package/dist/components/breadcrumb.mjs +0 -4
- package/dist/components/breadcrumb.mjs.map +0 -1
- package/dist/components/button.js +0 -17
- package/dist/components/button.js.map +0 -1
- package/dist/components/button.mjs +0 -4
- package/dist/components/button.mjs.map +0 -1
- package/dist/components/card.js +0 -37
- package/dist/components/card.js.map +0 -1
- package/dist/components/card.mjs +0 -4
- package/dist/components/card.mjs.map +0 -1
- package/dist/components/checkbox.js +0 -13
- package/dist/components/checkbox.js.map +0 -1
- package/dist/components/checkbox.mjs +0 -4
- package/dist/components/checkbox.mjs.map +0 -1
- package/dist/components/collapsible.js +0 -20
- package/dist/components/collapsible.js.map +0 -1
- package/dist/components/collapsible.mjs +0 -3
- package/dist/components/collapsible.mjs.map +0 -1
- package/dist/components/context-menu.js +0 -69
- package/dist/components/context-menu.js.map +0 -1
- package/dist/components/context-menu.mjs +0 -4
- package/dist/components/context-menu.mjs.map +0 -1
- package/dist/components/dialog.js +0 -49
- package/dist/components/dialog.js.map +0 -1
- package/dist/components/dialog.mjs +0 -4
- package/dist/components/dialog.mjs.map +0 -1
- package/dist/components/drawer.js +0 -49
- package/dist/components/drawer.js.map +0 -1
- package/dist/components/drawer.mjs +0 -4
- package/dist/components/drawer.mjs.map +0 -1
- package/dist/components/dropdown-menu.js +0 -69
- package/dist/components/dropdown-menu.js.map +0 -1
- package/dist/components/dropdown-menu.mjs +0 -4
- package/dist/components/dropdown-menu.mjs.map +0 -1
- package/dist/components/form.js +0 -42
- package/dist/components/form.js.map +0 -1
- package/dist/components/form.mjs +0 -5
- package/dist/components/form.mjs.map +0 -1
- package/dist/components/hover-card.js +0 -21
- package/dist/components/hover-card.js.map +0 -1
- package/dist/components/hover-card.mjs +0 -4
- package/dist/components/hover-card.mjs.map +0 -1
- package/dist/components/index.js +0 -1047
- package/dist/components/index.js.map +0 -1
- package/dist/components/index.mjs +0 -46
- package/dist/components/index.mjs.map +0 -1
- package/dist/components/input-otp.js +0 -25
- package/dist/components/input-otp.js.map +0 -1
- package/dist/components/input-otp.mjs +0 -4
- package/dist/components/input-otp.mjs.map +0 -1
- package/dist/components/input.js +0 -13
- package/dist/components/input.js.map +0 -1
- package/dist/components/input.mjs +0 -4
- package/dist/components/input.mjs.map +0 -1
- package/dist/components/label.js +0 -13
- package/dist/components/label.js.map +0 -1
- package/dist/components/label.mjs +0 -4
- package/dist/components/label.mjs.map +0 -1
- package/dist/components/menubar.js +0 -73
- package/dist/components/menubar.js.map +0 -1
- package/dist/components/menubar.mjs +0 -4
- package/dist/components/menubar.mjs.map +0 -1
- package/dist/components/navigation-menu.js +0 -45
- package/dist/components/navigation-menu.js.map +0 -1
- package/dist/components/navigation-menu.mjs +0 -4
- package/dist/components/navigation-menu.mjs.map +0 -1
- package/dist/components/pagination.js +0 -38
- package/dist/components/pagination.js.map +0 -1
- package/dist/components/pagination.mjs +0 -5
- package/dist/components/pagination.mjs.map +0 -1
- package/dist/components/popover.js +0 -25
- package/dist/components/popover.js.map +0 -1
- package/dist/components/popover.mjs +0 -4
- package/dist/components/popover.mjs.map +0 -1
- package/dist/components/progress.js +0 -13
- package/dist/components/progress.js.map +0 -1
- package/dist/components/progress.mjs +0 -4
- package/dist/components/progress.mjs.map +0 -1
- package/dist/components/radio-group.js +0 -17
- package/dist/components/radio-group.js.map +0 -1
- package/dist/components/radio-group.mjs +0 -4
- package/dist/components/radio-group.mjs.map +0 -1
- package/dist/components/resizable.js +0 -21
- package/dist/components/resizable.js.map +0 -1
- package/dist/components/resizable.mjs +0 -4
- package/dist/components/resizable.mjs.map +0 -1
- package/dist/components/scroll-area.js +0 -17
- package/dist/components/scroll-area.js.map +0 -1
- package/dist/components/scroll-area.mjs +0 -4
- package/dist/components/scroll-area.mjs.map +0 -1
- package/dist/components/select.js +0 -49
- package/dist/components/select.js.map +0 -1
- package/dist/components/select.mjs +0 -4
- package/dist/components/select.mjs.map +0 -1
- package/dist/components/separator.js +0 -13
- package/dist/components/separator.js.map +0 -1
- package/dist/components/separator.mjs +0 -4
- package/dist/components/separator.mjs.map +0 -1
- package/dist/components/sheet.js +0 -49
- package/dist/components/sheet.js.map +0 -1
- package/dist/components/sheet.mjs +0 -4
- package/dist/components/sheet.mjs.map +0 -1
- package/dist/components/sidebar.js +0 -111
- package/dist/components/sidebar.js.map +0 -1
- package/dist/components/sidebar.mjs +0 -10
- package/dist/components/sidebar.mjs.map +0 -1
- package/dist/components/skeleton.js +0 -13
- package/dist/components/skeleton.js.map +0 -1
- package/dist/components/skeleton.mjs +0 -4
- package/dist/components/skeleton.mjs.map +0 -1
- package/dist/components/slider.js +0 -13
- package/dist/components/slider.js.map +0 -1
- package/dist/components/slider.mjs +0 -4
- package/dist/components/slider.mjs.map +0 -1
- package/dist/components/switch.js +0 -13
- package/dist/components/switch.js.map +0 -1
- package/dist/components/switch.mjs +0 -4
- package/dist/components/switch.mjs.map +0 -1
- package/dist/components/table.js +0 -41
- package/dist/components/table.js.map +0 -1
- package/dist/components/table.mjs +0 -4
- package/dist/components/table.mjs.map +0 -1
- package/dist/components/tabs.js +0 -25
- package/dist/components/tabs.js.map +0 -1
- package/dist/components/tabs.mjs +0 -4
- package/dist/components/tabs.mjs.map +0 -1
- package/dist/components/textarea.js +0 -13
- package/dist/components/textarea.js.map +0 -1
- package/dist/components/textarea.mjs +0 -4
- package/dist/components/textarea.mjs.map +0 -1
- package/dist/components/toast.js +0 -37
- package/dist/components/toast.js.map +0 -1
- package/dist/components/toast.mjs +0 -4
- package/dist/components/toast.mjs.map +0 -1
- package/dist/components/toggle-group.js +0 -18
- package/dist/components/toggle-group.js.map +0 -1
- package/dist/components/toggle-group.mjs +0 -5
- package/dist/components/toggle-group.mjs.map +0 -1
- package/dist/components/toggle.js +0 -17
- package/dist/components/toggle.js.map +0 -1
- package/dist/components/toggle.mjs +0 -4
- package/dist/components/toggle.mjs.map +0 -1
- package/dist/components/tooltip.js +0 -25
- package/dist/components/tooltip.js.map +0 -1
- package/dist/components/tooltip.mjs +0 -4
- package/dist/components/tooltip.mjs.map +0 -1
- package/dist/effects/index.js +0 -162
- package/dist/effects/index.js.map +0 -1
- package/dist/effects/index.mjs +0 -156
- package/dist/effects/index.mjs.map +0 -1
- package/dist/lib/utils.js +0 -12
- package/dist/lib/utils.js.map +0 -1
- package/dist/lib/utils.mjs +0 -3
- package/dist/lib/utils.mjs.map +0 -1
- package/dist/markdown/index.js +0 -669
- package/dist/markdown/index.js.map +0 -1
- package/dist/markdown/index.mjs +0 -635
- package/dist/markdown/index.mjs.map +0 -1
- package/dist/qr/index.js +0 -101
- package/dist/qr/index.js.map +0 -1
- package/dist/qr/index.mjs +0 -98
- package/dist/qr/index.mjs.map +0 -1
- package/dist/upload/index.js +0 -166
- package/dist/upload/index.js.map +0 -1
- package/dist/upload/index.mjs +0 -163
- package/dist/upload/index.mjs.map +0 -1
- package/publish.sh +0 -27
|
@@ -0,0 +1,1208 @@
|
|
|
1
|
+
import { registrySchema, Registry, RegistryItem } from "../registry"
|
|
2
|
+
import { fetchRegistry, getRegistryItem, getRegistryItemUrl } from "../registry/api"
|
|
3
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js"
|
|
4
|
+
import {
|
|
5
|
+
CallToolRequestSchema,
|
|
6
|
+
ListToolsRequestSchema,
|
|
7
|
+
ListResourcesRequestSchema,
|
|
8
|
+
ReadResourceRequestSchema,
|
|
9
|
+
ListPromptsRequestSchema,
|
|
10
|
+
GetPromptRequestSchema,
|
|
11
|
+
} from "@modelcontextprotocol/sdk/types.js"
|
|
12
|
+
import { z } from "zod"
|
|
13
|
+
import { zodToJsonSchema } from "zod-to-json-schema"
|
|
14
|
+
import * as fs from "fs/promises"
|
|
15
|
+
import * as path from "path"
|
|
16
|
+
import { fileURLToPath } from "url"
|
|
17
|
+
import { dirname } from "path"
|
|
18
|
+
|
|
19
|
+
// Get package version
|
|
20
|
+
let packageVersion = "4.5.0"
|
|
21
|
+
try {
|
|
22
|
+
const packageJson = JSON.parse(await fs.readFile(path.join(dirname(fileURLToPath(import.meta.url)), "../../package.json"), "utf-8"))
|
|
23
|
+
packageVersion = packageJson.version || packageVersion
|
|
24
|
+
} catch (error) {
|
|
25
|
+
console.error("Could not load package.json for version", error)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Enhanced MCP Server implementation for @hanzo/ui registry
|
|
30
|
+
* Provides comprehensive tools, resources, and prompts for AI-assisted development
|
|
31
|
+
*/
|
|
32
|
+
export const server = new Server(
|
|
33
|
+
{
|
|
34
|
+
name: "hanzo-ui",
|
|
35
|
+
version: packageVersion,
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
capabilities: {
|
|
39
|
+
resources: {},
|
|
40
|
+
tools: {},
|
|
41
|
+
prompts: {},
|
|
42
|
+
},
|
|
43
|
+
}
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
// Cache for registry data
|
|
47
|
+
let registryCache: Registry | null = null
|
|
48
|
+
let registryCacheTime = 0
|
|
49
|
+
const CACHE_DURATION = 5 * 60 * 1000 // 5 minutes
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Fetches and caches the registry
|
|
53
|
+
*/
|
|
54
|
+
async function getRegistry(): Promise<Registry> {
|
|
55
|
+
const now = Date.now()
|
|
56
|
+
if (registryCache && now - registryCacheTime < CACHE_DURATION) {
|
|
57
|
+
return registryCache
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
try {
|
|
61
|
+
const registryUrl = process.env.REGISTRY_URL || "https://ui.hanzo.ai/registry/registry.json"
|
|
62
|
+
const [registryJson] = await fetchRegistry([registryUrl], {
|
|
63
|
+
useCache: false,
|
|
64
|
+
})
|
|
65
|
+
registryCache = registrySchema.parse(registryJson)
|
|
66
|
+
registryCacheTime = now
|
|
67
|
+
return registryCache
|
|
68
|
+
} catch (error) {
|
|
69
|
+
console.error("Failed to fetch registry:", error)
|
|
70
|
+
// Return cached version if available, otherwise minimal registry
|
|
71
|
+
return registryCache || {
|
|
72
|
+
name: "hanzo-ui",
|
|
73
|
+
items: [],
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Get the source code of a component from the primitives directory
|
|
80
|
+
*/
|
|
81
|
+
async function getComponentSource(componentName: string): Promise<string | null> {
|
|
82
|
+
try {
|
|
83
|
+
const primitivesPath = path.join(dirname(fileURLToPath(import.meta.url)), "../primitives")
|
|
84
|
+
const componentPath = path.join(primitivesPath, `${componentName}.tsx`)
|
|
85
|
+
|
|
86
|
+
// Check if file exists
|
|
87
|
+
await fs.access(componentPath)
|
|
88
|
+
const source = await fs.readFile(componentPath, "utf-8")
|
|
89
|
+
return source
|
|
90
|
+
} catch (error) {
|
|
91
|
+
// Try to find in registry
|
|
92
|
+
try {
|
|
93
|
+
const registryUrl = process.env.REGISTRY_URL || "https://ui.hanzo.ai/registry/registry.json"
|
|
94
|
+
const itemUrl = getRegistryItemUrl(componentName, registryUrl)
|
|
95
|
+
const component = await getRegistryItem(itemUrl, "")
|
|
96
|
+
|
|
97
|
+
if (component && component.files && component.files.length > 0) {
|
|
98
|
+
// Return the first file's content (usually the main component)
|
|
99
|
+
const mainFile = component.files.find(f => f.type === "registry:ui") || component.files[0]
|
|
100
|
+
return mainFile.content || null
|
|
101
|
+
}
|
|
102
|
+
} catch (registryError) {
|
|
103
|
+
console.error(`Failed to get component source for ${componentName}:`, registryError)
|
|
104
|
+
}
|
|
105
|
+
return null
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Register the available tools
|
|
110
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
111
|
+
return {
|
|
112
|
+
tools: [
|
|
113
|
+
{
|
|
114
|
+
name: "init",
|
|
115
|
+
description: "Initialize a new project using @hanzo/ui components and styles.",
|
|
116
|
+
inputSchema: zodToJsonSchema(z.object({
|
|
117
|
+
style: z.string().optional().describe("The style to use for the project (e.g., 'default' or 'new-york')"),
|
|
118
|
+
})),
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
name: "list_components",
|
|
122
|
+
description: "List all available components in the registry",
|
|
123
|
+
inputSchema: zodToJsonSchema(z.object({
|
|
124
|
+
type: z.string().optional().describe("Filter components by type (e.g., 'ui', 'block')"),
|
|
125
|
+
category: z.string().optional().describe("Filter components by category"),
|
|
126
|
+
})),
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
name: "get_component",
|
|
130
|
+
description: "Get detailed information about a specific component",
|
|
131
|
+
inputSchema: zodToJsonSchema(
|
|
132
|
+
z.object({
|
|
133
|
+
name: z.string().describe("The name of the component to get from the registry"),
|
|
134
|
+
})
|
|
135
|
+
),
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
name: "get_component_source",
|
|
139
|
+
description: "Get the full source code of a component",
|
|
140
|
+
inputSchema: zodToJsonSchema(
|
|
141
|
+
z.object({
|
|
142
|
+
name: z.string().describe("The name of the component to get source code for"),
|
|
143
|
+
})
|
|
144
|
+
),
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
name: "get_component_demo",
|
|
148
|
+
description: "Get a demo/example implementation of a component",
|
|
149
|
+
inputSchema: zodToJsonSchema(
|
|
150
|
+
z.object({
|
|
151
|
+
name: z.string().describe("The name of the component to get demo for"),
|
|
152
|
+
})
|
|
153
|
+
),
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
name: "add_component",
|
|
157
|
+
description: "Get instructions for adding a component to a project",
|
|
158
|
+
inputSchema: zodToJsonSchema(
|
|
159
|
+
z.object({
|
|
160
|
+
name: z.string().describe("The name of the component to add"),
|
|
161
|
+
style: z.string().optional().describe("The style to use (default, new-york, etc.)"),
|
|
162
|
+
})
|
|
163
|
+
),
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
name: "list_blocks",
|
|
167
|
+
description: "List all available UI blocks/patterns",
|
|
168
|
+
inputSchema: zodToJsonSchema(z.object({
|
|
169
|
+
category: z.string().optional().describe("Filter blocks by category"),
|
|
170
|
+
})),
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
name: "get_block",
|
|
174
|
+
description: "Get detailed information about a specific block",
|
|
175
|
+
inputSchema: zodToJsonSchema(
|
|
176
|
+
z.object({
|
|
177
|
+
name: z.string().describe("The name of the block to get"),
|
|
178
|
+
})
|
|
179
|
+
),
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
name: "list_styles",
|
|
183
|
+
description: "List all available styles in the registry",
|
|
184
|
+
inputSchema: zodToJsonSchema(z.object({})),
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
name: "search_registry",
|
|
188
|
+
description: "Search the registry for components matching criteria",
|
|
189
|
+
inputSchema: zodToJsonSchema(
|
|
190
|
+
z.object({
|
|
191
|
+
query: z.string().describe("Search term to look for in component names and descriptions"),
|
|
192
|
+
})
|
|
193
|
+
),
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
name: "get_installation_guide",
|
|
197
|
+
description: "Get the complete installation guide for setting up Hanzo UI",
|
|
198
|
+
inputSchema: zodToJsonSchema(z.object({})),
|
|
199
|
+
},
|
|
200
|
+
],
|
|
201
|
+
}
|
|
202
|
+
})
|
|
203
|
+
|
|
204
|
+
// Register available resources
|
|
205
|
+
server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
206
|
+
const registry = await getRegistry()
|
|
207
|
+
|
|
208
|
+
return {
|
|
209
|
+
resources: [
|
|
210
|
+
{
|
|
211
|
+
uri: "hanzo://components/list",
|
|
212
|
+
name: "Component List",
|
|
213
|
+
description: "Complete list of all available Hanzo UI components",
|
|
214
|
+
mimeType: "text/markdown",
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
uri: "hanzo://blocks/list",
|
|
218
|
+
name: "Block List",
|
|
219
|
+
description: "List of all UI blocks and patterns",
|
|
220
|
+
mimeType: "text/markdown",
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
uri: "hanzo://installation/guide",
|
|
224
|
+
name: "Installation Guide",
|
|
225
|
+
description: "Complete guide for installing and setting up Hanzo UI",
|
|
226
|
+
mimeType: "text/markdown",
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
uri: "hanzo://theming/guide",
|
|
230
|
+
name: "Theming Guide",
|
|
231
|
+
description: "Guide for customizing themes and styles",
|
|
232
|
+
mimeType: "text/markdown",
|
|
233
|
+
},
|
|
234
|
+
],
|
|
235
|
+
}
|
|
236
|
+
})
|
|
237
|
+
|
|
238
|
+
// Handle resource reads
|
|
239
|
+
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
240
|
+
const uri = request.params.uri
|
|
241
|
+
const registry = await getRegistry()
|
|
242
|
+
|
|
243
|
+
switch (uri) {
|
|
244
|
+
case "hanzo://components/list": {
|
|
245
|
+
const components = registry.items.filter(item => item.type.includes("ui:"))
|
|
246
|
+
const grouped = components.reduce((acc, item) => {
|
|
247
|
+
const category = item.category || "Uncategorized"
|
|
248
|
+
if (!acc[category]) acc[category] = []
|
|
249
|
+
acc[category].push(item)
|
|
250
|
+
return acc
|
|
251
|
+
}, {} as Record<string, RegistryItem[]>)
|
|
252
|
+
|
|
253
|
+
let content = "# Hanzo UI Components\n\n"
|
|
254
|
+
for (const [category, items] of Object.entries(grouped)) {
|
|
255
|
+
content += `## ${category}\n\n`
|
|
256
|
+
for (const item of items) {
|
|
257
|
+
content += `### ${item.name}\n`
|
|
258
|
+
content += `${item.description || 'No description'}\n\n`
|
|
259
|
+
content += `**Command:** \`npx @hanzo/ui@latest add ${item.name}\`\n\n`
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
return {
|
|
264
|
+
contents: [{ uri, mimeType: "text/markdown", text: content }],
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
case "hanzo://blocks/list": {
|
|
269
|
+
const blocks = registry.items.filter(item => item.type.includes("block"))
|
|
270
|
+
let content = "# Hanzo UI Blocks\n\n"
|
|
271
|
+
|
|
272
|
+
for (const block of blocks) {
|
|
273
|
+
content += `## ${block.name}\n`
|
|
274
|
+
content += `${block.description || 'No description'}\n\n`
|
|
275
|
+
content += `**Command:** \`npx @hanzo/ui@latest add ${block.name}\`\n\n`
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
return {
|
|
279
|
+
contents: [{ uri, mimeType: "text/markdown", text: content }],
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
case "hanzo://installation/guide": {
|
|
284
|
+
const content = `# Hanzo UI Installation Guide
|
|
285
|
+
|
|
286
|
+
## Quick Start
|
|
287
|
+
|
|
288
|
+
### 1. Create a new project
|
|
289
|
+
\`\`\`bash
|
|
290
|
+
npm create next-app@latest my-app --typescript --tailwind --app
|
|
291
|
+
cd my-app
|
|
292
|
+
\`\`\`
|
|
293
|
+
|
|
294
|
+
### 2. Initialize Hanzo UI
|
|
295
|
+
\`\`\`bash
|
|
296
|
+
npx @hanzo/ui@latest init
|
|
297
|
+
\`\`\`
|
|
298
|
+
|
|
299
|
+
This will:
|
|
300
|
+
- Install dependencies
|
|
301
|
+
- Configure Tailwind CSS
|
|
302
|
+
- Set up the project structure
|
|
303
|
+
- Add the cn() utility function
|
|
304
|
+
|
|
305
|
+
### 3. Add components
|
|
306
|
+
\`\`\`bash
|
|
307
|
+
# Add specific components
|
|
308
|
+
npx @hanzo/ui@latest add button
|
|
309
|
+
npx @hanzo/ui@latest add card dialog
|
|
310
|
+
|
|
311
|
+
# Add multiple components
|
|
312
|
+
npx @hanzo/ui@latest add button card dialog
|
|
313
|
+
\`\`\`
|
|
314
|
+
|
|
315
|
+
## Manual Installation
|
|
316
|
+
|
|
317
|
+
### 1. Install dependencies
|
|
318
|
+
\`\`\`bash
|
|
319
|
+
npm install tailwindcss-animate class-variance-authority clsx tailwind-merge
|
|
320
|
+
\`\`\`
|
|
321
|
+
|
|
322
|
+
### 2. Configure tailwind.config.js
|
|
323
|
+
\`\`\`javascript
|
|
324
|
+
module.exports = {
|
|
325
|
+
darkMode: ["class"],
|
|
326
|
+
content: [
|
|
327
|
+
'./pages/**/*.{ts,tsx}',
|
|
328
|
+
'./components/**/*.{ts,tsx}',
|
|
329
|
+
'./app/**/*.{ts,tsx}',
|
|
330
|
+
'./src/**/*.{ts,tsx}',
|
|
331
|
+
],
|
|
332
|
+
theme: {
|
|
333
|
+
extend: {},
|
|
334
|
+
},
|
|
335
|
+
plugins: [require("tailwindcss-animate")],
|
|
336
|
+
}
|
|
337
|
+
\`\`\`
|
|
338
|
+
|
|
339
|
+
### 3. Add the cn() utility
|
|
340
|
+
Create \`lib/utils.ts\`:
|
|
341
|
+
\`\`\`typescript
|
|
342
|
+
import { ClassValue, clsx } from "clsx"
|
|
343
|
+
import { twMerge } from "tailwind-merge"
|
|
344
|
+
|
|
345
|
+
export function cn(...inputs: ClassValue[]) {
|
|
346
|
+
return twMerge(clsx(inputs))
|
|
347
|
+
}
|
|
348
|
+
\`\`\`
|
|
349
|
+
|
|
350
|
+
## Using Components
|
|
351
|
+
|
|
352
|
+
Import and use components in your application:
|
|
353
|
+
|
|
354
|
+
\`\`\`tsx
|
|
355
|
+
import { Button } from "@/components/ui/button"
|
|
356
|
+
|
|
357
|
+
export default function Home() {
|
|
358
|
+
return (
|
|
359
|
+
<Button variant="outline">Click me</Button>
|
|
360
|
+
)
|
|
361
|
+
}
|
|
362
|
+
\`\`\`
|
|
363
|
+
`
|
|
364
|
+
return {
|
|
365
|
+
contents: [{ uri, mimeType: "text/markdown", text: content }],
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
case "hanzo://theming/guide": {
|
|
370
|
+
const content = `# Hanzo UI Theming Guide
|
|
371
|
+
|
|
372
|
+
## Color System
|
|
373
|
+
|
|
374
|
+
Hanzo UI uses CSS variables for theming, making it easy to customize colors.
|
|
375
|
+
|
|
376
|
+
### Default Theme Variables
|
|
377
|
+
|
|
378
|
+
Add to your \`globals.css\`:
|
|
379
|
+
|
|
380
|
+
\`\`\`css
|
|
381
|
+
@layer base {
|
|
382
|
+
:root {
|
|
383
|
+
--background: 0 0% 100%;
|
|
384
|
+
--foreground: 222.2 84% 4.9%;
|
|
385
|
+
--card: 0 0% 100%;
|
|
386
|
+
--card-foreground: 222.2 84% 4.9%;
|
|
387
|
+
--popover: 0 0% 100%;
|
|
388
|
+
--popover-foreground: 222.2 84% 4.9%;
|
|
389
|
+
--primary: 222.2 47.4% 11.2%;
|
|
390
|
+
--primary-foreground: 210 40% 98%;
|
|
391
|
+
--secondary: 210 40% 96.1%;
|
|
392
|
+
--secondary-foreground: 222.2 47.4% 11.2%;
|
|
393
|
+
--muted: 210 40% 96.1%;
|
|
394
|
+
--muted-foreground: 215.4 16.3% 46.9%;
|
|
395
|
+
--accent: 210 40% 96.1%;
|
|
396
|
+
--accent-foreground: 222.2 47.4% 11.2%;
|
|
397
|
+
--destructive: 0 84.2% 60.2%;
|
|
398
|
+
--destructive-foreground: 210 40% 98%;
|
|
399
|
+
--border: 214.3 31.8% 91.4%;
|
|
400
|
+
--input: 214.3 31.8% 91.4%;
|
|
401
|
+
--ring: 222.2 84% 4.9%;
|
|
402
|
+
--radius: 0.5rem;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
.dark {
|
|
406
|
+
--background: 222.2 84% 4.9%;
|
|
407
|
+
--foreground: 210 40% 98%;
|
|
408
|
+
/* ... dark mode colors ... */
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
\`\`\`
|
|
412
|
+
|
|
413
|
+
## Custom Themes
|
|
414
|
+
|
|
415
|
+
### Creating a Custom Theme
|
|
416
|
+
|
|
417
|
+
1. Define your color palette
|
|
418
|
+
2. Convert colors to HSL format
|
|
419
|
+
3. Update CSS variables
|
|
420
|
+
4. Apply to components
|
|
421
|
+
|
|
422
|
+
### Example: Brand Theme
|
|
423
|
+
|
|
424
|
+
\`\`\`css
|
|
425
|
+
@layer base {
|
|
426
|
+
:root {
|
|
427
|
+
--primary: 262 80% 50%; /* Purple */
|
|
428
|
+
--secondary: 173 80% 40%; /* Teal */
|
|
429
|
+
/* ... other custom colors ... */
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
\`\`\`
|
|
433
|
+
|
|
434
|
+
## Component Variants
|
|
435
|
+
|
|
436
|
+
Many components support variants for different styles:
|
|
437
|
+
|
|
438
|
+
\`\`\`tsx
|
|
439
|
+
<Button variant="default">Default</Button>
|
|
440
|
+
<Button variant="destructive">Destructive</Button>
|
|
441
|
+
<Button variant="outline">Outline</Button>
|
|
442
|
+
<Button variant="secondary">Secondary</Button>
|
|
443
|
+
<Button variant="ghost">Ghost</Button>
|
|
444
|
+
<Button variant="link">Link</Button>
|
|
445
|
+
\`\`\`
|
|
446
|
+
|
|
447
|
+
## Dark Mode
|
|
448
|
+
|
|
449
|
+
Toggle dark mode with a simple class:
|
|
450
|
+
|
|
451
|
+
\`\`\`tsx
|
|
452
|
+
// Add to your root layout or app
|
|
453
|
+
<html className="dark">
|
|
454
|
+
{/* Your app */}
|
|
455
|
+
</html>
|
|
456
|
+
\`\`\`
|
|
457
|
+
|
|
458
|
+
## Advanced Customization
|
|
459
|
+
|
|
460
|
+
### Custom Component Styles
|
|
461
|
+
|
|
462
|
+
Override component styles using className:
|
|
463
|
+
|
|
464
|
+
\`\`\`tsx
|
|
465
|
+
<Button
|
|
466
|
+
className="bg-gradient-to-r from-purple-500 to-pink-500"
|
|
467
|
+
>
|
|
468
|
+
Gradient Button
|
|
469
|
+
</Button>
|
|
470
|
+
\`\`\`
|
|
471
|
+
|
|
472
|
+
### Global Style Overrides
|
|
473
|
+
|
|
474
|
+
Add to your CSS file:
|
|
475
|
+
|
|
476
|
+
\`\`\`css
|
|
477
|
+
/* Override all buttons */
|
|
478
|
+
.ui-button {
|
|
479
|
+
@apply font-bold tracking-wide;
|
|
480
|
+
}
|
|
481
|
+
\`\`\`
|
|
482
|
+
`
|
|
483
|
+
return {
|
|
484
|
+
contents: [{ uri, mimeType: "text/markdown", text: content }],
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
default:
|
|
489
|
+
throw new Error(`Unknown resource: ${uri}`)
|
|
490
|
+
}
|
|
491
|
+
})
|
|
492
|
+
|
|
493
|
+
// Register available prompts
|
|
494
|
+
server.setRequestHandler(ListPromptsRequestSchema, async () => {
|
|
495
|
+
return {
|
|
496
|
+
prompts: [
|
|
497
|
+
{
|
|
498
|
+
name: "component_usage",
|
|
499
|
+
description: "Generate usage examples for a Hanzo UI component",
|
|
500
|
+
arguments: [
|
|
501
|
+
{
|
|
502
|
+
name: "component",
|
|
503
|
+
description: "Name of the component",
|
|
504
|
+
required: true,
|
|
505
|
+
},
|
|
506
|
+
],
|
|
507
|
+
},
|
|
508
|
+
{
|
|
509
|
+
name: "build_page",
|
|
510
|
+
description: "Build a complete page using Hanzo UI components",
|
|
511
|
+
arguments: [
|
|
512
|
+
{
|
|
513
|
+
name: "page_type",
|
|
514
|
+
description: "Type of page (landing, dashboard, form, etc.)",
|
|
515
|
+
required: true,
|
|
516
|
+
},
|
|
517
|
+
],
|
|
518
|
+
},
|
|
519
|
+
{
|
|
520
|
+
name: "component_composition",
|
|
521
|
+
description: "Create a custom component by composing Hanzo UI primitives",
|
|
522
|
+
arguments: [
|
|
523
|
+
{
|
|
524
|
+
name: "component_name",
|
|
525
|
+
description: "Name for the new component",
|
|
526
|
+
required: true,
|
|
527
|
+
},
|
|
528
|
+
{
|
|
529
|
+
name: "description",
|
|
530
|
+
description: "What the component should do",
|
|
531
|
+
required: true,
|
|
532
|
+
},
|
|
533
|
+
],
|
|
534
|
+
},
|
|
535
|
+
{
|
|
536
|
+
name: "accessibility_review",
|
|
537
|
+
description: "Review and improve component accessibility",
|
|
538
|
+
arguments: [
|
|
539
|
+
{
|
|
540
|
+
name: "component_code",
|
|
541
|
+
description: "The component code to review",
|
|
542
|
+
required: true,
|
|
543
|
+
},
|
|
544
|
+
],
|
|
545
|
+
},
|
|
546
|
+
{
|
|
547
|
+
name: "theme_customization",
|
|
548
|
+
description: "Generate custom theme for Hanzo UI",
|
|
549
|
+
arguments: [
|
|
550
|
+
{
|
|
551
|
+
name: "brand_colors",
|
|
552
|
+
description: "Primary brand colors",
|
|
553
|
+
required: true,
|
|
554
|
+
},
|
|
555
|
+
{
|
|
556
|
+
name: "style",
|
|
557
|
+
description: "Style preference (minimal, bold, playful, professional)",
|
|
558
|
+
required: false,
|
|
559
|
+
},
|
|
560
|
+
],
|
|
561
|
+
},
|
|
562
|
+
],
|
|
563
|
+
}
|
|
564
|
+
})
|
|
565
|
+
|
|
566
|
+
// Handle prompt requests
|
|
567
|
+
server.setRequestHandler(GetPromptRequestSchema, async (request) => {
|
|
568
|
+
const promptName = request.params.name
|
|
569
|
+
const args = request.params.arguments || {}
|
|
570
|
+
|
|
571
|
+
switch (promptName) {
|
|
572
|
+
case "component_usage": {
|
|
573
|
+
const componentName = args.component as string
|
|
574
|
+
return {
|
|
575
|
+
messages: [
|
|
576
|
+
{
|
|
577
|
+
role: "user",
|
|
578
|
+
content: {
|
|
579
|
+
type: "text",
|
|
580
|
+
text: `Generate comprehensive usage examples for the Hanzo UI ${componentName} component. Include:
|
|
581
|
+
1. Basic usage
|
|
582
|
+
2. With all variants (if applicable)
|
|
583
|
+
3. With different props/options
|
|
584
|
+
4. In common scenarios
|
|
585
|
+
5. Accessibility considerations
|
|
586
|
+
6. Common patterns and best practices`,
|
|
587
|
+
},
|
|
588
|
+
},
|
|
589
|
+
],
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
case "build_page": {
|
|
594
|
+
const pageType = args.page_type as string
|
|
595
|
+
return {
|
|
596
|
+
messages: [
|
|
597
|
+
{
|
|
598
|
+
role: "user",
|
|
599
|
+
content: {
|
|
600
|
+
type: "text",
|
|
601
|
+
text: `Build a complete ${pageType} page using Hanzo UI components. Requirements:
|
|
602
|
+
1. Use appropriate Hanzo UI components
|
|
603
|
+
2. Implement responsive design
|
|
604
|
+
3. Include proper accessibility
|
|
605
|
+
4. Follow Hanzo UI design patterns
|
|
606
|
+
5. Structure with semantic HTML
|
|
607
|
+
6. Add appropriate interactions
|
|
608
|
+
7. Include comments explaining component choices`,
|
|
609
|
+
},
|
|
610
|
+
},
|
|
611
|
+
],
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
case "component_composition": {
|
|
616
|
+
const componentName = args.component_name as string
|
|
617
|
+
const description = args.description as string
|
|
618
|
+
return {
|
|
619
|
+
messages: [
|
|
620
|
+
{
|
|
621
|
+
role: "user",
|
|
622
|
+
content: {
|
|
623
|
+
type: "text",
|
|
624
|
+
text: `Create a custom "${componentName}" component that ${description}.
|
|
625
|
+
Requirements:
|
|
626
|
+
1. Compose using existing Hanzo UI primitives
|
|
627
|
+
2. Follow Hanzo UI patterns and conventions
|
|
628
|
+
3. Include TypeScript types
|
|
629
|
+
4. Make it reusable and configurable
|
|
630
|
+
5. Add proper accessibility attributes
|
|
631
|
+
6. Include usage examples
|
|
632
|
+
7. Follow the component API patterns from Hanzo UI`,
|
|
633
|
+
},
|
|
634
|
+
},
|
|
635
|
+
],
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
case "accessibility_review": {
|
|
640
|
+
const code = args.component_code as string
|
|
641
|
+
return {
|
|
642
|
+
messages: [
|
|
643
|
+
{
|
|
644
|
+
role: "user",
|
|
645
|
+
content: {
|
|
646
|
+
type: "text",
|
|
647
|
+
text: `Review this component for accessibility and suggest improvements:
|
|
648
|
+
|
|
649
|
+
\`\`\`tsx
|
|
650
|
+
${code}
|
|
651
|
+
\`\`\`
|
|
652
|
+
|
|
653
|
+
Check for:
|
|
654
|
+
1. ARIA attributes
|
|
655
|
+
2. Keyboard navigation
|
|
656
|
+
3. Screen reader support
|
|
657
|
+
4. Color contrast
|
|
658
|
+
5. Focus management
|
|
659
|
+
6. Semantic HTML
|
|
660
|
+
7. Alternative text
|
|
661
|
+
8. Error handling
|
|
662
|
+
|
|
663
|
+
Provide the improved version with explanations.`,
|
|
664
|
+
},
|
|
665
|
+
},
|
|
666
|
+
],
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
case "theme_customization": {
|
|
671
|
+
const brandColors = args.brand_colors as string
|
|
672
|
+
const style = args.style as string || "professional"
|
|
673
|
+
return {
|
|
674
|
+
messages: [
|
|
675
|
+
{
|
|
676
|
+
role: "user",
|
|
677
|
+
content: {
|
|
678
|
+
type: "text",
|
|
679
|
+
text: `Generate a custom Hanzo UI theme with these brand colors: ${brandColors}
|
|
680
|
+
Style preference: ${style}
|
|
681
|
+
|
|
682
|
+
Provide:
|
|
683
|
+
1. Complete CSS variables for light mode
|
|
684
|
+
2. Complete CSS variables for dark mode
|
|
685
|
+
3. Color palette with all shades
|
|
686
|
+
4. Example component styling
|
|
687
|
+
5. Integration instructions
|
|
688
|
+
6. Preview of how components will look`,
|
|
689
|
+
},
|
|
690
|
+
},
|
|
691
|
+
],
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
default:
|
|
696
|
+
throw new Error(`Unknown prompt: ${promptName}`)
|
|
697
|
+
}
|
|
698
|
+
})
|
|
699
|
+
|
|
700
|
+
// Handle tool calls (existing implementation with additions)
|
|
701
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
702
|
+
const args = request.params.arguments || {}
|
|
703
|
+
|
|
704
|
+
switch (request.params.name) {
|
|
705
|
+
// ... existing tool implementations ...
|
|
706
|
+
|
|
707
|
+
case "get_component_source": {
|
|
708
|
+
const name = z.string().parse(args.name)
|
|
709
|
+
const source = await getComponentSource(name)
|
|
710
|
+
|
|
711
|
+
if (!source) {
|
|
712
|
+
return {
|
|
713
|
+
content: [{
|
|
714
|
+
type: "text",
|
|
715
|
+
text: `Could not find source code for component '${name}'`,
|
|
716
|
+
}],
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
return {
|
|
721
|
+
content: [{
|
|
722
|
+
type: "text",
|
|
723
|
+
text: `# Source Code: ${name}\n\n\`\`\`tsx\n${source}\n\`\`\``,
|
|
724
|
+
}],
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
case "get_component_demo": {
|
|
729
|
+
const name = z.string().parse(args.name)
|
|
730
|
+
const registry = await getRegistry()
|
|
731
|
+
const component = registry.items.find(item => item.name === name)
|
|
732
|
+
|
|
733
|
+
if (!component) {
|
|
734
|
+
return {
|
|
735
|
+
content: [{
|
|
736
|
+
type: "text",
|
|
737
|
+
text: `Component '${name}' not found`,
|
|
738
|
+
}],
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
// Generate a demo based on component type
|
|
743
|
+
let demo = `# ${name} Demo\n\n\`\`\`tsx\n`
|
|
744
|
+
demo += `import { ${name.charAt(0).toUpperCase() + name.slice(1)} } from "@/components/ui/${name}"\n\n`
|
|
745
|
+
demo += `export default function ${name.charAt(0).toUpperCase() + name.slice(1)}Demo() {\n`
|
|
746
|
+
demo += ` return (\n`
|
|
747
|
+
demo += ` <div className="space-y-4">\n`
|
|
748
|
+
|
|
749
|
+
// Add component-specific demo content
|
|
750
|
+
if (name === "button") {
|
|
751
|
+
demo += ` <div className="flex gap-4">\n`
|
|
752
|
+
demo += ` <${name.charAt(0).toUpperCase() + name.slice(1)}>Default</${name.charAt(0).toUpperCase() + name.slice(1)}>\n`
|
|
753
|
+
demo += ` <${name.charAt(0).toUpperCase() + name.slice(1)} variant="outline">Outline</${name.charAt(0).toUpperCase() + name.slice(1)}>\n`
|
|
754
|
+
demo += ` <${name.charAt(0).toUpperCase() + name.slice(1)} variant="secondary">Secondary</${name.charAt(0).toUpperCase() + name.slice(1)}>\n`
|
|
755
|
+
demo += ` <${name.charAt(0).toUpperCase() + name.slice(1)} variant="destructive">Destructive</${name.charAt(0).toUpperCase() + name.slice(1)}>\n`
|
|
756
|
+
demo += ` </div>\n`
|
|
757
|
+
} else {
|
|
758
|
+
demo += ` <${name.charAt(0).toUpperCase() + name.slice(1)} />\n`
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
demo += ` </div>\n`
|
|
762
|
+
demo += ` )\n`
|
|
763
|
+
demo += `}\n`
|
|
764
|
+
demo += `\`\`\`\n\n`
|
|
765
|
+
|
|
766
|
+
// Add usage notes
|
|
767
|
+
demo += `## Usage Notes\n\n`
|
|
768
|
+
demo += `- Import the component from \`@/components/ui/${name}\`\n`
|
|
769
|
+
demo += `- ${component.description || 'No description available'}\n`
|
|
770
|
+
|
|
771
|
+
if (component.dependencies && component.dependencies.length > 0) {
|
|
772
|
+
demo += `\n## Required Dependencies\n\n`
|
|
773
|
+
component.dependencies.forEach(dep => {
|
|
774
|
+
demo += `- ${dep}\n`
|
|
775
|
+
})
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
return {
|
|
779
|
+
content: [{ type: "text", text: demo }],
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
case "list_blocks": {
|
|
784
|
+
const registry = await getRegistry()
|
|
785
|
+
const blocks = registry.items.filter(item =>
|
|
786
|
+
item.type.includes("block") || item.type.includes("section")
|
|
787
|
+
)
|
|
788
|
+
|
|
789
|
+
const categoryFilter = args.category as string | undefined
|
|
790
|
+
const filtered = categoryFilter
|
|
791
|
+
? blocks.filter(b => b.category === categoryFilter)
|
|
792
|
+
: blocks
|
|
793
|
+
|
|
794
|
+
let content = "# Available UI Blocks\n\n"
|
|
795
|
+
|
|
796
|
+
if (filtered.length === 0) {
|
|
797
|
+
content += "No blocks found"
|
|
798
|
+
if (categoryFilter) {
|
|
799
|
+
content += ` in category '${categoryFilter}'`
|
|
800
|
+
}
|
|
801
|
+
content += ".\n"
|
|
802
|
+
} else {
|
|
803
|
+
const byCategory = filtered.reduce((acc, block) => {
|
|
804
|
+
const cat = block.category || "Uncategorized"
|
|
805
|
+
if (!acc[cat]) acc[cat] = []
|
|
806
|
+
acc[cat].push(block)
|
|
807
|
+
return acc
|
|
808
|
+
}, {} as Record<string, typeof blocks>)
|
|
809
|
+
|
|
810
|
+
for (const [category, items] of Object.entries(byCategory)) {
|
|
811
|
+
content += `## ${category}\n\n`
|
|
812
|
+
for (const item of items) {
|
|
813
|
+
content += `### ${item.name}\n`
|
|
814
|
+
content += `${item.description || 'No description'}\n`
|
|
815
|
+
content += `**Install:** \`npx @hanzo/ui@latest add ${item.name}\`\n\n`
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
return {
|
|
821
|
+
content: [{ type: "text", text: content }],
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
case "get_block": {
|
|
826
|
+
const name = z.string().parse(args.name)
|
|
827
|
+
const registry = await getRegistry()
|
|
828
|
+
const block = registry.items.find(item =>
|
|
829
|
+
item.name === name && (item.type.includes("block") || item.type.includes("section"))
|
|
830
|
+
)
|
|
831
|
+
|
|
832
|
+
if (!block) {
|
|
833
|
+
return {
|
|
834
|
+
content: [{
|
|
835
|
+
type: "text",
|
|
836
|
+
text: `Block '${name}' not found`,
|
|
837
|
+
}],
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
let content = `# ${block.name} Block\n\n`
|
|
842
|
+
content += `${block.description || 'No description'}\n\n`
|
|
843
|
+
|
|
844
|
+
if (block.category) {
|
|
845
|
+
content += `**Category:** ${block.category}\n\n`
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
// Dependencies
|
|
849
|
+
if (block.dependencies && block.dependencies.length > 0) {
|
|
850
|
+
content += `## NPM Dependencies\n\n`
|
|
851
|
+
block.dependencies.forEach(dep => {
|
|
852
|
+
content += `- ${dep}\n`
|
|
853
|
+
})
|
|
854
|
+
content += "\n"
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
// Component dependencies
|
|
858
|
+
if (block.registryDependencies && block.registryDependencies.length > 0) {
|
|
859
|
+
content += `## Required Components\n\n`
|
|
860
|
+
block.registryDependencies.forEach(dep => {
|
|
861
|
+
content += `- ${dep}\n`
|
|
862
|
+
})
|
|
863
|
+
content += "\n"
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
// Installation
|
|
867
|
+
content += `## Installation\n\n`
|
|
868
|
+
content += `\`\`\`bash\n`
|
|
869
|
+
content += `npx @hanzo/ui@latest add ${name}\n`
|
|
870
|
+
content += `\`\`\`\n\n`
|
|
871
|
+
|
|
872
|
+
// Files
|
|
873
|
+
if (block.files && block.files.length > 0) {
|
|
874
|
+
content += `## Files\n\n`
|
|
875
|
+
block.files.forEach(file => {
|
|
876
|
+
content += `- \`${file.path}\` (${file.type})\n`
|
|
877
|
+
})
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
return {
|
|
881
|
+
content: [{ type: "text", text: content }],
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
case "get_installation_guide": {
|
|
886
|
+
const content = `# Hanzo UI Complete Installation Guide
|
|
887
|
+
|
|
888
|
+
## Prerequisites
|
|
889
|
+
|
|
890
|
+
- Node.js 18.17 or later
|
|
891
|
+
- React 18 or later
|
|
892
|
+
- Tailwind CSS 3.4 or later
|
|
893
|
+
|
|
894
|
+
## Automatic Installation (Recommended)
|
|
895
|
+
|
|
896
|
+
### Step 1: Create Your Project
|
|
897
|
+
|
|
898
|
+
Choose your preferred framework:
|
|
899
|
+
|
|
900
|
+
#### Next.js
|
|
901
|
+
\`\`\`bash
|
|
902
|
+
npx create-next-app@latest my-app --typescript --tailwind --app
|
|
903
|
+
cd my-app
|
|
904
|
+
\`\`\`
|
|
905
|
+
|
|
906
|
+
#### Vite
|
|
907
|
+
\`\`\`bash
|
|
908
|
+
npm create vite@latest my-app -- --template react-ts
|
|
909
|
+
cd my-app
|
|
910
|
+
npm install -D tailwindcss postcss autoprefixer
|
|
911
|
+
npx tailwindcss init -p
|
|
912
|
+
\`\`\`
|
|
913
|
+
|
|
914
|
+
#### Remix
|
|
915
|
+
\`\`\`bash
|
|
916
|
+
npx create-remix@latest my-app
|
|
917
|
+
cd my-app
|
|
918
|
+
npm install -D tailwindcss postcss autoprefixer
|
|
919
|
+
npx tailwindcss init -p
|
|
920
|
+
\`\`\`
|
|
921
|
+
|
|
922
|
+
### Step 2: Initialize Hanzo UI
|
|
923
|
+
|
|
924
|
+
Run the init command to set up your project:
|
|
925
|
+
|
|
926
|
+
\`\`\`bash
|
|
927
|
+
npx @hanzo/ui@latest init
|
|
928
|
+
\`\`\`
|
|
929
|
+
|
|
930
|
+
You will be asked a few questions:
|
|
931
|
+
|
|
932
|
+
1. **Style** - Choose between Default and New York styles
|
|
933
|
+
2. **Base color** - Choose your base color scheme
|
|
934
|
+
3. **CSS variables** - Use CSS variables for theming (recommended)
|
|
935
|
+
4. **Components path** - Where to add components (default: @/components)
|
|
936
|
+
5. **Utils path** - Where to add the cn utility (default: @/lib/utils)
|
|
937
|
+
6. **React Server Components** - Whether to use RSC
|
|
938
|
+
7. **Components.json** - Write configuration to components.json
|
|
939
|
+
|
|
940
|
+
### Step 3: Start Adding Components
|
|
941
|
+
|
|
942
|
+
\`\`\`bash
|
|
943
|
+
# Add individual components
|
|
944
|
+
npx @hanzo/ui@latest add button
|
|
945
|
+
npx @hanzo/ui@latest add card
|
|
946
|
+
npx @hanzo/ui@latest add dialog
|
|
947
|
+
|
|
948
|
+
# Add multiple at once
|
|
949
|
+
npx @hanzo/ui@latest add button card dialog form
|
|
950
|
+
|
|
951
|
+
# Add all components (use with caution)
|
|
952
|
+
npx @hanzo/ui@latest add --all
|
|
953
|
+
\`\`\`
|
|
954
|
+
|
|
955
|
+
## Manual Installation
|
|
956
|
+
|
|
957
|
+
If you prefer to set up manually:
|
|
958
|
+
|
|
959
|
+
### Step 1: Install Dependencies
|
|
960
|
+
|
|
961
|
+
\`\`\`bash
|
|
962
|
+
npm install tailwindcss-animate class-variance-authority clsx tailwind-merge lucide-react
|
|
963
|
+
\`\`\`
|
|
964
|
+
|
|
965
|
+
### Step 2: Configure Path Aliases
|
|
966
|
+
|
|
967
|
+
Update your \`tsconfig.json\`:
|
|
968
|
+
|
|
969
|
+
\`\`\`json
|
|
970
|
+
{
|
|
971
|
+
"compilerOptions": {
|
|
972
|
+
"baseUrl": ".",
|
|
973
|
+
"paths": {
|
|
974
|
+
"@/*": ["./src/*"]
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
\`\`\`
|
|
979
|
+
|
|
980
|
+
### Step 3: Configure Tailwind
|
|
981
|
+
|
|
982
|
+
Update \`tailwind.config.js\`:
|
|
983
|
+
|
|
984
|
+
\`\`\`javascript
|
|
985
|
+
/** @type {import('tailwindcss').Config} */
|
|
986
|
+
module.exports = {
|
|
987
|
+
darkMode: ["class"],
|
|
988
|
+
content: [
|
|
989
|
+
'./pages/**/*.{ts,tsx}',
|
|
990
|
+
'./components/**/*.{ts,tsx}',
|
|
991
|
+
'./app/**/*.{ts,tsx}',
|
|
992
|
+
'./src/**/*.{ts,tsx}',
|
|
993
|
+
],
|
|
994
|
+
prefix: "",
|
|
995
|
+
theme: {
|
|
996
|
+
container: {
|
|
997
|
+
center: true,
|
|
998
|
+
padding: "2rem",
|
|
999
|
+
screens: {
|
|
1000
|
+
"2xl": "1400px",
|
|
1001
|
+
},
|
|
1002
|
+
},
|
|
1003
|
+
extend: {
|
|
1004
|
+
colors: {
|
|
1005
|
+
border: "hsl(var(--border))",
|
|
1006
|
+
input: "hsl(var(--input))",
|
|
1007
|
+
ring: "hsl(var(--ring))",
|
|
1008
|
+
background: "hsl(var(--background))",
|
|
1009
|
+
foreground: "hsl(var(--foreground))",
|
|
1010
|
+
primary: {
|
|
1011
|
+
DEFAULT: "hsl(var(--primary))",
|
|
1012
|
+
foreground: "hsl(var(--primary-foreground))",
|
|
1013
|
+
},
|
|
1014
|
+
secondary: {
|
|
1015
|
+
DEFAULT: "hsl(var(--secondary))",
|
|
1016
|
+
foreground: "hsl(var(--secondary-foreground))",
|
|
1017
|
+
},
|
|
1018
|
+
destructive: {
|
|
1019
|
+
DEFAULT: "hsl(var(--destructive))",
|
|
1020
|
+
foreground: "hsl(var(--destructive-foreground))",
|
|
1021
|
+
},
|
|
1022
|
+
muted: {
|
|
1023
|
+
DEFAULT: "hsl(var(--muted))",
|
|
1024
|
+
foreground: "hsl(var(--muted-foreground))",
|
|
1025
|
+
},
|
|
1026
|
+
accent: {
|
|
1027
|
+
DEFAULT: "hsl(var(--accent))",
|
|
1028
|
+
foreground: "hsl(var(--accent-foreground))",
|
|
1029
|
+
},
|
|
1030
|
+
popover: {
|
|
1031
|
+
DEFAULT: "hsl(var(--popover))",
|
|
1032
|
+
foreground: "hsl(var(--popover-foreground))",
|
|
1033
|
+
},
|
|
1034
|
+
card: {
|
|
1035
|
+
DEFAULT: "hsl(var(--card))",
|
|
1036
|
+
foreground: "hsl(var(--card-foreground))",
|
|
1037
|
+
},
|
|
1038
|
+
},
|
|
1039
|
+
borderRadius: {
|
|
1040
|
+
lg: "var(--radius)",
|
|
1041
|
+
md: "calc(var(--radius) - 2px)",
|
|
1042
|
+
sm: "calc(var(--radius) - 4px)",
|
|
1043
|
+
},
|
|
1044
|
+
keyframes: {
|
|
1045
|
+
"accordion-down": {
|
|
1046
|
+
from: { height: "0" },
|
|
1047
|
+
to: { height: "var(--radix-accordion-content-height)" },
|
|
1048
|
+
},
|
|
1049
|
+
"accordion-up": {
|
|
1050
|
+
from: { height: "var(--radix-accordion-content-height)" },
|
|
1051
|
+
to: { height: "0" },
|
|
1052
|
+
},
|
|
1053
|
+
},
|
|
1054
|
+
animation: {
|
|
1055
|
+
"accordion-down": "accordion-down 0.2s ease-out",
|
|
1056
|
+
"accordion-up": "accordion-up 0.2s ease-out",
|
|
1057
|
+
},
|
|
1058
|
+
},
|
|
1059
|
+
},
|
|
1060
|
+
plugins: [require("tailwindcss-animate")],
|
|
1061
|
+
}
|
|
1062
|
+
\`\`\`
|
|
1063
|
+
|
|
1064
|
+
### Step 4: Add CSS Variables
|
|
1065
|
+
|
|
1066
|
+
Add to your \`globals.css\`:
|
|
1067
|
+
|
|
1068
|
+
\`\`\`css
|
|
1069
|
+
@tailwind base;
|
|
1070
|
+
@tailwind components;
|
|
1071
|
+
@tailwind utilities;
|
|
1072
|
+
|
|
1073
|
+
@layer base {
|
|
1074
|
+
:root {
|
|
1075
|
+
--background: 0 0% 100%;
|
|
1076
|
+
--foreground: 222.2 84% 4.9%;
|
|
1077
|
+
--card: 0 0% 100%;
|
|
1078
|
+
--card-foreground: 222.2 84% 4.9%;
|
|
1079
|
+
--popover: 0 0% 100%;
|
|
1080
|
+
--popover-foreground: 222.2 84% 4.9%;
|
|
1081
|
+
--primary: 222.2 47.4% 11.2%;
|
|
1082
|
+
--primary-foreground: 210 40% 98%;
|
|
1083
|
+
--secondary: 210 40% 96.1%;
|
|
1084
|
+
--secondary-foreground: 222.2 47.4% 11.2%;
|
|
1085
|
+
--muted: 210 40% 96.1%;
|
|
1086
|
+
--muted-foreground: 215.4 16.3% 46.9%;
|
|
1087
|
+
--accent: 210 40% 96.1%;
|
|
1088
|
+
--accent-foreground: 222.2 47.4% 11.2%;
|
|
1089
|
+
--destructive: 0 84.2% 60.2%;
|
|
1090
|
+
--destructive-foreground: 210 40% 98%;
|
|
1091
|
+
--border: 214.3 31.8% 91.4%;
|
|
1092
|
+
--input: 214.3 31.8% 91.4%;
|
|
1093
|
+
--ring: 222.2 84% 4.9%;
|
|
1094
|
+
--radius: 0.5rem;
|
|
1095
|
+
}
|
|
1096
|
+
|
|
1097
|
+
.dark {
|
|
1098
|
+
--background: 222.2 84% 4.9%;
|
|
1099
|
+
--foreground: 210 40% 98%;
|
|
1100
|
+
--card: 222.2 84% 4.9%;
|
|
1101
|
+
--card-foreground: 210 40% 98%;
|
|
1102
|
+
--popover: 222.2 84% 4.9%;
|
|
1103
|
+
--popover-foreground: 210 40% 98%;
|
|
1104
|
+
--primary: 210 40% 98%;
|
|
1105
|
+
--primary-foreground: 222.2 47.4% 11.2%;
|
|
1106
|
+
--secondary: 217.2 32.6% 17.5%;
|
|
1107
|
+
--secondary-foreground: 210 40% 98%;
|
|
1108
|
+
--muted: 217.2 32.6% 17.5%;
|
|
1109
|
+
--muted-foreground: 215 20.2% 65.1%;
|
|
1110
|
+
--accent: 217.2 32.6% 17.5%;
|
|
1111
|
+
--accent-foreground: 210 40% 98%;
|
|
1112
|
+
--destructive: 0 62.8% 30.6%;
|
|
1113
|
+
--destructive-foreground: 210 40% 98%;
|
|
1114
|
+
--border: 217.2 32.6% 17.5%;
|
|
1115
|
+
--input: 217.2 32.6% 17.5%;
|
|
1116
|
+
--ring: 212.7 26.8% 83.9%;
|
|
1117
|
+
}
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
@layer base {
|
|
1121
|
+
* {
|
|
1122
|
+
@apply border-border;
|
|
1123
|
+
}
|
|
1124
|
+
body {
|
|
1125
|
+
@apply bg-background text-foreground;
|
|
1126
|
+
}
|
|
1127
|
+
}
|
|
1128
|
+
\`\`\`
|
|
1129
|
+
|
|
1130
|
+
### Step 5: Add the cn Utility
|
|
1131
|
+
|
|
1132
|
+
Create \`lib/utils.ts\`:
|
|
1133
|
+
|
|
1134
|
+
\`\`\`typescript
|
|
1135
|
+
import { ClassValue, clsx } from "clsx"
|
|
1136
|
+
import { twMerge } from "tailwind-merge"
|
|
1137
|
+
|
|
1138
|
+
export function cn(...inputs: ClassValue[]) {
|
|
1139
|
+
return twMerge(clsx(inputs))
|
|
1140
|
+
}
|
|
1141
|
+
\`\`\`
|
|
1142
|
+
|
|
1143
|
+
## Verify Installation
|
|
1144
|
+
|
|
1145
|
+
Create a test component to verify everything works:
|
|
1146
|
+
|
|
1147
|
+
\`\`\`tsx
|
|
1148
|
+
// app/page.tsx or src/App.tsx
|
|
1149
|
+
import { Button } from "@/components/ui/button"
|
|
1150
|
+
|
|
1151
|
+
export default function Home() {
|
|
1152
|
+
return (
|
|
1153
|
+
<div className="flex min-h-screen items-center justify-center">
|
|
1154
|
+
<Button>Hello Hanzo UI!</Button>
|
|
1155
|
+
</div>
|
|
1156
|
+
)
|
|
1157
|
+
}
|
|
1158
|
+
\`\`\`
|
|
1159
|
+
|
|
1160
|
+
## Next Steps
|
|
1161
|
+
|
|
1162
|
+
1. **Explore Components** - Browse available components with \`list_components\`
|
|
1163
|
+
2. **Customize Theme** - Adjust CSS variables to match your brand
|
|
1164
|
+
3. **Add More Components** - Install components as needed
|
|
1165
|
+
4. **Check Documentation** - Visit ui.hanzo.ai for full docs
|
|
1166
|
+
|
|
1167
|
+
## Troubleshooting
|
|
1168
|
+
|
|
1169
|
+
### Module Resolution Issues
|
|
1170
|
+
Ensure your path aliases are correctly configured in both tsconfig.json and your bundler config.
|
|
1171
|
+
|
|
1172
|
+
### Styling Not Applied
|
|
1173
|
+
Make sure Tailwind CSS is properly configured and your CSS file is imported in your app.
|
|
1174
|
+
|
|
1175
|
+
### Type Errors
|
|
1176
|
+
Install TypeScript definitions: \`npm install -D @types/react @types/react-dom\`
|
|
1177
|
+
|
|
1178
|
+
### Dark Mode Not Working
|
|
1179
|
+
Ensure you're toggling the \`dark\` class on your HTML element.
|
|
1180
|
+
|
|
1181
|
+
Need help? Visit ui.hanzo.ai or check our GitHub repository.`
|
|
1182
|
+
|
|
1183
|
+
return {
|
|
1184
|
+
content: [{ type: "text", text: content }],
|
|
1185
|
+
}
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1188
|
+
// Include all existing tool implementations from the original file
|
|
1189
|
+
default: {
|
|
1190
|
+
// Fallback to original implementation for other tools
|
|
1191
|
+
const originalTools = ["init", "list_components", "get_component", "add_component", "list_styles", "search_registry"]
|
|
1192
|
+
if (originalTools.includes(request.params.name)) {
|
|
1193
|
+
// Call original implementation (would need to be imported/included)
|
|
1194
|
+
// For now, return an error
|
|
1195
|
+
throw new Error(`Tool ${request.params.name} needs original implementation`)
|
|
1196
|
+
}
|
|
1197
|
+
throw new Error(`Unknown tool: ${request.params.name}`)
|
|
1198
|
+
}
|
|
1199
|
+
}
|
|
1200
|
+
})
|
|
1201
|
+
|
|
1202
|
+
// Export for use
|
|
1203
|
+
export default server
|
|
1204
|
+
|
|
1205
|
+
// Support CommonJS
|
|
1206
|
+
if (typeof module !== 'undefined') {
|
|
1207
|
+
module.exports = { server }
|
|
1208
|
+
}
|