From cde3bd93de4348b2f76891f0fd97f103adc7437c Mon Sep 17 00:00:00 2001 From: Carlos Costa Date: Thu, 12 Nov 2026 18:44:22 -0300 Subject: [PATCH 01/13] feat(toast): export ToastProviderProps for registry introspection --- src/dashkit/Toast/Toast.tsx | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/dashkit/Toast/Toast.tsx b/src/dashkit/Toast/Toast.tsx index d66deae..2800a21 100644 --- a/src/dashkit/Toast/Toast.tsx +++ b/src/dashkit/Toast/Toast.tsx @@ -21,15 +21,17 @@ const viewportPositionClasses: Record = { 'bottom-center': 'bottom-8 left-1/2 -translate-x-1/2 items-center', }; +export interface ToastProviderProps { + children: React.ReactNode; + position?: ToastPosition; + invert?: boolean; +} + export function ToastProvider({ children, position = 'bottom-right', invert = false -}: { - children: React.ReactNode; - position?: ToastPosition; - invert?: boolean; -}) { +}: ToastProviderProps) { const { toasts } = useToast(); const isMounted = React.useSyncExternalStore( React.useCallback(() => () => {}, []), From 63f495f427d16dfb3273c735bbef6ce186105e2a Mon Sep 17 00:00:00 2001 From: Carlos Costa Date: Thu, 12 Nov 2026 18:45:11 -0300 Subject: [PATCH 02/13] fix(docs): strip inline demos and not-prose previews in llms generator and fix API patterns --- scripts/generate-llms.ts | 127 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 122 insertions(+), 5 deletions(-) diff --git a/scripts/generate-llms.ts b/scripts/generate-llms.ts index 27cd47f..fac9b46 100644 --- a/scripts/generate-llms.ts +++ b/scripts/generate-llms.ts @@ -164,6 +164,113 @@ export function convertPropertyDocToMarkdown(docStr: string): string { } } +function stripTopLevelExports(text: string): string { + const exportRegex = /^export\s+(?:const|function)\s+[A-Za-z0-9_]+/gm; + let result = ''; + let lastIndex = 0; + + while (true) { + exportRegex.lastIndex = lastIndex; + const match = exportRegex.exec(text); + if (!match) { + result += text.slice(lastIndex); + break; + } + + result += text.slice(lastIndex, match.index); + + let i = match.index; + let depth = 0; + let enteredBlock = false; + let inString: string | null = null; + let escaped = false; + + while (i < text.length) { + const ch = text[i]; + + if (inString) { + if (escaped) { + escaped = false; + } else if (ch === '\\') { + escaped = true; + } else if (ch === inString) { + inString = null; + } + i++; + continue; + } + + if (ch === '\'' || ch === '"' || ch === '`') { + inString = ch; + i++; + continue; + } + + if (ch === '{' || ch === '(' || ch === '[') { + depth++; + enteredBlock = true; + } else if (ch === '}' || ch === ')' || ch === ']') { + depth = Math.max(0, depth - 1); + if (enteredBlock && depth === 0) { + i++; + if (text[i] === ';') i++; + break; + } + } + i++; + } + + lastIndex = i; + } + + return result; +} + +function stripNotProseDivs(text: string): string { + const openRegex = /]*\bnot-prose\b[^>]*>/g; + let result = ''; + let lastIndex = 0; + + while (true) { + openRegex.lastIndex = lastIndex; + const match = openRegex.exec(text); + if (!match) { + result += text.slice(lastIndex); + break; + } + + result += text.slice(lastIndex, match.index); + + let i = match.index + match[0].length; + let depth = 1; + + while (i < text.length && depth > 0) { + const nextOpen = text.indexOf('', i); + + if (nextClose === -1) { + i = text.length; + break; + } + + if (nextOpen !== -1 && nextOpen < nextClose) { + const after = text[nextOpen + 4]; + if (after === '>' || after === ' ' || after === '\n' || after === '\r' || after === '\t') { + depth++; + } + i = nextOpen + 4; + } else { + depth--; + i = nextClose + 6; + } + } + + lastIndex = i; + } + + return result; +} + export function cleanMdxForDocumentation(content: string): string { const parts = content.split(/(```[\s\S]*?```)/g); let removedTitleH1 = false; @@ -176,8 +283,9 @@ export function cleanMdxForDocumentation(content: string): string { // Outside code block let text = parts[i]; - // Remove import statements + // Remove import statements and inline demo exports text = text.replace(/^import\s+[\s\S]*?from\s+['"][^'"]+['"];?\s*$/gm, ''); + text = stripTopLevelExports(text); // Remove the top-level MDX H1 title (already emitted as `## ` by the generator) if (!removedTitleH1 && /^#\s+.+$/m.test(text)) { @@ -191,8 +299,9 @@ export function cleanMdxForDocumentation(content: string): string { // to repeat across components, while H1/H2 anchors are strictly unique. text = text.replace(/^(#{1,5})\s+/gm, (_match, hashes: string) => `#${hashes} `); - // Remove ... + // Remove ... and
...
text = text.replace(//g, ''); + text = stripNotProseDivs(text); // Convert to Markdown tables text = text.replace(/|<\/PropertyDoc>)/g, (match) => { @@ -274,9 +383,12 @@ export function generateLlmsTxt(): string { lines.push('2. **Tier 2 (Component-Wide Style)**: Edit `cva(...)` variants directly inside `src/dashkit//.tsx`.'); lines.push('3. **Tier 3 (One-Off Instance Override)**: Pass `className` (merged via `cn()`, which resolves `rounded-*` and `bg-none` against `ds-rounded*` and `ds-*-gradient`) or target sub-elements via `data-slot` (`className="[&_[data-slot=label]]:uppercase [&_[data-slot=trigger]]:rounded-full"`).\n'); + const totalComponents = Object.keys(registry).length; + lines.push('## Component API Patterns (Compound vs. Prop-Driven)\n'); lines.push('- **Compound Components (use subcomponents via `children`)**:'); - lines.push(' - `Card`: `Card`, `CardHeader` (props: `title`, `description`, `action`), `CardContent`, `CardFooter`'); + lines.push(' - `Card`: `Card`, `CardHeader` (props: `leftIcon`, `action`), `CardTitle`, `CardDescription`, `CardContent`, `CardFooter`'); + lines.push(' - `BentoGrid`: `BentoGrid`, `BentoGridItem`'); lines.push(' - `Tabs`: `Tabs`, `TabsList`, `TabsTrigger`, `TabsContent`'); lines.push(' - `Accordion`: `Accordion`, `AccordionItem`, `AccordionTrigger`, `AccordionContent`'); lines.push(' - `Modal`: `Modal`, `ModalHeader`, `ModalContent`, `ModalFooter`'); @@ -284,9 +396,14 @@ export function generateLlmsTxt(): string { lines.push(' - `Dropdown`: `Dropdown`, `DropdownTrigger`, `DropdownContent`, `DropdownItem`, `DropdownLabel`, `DropdownSeparator`'); lines.push(' - `Popover`: `Popover`, `PopoverTrigger`, `PopoverContent`'); lines.push(' - `Table`: `TableContainer`, `Table`, `TableHeader`, `TableBody`, `TableFooter`, `TableRow`, `TableHead`, `TableCell`, `TableCaption`'); - lines.push(' - `Navbar`: `Navbar`, `NavbarBrand`, `NavbarLinks`, `NavbarLink`, `NavbarActions`'); + lines.push(' - `Navbar`: `Navbar`, `NavbarBrand`, `NavbarLinks`, `NavbarActions`'); + lines.push(' - `NavigationMenu`: `NavigationMenu`, `NavigationMenuList`, `NavigationMenuItem`, `NavigationMenuTrigger`, `NavigationMenuContent`, `NavigationMenuLink`, `NavigationMenuViewport`'); + lines.push(' - `Sidebar`: `SidebarProvider`, `Sidebar`, `SidebarTrigger`, `SidebarContent`, `SidebarHeader`, `SidebarSection`, `SidebarItem`, `SidebarSubList`, `SidebarSubItem`, `SidebarFooter`'); lines.push(' - `Breadcrumb`: `Breadcrumb`, `BreadcrumbList`, `BreadcrumbItem`, `BreadcrumbSeparator`, `BreadcrumbEllipsis`'); lines.push(' - `Stepper`: `Stepper`, `Step`'); + lines.push(' - `Dock`: `Dock`, `DockItem`'); + lines.push(' - `ButtonGroup`: `ButtonGroup`, `ButtonGroupItem`'); + lines.push(' - `Avatar`: `Avatar`, `AvatarGroup`'); lines.push('- **Prop-Driven Components (pass data via props, do NOT invent subcomponents)**:'); lines.push(' - `Select`, `Combobox`: Pass `options={[{ value, label }]}`, `value`, `onChange`, `label`.'); lines.push(' - `Input`, `Textarea`, `DatePicker`, `DateField`, `ColorPicker`, `CopyField`, `OtpInput`, `Checkbox`, `Radio`, `Switch`, `Slider`: Pass `label`, `description` / `helperText`, `error` directly as props.'); @@ -294,7 +411,7 @@ export function generateLlmsTxt(): string { lines.push(' - `AreaChart`, `BarChart`, `LineChart`, `PieChart`: Pass `data` and `series` props.\n'); lines.push('## Component Catalog\n'); - lines.push('Complete list of 55 production-ready components. For full API signatures, props tables, and code snippets, see [llms-full.txt](llms-full.txt).\n'); + lines.push(`Complete list of ${totalComponents} production-ready components. For full API signatures, props tables, and code snippets, see [llms-full.txt](llms-full.txt).\n`); for (const cat of CATEGORIES) { lines.push(`### ${cat.name}\n`); From 9e9168cc1fe48b732772eb4205c09238d51df9f6 Mon Sep 17 00:00:00 2001 From: Carlos Costa Date: Thu, 12 Nov 2026 18:45:49 -0300 Subject: [PATCH 03/13] test(docs): add regression checks for llms cleaner, API patterns, and toast props --- scripts/tests/llms.test.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/scripts/tests/llms.test.ts b/scripts/tests/llms.test.ts index 76af71a..01d1dc5 100644 --- a/scripts/tests/llms.test.ts +++ b/scripts/tests/llms.test.ts @@ -130,5 +130,21 @@ describe('LLMs Documentation Generator', () => { expect(llmsContent).toContain('data-primary'); expect(llmsContent).toContain('3-Tier AI Customization Protocol'); expect(llmsContent).toContain('Component API Patterns (Compound vs. Prop-Driven)'); + expect(llmsContent).not.toContain('`NavbarLink`'); + expect(llmsContent).not.toContain('CardHeader (props: title, description'); + }); + + it('should strip inline demo exports and not-prose preview blocks from llms-full.txt', () => { + const llmsFullContent = generateLlmsFullTxt(); + expect(llmsFullContent).not.toContain('SelectDemo'); + expect(llmsFullContent).not.toContain('not-prose'); + }); + + it('should extract propsDefinitions for every registered component including toast', () => { + const { registryJsonPath } = buildLlmsFiles(); + const registryJson = JSON.parse(fs.readFileSync(registryJsonPath, 'utf8')); + for (const [slug, entry] of Object.entries<{ propsDefinitions: string[] }>(registryJson.components)) { + expect(entry.propsDefinitions.length, `Missing propsDefinitions for ${slug}`).toBeGreaterThan(0); + } }); }); From d2a81ba07c97aaf7627dfececee3f00d3446b248 Mon Sep 17 00:00:00 2001 From: Carlos Costa Date: Thu, 12 Nov 2026 18:46:04 -0300 Subject: [PATCH 04/13] fix(cli): update compound component API patterns in ai-rules output --- scripts/commands.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/commands.ts b/scripts/commands.ts index 10d4084..cf5a091 100644 --- a/scripts/commands.ts +++ b/scripts/commands.ts @@ -805,7 +805,7 @@ async function writeAiRulesFile( '3. **Instance Overrides (`className` & `data-slot`)**: Use `className` (merged via `cn()`) or `data-slot` selectors (`className="[&_[data-slot=label]]:uppercase"`) for one-off tweaks.', '', '### Component API Patterns', - '- **Compound (`children`)**: `Card` (`CardHeader`, `CardContent`, `CardFooter`), `Tabs` (`TabsList`, `TabsTrigger`, `TabsContent`), `Accordion` (`AccordionItem`, `AccordionTrigger`, `AccordionContent`), `Modal` (`ModalHeader`, `ModalContent`, `ModalFooter`), `Drawer` (`DrawerHeader`, `DrawerContent`, `DrawerFooter`), `Dropdown`, `Popover`, `Table`, `Navbar`, `Breadcrumb`, `Stepper`.', + '- **Compound (`children`)**: `Card` (`CardHeader`, `CardTitle`, `CardDescription`, `CardContent`, `CardFooter`), `BentoGrid` (`BentoGridItem`), `Tabs` (`TabsList`, `TabsTrigger`, `TabsContent`), `Accordion` (`AccordionItem`, `AccordionTrigger`, `AccordionContent`), `Modal` (`ModalHeader`, `ModalContent`, `ModalFooter`), `Drawer` (`DrawerHeader`, `DrawerContent`, `DrawerFooter`), `Dropdown`, `Popover`, `Table` (`TableContainer`, `TableHeader`, `TableBody`, `TableRow`, `TableHead`, `TableCell`), `Navbar` (`NavbarBrand`, `NavbarLinks`, `NavbarActions`), `NavigationMenu`, `Sidebar` (`SidebarProvider`, `SidebarHeader`, `SidebarContent`, `SidebarSection`, `SidebarItem`, `SidebarFooter`), `Breadcrumb`, `Stepper` (`Step`), `Dock` (`DockItem`), `ButtonGroup` (`ButtonGroupItem`), `Avatar` (`AvatarGroup`).', '- **Prop-Driven (`options` / props)**: `Select` & `Combobox` use `options={[{ value, label }]}`; `Input`, `Textarea`, `DatePicker`, `DateField`, `ColorPicker`, `CopyField`, `OtpInput`, `Checkbox`, `Radio`, `Switch`, `Slider` take `label`, `description`/`helperText`, `error` as props; `StatsCard` takes `title`, `value`, `trend`, `status`, `chart`.', '', ].join('\n'); From 2a78bfe5c7347b1aea2b3fab5a3b9bd4f4a21ab4 Mon Sep 17 00:00:00 2001 From: Carlos Costa Date: Thu, 12 Nov 2026 18:46:22 -0300 Subject: [PATCH 05/13] docs(ai): update component count to 56 and complete compound API patterns --- src/pages/ai.mdx | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/pages/ai.mdx b/src/pages/ai.mdx index e2dd5b8..e15aaeb 100644 --- a/src/pages/ai.mdx +++ b/src/pages/ai.mdx @@ -8,8 +8,8 @@ Feed Dashkit's structured documentation directly into your AI assistant's contex | Resource | Path | Purpose | | :--- | :--- | :--- | -| **LLM Index** | [`/llms.txt`](/llms.txt) | Compact architecture overview, token reference, CLI commands, and 55-component catalog. | -| **Full Technical Context** | [`/llms-full.txt`](/llms-full.txt) | Complete single-file specification with installation commands, JSX examples, and Markdown props tables for all 55 components. | +| **LLM Index** | [`/llms.txt`](/llms.txt) | Compact architecture overview, token reference, CLI commands, and 56-component catalog. | +| **Full Technical Context** | [`/llms-full.txt`](/llms-full.txt) | Complete single-file specification with installation commands, JSX examples, and Markdown props tables for all 56 components. | | **JSON Registry Schema** | [`/registry.json`](/registry.json) | Machine-readable JSON metadata containing component slugs, file paths, NPM dependencies, registry dependencies, exports, and raw TypeScript `*Props` interfaces. | ## Automatic AI Rules (`dashkit ai-rules`) @@ -34,7 +34,7 @@ Autonomous agents can query the Dashkit CLI in non-interactive mode using `--jso # Inspect exports, dependencies, and TypeScript Props for a component bunx carllosnc/dashkit info card --json -# List all 55 components and check which ones are installed locally +# List all 56 components and check which ones are installed locally bunx carllosnc/dashkit list --json # Check if any local component files were customized vs. upstream @@ -90,16 +90,22 @@ Dashkit components follow two predictable composition patterns: Use exported sub-components for structural layouts and overlays: - **Card**: `Card`, `CardHeader`, `CardTitle`, `CardDescription`, `CardContent`, `CardFooter` +- **BentoGrid**: `BentoGrid`, `BentoGridItem` - **Tabs**: `Tabs`, `TabsList`, `TabsTrigger`, `TabsContent` - **Accordion**: `Accordion`, `AccordionItem`, `AccordionTrigger`, `AccordionContent` - **Modal**: `Modal`, `ModalHeader`, `ModalContent`, `ModalFooter` - **Drawer**: `Drawer`, `DrawerHeader`, `DrawerContent`, `DrawerFooter` - **Dropdown**: `Dropdown`, `DropdownTrigger`, `DropdownContent`, `DropdownItem`, `DropdownLabel`, `DropdownSeparator` - **Popover**: `Popover`, `PopoverTrigger`, `PopoverContent` -- **Table**: `Table`, `TableHeader`, `TableBody`, `TableFooter`, `TableRow`, `TableHead`, `TableCell`, `TableCaption` +- **Table**: `TableContainer`, `Table`, `TableHeader`, `TableBody`, `TableFooter`, `TableRow`, `TableHead`, `TableCell`, `TableCaption` - **Navbar**: `Navbar`, `NavbarBrand`, `NavbarLinks`, `NavbarActions` +- **NavigationMenu**: `NavigationMenu`, `NavigationMenuList`, `NavigationMenuItem`, `NavigationMenuTrigger`, `NavigationMenuContent`, `NavigationMenuLink`, `NavigationMenuViewport` - **Breadcrumb**: `Breadcrumb`, `BreadcrumbList`, `BreadcrumbItem`, `BreadcrumbSeparator`, `BreadcrumbEllipsis` -- **Sidebar**: `Sidebar`, `SidebarHeader`, `SidebarSection`, `SidebarItem`, `SidebarFooter` +- **Sidebar**: `SidebarProvider`, `Sidebar`, `SidebarTrigger`, `SidebarContent`, `SidebarHeader`, `SidebarSection`, `SidebarItem`, `SidebarSubList`, `SidebarSubItem`, `SidebarFooter` +- **Stepper**: `Stepper`, `Step` +- **Dock**: `Dock`, `DockItem` +- **ButtonGroup**: `ButtonGroup`, `ButtonGroupItem` +- **Avatar**: `Avatar`, `AvatarGroup` ### 2. Prop-Driven Components (Configure via Props) From 13fc7f535640922c182a2086bd52d5c7c9c53cf7 Mon Sep 17 00:00:00 2001 From: Carlos Costa Date: Thu, 12 Nov 2026 18:46:36 -0300 Subject: [PATCH 06/13] docs(cli): update component count to 56 --- src/pages/cli.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/cli.mdx b/src/pages/cli.mdx index 05e86d5..7c73db8 100644 --- a/src/pages/cli.mdx +++ b/src/pages/cli.mdx @@ -26,7 +26,7 @@ Add one or multiple components in a single command. The CLI resolves recursive D bunx carllosnc/dashkit add button card input modal ``` -To install all 55 components at once: +To install all 56 components at once: ```bash bunx carllosnc/dashkit add --all @@ -67,7 +67,7 @@ Copies one or more components and their `registryDependencies` into your project bunx carllosnc/dashkit add [components...] [options] ``` -- `-a, --all`: Add all 55 components in the registry. +- `-a, --all`: Add all 56 components in the registry. - `-o, --output `: Target directory (defaults to `componentsDir` in `dashkit.json` or `src/dashkit`). - `--no-install`: Skip automatic installation of missing NPM dependencies. - `-f, --force`: Overwrite existing local component files without prompting. From ecdea7f8684f0a01f2611cc261b3e99e190c2681 Mon Sep 17 00:00:00 2001 From: Carlos Costa Date: Thu, 12 Nov 2026 18:46:50 -0300 Subject: [PATCH 07/13] docs(readme): update component count to 56 and list BentoGrid --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c44f0e0..0a8ae94 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ Dashkit provides an interactive CLI to streamline component integration. - `dashkit init [-y]`: Configures `dashkit.json`, copies `dashkit.css` and `utils/`, and injects the `@import` into your main CSS file. - `dashkit add [components...]`: Scaffolds one or more components, resolves dependencies in a single batch, and updates the root `index.ts` barrel. - - `-a, --all`: Add all 55 registry components at once. + - `-a, --all`: Add all 56 registry components at once. - `-o, --output `: Specify a custom destination path. - `--no-install`: Skip automatic installation of third-party package dependencies. - `-f, --force`: Overwrite existing files on disk. @@ -77,10 +77,11 @@ Dashkit provides native context for AI coding assistants (Cursor, Claude Code, W ## Available Components -Dashkit includes 55 production-ready components: +Dashkit includes 56 production-ready components: ### Layout & Containers - Accordion +- BentoGrid - Card - Surface - Divider @@ -180,7 +181,7 @@ Dashkit is actively expanding its capabilities with an emphasis on developer erg - **Dashkit UI Builder Skill**: Dedicated AI agent skill (`SKILL.md`) with curated layout recipes, component pairing patterns, visual hierarchy rules, and best practices for generating modern UIs with Dashkit. - **Official MCP Server**: Model Context Protocol server (`@dashkit/mcp`) with component search, prop inspection, and scaffolding tools. -- **Code Metadata & Typing**: JSDoc annotations with `@example` and `@default` blocks across all 55 components for inline LLM autocomplete. +- **Code Metadata & Typing**: JSDoc annotations with `@example` and `@default` blocks across all 56 components for inline LLM autocomplete. - **Extended Slot & Prop Forwarding**: Complete `data-slot` coverage and `ComponentPropsWithoutRef` + `ref` forwarding across every overlay, navigation, and data display primitive. For detailed tracking and upcoming milestones, see [ROADMAP.md](ROADMAP.md). From 3749b577baca206c404dc731a9910aa62dd127c9 Mon Sep 17 00:00:00 2001 From: Carlos Costa Date: Thu, 12 Nov 2026 18:47:09 -0300 Subject: [PATCH 08/13] docs(agents): document build:llms command --- AGENTS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/AGENTS.md b/AGENTS.md index 643eb19..333f012 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -14,6 +14,7 @@ - `bun run build` — typecheck and build - `bun run check:all` — test + lint + build - `bun run build:cli` — build the CLI bundle +- `bun run build:llms` — regenerate `public/llms.txt`, `public/llms-full.txt`, and `public/registry.json` ## Architecture & Styling Guidelines From a46f7e7bc93962a38adf4458adac0bd3bafe1b98 Mon Sep 17 00:00:00 2001 From: Carlos Costa Date: Thu, 12 Nov 2026 18:47:25 -0300 Subject: [PATCH 09/13] fix(docs): preserve blockquotes and ordered lists in Copy Page for AI --- src/layouts/MdxWrapper.tsx | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/layouts/MdxWrapper.tsx b/src/layouts/MdxWrapper.tsx index dabe273..3775ded 100644 --- a/src/layouts/MdxWrapper.tsx +++ b/src/layouts/MdxWrapper.tsx @@ -270,11 +270,15 @@ function extractMarkdownFromDom(root: HTMLElement): string { lines.push(`\n#### ${node.textContent?.trim() ?? ''}\n`); } else if (tag === 'p') { lines.push(`${node.textContent?.trim() ?? ''}\n`); + } else if (tag === 'blockquote') { + const quoteLines = (node.textContent?.trim() ?? '').split('\n').map((l) => `> ${l.trim()}`); + lines.push(`${quoteLines.join('\n')}\n`); } else if (tag === 'ul' || tag === 'ol') { const items = Array.from(node.querySelectorAll(':scope > li')); - for (const li of items) { - lines.push(`- ${li.textContent?.trim() ?? ''}`); - } + items.forEach((li, idx) => { + const prefix = tag === 'ol' ? `${idx + 1}.` : '-'; + lines.push(`${prefix} ${li.textContent?.trim() ?? ''}`); + }); lines.push(''); } else if (node.querySelector('pre')) { const pre = node.querySelector('pre'); From 4269cbf95971d2237277eb31aa0e3721395d6e0c Mon Sep 17 00:00:00 2001 From: Carlos Costa Date: Thu, 12 Nov 2026 18:48:35 -0300 Subject: [PATCH 10/13] docs(llms): regenerate llms.txt with 56 components and accurate API patterns --- public/llms.txt | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/public/llms.txt b/public/llms.txt index e0a7ddb..8bb40fd 100644 --- a/public/llms.txt +++ b/public/llms.txt @@ -67,7 +67,8 @@ Apply on ``, ``, or any scoped container `
`: ## Component API Patterns (Compound vs. Prop-Driven) - **Compound Components (use subcomponents via `children`)**: - - `Card`: `Card`, `CardHeader` (props: `title`, `description`, `action`), `CardContent`, `CardFooter` + - `Card`: `Card`, `CardHeader` (props: `leftIcon`, `action`), `CardTitle`, `CardDescription`, `CardContent`, `CardFooter` + - `BentoGrid`: `BentoGrid`, `BentoGridItem` - `Tabs`: `Tabs`, `TabsList`, `TabsTrigger`, `TabsContent` - `Accordion`: `Accordion`, `AccordionItem`, `AccordionTrigger`, `AccordionContent` - `Modal`: `Modal`, `ModalHeader`, `ModalContent`, `ModalFooter` @@ -75,9 +76,14 @@ Apply on ``, ``, or any scoped container `
`: - `Dropdown`: `Dropdown`, `DropdownTrigger`, `DropdownContent`, `DropdownItem`, `DropdownLabel`, `DropdownSeparator` - `Popover`: `Popover`, `PopoverTrigger`, `PopoverContent` - `Table`: `TableContainer`, `Table`, `TableHeader`, `TableBody`, `TableFooter`, `TableRow`, `TableHead`, `TableCell`, `TableCaption` - - `Navbar`: `Navbar`, `NavbarBrand`, `NavbarLinks`, `NavbarLink`, `NavbarActions` + - `Navbar`: `Navbar`, `NavbarBrand`, `NavbarLinks`, `NavbarActions` + - `NavigationMenu`: `NavigationMenu`, `NavigationMenuList`, `NavigationMenuItem`, `NavigationMenuTrigger`, `NavigationMenuContent`, `NavigationMenuLink`, `NavigationMenuViewport` + - `Sidebar`: `SidebarProvider`, `Sidebar`, `SidebarTrigger`, `SidebarContent`, `SidebarHeader`, `SidebarSection`, `SidebarItem`, `SidebarSubList`, `SidebarSubItem`, `SidebarFooter` - `Breadcrumb`: `Breadcrumb`, `BreadcrumbList`, `BreadcrumbItem`, `BreadcrumbSeparator`, `BreadcrumbEllipsis` - `Stepper`: `Stepper`, `Step` + - `Dock`: `Dock`, `DockItem` + - `ButtonGroup`: `ButtonGroup`, `ButtonGroupItem` + - `Avatar`: `Avatar`, `AvatarGroup` - **Prop-Driven Components (pass data via props, do NOT invent subcomponents)**: - `Select`, `Combobox`: Pass `options={[{ value, label }]}`, `value`, `onChange`, `label`. - `Input`, `Textarea`, `DatePicker`, `DateField`, `ColorPicker`, `CopyField`, `OtpInput`, `Checkbox`, `Radio`, `Switch`, `Slider`: Pass `label`, `description` / `helperText`, `error` directly as props. @@ -86,7 +92,7 @@ Apply on ``, ``, or any scoped container `
`: ## Component Catalog -Complete list of 55 production-ready components. For full API signatures, props tables, and code snippets, see [llms-full.txt](llms-full.txt). +Complete list of 56 production-ready components. For full API signatures, props tables, and code snippets, see [llms-full.txt](llms-full.txt). ### Layout & Containers From 8e702efafbe2776523a7f06176380a405ab1e91b Mon Sep 17 00:00:00 2001 From: Carlos Costa Date: Thu, 12 Nov 2026 18:48:39 -0300 Subject: [PATCH 11/13] docs(llms): regenerate llms-full.txt without inline demo noise --- public/llms-full.txt | 578 +++---------------------------------------- 1 file changed, 38 insertions(+), 540 deletions(-) diff --git a/public/llms-full.txt b/public/llms-full.txt index f0b5de9..2e577cd 100644 --- a/public/llms-full.txt +++ b/public/llms-full.txt @@ -57,29 +57,6 @@ bunx carllosnc/dashkit add accordion The accordion supports `single` (default) or `multiple` expansion modes via the `type` prop. - - - Minimalist Performance - - No boxes, no shadows. Just clean spacers and thin lines for a modern, high-density dashboard look. We've removed the container styling to let your content breathe. - - - - - Seamless Integration - - Designed to fit anywhere—sidebars, settings pages, or complex forms without added visual noise. The spring animations provide a premium feel without being distracting. - - - - - Accessibility First - - Fully accessible via keyboard navigation. Users can toggle items using the Enter or Space key, following the standard WAI-ARIA design pattern for accordions. - - - - ```tsx @@ -98,31 +75,6 @@ The accordion supports `single` (default) or `multiple` expansion modes via the Use the `type="multiple"` prop to allow more than one item to be expanded at the same time. - - - - - - Real-time Updates - - - - Synchronize state across multiple browser tabs with zero latency using our optimized WebSocket provider. - - - - - - - Audit Logs Tracking - - - - Every action is recorded and verifiable. Export logs to CSV or JSON for compliance reporting. - - - - ```tsx @@ -203,63 +155,6 @@ import { BentoGrid, BentoGridItem } from '@/dashkit/BentoGrid'; By default, `BentoGrid` uses `gap="none"` to render a continuous `1px` hairline divider between cells without double borders—even when combining multi-row vertical spans (`rowSpan={2}`) and full-width spans (`colSpan="full"`). - - - 01 / Ingestion - - Edge Collector - Low-latency telemetry pipelines across 38 regions. - - - - - 02 / Cache - - 99.98% Hit Rate - In-memory distributed read replicas. - - - - - - 03 / Architecture - - - - 1.42M req/s - - Tall vertical cell spanning two rows alongside the 2x2 grid on the left, sharing a single 1px border on all sides. - - - cluster-us-east-primary - - - - 04 / Storage - - Zero-Copy Snapshots - Instant branching for isolated preview environments. - - - - - 05 / Security - - mTLS Enforced - Automated certificate rotation every 24h. - - - - - - 06 / Full-Width Footer - Global Consensus Layer - Spans all 12 columns across the bottom while preserving a crisp 1px top divider. - - - - - ```tsx @@ -282,27 +177,6 @@ By default, `BentoGrid` uses `gap="none"` to render a continuous `1px` hairline Set `rounded="none"` for a sharp editorial or architectural blueprint layout where every outer corner and inner intersection meets at 90 degrees. - - - col-span-4 - - - col-span-3 - - - col-span-5 / row-span-2 - - - col-span-4 - - - col-span-3 - - - col-span-full - - - ```tsx @@ -322,17 +196,6 @@ Set `rounded="none"` for a sharp editorial or architectural blueprint layout whe Pass `gap="sm" | "md" | "lg"` when you want detached Bento cards instead of shared hairline borders. - - - Detached Bento Card (2 cols) - Automatically switches to individual card borders when gap is enabled. - - - Side Card (1 col) - Muted surface variant. - - - ```tsx @@ -400,20 +263,6 @@ import { The card can be used as a simple container or with its sub-components for more structure. - - - Project Overhaul - A comprehensive update to the dashboard architecture and visual identity. - - - A standard composed card using the modular component internal structure for full layout control. This design pattern allows for deep nesting and flexible content slots. - - - Dismiss - View Details - - - ```tsx @@ -438,18 +287,6 @@ The card can be used as a simple container or with its sub-components for more s The `CardHeader` supports a `leftIcon` prop to easily add visual context and an `action` prop for right-aligned elements like badges, buttons, or menus. - - } - action={} - > - Security Overview - Manage your system security settings and firewall rules. - - - Enable advanced threat protection and automated security scanning for all connected infrastructure nodes. - - - ```tsx import { FiShield } from 'react-icons/fi'; @@ -476,28 +313,6 @@ import { Badge, Card, CardHeader, CardTitle, CardDescription } from '@/dashkit'; Cards are built using sub-components to provide maximum flexibility for different use cases. While `leftIcon` and `action` handle common patterns, you can still compose the header manually for more complex layouts. - - }> - System Analytics - Real-time monitoring of global infrastructure and system health. - - - - - Uptime - 99.99% - - - Latency - 12ms - - - - - View Global Status - - - ```tsx @@ -732,7 +547,7 @@ Horizontal dividers can contain text or other components, positioned along the l - Installation: `bunx carllosnc/dashkit add scrollarea` - NPM Dependencies: `clsx`, `tailwind-merge`, `class-variance-authority` -export const VerticalExample = () => ( +=> ( @@ -746,7 +561,7 @@ export const VerticalExample = () => ( ); -export const HorizontalExample = () => ( + => ( @@ -1030,7 +845,7 @@ The Navigation Menu uses a value-based system to track the active item. Ensure t - NPM Dependencies: `framer-motion`, `clsx`, `tailwind-merge`, `react-icons` - Dashkit Dependencies: `iconbutton`, `tooltip`, `backdrop` -export const InteractiveSidebar = () => { +=> { const [activeTab, setActiveTab] = useState('dashboard'); const [isOpen, setIsOpen] = useState(true); @@ -1094,7 +909,7 @@ export const InteractiveSidebar = () => { ); }; -export const CollapsibleSectionExample = () => { + => { return ( @@ -1166,8 +981,6 @@ The `Sidebar` uses a semantic composition of headers, content scroll area, secti - - ```tsx import { Sidebar, SidebarHeader, SidebarContent, SidebarSection, SidebarItem } from '@/dashkit'; import { FiLayout, FiActivity, FiSettings } from 'react-icons/fi'; @@ -1544,21 +1357,6 @@ bunx carllosnc/dashkit add tabs The component is highly accessible and supports a fluid layout for its triggers. - - - Account - Password - - - Account Settings - Update your account email and personal information. - - - Password - Change your password and manage your security settings. - - - ```tsx @@ -1580,39 +1378,6 @@ The component is highly accessible and supports a fluid layout for its triggers. Use `variant="pills"` to render tabs inside a compact, segmented track with an elevated floating indicator that smoothly slides between options. - - - Overview - Analytics - Reports - Notifications - - - - Platform Overview - General metric summary across all edge environments. - - - - - Live Analytics - Real-time latency, request rate, and error rate telemetry. - - - - - Generated Reports - Weekly and monthly compliance export records. - - - - - Notification Feeds - System warnings and deployment completion triggers. - - - - ```tsx @@ -1633,51 +1398,6 @@ Use `variant="pills"` to render tabs inside a compact, segmented track with an e You can easily integrate icons and complex child layouts within your tabs. - - - - - - Profile - - - - Activity - - - - Settings - - - - - User Profile - - Update your personal details and public information. All changes are saved automatically. - - - - Recent Activity - - - - Successfully deployed project dashkit - - - - Updated registry.json - - - - - Preferences - - Manage your notification types, connected accounts, and general dashboard settings. - - - - - ```tsx @@ -1756,26 +1476,6 @@ bunx carllosnc/dashkit add stepper Displays a multi-step sequence with active, completed, and inactive states. Uses `framer-motion` for animated connecting lines. - - {React.createElement(() => { - const [step, setStep] = useState(1); - return ( - - - - - - - - - setStep(prev => prev - 1)}>Back - setStep(prev => prev + 1)}>Next Step - - - ); - })} - - ```tsx import { useState } from 'react'; @@ -1806,15 +1506,6 @@ export function StepperExample() { Set `orientation="vertical"` to stack the steps vertically, which is highly suited for sidebars or logs. - - - - - - - - - ```tsx import { Stepper, Step } from '@/dashkit/Stepper'; @@ -1831,14 +1522,6 @@ import { Stepper, Step } from '@/dashkit/Stepper'; By default, steps are auto-numbered. You can supply an `icon` prop to customize the visual indicator for each step. - - - } /> - } /> - } /> - - - ```tsx import { Stepper, Step } from '@/dashkit/Stepper'; @@ -1856,15 +1539,6 @@ import { FiUser, FiCreditCard, FiCheckCircle } from 'react-icons/fi'; Control the stepper's accent theme using the `color` prop. Use `"primary"` (default) for brand accenting or `"base"` for clean, monochrome neutral styling. - - Base Monochrome Theme (`color="base"`) - - - - - - - ```tsx @@ -1923,13 +1597,6 @@ A functional and responsive component for navigating between large sets of data Provide the `currentPage`, `totalPages`, and an `onChange` callback to sync state perfectly. - {React.createElement(() => { - const [page, setPage] = useState(1); - return ( - - ); - })} - ```tsx import { useState } from 'react'; @@ -1952,13 +1619,6 @@ export function PaginationExample() { When `totalPages` is small (e.g., 5 pages), the component automatically hides the ellipsis logic and simply renders a cohesive string of pages. - {React.createElement(() => { - const [page, setPage] = useState(2); - return ( - - ); - })} - ```tsx import { useState } from 'react'; @@ -1981,13 +1641,6 @@ export function PaginationShortExample() { The `Pagination` component automatically calculates ellipsis (`...`) truncations for large ranges to prevent overflowing. - {React.createElement(() => { - const [page, setPage] = useState(50); - return ( - - ); - })} - ```tsx import { useState } from 'react'; @@ -2010,13 +1663,6 @@ export function PaginationLargeDataExample() { By configuring `siblingCount={0}`, you can minimize the footprint of the pagination. The component defaults to `siblingCount={1}`. - {React.createElement(() => { - const [page, setPage] = useState(25); - return ( - - ); - })} - ```tsx import { useState } from 'react'; @@ -2055,7 +1701,7 @@ export function PaginationMinimalExample() { - Installation: `bunx carllosnc/dashkit add dock` - NPM Dependencies: `framer-motion`, `clsx`, `tailwind-merge` -export const DockDemo = () => { +=> { return ( @@ -2472,7 +2118,7 @@ Vertical groups are useful for sidebars or property menus. - Installation: `bunx carllosnc/dashkit add input` - NPM Dependencies: `clsx`, `tailwind-merge`, `class-variance-authority` -export const PatternsExample = () => { +=> { const formatCPF = (val) => val .replace(/^(\d{3})(\d)/, '$1.$2') .replace(/^(\d{3})\.(\d{3})(\d)/, '$1.$2.$3') @@ -2730,7 +2376,7 @@ The component extends all native `TextareaHTMLAttributes` props, plus the follow - Installation: `bunx carllosnc/dashkit add checkbox` - NPM Dependencies: `clsx`, `tailwind-merge` -export const ControlledExample = () => { +=> { const [checked, setChecked] = useState(false); return ( @@ -2863,7 +2509,7 @@ The component extends all native `InputHTMLAttributes` props (excluding `type`), - Installation: `bunx carllosnc/dashkit add radio` - NPM Dependencies: `clsx`, `tailwind-merge` -export const RadioDemo = () => { +=> { const [selected, setSelected] = useState('one'); const options = [ @@ -2990,7 +2636,7 @@ Extends all native `RadioHTMLAttributes` (except `type`), plus these specialties - Installation: `bunx carllosnc/dashkit add switch` - NPM Dependencies: `clsx`, `tailwind-merge` -export const SwitchDemo = () => { +=> { const [enabled, setEnabled] = useState(false); return ( @@ -3100,7 +2746,7 @@ Extends all native `CheckboxHTMLAttributes` (except `type`), plus these specialt - Installation: `bunx carllosnc/dashkit add select` - NPM Dependencies: `clsx`, `tailwind-merge`, `class-variance-authority`, `react-icons` -export const SelectDemo = () => { +=> { const [value, setValue] = useState(''); const shippingOptions = [ @@ -3197,20 +2843,7 @@ export function ShippingForm() { - NPM Dependencies: `framer-motion`, `clsx`, `tailwind-merge`, `react-icons` - Dashkit Dependencies: `chip` -export const frameworks = [ - { value: 'nextjs', label: 'Next.js' }, - { value: 'sveltekit', label: 'SvelteKit' }, - { value: 'nuxt', label: 'Nuxt.js' }, - { value: 'remix', label: 'Remix' }, - { value: 'astro', label: 'Astro' }, - { value: 'gatsby', label: 'Gatsby' }, - { value: 'vite', label: 'Vite' }, - { value: 'webpack', label: 'Webpack' }, - { value: 'parcel', label: 'Parcel' }, - { value: 'rollup', label: 'Rollup' }, -]; - -export const BasicExample = () => { +=> { const [value, setValue] = useState('nextjs'); return ( @@ -3219,7 +2852,7 @@ export const BasicExample = () => { ); }; -export const MultiSelectExample = () => { + => { const [multiValue, setMultiValue] = useState(['nextjs', 'vite']); return ( @@ -3344,7 +2977,7 @@ The combobox supports different visual states like `disabled` or pre-filled valu - Installation: `bunx carllosnc/dashkit add slider` - NPM Dependencies: `clsx`, `tailwind-merge` -export const SliderDemo = () => { +=> { const [value, setValue] = useState(50); return ( @@ -3467,7 +3100,7 @@ Extends all native `InputHTMLAttributes` (except `type` and `onChange`), plus th - Installation: `bunx carllosnc/dashkit add datefield` - NPM Dependencies: `clsx`, `tailwind-merge` -export const BasicExample = () => { +=> { const [value, setValue] = useState(null); return ( @@ -3476,7 +3109,7 @@ export const BasicExample = () => { ); }; -export const InteractiveDateField = () => { + => { const [value, setValue] = useState(new Date()); return ( @@ -3681,7 +3314,7 @@ You can provide custom labels, descriptions, and placeholders. - Installation: `bunx carllosnc/dashkit add otpinput` - NPM Dependencies: `clsx`, `tailwind-merge` -export const OtpInputDemo = () => { +=> { const [otp, setOtp] = useState(''); const [isVerifying, setIsVerifying] = useState(false); const [isComplete, setIsComplete] = useState(false); @@ -3905,7 +3538,7 @@ Add a `label` and `description` to provide context for the value. - NPM Dependencies: `framer-motion`, `clsx`, `tailwind-merge`, `class-variance-authority`, `react-icons` - Dashkit Dependencies: `backdrop`, `iconbutton` -export const BasicModal = () => { +=> { const [isOpen, setIsOpen] = useState(false); return ( <> @@ -3930,7 +3563,7 @@ export const BasicModal = () => { ); }; -export const ComposableModal = () => { + => { const [isOpen, setIsOpen] = useState(false); return ( <> @@ -3960,7 +3593,7 @@ export const ComposableModal = () => { ); }; -export const AlertModalExample = () => { + => { const [isOpen, setIsOpen] = useState(false); return ( <> @@ -3990,7 +3623,7 @@ export const AlertModalExample = () => { ); }; -export const FullScreenExample = () => { + => { const [isOpen, setIsOpen] = useState(false); return ( <> @@ -4161,7 +3794,7 @@ The `full` size provides a take-over experience while maintaining focus on a sin - NPM Dependencies: `framer-motion`, `clsx`, `tailwind-merge`, `class-variance-authority`, `react-icons` - Dashkit Dependencies: `backdrop` -export const DrawerDemo = () => { +=> { const [activeDrawer, setActiveDrawer] = useState(null); const closeDrawer = () => setActiveDrawer(null); @@ -4296,7 +3929,7 @@ The sub-components `DrawerHeader`, `DrawerContent`, and `DrawerFooter` all accep - Installation: `bunx carllosnc/dashkit add dropdown` - NPM Dependencies: `clsx`, `tailwind-merge`, `react-icons` -export const DropdownDemo = () => { +=> { const [selected, setSelected] = useState('Personal'); return ( @@ -4368,7 +4001,7 @@ export const DropdownDemo = () => { ); } -export const BasicMenuDemo = () => { + => { return ( @@ -4386,7 +4019,7 @@ export const BasicMenuDemo = () => { ); } -export const SelectableMenuDemo = () => { + => { const [selected, setSelected] = useState('Personal'); return ( @@ -4419,7 +4052,7 @@ export const SelectableMenuDemo = () => { ); } -export const CustomTriggerDemo = () => { + => { return ( @@ -4696,7 +4329,7 @@ Since the `PopoverContent` is just a container, you can put any React components - Installation: `bunx carllosnc/dashkit add tooltip` - NPM Dependencies: `framer-motion`, `clsx`, `tailwind-merge` -export const TooltipDemo = () => { +=> { return ( @@ -4752,7 +4385,7 @@ export const TooltipDemo = () => { ); } -export const PositioningDemo = () => { + => { return ( @@ -4874,7 +4507,7 @@ Tooltips can be positioned on the `top`, `bottom`, `left`, or `right` of the tri - Installation: `bunx carllosnc/dashkit add toast` - NPM Dependencies: `framer-motion`, `clsx`, `tailwind-merge`, `react-icons` -export const ToastExamples = () => { +=> { const showStacked = () => { toast({ title: 'Success!', description: 'The operation completed successfully.', type: 'success' }); setTimeout(() => toast({ title: 'New Update', description: 'V5.2.0 is now available.', type: 'info' }), 400); @@ -4898,7 +4531,7 @@ export const ToastExamples = () => { ); }; -export const PositionExamples = () => { + => { return ( toast({ title: 'Top Right', position: 'top-right', type: 'info' })}> @@ -4914,7 +4547,7 @@ export const PositionExamples = () => { ); }; -export const InvertedExamples = () => { + => { return ( toast({ title: 'System Updated', description: 'All changes saved to the cloud.', type: 'success', invert: true })}> @@ -5060,7 +4693,7 @@ bunx carllosnc/dashkit add backdrop The backdrop component is usually controlled by a state. -export const BasicExample = () => { + => { const [show, setShow] = useState(false); return ( <> @@ -5087,7 +4720,7 @@ return ( You can pass children to the backdrop, which will be centered on top of the overlay. -export const ChildrenExample = () => { + => { const [show, setShow] = useState(false); return ( <> @@ -5430,7 +5063,7 @@ Control the visibility of the background track and the shape of the progress end - Installation: `bunx carllosnc/dashkit add skeleton` - NPM Dependencies: `clsx`, `tailwind-merge`, `class-variance-authority` -export const SkeletonDemo = () => { +=> { return ( @@ -5569,34 +5202,7 @@ Disable animations entirely with `animation="none"`. - NPM Dependencies: `framer-motion`, `clsx`, `tailwind-merge`, `react-icons` - Dashkit Dependencies: `iconbutton` -export const FloatActionMenuDemo = () => ( - - - - Slide-in Interaction - - - The button remains fixed while the menu slides in from the right to left. - - - - } - position="bottom-right" - className="absolute" - > - - {[ - { icon: , label: 'Enable Alerts', color: 'text-orange-500' }, - { icon: , label: 'View messages', color: 'text-emerald-500' }, - { icon: , label: 'Global Settings', color: 'text-ds-500' }, - { icon: , label: 'My profile', color: 'text-blue-500' }, - ].map((item, i) => ( - - {item.label} - - ))} - - +=> ( ) @@ -6039,7 +5645,7 @@ Combine badges with other components to create rich status indicators. - Installation: `bunx carllosnc/dashkit add chip` - NPM Dependencies: `clsx`, `tailwind-merge`, `class-variance-authority`, `react-icons` -export const MultiSelectExample = () => { +=> { const [selectedChips, setSelectedChips] = useState(['React', 'Vite']); const toggleChip = (label) => { setSelectedChips(prev => @@ -6056,7 +5662,7 @@ export const MultiSelectExample = () => { ); }; -export const RemovableExample = () => { + => { const [chips, setChips] = useState(['Personal', 'Work', 'Urgent', 'Low Priority']); const removeChip = (label) => { setChips(prev => prev.filter(c => c !== label)); @@ -6340,10 +5946,6 @@ bunx carllosnc/dashkit add statscard The `StatsCard` is perfect for dashboards and summary sections. - - - - ```tsx import { StatsCard } from 'dashkit'; @@ -6379,17 +5981,6 @@ export default () => ( Add visual context using icons from `react-icons`. - } - status="info" - description="Completion across all active sprints" - /> - } - status="warning" - trend={8} - trendLabel="today" - description="Unassigned support requests" - /> - ```tsx import { StatsCard } from 'dashkit'; @@ -6419,10 +6010,6 @@ export default () => ( Visualize data trends directly within the card using the `chart` prop. - - - - ```tsx import { StatsCard } from 'dashkit'; @@ -6446,9 +6033,6 @@ export default () => ( Combine sparklines and descriptive footers for maximum context. - - - ```tsx import { StatsCard } from 'dashkit'; @@ -6508,18 +6092,10 @@ export default () => ( - Installation: `bunx carllosnc/dashkit add animatenumber` - NPM Dependencies: `framer-motion`, `clsx`, `tailwind-merge` -export const AnimateNumberExample = () => { +=> { const [val, setVal] = useState(1250); return ( - - - - - setVal(v => v + Math.floor(Math.random() * 100))}>Update Value - setVal(1250)}>Reset - - ); } @@ -6622,8 +6198,6 @@ bunx carllosnc/dashkit add systemlogs The `SystemLogs` component takes an array of `logs` and renders them in a dark, monospace container that mimics a terminal environment. - - ```tsx import { SystemLogs } from '@/dashkit/SystemLogs/SystemLogs' @@ -6658,8 +6232,6 @@ The component supports five distinct log levels, each with its own visual style: - `stable`: Stability or state updates (indicated by `[STB]`) - - ### Customization @@ -6704,86 +6276,12 @@ Built with a composition pattern for ultimate flexibility. Renders a clean seman - - Inventory list exported today. - - - Invoice - Status - Method - Amount - - - - - INV001 - Paid - Credit Card - $250.00 - - - INV002 - Pending - PayPal - $150.00 - - - INV003 - Unpaid - Bank Transfer - $350.00 - - - - - Total: $750.00 - - - - - - ### Actions Support Tables often need a way to perform operations on specific rows. You can easily integrate a `Dropdown` for clean, consolidated actions. - - - Customer - Email - Actions - - - - {[ - { name: 'John Cooper', email: 'john@example.com' }, - { name: 'Sarah Miller', email: 'sarah@example.com' }, - ].map((user) => ( - - {user.name} - {user.email} - - - - } variant="ghost" size="sm" /> - - - Actions - View details - Edit customer - - Delete customer - - - - - ))} - - - - ```tsx @@ -7190,7 +6688,7 @@ Apply SVG patterns across the entire chart with the `texture` prop (`'striped' | - Installation: `bunx carllosnc/dashkit add imageexpander` - NPM Dependencies: `framer-motion`, `clsx`, `tailwind-merge`, `react-icons` -export const ImageExpanderDemo = () => { +=> { const images = [ { url: "https://images.unsplash.com/photo-1465146344425-f00d5f5c8f07?q=80&w=1176&auto=format&fit=crop", From afa6183cb2a8700ab5364531a37f260d56c5f759 Mon Sep 17 00:00:00 2001 From: Carlos Costa Date: Thu, 12 Nov 2026 18:48:43 -0300 Subject: [PATCH 12/13] docs(registry): regenerate registry.json with ToastProviderProps --- public/registry.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/public/registry.json b/public/registry.json index e1e6564..79f2946 100644 --- a/public/registry.json +++ b/public/registry.json @@ -1529,7 +1529,9 @@ "toast", "resetToasts" ], - "propsDefinitions": [] + "propsDefinitions": [ + "export interface ToastProviderProps {\r\n children: React.ReactNode;\r\n position?: ToastPosition;\r\n invert?: boolean;\r\n}" + ] }, "tooltip": { "slug": "tooltip", From 034d72978d3e54f38accb99a6902415151d97e9c Mon Sep 17 00:00:00 2001 From: Carlos Costa Date: Thu, 12 Nov 2026 18:48:47 -0300 Subject: [PATCH 13/13] build(cli): rebuild cli bundle with updated ai-rules --- exec/cli.js | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/exec/cli.js b/exec/cli.js index 37ab204..d003714 100755 --- a/exec/cli.js +++ b/exec/cli.js @@ -1,32 +1,32 @@ #!/usr/bin/env node -import{Command as Re}from"commander";import h from"fs-extra";import u from"path";import f from"chalk";import ee from"ora";import{fileURLToPath as Ae}from"url";import{execSync as $e}from"child_process";import Ie from"enquirer";var w={accordion:{name:"Accordion",files:["src/dashkit/Accordion/Accordion.tsx","src/dashkit/Accordion/AccordionItem.tsx","src/dashkit/Accordion/AccordionTrigger.tsx","src/dashkit/Accordion/AccordionContent.tsx","src/dashkit/Accordion/AccordionContext.ts","src/dashkit/Accordion/Accordion.test.tsx","src/dashkit/Accordion/index.ts"],dependencies:["framer-motion","clsx","tailwind-merge","react-icons"]},avatar:{name:"Avatar",files:["src/dashkit/Avatar/Avatar.tsx","src/dashkit/Avatar/AvatarGroup.tsx","src/dashkit/Avatar/Avatar.test.tsx","src/dashkit/Avatar/index.ts"],dependencies:["framer-motion","clsx","tailwind-merge","class-variance-authority"]},badge:{name:"Badge",files:["src/dashkit/Badge/Badge.tsx","src/dashkit/Badge/FloatBadge.tsx","src/dashkit/Badge/Badge.test.tsx","src/dashkit/Badge/index.ts"],dependencies:["framer-motion","clsx","tailwind-merge","class-variance-authority"]},floatbadge:{name:"FloatBadge",files:["src/dashkit/Badge/FloatBadge.tsx"],dependencies:["clsx","tailwind-merge"],registryDependencies:["badge"]},"bento-grid":{name:"BentoGrid",files:["src/dashkit/BentoGrid/BentoGrid.tsx","src/dashkit/BentoGrid/BentoGrid.test.tsx","src/dashkit/BentoGrid/index.ts"],dependencies:["clsx","tailwind-merge","class-variance-authority"]},button:{name:"Button",files:["src/dashkit/Button/Button.tsx","src/dashkit/Button/Button.test.tsx","src/dashkit/Button/index.ts"],registryDependencies:["spinner"],dependencies:["clsx","tailwind-merge","class-variance-authority"]},card:{name:"Card",files:["src/dashkit/Card/Card.tsx","src/dashkit/Card/CardHeader.tsx","src/dashkit/Card/CardContent.tsx","src/dashkit/Card/CardFooter.tsx","src/dashkit/Card/Card.test.tsx","src/dashkit/Card/index.ts"],registryDependencies:["badge","button"],dependencies:["framer-motion","clsx","tailwind-merge","class-variance-authority"]},chip:{name:"Chip",files:["src/dashkit/Chip/Chip.tsx","src/dashkit/Chip/Chip.test.tsx","src/dashkit/Chip/index.ts"],dependencies:["clsx","tailwind-merge","class-variance-authority","react-icons"]},checkbox:{name:"Checkbox",files:["src/dashkit/Checkbox/Checkbox.tsx","src/dashkit/Checkbox/Checkbox.test.tsx","src/dashkit/Checkbox/index.ts"],dependencies:["clsx","tailwind-merge"]},drawer:{name:"Drawer",files:["src/dashkit/Drawer/Drawer.tsx","src/dashkit/Drawer/useDrawer.ts","src/dashkit/Drawer/Drawer.test.tsx","src/dashkit/Drawer/index.ts"],registryDependencies:["backdrop"],dependencies:["framer-motion","clsx","tailwind-merge","class-variance-authority","react-icons"]},dropdown:{name:"Dropdown",files:["src/dashkit/Dropdown/Dropdown.tsx","src/dashkit/Dropdown/DropdownContent.tsx","src/dashkit/Dropdown/DropdownItem.tsx","src/dashkit/Dropdown/DropdownLabel.tsx","src/dashkit/Dropdown/DropdownSeparator.tsx","src/dashkit/Dropdown/DropdownTrigger.tsx","src/dashkit/Dropdown/useDropdown.ts","src/dashkit/Dropdown/Dropdown.test.tsx","src/dashkit/Dropdown/index.ts"],dependencies:["clsx","tailwind-merge","react-icons"]},imageexpander:{name:"ImageExpander",files:["src/dashkit/ImageExpander/ImageExpander.tsx","src/dashkit/ImageExpander/useImageExpander.ts","src/dashkit/ImageExpander/ImageExpander.test.tsx","src/dashkit/ImageExpander/index.ts"],dependencies:["framer-motion","clsx","tailwind-merge","react-icons"]},input:{name:"Input",files:["src/dashkit/Input/Input.tsx","src/dashkit/Input/Input.test.tsx","src/dashkit/Input/index.ts"],dependencies:["clsx","tailwind-merge","class-variance-authority"]},modal:{name:"Modal",files:["src/dashkit/Modal/Modal.tsx","src/dashkit/Modal/ModalContent.tsx","src/dashkit/Modal/ModalFooter.tsx","src/dashkit/Modal/ModalHeader.tsx","src/dashkit/Modal/useModal.ts","src/dashkit/Modal/Modal.test.tsx","src/dashkit/Modal/index.ts"],registryDependencies:["backdrop","iconbutton"],dependencies:["framer-motion","clsx","tailwind-merge","class-variance-authority","react-icons"]},otpinput:{name:"OtpInput",files:["src/dashkit/OtpInput/OtpInput.tsx","src/dashkit/OtpInput/useOtpInput.ts","src/dashkit/OtpInput/OtpInput.test.tsx","src/dashkit/OtpInput/index.ts"],dependencies:["clsx","tailwind-merge"]},radio:{name:"Radio",files:["src/dashkit/Radio/Radio.tsx","src/dashkit/Radio/useRadio.ts","src/dashkit/Radio/Radio.test.tsx","src/dashkit/Radio/index.ts"],dependencies:["clsx","tailwind-merge"]},select:{name:"Select",files:["src/dashkit/Select/Select.tsx","src/dashkit/Select/useSelect.ts","src/dashkit/Select/Select.test.tsx","src/dashkit/Select/index.ts"],dependencies:["clsx","tailwind-merge","class-variance-authority","react-icons"]},switch:{name:"Switch",files:["src/dashkit/Switch/Switch.tsx","src/dashkit/Switch/useSwitch.ts","src/dashkit/Switch/Switch.test.tsx","src/dashkit/Switch/index.ts"],dependencies:["clsx","tailwind-merge"]},slider:{name:"Slider",files:["src/dashkit/Slider/Slider.tsx","src/dashkit/Slider/useSlider.ts","src/dashkit/Slider/Slider.test.tsx","src/dashkit/Slider/index.ts"],dependencies:["clsx","tailwind-merge"]},surface:{name:"Surface",files:["src/dashkit/Surface/Surface.tsx","src/dashkit/Surface/Surface.test.tsx","src/dashkit/Surface/index.ts"],dependencies:["clsx","tailwind-merge","class-variance-authority"]},tabs:{name:"Tabs",files:["src/dashkit/Tabs/Tabs.tsx","src/dashkit/Tabs/Tabs.test.tsx","src/dashkit/Tabs/index.ts"],dependencies:["framer-motion","clsx","tailwind-merge","class-variance-authority"]},toast:{name:"Toast",files:["src/dashkit/Toast/Toast.tsx","src/dashkit/Toast/useToast.ts","src/dashkit/Toast/Toast.test.tsx","src/dashkit/Toast/index.ts"],dependencies:["framer-motion","clsx","tailwind-merge","react-icons"]},stepper:{name:"Stepper",files:["src/dashkit/Stepper/Stepper.tsx","src/dashkit/Stepper/Stepper.test.tsx","src/dashkit/Stepper/index.ts"],dependencies:["framer-motion","clsx","tailwind-merge","react-icons"]},pagination:{name:"Pagination",files:["src/dashkit/Pagination/Pagination.tsx","src/dashkit/Pagination/Pagination.test.tsx","src/dashkit/Pagination/index.ts"],dependencies:["clsx","tailwind-merge","react-icons","framer-motion"]},spinner:{name:"Spinner",files:["src/dashkit/Spinner/Spinner.tsx","src/dashkit/Spinner/Spinner.test.tsx","src/dashkit/Spinner/index.ts"],dependencies:["framer-motion","clsx","tailwind-merge"]},navbar:{name:"Navbar",files:["src/dashkit/Navbar/Navbar.tsx","src/dashkit/Navbar/NavbarActions.tsx","src/dashkit/Navbar/NavbarBrand.tsx","src/dashkit/Navbar/NavbarLinks.tsx","src/dashkit/Navbar/Navbar.test.tsx","src/dashkit/Navbar/index.ts"],dependencies:["clsx","tailwind-merge","class-variance-authority"]},skeleton:{name:"Skeleton",files:["src/dashkit/Skeleton/Skeleton.tsx","src/dashkit/Skeleton/Skeleton.test.tsx","src/dashkit/Skeleton/index.ts"],dependencies:["clsx","tailwind-merge","class-variance-authority"]},breadcrumb:{name:"Breadcrumb",files:["src/dashkit/Breadcrumb/Breadcrumb.tsx","src/dashkit/Breadcrumb/BreadcrumbList.tsx","src/dashkit/Breadcrumb/BreadcrumbItem.tsx","src/dashkit/Breadcrumb/BreadcrumbSeparator.tsx","src/dashkit/Breadcrumb/BreadcrumbEllipsis.tsx","src/dashkit/Breadcrumb/Breadcrumb.test.tsx","src/dashkit/Breadcrumb/index.ts"],dependencies:["clsx","tailwind-merge","react-icons"]},iconbutton:{name:"IconButton",files:["src/dashkit/IconButton/IconButton.tsx","src/dashkit/IconButton/IconButton.test.tsx","src/dashkit/IconButton/index.ts"],dependencies:["clsx","tailwind-merge","class-variance-authority"]},areachart:{name:"AreaChart",files:["src/dashkit/AreaChart/AreaChart.tsx","src/dashkit/AreaChart/useAreaChart.ts","src/dashkit/AreaChart/AreaChart.test.tsx","src/dashkit/AreaChart/index.ts"],dependencies:["framer-motion","clsx","tailwind-merge"]},barchart:{name:"BarChart",files:["src/dashkit/BarChart/BarChart.tsx","src/dashkit/BarChart/useBarChart.ts","src/dashkit/BarChart/BarChart.test.tsx","src/dashkit/BarChart/index.ts"],dependencies:["framer-motion","clsx","tailwind-merge"]},linechart:{name:"LineChart",files:["src/dashkit/LineChart/LineChart.tsx","src/dashkit/LineChart/useLineChart.ts","src/dashkit/LineChart/LineChart.test.tsx","src/dashkit/LineChart/index.ts"],dependencies:["framer-motion","clsx","tailwind-merge"]},piechart:{name:"PieChart",files:["src/dashkit/PieChart/PieChart.tsx","src/dashkit/PieChart/usePieChart.ts","src/dashkit/PieChart/PieChart.test.tsx","src/dashkit/PieChart/index.ts"],dependencies:["framer-motion","clsx","tailwind-merge"]},progressbar:{name:"ProgressBar",files:["src/dashkit/ProgressBar/ProgressBar.tsx","src/dashkit/ProgressBar/useProgressBar.ts","src/dashkit/ProgressBar/ProgressBar.test.tsx","src/dashkit/ProgressBar/index.ts"],dependencies:["framer-motion","clsx","tailwind-merge","class-variance-authority"]},buttongroup:{name:"ButtonGroup",files:["src/dashkit/ButtonGroup/ButtonGroup.tsx","src/dashkit/ButtonGroup/ButtonGroup.test.tsx","src/dashkit/ButtonGroup/index.ts"],dependencies:["clsx","tailwind-merge","class-variance-authority"]},combobox:{name:"Combobox",files:["src/dashkit/Combobox/Combobox.tsx","src/dashkit/Combobox/useCombobox.ts","src/dashkit/Combobox/Combobox.test.tsx","src/dashkit/Combobox/index.ts"],dependencies:["framer-motion","clsx","tailwind-merge","react-icons"],registryDependencies:["chip"]},divider:{name:"Divider",files:["src/dashkit/Divider/Divider.tsx","src/dashkit/Divider/Divider.test.tsx","src/dashkit/Divider/index.ts"],dependencies:["clsx","tailwind-merge","class-variance-authority"]},sidebar:{name:"Sidebar",files:["src/dashkit/Sidebar/Sidebar.tsx","src/dashkit/Sidebar/useSidebar.ts","src/dashkit/Sidebar/SidebarContext.tsx","src/dashkit/Sidebar/Sidebar.test.tsx","src/dashkit/Sidebar/index.ts"],dependencies:["framer-motion","clsx","tailwind-merge","react-icons"],registryDependencies:["iconbutton","tooltip","backdrop"]},"float-action-menu":{name:"FloatActionMenu",files:["src/dashkit/FloatActionMenu/FloatActionMenu.tsx","src/dashkit/FloatActionMenu/useFloatActionMenu.ts","src/dashkit/FloatActionMenu/FloatActionMenu.test.tsx","src/dashkit/FloatActionMenu/index.ts"],dependencies:["framer-motion","clsx","tailwind-merge","react-icons"],registryDependencies:["iconbutton"]},textarea:{name:"Textarea",files:["src/dashkit/Textarea/Textarea.tsx","src/dashkit/Textarea/useTextarea.ts","src/dashkit/Textarea/Textarea.test.tsx","src/dashkit/Textarea/index.ts"],dependencies:["clsx","tailwind-merge"]},datepicker:{name:"DatePicker",files:["src/dashkit/DatePicker/DatePicker.tsx","src/dashkit/DatePicker/useDatePicker.ts","src/dashkit/DatePicker/DatePicker.test.tsx","src/dashkit/DatePicker/index.ts"],dependencies:["clsx","tailwind-merge","react-icons"]},table:{name:"Table",files:["src/dashkit/Table/Table.tsx","src/dashkit/Table/Table.test.tsx","src/dashkit/Table/index.ts"],dependencies:["clsx","tailwind-merge"]},animatenumber:{name:"AnimateNumber",files:["src/dashkit/AnimateNumber/AnimateNumber.tsx","src/dashkit/AnimateNumber/Digit.tsx","src/dashkit/AnimateNumber/AnimateNumber.test.tsx","src/dashkit/AnimateNumber/index.ts"],dependencies:["framer-motion","clsx","tailwind-merge"]},circularprogress:{name:"CircularProgress",files:["src/dashkit/CircularProgress/CircularProgress.tsx","src/dashkit/CircularProgress/CircularProgress.test.tsx","src/dashkit/CircularProgress/index.ts"],dependencies:["framer-motion","clsx","tailwind-merge"]},dock:{name:"Dock",files:["src/dashkit/Dock/Dock.tsx","src/dashkit/Dock/DockItem.tsx","src/dashkit/Dock/Dock.test.tsx","src/dashkit/Dock/index.ts"],dependencies:["framer-motion","clsx","tailwind-merge"]},popover:{name:"Popover",files:["src/dashkit/Popover/Popover.tsx","src/dashkit/Popover/PopoverContent.tsx","src/dashkit/Popover/PopoverTrigger.tsx","src/dashkit/Popover/usePopover.ts","src/dashkit/Popover/Popover.test.tsx","src/dashkit/Popover/index.ts"],dependencies:["framer-motion","clsx","tailwind-merge"]},tooltip:{name:"Tooltip",files:["src/dashkit/Tooltip/Tooltip.tsx","src/dashkit/Tooltip/Tooltip.test.tsx","src/dashkit/Tooltip/index.ts"],dependencies:["framer-motion","clsx","tailwind-merge"]},systemlogs:{name:"SystemLogs",files:["src/dashkit/SystemLogs/SystemLogs.tsx","src/dashkit/SystemLogs/SystemLogs.test.tsx","src/dashkit/SystemLogs/index.ts"],dependencies:["clsx","tailwind-merge","react-icons"],registryDependencies:["badge"]},datefield:{name:"DateField",files:["src/dashkit/DateField/DateField.tsx","src/dashkit/DateField/useDateField.ts","src/dashkit/DateField/DateField.test.tsx","src/dashkit/DateField/index.ts"],dependencies:["clsx","tailwind-merge"]},"navigation-menu":{name:"NavigationMenu",files:["src/dashkit/NavigationMenu/NavigationMenu.tsx","src/dashkit/NavigationMenu/NavigationMenuContent.tsx","src/dashkit/NavigationMenu/NavigationMenuContext.tsx","src/dashkit/NavigationMenu/NavigationMenuItem.tsx","src/dashkit/NavigationMenu/NavigationMenuLink.tsx","src/dashkit/NavigationMenu/NavigationMenuList.tsx","src/dashkit/NavigationMenu/NavigationMenuTrigger.tsx","src/dashkit/NavigationMenu/NavigationMenuViewport.tsx","src/dashkit/NavigationMenu/useNavigationMenu.ts","src/dashkit/NavigationMenu/useNavigationMenuViewport.ts","src/dashkit/NavigationMenu/NavigationMenu.test.tsx","src/dashkit/NavigationMenu/index.ts"],dependencies:["framer-motion","clsx","tailwind-merge","react-icons"]},backdrop:{name:"Backdrop",files:["src/dashkit/Backdrop/Backdrop.tsx","src/dashkit/Backdrop/Backdrop.test.tsx","src/dashkit/Backdrop/index.ts"],dependencies:["framer-motion","clsx","tailwind-merge"]},scrollarea:{name:"ScrollArea",files:["src/dashkit/ScrollArea/ScrollArea.tsx","src/dashkit/ScrollArea/ScrollArea.test.tsx","src/dashkit/ScrollArea/index.ts"],dependencies:["clsx","tailwind-merge","class-variance-authority"]},statscard:{name:"StatsCard",files:["src/dashkit/StatsCard/StatsCard.tsx","src/dashkit/StatsCard/StatsCard.test.tsx","src/dashkit/StatsCard/index.ts"],dependencies:["framer-motion","clsx","tailwind-merge","react-icons"],registryDependencies:["card","animatenumber","divider"]},colorpicker:{name:"ColorPicker",files:["src/dashkit/ColorPicker/ColorPicker.tsx","src/dashkit/ColorPicker/ColorPicker.test.tsx","src/dashkit/ColorPicker/index.ts"],dependencies:["clsx","tailwind-merge","react-icons"],registryDependencies:["popover","input"]},copyfield:{name:"CopyField",files:["src/dashkit/CopyField/CopyField.tsx","src/dashkit/CopyField/CopyField.test.tsx","src/dashkit/CopyField/index.ts"],dependencies:["clsx","tailwind-merge","react-icons"],registryDependencies:["input","iconbutton","toast"]},listtile:{name:"ListTile",files:["src/dashkit/ListTile/ListTile.tsx","src/dashkit/ListTile/ListTile.test.tsx","src/dashkit/ListTile/index.ts"],dependencies:["framer-motion","clsx","tailwind-merge"]}};import F from"fs-extra";import B from"path";import Z from"chalk";import Q from"ora";import v from"fs-extra";import M from"path";var ne="dashkit.json";function S(e){let t=e.trim().replace(/\\/g,"/").replace(/^\.\/+/,"").replace(/\/+$/,"");return t==="."?"":t}function U(e,t="dashkit"){let s=S(e)||S(t)||"dashkit";return(s.split("/").pop()??"").toLowerCase().includes("dashkit")?s:`${s}/dashkit`}async function re(e){let t={componentsDir:S(e.componentsDir),cssDir:S(e.cssDir)};await v.writeJson(M.resolve(process.cwd(),ne),t,{spaces:2})}async function $(){let e=M.resolve(process.cwd(),ne);if(await v.pathExists(e))try{return await v.readJson(e)}catch{return null}return null}async function I(){let e=process.cwd(),t=await v.pathExists(M.resolve(e,"src")),s=await v.pathExists(M.resolve(e,"app"))||await v.pathExists(M.resolve(e,"src","app"));return{hasSrc:t,hasApp:s}}function T(e){let t=e.hasSrc?"src/dashkit":"dashkit";return{components:t,css:t}}async function Y(e=process.cwd()){let t=["src/index.css","src/main.css","src/app.css","src/globals.css","src/app/globals.css","app/globals.css","styles/globals.css","index.css"];for(let s of t){let i=M.resolve(e,s);if(await v.pathExists(i))return i}return null}function X(e,t){let s=M.relative(M.dirname(e),t).replace(/\\/g,"/");return s.startsWith(".")||(s=`./${s}`),s}async function ae(e,t){if(!await v.pathExists(e))return{updated:!1,reason:"main_css_not_found"};let s=await v.readFile(e,"utf8");if(s.includes("dashkit.css"))return{updated:!1,reason:"already_imported"};let i=X(e,t),r=`@import "${i}";`,p=/(@import\s+['"]tailwindcss['"];?)(?:\r?\n|$)/,o;return p.test(s)?o=s.replace(p,`$1 +import{Command as Re}from"commander";import h from"fs-extra";import u from"path";import f from"chalk";import ee from"ora";import{fileURLToPath as Ae}from"url";import{execSync as $e}from"child_process";import Ie from"enquirer";var w={accordion:{name:"Accordion",files:["src/dashkit/Accordion/Accordion.tsx","src/dashkit/Accordion/AccordionItem.tsx","src/dashkit/Accordion/AccordionTrigger.tsx","src/dashkit/Accordion/AccordionContent.tsx","src/dashkit/Accordion/AccordionContext.ts","src/dashkit/Accordion/Accordion.test.tsx","src/dashkit/Accordion/index.ts"],dependencies:["framer-motion","clsx","tailwind-merge","react-icons"]},avatar:{name:"Avatar",files:["src/dashkit/Avatar/Avatar.tsx","src/dashkit/Avatar/AvatarGroup.tsx","src/dashkit/Avatar/Avatar.test.tsx","src/dashkit/Avatar/index.ts"],dependencies:["framer-motion","clsx","tailwind-merge","class-variance-authority"]},badge:{name:"Badge",files:["src/dashkit/Badge/Badge.tsx","src/dashkit/Badge/FloatBadge.tsx","src/dashkit/Badge/Badge.test.tsx","src/dashkit/Badge/index.ts"],dependencies:["framer-motion","clsx","tailwind-merge","class-variance-authority"]},floatbadge:{name:"FloatBadge",files:["src/dashkit/Badge/FloatBadge.tsx"],dependencies:["clsx","tailwind-merge"],registryDependencies:["badge"]},"bento-grid":{name:"BentoGrid",files:["src/dashkit/BentoGrid/BentoGrid.tsx","src/dashkit/BentoGrid/BentoGrid.test.tsx","src/dashkit/BentoGrid/index.ts"],dependencies:["clsx","tailwind-merge","class-variance-authority"]},button:{name:"Button",files:["src/dashkit/Button/Button.tsx","src/dashkit/Button/Button.test.tsx","src/dashkit/Button/index.ts"],registryDependencies:["spinner"],dependencies:["clsx","tailwind-merge","class-variance-authority"]},card:{name:"Card",files:["src/dashkit/Card/Card.tsx","src/dashkit/Card/CardHeader.tsx","src/dashkit/Card/CardContent.tsx","src/dashkit/Card/CardFooter.tsx","src/dashkit/Card/Card.test.tsx","src/dashkit/Card/index.ts"],registryDependencies:["badge","button"],dependencies:["framer-motion","clsx","tailwind-merge","class-variance-authority"]},chip:{name:"Chip",files:["src/dashkit/Chip/Chip.tsx","src/dashkit/Chip/Chip.test.tsx","src/dashkit/Chip/index.ts"],dependencies:["clsx","tailwind-merge","class-variance-authority","react-icons"]},checkbox:{name:"Checkbox",files:["src/dashkit/Checkbox/Checkbox.tsx","src/dashkit/Checkbox/Checkbox.test.tsx","src/dashkit/Checkbox/index.ts"],dependencies:["clsx","tailwind-merge"]},drawer:{name:"Drawer",files:["src/dashkit/Drawer/Drawer.tsx","src/dashkit/Drawer/useDrawer.ts","src/dashkit/Drawer/Drawer.test.tsx","src/dashkit/Drawer/index.ts"],registryDependencies:["backdrop"],dependencies:["framer-motion","clsx","tailwind-merge","class-variance-authority","react-icons"]},dropdown:{name:"Dropdown",files:["src/dashkit/Dropdown/Dropdown.tsx","src/dashkit/Dropdown/DropdownContent.tsx","src/dashkit/Dropdown/DropdownItem.tsx","src/dashkit/Dropdown/DropdownLabel.tsx","src/dashkit/Dropdown/DropdownSeparator.tsx","src/dashkit/Dropdown/DropdownTrigger.tsx","src/dashkit/Dropdown/useDropdown.ts","src/dashkit/Dropdown/Dropdown.test.tsx","src/dashkit/Dropdown/index.ts"],dependencies:["clsx","tailwind-merge","react-icons"]},imageexpander:{name:"ImageExpander",files:["src/dashkit/ImageExpander/ImageExpander.tsx","src/dashkit/ImageExpander/useImageExpander.ts","src/dashkit/ImageExpander/ImageExpander.test.tsx","src/dashkit/ImageExpander/index.ts"],dependencies:["framer-motion","clsx","tailwind-merge","react-icons"]},input:{name:"Input",files:["src/dashkit/Input/Input.tsx","src/dashkit/Input/Input.test.tsx","src/dashkit/Input/index.ts"],dependencies:["clsx","tailwind-merge","class-variance-authority"]},modal:{name:"Modal",files:["src/dashkit/Modal/Modal.tsx","src/dashkit/Modal/ModalContent.tsx","src/dashkit/Modal/ModalFooter.tsx","src/dashkit/Modal/ModalHeader.tsx","src/dashkit/Modal/useModal.ts","src/dashkit/Modal/Modal.test.tsx","src/dashkit/Modal/index.ts"],registryDependencies:["backdrop","iconbutton"],dependencies:["framer-motion","clsx","tailwind-merge","class-variance-authority","react-icons"]},otpinput:{name:"OtpInput",files:["src/dashkit/OtpInput/OtpInput.tsx","src/dashkit/OtpInput/useOtpInput.ts","src/dashkit/OtpInput/OtpInput.test.tsx","src/dashkit/OtpInput/index.ts"],dependencies:["clsx","tailwind-merge"]},radio:{name:"Radio",files:["src/dashkit/Radio/Radio.tsx","src/dashkit/Radio/useRadio.ts","src/dashkit/Radio/Radio.test.tsx","src/dashkit/Radio/index.ts"],dependencies:["clsx","tailwind-merge"]},select:{name:"Select",files:["src/dashkit/Select/Select.tsx","src/dashkit/Select/useSelect.ts","src/dashkit/Select/Select.test.tsx","src/dashkit/Select/index.ts"],dependencies:["clsx","tailwind-merge","class-variance-authority","react-icons"]},switch:{name:"Switch",files:["src/dashkit/Switch/Switch.tsx","src/dashkit/Switch/useSwitch.ts","src/dashkit/Switch/Switch.test.tsx","src/dashkit/Switch/index.ts"],dependencies:["clsx","tailwind-merge"]},slider:{name:"Slider",files:["src/dashkit/Slider/Slider.tsx","src/dashkit/Slider/useSlider.ts","src/dashkit/Slider/Slider.test.tsx","src/dashkit/Slider/index.ts"],dependencies:["clsx","tailwind-merge"]},surface:{name:"Surface",files:["src/dashkit/Surface/Surface.tsx","src/dashkit/Surface/Surface.test.tsx","src/dashkit/Surface/index.ts"],dependencies:["clsx","tailwind-merge","class-variance-authority"]},tabs:{name:"Tabs",files:["src/dashkit/Tabs/Tabs.tsx","src/dashkit/Tabs/Tabs.test.tsx","src/dashkit/Tabs/index.ts"],dependencies:["framer-motion","clsx","tailwind-merge","class-variance-authority"]},toast:{name:"Toast",files:["src/dashkit/Toast/Toast.tsx","src/dashkit/Toast/useToast.ts","src/dashkit/Toast/Toast.test.tsx","src/dashkit/Toast/index.ts"],dependencies:["framer-motion","clsx","tailwind-merge","react-icons"]},stepper:{name:"Stepper",files:["src/dashkit/Stepper/Stepper.tsx","src/dashkit/Stepper/Stepper.test.tsx","src/dashkit/Stepper/index.ts"],dependencies:["framer-motion","clsx","tailwind-merge","react-icons"]},pagination:{name:"Pagination",files:["src/dashkit/Pagination/Pagination.tsx","src/dashkit/Pagination/Pagination.test.tsx","src/dashkit/Pagination/index.ts"],dependencies:["clsx","tailwind-merge","react-icons","framer-motion"]},spinner:{name:"Spinner",files:["src/dashkit/Spinner/Spinner.tsx","src/dashkit/Spinner/Spinner.test.tsx","src/dashkit/Spinner/index.ts"],dependencies:["framer-motion","clsx","tailwind-merge"]},navbar:{name:"Navbar",files:["src/dashkit/Navbar/Navbar.tsx","src/dashkit/Navbar/NavbarActions.tsx","src/dashkit/Navbar/NavbarBrand.tsx","src/dashkit/Navbar/NavbarLinks.tsx","src/dashkit/Navbar/Navbar.test.tsx","src/dashkit/Navbar/index.ts"],dependencies:["clsx","tailwind-merge","class-variance-authority"]},skeleton:{name:"Skeleton",files:["src/dashkit/Skeleton/Skeleton.tsx","src/dashkit/Skeleton/Skeleton.test.tsx","src/dashkit/Skeleton/index.ts"],dependencies:["clsx","tailwind-merge","class-variance-authority"]},breadcrumb:{name:"Breadcrumb",files:["src/dashkit/Breadcrumb/Breadcrumb.tsx","src/dashkit/Breadcrumb/BreadcrumbList.tsx","src/dashkit/Breadcrumb/BreadcrumbItem.tsx","src/dashkit/Breadcrumb/BreadcrumbSeparator.tsx","src/dashkit/Breadcrumb/BreadcrumbEllipsis.tsx","src/dashkit/Breadcrumb/Breadcrumb.test.tsx","src/dashkit/Breadcrumb/index.ts"],dependencies:["clsx","tailwind-merge","react-icons"]},iconbutton:{name:"IconButton",files:["src/dashkit/IconButton/IconButton.tsx","src/dashkit/IconButton/IconButton.test.tsx","src/dashkit/IconButton/index.ts"],dependencies:["clsx","tailwind-merge","class-variance-authority"]},areachart:{name:"AreaChart",files:["src/dashkit/AreaChart/AreaChart.tsx","src/dashkit/AreaChart/useAreaChart.ts","src/dashkit/AreaChart/AreaChart.test.tsx","src/dashkit/AreaChart/index.ts"],dependencies:["framer-motion","clsx","tailwind-merge"]},barchart:{name:"BarChart",files:["src/dashkit/BarChart/BarChart.tsx","src/dashkit/BarChart/useBarChart.ts","src/dashkit/BarChart/BarChart.test.tsx","src/dashkit/BarChart/index.ts"],dependencies:["framer-motion","clsx","tailwind-merge"]},linechart:{name:"LineChart",files:["src/dashkit/LineChart/LineChart.tsx","src/dashkit/LineChart/useLineChart.ts","src/dashkit/LineChart/LineChart.test.tsx","src/dashkit/LineChart/index.ts"],dependencies:["framer-motion","clsx","tailwind-merge"]},piechart:{name:"PieChart",files:["src/dashkit/PieChart/PieChart.tsx","src/dashkit/PieChart/usePieChart.ts","src/dashkit/PieChart/PieChart.test.tsx","src/dashkit/PieChart/index.ts"],dependencies:["framer-motion","clsx","tailwind-merge"]},progressbar:{name:"ProgressBar",files:["src/dashkit/ProgressBar/ProgressBar.tsx","src/dashkit/ProgressBar/useProgressBar.ts","src/dashkit/ProgressBar/ProgressBar.test.tsx","src/dashkit/ProgressBar/index.ts"],dependencies:["framer-motion","clsx","tailwind-merge","class-variance-authority"]},buttongroup:{name:"ButtonGroup",files:["src/dashkit/ButtonGroup/ButtonGroup.tsx","src/dashkit/ButtonGroup/ButtonGroup.test.tsx","src/dashkit/ButtonGroup/index.ts"],dependencies:["clsx","tailwind-merge","class-variance-authority"]},combobox:{name:"Combobox",files:["src/dashkit/Combobox/Combobox.tsx","src/dashkit/Combobox/useCombobox.ts","src/dashkit/Combobox/Combobox.test.tsx","src/dashkit/Combobox/index.ts"],dependencies:["framer-motion","clsx","tailwind-merge","react-icons"],registryDependencies:["chip"]},divider:{name:"Divider",files:["src/dashkit/Divider/Divider.tsx","src/dashkit/Divider/Divider.test.tsx","src/dashkit/Divider/index.ts"],dependencies:["clsx","tailwind-merge","class-variance-authority"]},sidebar:{name:"Sidebar",files:["src/dashkit/Sidebar/Sidebar.tsx","src/dashkit/Sidebar/useSidebar.ts","src/dashkit/Sidebar/SidebarContext.tsx","src/dashkit/Sidebar/Sidebar.test.tsx","src/dashkit/Sidebar/index.ts"],dependencies:["framer-motion","clsx","tailwind-merge","react-icons"],registryDependencies:["iconbutton","tooltip","backdrop"]},"float-action-menu":{name:"FloatActionMenu",files:["src/dashkit/FloatActionMenu/FloatActionMenu.tsx","src/dashkit/FloatActionMenu/useFloatActionMenu.ts","src/dashkit/FloatActionMenu/FloatActionMenu.test.tsx","src/dashkit/FloatActionMenu/index.ts"],dependencies:["framer-motion","clsx","tailwind-merge","react-icons"],registryDependencies:["iconbutton"]},textarea:{name:"Textarea",files:["src/dashkit/Textarea/Textarea.tsx","src/dashkit/Textarea/useTextarea.ts","src/dashkit/Textarea/Textarea.test.tsx","src/dashkit/Textarea/index.ts"],dependencies:["clsx","tailwind-merge"]},datepicker:{name:"DatePicker",files:["src/dashkit/DatePicker/DatePicker.tsx","src/dashkit/DatePicker/useDatePicker.ts","src/dashkit/DatePicker/DatePicker.test.tsx","src/dashkit/DatePicker/index.ts"],dependencies:["clsx","tailwind-merge","react-icons"]},table:{name:"Table",files:["src/dashkit/Table/Table.tsx","src/dashkit/Table/Table.test.tsx","src/dashkit/Table/index.ts"],dependencies:["clsx","tailwind-merge"]},animatenumber:{name:"AnimateNumber",files:["src/dashkit/AnimateNumber/AnimateNumber.tsx","src/dashkit/AnimateNumber/Digit.tsx","src/dashkit/AnimateNumber/AnimateNumber.test.tsx","src/dashkit/AnimateNumber/index.ts"],dependencies:["framer-motion","clsx","tailwind-merge"]},circularprogress:{name:"CircularProgress",files:["src/dashkit/CircularProgress/CircularProgress.tsx","src/dashkit/CircularProgress/CircularProgress.test.tsx","src/dashkit/CircularProgress/index.ts"],dependencies:["framer-motion","clsx","tailwind-merge"]},dock:{name:"Dock",files:["src/dashkit/Dock/Dock.tsx","src/dashkit/Dock/DockItem.tsx","src/dashkit/Dock/Dock.test.tsx","src/dashkit/Dock/index.ts"],dependencies:["framer-motion","clsx","tailwind-merge"]},popover:{name:"Popover",files:["src/dashkit/Popover/Popover.tsx","src/dashkit/Popover/PopoverContent.tsx","src/dashkit/Popover/PopoverTrigger.tsx","src/dashkit/Popover/usePopover.ts","src/dashkit/Popover/Popover.test.tsx","src/dashkit/Popover/index.ts"],dependencies:["framer-motion","clsx","tailwind-merge"]},tooltip:{name:"Tooltip",files:["src/dashkit/Tooltip/Tooltip.tsx","src/dashkit/Tooltip/Tooltip.test.tsx","src/dashkit/Tooltip/index.ts"],dependencies:["framer-motion","clsx","tailwind-merge"]},systemlogs:{name:"SystemLogs",files:["src/dashkit/SystemLogs/SystemLogs.tsx","src/dashkit/SystemLogs/SystemLogs.test.tsx","src/dashkit/SystemLogs/index.ts"],dependencies:["clsx","tailwind-merge","react-icons"],registryDependencies:["badge"]},datefield:{name:"DateField",files:["src/dashkit/DateField/DateField.tsx","src/dashkit/DateField/useDateField.ts","src/dashkit/DateField/DateField.test.tsx","src/dashkit/DateField/index.ts"],dependencies:["clsx","tailwind-merge"]},"navigation-menu":{name:"NavigationMenu",files:["src/dashkit/NavigationMenu/NavigationMenu.tsx","src/dashkit/NavigationMenu/NavigationMenuContent.tsx","src/dashkit/NavigationMenu/NavigationMenuContext.tsx","src/dashkit/NavigationMenu/NavigationMenuItem.tsx","src/dashkit/NavigationMenu/NavigationMenuLink.tsx","src/dashkit/NavigationMenu/NavigationMenuList.tsx","src/dashkit/NavigationMenu/NavigationMenuTrigger.tsx","src/dashkit/NavigationMenu/NavigationMenuViewport.tsx","src/dashkit/NavigationMenu/useNavigationMenu.ts","src/dashkit/NavigationMenu/useNavigationMenuViewport.ts","src/dashkit/NavigationMenu/NavigationMenu.test.tsx","src/dashkit/NavigationMenu/index.ts"],dependencies:["framer-motion","clsx","tailwind-merge","react-icons"]},backdrop:{name:"Backdrop",files:["src/dashkit/Backdrop/Backdrop.tsx","src/dashkit/Backdrop/Backdrop.test.tsx","src/dashkit/Backdrop/index.ts"],dependencies:["framer-motion","clsx","tailwind-merge"]},scrollarea:{name:"ScrollArea",files:["src/dashkit/ScrollArea/ScrollArea.tsx","src/dashkit/ScrollArea/ScrollArea.test.tsx","src/dashkit/ScrollArea/index.ts"],dependencies:["clsx","tailwind-merge","class-variance-authority"]},statscard:{name:"StatsCard",files:["src/dashkit/StatsCard/StatsCard.tsx","src/dashkit/StatsCard/StatsCard.test.tsx","src/dashkit/StatsCard/index.ts"],dependencies:["framer-motion","clsx","tailwind-merge","react-icons"],registryDependencies:["card","animatenumber","divider"]},colorpicker:{name:"ColorPicker",files:["src/dashkit/ColorPicker/ColorPicker.tsx","src/dashkit/ColorPicker/ColorPicker.test.tsx","src/dashkit/ColorPicker/index.ts"],dependencies:["clsx","tailwind-merge","react-icons"],registryDependencies:["popover","input"]},copyfield:{name:"CopyField",files:["src/dashkit/CopyField/CopyField.tsx","src/dashkit/CopyField/CopyField.test.tsx","src/dashkit/CopyField/index.ts"],dependencies:["clsx","tailwind-merge","react-icons"],registryDependencies:["input","iconbutton","toast"]},listtile:{name:"ListTile",files:["src/dashkit/ListTile/ListTile.tsx","src/dashkit/ListTile/ListTile.test.tsx","src/dashkit/ListTile/index.ts"],dependencies:["framer-motion","clsx","tailwind-merge"]}};import B from"fs-extra";import F from"path";import Z from"chalk";import Q from"ora";import v from"fs-extra";import M from"path";var ne="dashkit.json";function S(e){let t=e.trim().replace(/\\/g,"/").replace(/^\.\/+/,"").replace(/\/+$/,"");return t==="."?"":t}function U(e,t="dashkit"){let s=S(e)||S(t)||"dashkit";return(s.split("/").pop()??"").toLowerCase().includes("dashkit")?s:`${s}/dashkit`}async function re(e){let t={componentsDir:S(e.componentsDir),cssDir:S(e.cssDir)};await v.writeJson(M.resolve(process.cwd(),ne),t,{spaces:2})}async function $(){let e=M.resolve(process.cwd(),ne);if(await v.pathExists(e))try{return await v.readJson(e)}catch{return null}return null}async function I(){let e=process.cwd(),t=await v.pathExists(M.resolve(e,"src")),s=await v.pathExists(M.resolve(e,"app"))||await v.pathExists(M.resolve(e,"src","app"));return{hasSrc:t,hasApp:s}}function T(e){let t=e.hasSrc?"src/dashkit":"dashkit";return{components:t,css:t}}async function Y(e=process.cwd()){let t=["src/index.css","src/main.css","src/app.css","src/globals.css","src/app/globals.css","app/globals.css","styles/globals.css","index.css"];for(let s of t){let i=M.resolve(e,s);if(await v.pathExists(i))return i}return null}function X(e,t){let s=M.relative(M.dirname(e),t).replace(/\\/g,"/");return s.startsWith(".")||(s=`./${s}`),s}async function ae(e,t){if(!await v.pathExists(e))return{updated:!1,reason:"main_css_not_found"};let s=await v.readFile(e,"utf8");if(s.includes("dashkit.css"))return{updated:!1,reason:"already_imported"};let i=X(e,t),r=`@import "${i}";`,p=/(@import\s+['"]tailwindcss['"];?)(?:\r?\n|$)/,o;return p.test(s)?o=s.replace(p,`$1 ${r} `):o=`${r} -${s}`,await v.writeFile(e,o,"utf8"),{updated:!0,importPath:i}}import L from"chalk";var Se={success:"[SUCCESS]",warning:"[WARNING]",error:"[ERROR]",info:"[INFO]"},Pe={success:L.green,warning:L.yellow,error:L.red,info:L.blue};function V(e,t="info"){let s=Se[t],i=Pe[t];(t==="error"?console.error:console.log)(i(`${s} ${e}`))}var a={success:e=>V(e,"success"),warning:e=>V(e,"warning"),error:e=>V(e,"error"),info:e=>V(e,"info"),bold:e=>console.log(L.bold(e))};function G(){let e=process.cwd();return F.existsSync(B.resolve(e,"bun.lock"))||F.existsSync(B.resolve(e,"bun.lockb"))?"bun":F.existsSync(B.resolve(e,"pnpm-lock.yaml"))?"pnpm":F.existsSync(B.resolve(e,"yarn.lock"))?"yarn":F.existsSync(B.resolve(e,"package-lock.json"))?"npm":"bun"}async function R(e){let t=B.resolve(process.cwd(),"package.json");if(!await F.pathExists(t))return e;try{let s=await F.readJson(t),i={...s.dependencies,...s.devDependencies};return e.filter(r=>!i[r])}catch{return e}}async function oe(){a.bold(` +${s}`,await v.writeFile(e,o,"utf8"),{updated:!0,importPath:i}}import L from"chalk";var Se={success:"[SUCCESS]",warning:"[WARNING]",error:"[ERROR]",info:"[INFO]"},Pe={success:L.green,warning:L.yellow,error:L.red,info:L.blue};function H(e,t="info"){let s=Se[t],i=Pe[t];(t==="error"?console.error:console.log)(i(`${s} ${e}`))}var a={success:e=>H(e,"success"),warning:e=>H(e,"warning"),error:e=>H(e,"error"),info:e=>H(e,"info"),bold:e=>console.log(L.bold(e))};function G(){let e=process.cwd();return B.existsSync(F.resolve(e,"bun.lock"))||B.existsSync(F.resolve(e,"bun.lockb"))?"bun":B.existsSync(F.resolve(e,"pnpm-lock.yaml"))?"pnpm":B.existsSync(F.resolve(e,"yarn.lock"))?"yarn":B.existsSync(F.resolve(e,"package-lock.json"))?"npm":"bun"}async function R(e){let t=F.resolve(process.cwd(),"package.json");if(!await B.pathExists(t))return e;try{let s=await B.readJson(t),i={...s.dependencies,...s.devDependencies};return e.filter(r=>!i[r])}catch{return e}}async function oe(){a.bold(` Dashkit UI - Health Check -`);let e=await I(),t=await $(),s=(t==null?void 0:t.cssDir)??T(e).css,i=0,r=Q(`Verifying ${Z.bold("core dependencies")}...`).start(),p=await R(["react","react-dom","typescript","tailwindcss"]);r.stop(),p.length===0?a.success("React, TypeScript, and TailwindCSS are correctly installed."):a.warning(`Missing some core dependencies: ${p.join(", ")}`);let o=Q(`Verifying ${Z.bold("dashkit.css")}...`).start(),l=B.resolve(process.cwd(),s,"dashkit.css");o.stop(),F.existsSync(l)?a.success(`dashkit.css found in ${s===""?"root":s+"/"}.`):(a.error('dashkit.css not found. Please run "dashkit init".'),i++);let c=Q(`Verifying ${Z.bold("design system context")}...`).start(),n=await Y();if(c.stop(),n){let m=B.relative(process.cwd(),n).replace(/\\/g,"/");a.success(`Basic styling (${m}) found.`);try{(await F.readFile(n,"utf8")).includes("dashkit.css")?a.success(`dashkit.css imported in ${m}.`):a.warning(`${m} found, but dashkit.css is not imported in it.`)}catch{}}else{let m=B.join(e.hasSrc?"src":"","index.css");a.info(`Design system base (${m}) not found.`)}let d=G();a.bold(` +`);let e=await I(),t=await $(),s=(t==null?void 0:t.cssDir)??T(e).css,i=0,r=Q(`Verifying ${Z.bold("core dependencies")}...`).start(),p=await R(["react","react-dom","typescript","tailwindcss"]);r.stop(),p.length===0?a.success("React, TypeScript, and TailwindCSS are correctly installed."):a.warning(`Missing some core dependencies: ${p.join(", ")}`);let o=Q(`Verifying ${Z.bold("dashkit.css")}...`).start(),l=F.resolve(process.cwd(),s,"dashkit.css");o.stop(),B.existsSync(l)?a.success(`dashkit.css found in ${s===""?"root":s+"/"}.`):(a.error('dashkit.css not found. Please run "dashkit init".'),i++);let c=Q(`Verifying ${Z.bold("design system context")}...`).start(),n=await Y();if(c.stop(),n){let m=F.relative(process.cwd(),n).replace(/\\/g,"/");a.success(`Basic styling (${m}) found.`);try{(await B.readFile(n,"utf8")).includes("dashkit.css")?a.success(`dashkit.css imported in ${m}.`):a.warning(`${m} found, but dashkit.css is not imported in it.`)}catch{}}else{let m=F.join(e.hasSrc?"src":"","index.css");a.info(`Design system base (${m}) not found.`)}let d=G();a.bold(` Environment Info:`),a.bold(` Package Manager: ${d}`),a.bold(` Project Root: ${process.cwd()} `),i===0?a.success(`Everything looks good! Your component library is healthy. `):(a.error(`Found ${i} issues. Please address them before distributing. -`),process.exit(1))}var{MultiSelect:Te,Input:ce,Confirm:q}=Ie,Fe=Ae(import.meta.url),Be=u.dirname(Fe),_=u.resolve(Be,"..");async function je(e,t,s=!1){if(!await h.pathExists(t))throw new Error(`Source file not found: ${t}`);return!s&&await h.pathExists(e)?"kept":(await h.ensureDir(u.dirname(e)),await h.copy(t,e),"installed")}async function de(e,t=!1){let s=u.resolve(_,"src","dashkit","utils");if(!await h.pathExists(s))return[];let i=(await h.readdir(s)).filter(p=>/\.(ts|tsx)$/.test(p)&&!/\.(test|spec)\.(ts|tsx)$/.test(p)),r=[];await h.ensureDir(e);for(let p of i){let o=u.join(e,p);!t&&await h.pathExists(o)||(await h.copy(u.join(s,p),o),r.push(p))}return r}async function Ne(e,t,s=!1,i=!1){let r=i?e.files:e.files.filter(n=>!/\.(test|spec)\.(ts|tsx)$/.test(n)),p=[];for(let n of r){let d=u.resolve(_,n),m=u.join(t,u.basename(n));if(!await h.pathExists(d))throw new Error(`File not found: ${d}`);p.push({sourcePath:d,targetPath:m,exists:await h.pathExists(m)})}let o=p.filter(n=>n.exists),l=s;if(o.length>0&&!l&&process.stdin.isTTY&&process.stdout.isTTY)try{l=await new q({name:"overwrite",message:`${o.length} file(s) for ${e.name} already exist. Overwrite?`,initial:!1}).run()}catch{l=!1}let c={copied:0,kept:[]};for(let n of p){if(n.exists&&!l){c.kept.push(u.basename(n.targetPath));continue}await h.copy(n.sourcePath,n.targetPath),c.copied+=1}return c.kept.length>0&&a.warning(`Kept existing file(s) for ${e.name}: ${c.kept.join(", ")} (use --force to overwrite).`),c}async function le(e,t=!1){let s=await R(e);if(s.length===0)return;let i=G(),p=`${i} ${i==="npm"?"install":"add"} ${s.join(" ")}`,o=ee({text:"Installing dependencies...",isSilent:t||!process.stdout.isTTY}).start();try{$e(p,{stdio:t?"pipe":"inherit",cwd:process.cwd()}),o.stop(),t||a.success("Dependencies installed.")}catch{o.stop(),t||(a.error("Failed to install dependencies. Please run:"),a.bold(` ${p}`)),process.exitCode=1}}async function pe(e,t,s=!1,i=new Set,r=new Set){let p=e.toLowerCase(),o=w[p];if(!o)return a.error(`Component "${e}" not found in registry.`),process.exitCode=1,!1;if(r.has(p))return!0;r.add(p);let l=ee(s?`Adding dependency ${f.bold(o.name)}...`:`Adding ${f.bold(o.name)}...`).start();try{let c=u.resolve(process.cwd(),t.output,o.name);if(await h.ensureDir(c),await Ne(o,c,t.force,t.tests),o.dependencies&&o.dependencies.forEach(n=>i.add(n)),o.registryDependencies)for(let n of o.registryDependencies)await pe(n,t,!0,i,r);return l.stop(),s||a.success(`Component ${f.bold(o.name)} added.`),!0}catch(c){return l.stop(),a.error(`Error adding ${s?"dependency ":""}${o.name}`),c instanceof Error&&a.error(c.message),process.exitCode=1,!1}}async function Me(){let e=Object.keys(w).map(t=>({name:t,message:w[t].name,value:t})).sort((t,s)=>t.message.localeCompare(s.message));try{return await new Te({name:"components",message:"Select components to add (Space to select, Enter to confirm):",choices:e,symbols:{indicator:(s,i)=>i.enabled?"[\u25CF]":"[ ]"}}).run()}catch{process.exit(0)}}async function Ee(e){if(!await h.pathExists(e))return;let t=await h.readdir(e,{withFileTypes:!0}),s=[];for(let l of t){if(!l.isDirectory()||l.name==="utils")continue;let c=u.join(e,l.name,"index.ts");await h.pathExists(c)&&s.push(l.name)}if(s.length===0)return;s.sort((l,c)=>l.localeCompare(c));let i=u.join(e,"index.ts"),r=[];if(await h.pathExists(i)){let l=await h.readFile(i,"utf8");for(let c of l.split(/\r?\n/)){let n=c.trim();n.length>0&&r.push(n)}}let p=new Set(r);for(let l of s)p.add(`export * from './${l}';`);let o=Array.from(p).sort((l,c)=>l.localeCompare(c));await h.writeFile(i,o.join(` +`),process.exit(1))}var{MultiSelect:Te,Input:ce,Confirm:V}=Ie,Be=Ae(import.meta.url),Fe=u.dirname(Be),_=u.resolve(Fe,"..");async function Ne(e,t,s=!1){if(!await h.pathExists(t))throw new Error(`Source file not found: ${t}`);return!s&&await h.pathExists(e)?"kept":(await h.ensureDir(u.dirname(e)),await h.copy(t,e),"installed")}async function de(e,t=!1){let s=u.resolve(_,"src","dashkit","utils");if(!await h.pathExists(s))return[];let i=(await h.readdir(s)).filter(p=>/\.(ts|tsx)$/.test(p)&&!/\.(test|spec)\.(ts|tsx)$/.test(p)),r=[];await h.ensureDir(e);for(let p of i){let o=u.join(e,p);!t&&await h.pathExists(o)||(await h.copy(u.join(s,p),o),r.push(p))}return r}async function je(e,t,s=!1,i=!1){let r=i?e.files:e.files.filter(n=>!/\.(test|spec)\.(ts|tsx)$/.test(n)),p=[];for(let n of r){let d=u.resolve(_,n),m=u.join(t,u.basename(n));if(!await h.pathExists(d))throw new Error(`File not found: ${d}`);p.push({sourcePath:d,targetPath:m,exists:await h.pathExists(m)})}let o=p.filter(n=>n.exists),l=s;if(o.length>0&&!l&&process.stdin.isTTY&&process.stdout.isTTY)try{l=await new V({name:"overwrite",message:`${o.length} file(s) for ${e.name} already exist. Overwrite?`,initial:!1}).run()}catch{l=!1}let c={copied:0,kept:[]};for(let n of p){if(n.exists&&!l){c.kept.push(u.basename(n.targetPath));continue}await h.copy(n.sourcePath,n.targetPath),c.copied+=1}return c.kept.length>0&&a.warning(`Kept existing file(s) for ${e.name}: ${c.kept.join(", ")} (use --force to overwrite).`),c}async function le(e,t=!1){let s=await R(e);if(s.length===0)return;let i=G(),p=`${i} ${i==="npm"?"install":"add"} ${s.join(" ")}`,o=ee({text:"Installing dependencies...",isSilent:t||!process.stdout.isTTY}).start();try{$e(p,{stdio:t?"pipe":"inherit",cwd:process.cwd()}),o.stop(),t||a.success("Dependencies installed.")}catch{o.stop(),t||(a.error("Failed to install dependencies. Please run:"),a.bold(` ${p}`)),process.exitCode=1}}async function pe(e,t,s=!1,i=new Set,r=new Set){let p=e.toLowerCase(),o=w[p];if(!o)return a.error(`Component "${e}" not found in registry.`),process.exitCode=1,!1;if(r.has(p))return!0;r.add(p);let l=ee(s?`Adding dependency ${f.bold(o.name)}...`:`Adding ${f.bold(o.name)}...`).start();try{let c=u.resolve(process.cwd(),t.output,o.name);if(await h.ensureDir(c),await je(o,c,t.force,t.tests),o.dependencies&&o.dependencies.forEach(n=>i.add(n)),o.registryDependencies)for(let n of o.registryDependencies)await pe(n,t,!0,i,r);return l.stop(),s||a.success(`Component ${f.bold(o.name)} added.`),!0}catch(c){return l.stop(),a.error(`Error adding ${s?"dependency ":""}${o.name}`),c instanceof Error&&a.error(c.message),process.exitCode=1,!1}}async function Me(){let e=Object.keys(w).map(t=>({name:t,message:w[t].name,value:t})).sort((t,s)=>t.message.localeCompare(s.message));try{return await new Te({name:"components",message:"Select components to add (Space to select, Enter to confirm):",choices:e,symbols:{indicator:(s,i)=>i.enabled?"[\u25CF]":"[ ]"}}).run()}catch{process.exit(0)}}async function Ee(e){if(!await h.pathExists(e))return;let t=await h.readdir(e,{withFileTypes:!0}),s=[];for(let l of t){if(!l.isDirectory()||l.name==="utils")continue;let c=u.join(e,l.name,"index.ts");await h.pathExists(c)&&s.push(l.name)}if(s.length===0)return;s.sort((l,c)=>l.localeCompare(c));let i=u.join(e,"index.ts"),r=[];if(await h.pathExists(i)){let l=await h.readFile(i,"utf8");for(let c of l.split(/\r?\n/)){let n=c.trim();n.length>0&&r.push(n)}}let p=new Set(r);for(let l of s)p.add(`export * from './${l}';`);let o=Array.from(p).sort((l,c)=>l.localeCompare(c));await h.writeFile(i,o.join(` `)+` -`,"utf8")}async function me(e,t){let s=await I(),i=T(s),r=await $();t.output||(t.output=(r==null?void 0:r.componentsDir)??i.components);let p=u.resolve(process.cwd(),t.output,"utils"),o=await de(p,t.force);o.length>0&&a.success(`Installed utils/${o.join(", utils/")}.`);let l=(r==null?void 0:r.cssDir)??i.css,c=u.resolve(process.cwd(),l,"dashkit.css");await h.pathExists(c)||a.warning(`dashkit.css not found at ${c} \u2014 run \`dashkit init\` to install it (component styles need its tokens).`);let n=Array.isArray(e)?e:e?[e]:[],d;if(t.all)d=Object.keys(w);else if(n.length>0)d=n;else if(!process.stdin.isTTY||!process.stdout.isTTY){a.error("No component specified in non-interactive mode. Usage: dashkit add "),process.exitCode=1;return}else d=await Me();if(d.length>0){let m=new Set,g=new Set,x=!1;for(let b of d)await pe(b,t,!1,g,m)&&(x=!0);if(x){if(t.install)await le(Array.from(g));else{let k=await R(Array.from(g));if(k.length>0){let C=G(),y=C==="npm"?"install":"add";a.info(`Install missing dependencies: ${f.bold(`${C} ${y} ${k.join(" ")}`)}`)}}let b=u.resolve(process.cwd(),t.output);await Ee(b)}}}async function ue(e={}){let t=await I(),s=T(t),i=await $(),r=(i==null?void 0:i.componentsDir)??s.components,p=u.resolve(process.cwd(),r),l=Object.keys(w).sort((d,m)=>w[d].name.localeCompare(w[m].name)).map(d=>{let m=w[d],g=u.join(p,m.name),x=h.existsSync(g);return{key:d,name:m.name,installed:x,dependencies:m.dependencies??[],registryDependencies:m.registryDependencies??[]}}),c=e.installed?l.filter(d=>d.installed):l;if(e.json){console.log(JSON.stringify(c,null,2));return}let n=l.filter(d=>d.installed).length;a.bold(` +`,"utf8")}async function me(e,t){let s=await I(),i=T(s),r=await $();t.output||(t.output=(r==null?void 0:r.componentsDir)??i.components);let p=u.resolve(process.cwd(),t.output,"utils"),o=await de(p,t.force);o.length>0&&a.success(`Installed utils/${o.join(", utils/")}.`);let l=(r==null?void 0:r.cssDir)??i.css,c=u.resolve(process.cwd(),l,"dashkit.css");await h.pathExists(c)||a.warning(`dashkit.css not found at ${c} \u2014 run \`dashkit init\` to install it (component styles need its tokens).`);let n=Array.isArray(e)?e:e?[e]:[],d;if(t.all)d=Object.keys(w);else if(n.length>0)d=n;else if(!process.stdin.isTTY||!process.stdout.isTTY){a.error("No component specified in non-interactive mode. Usage: dashkit add "),process.exitCode=1;return}else d=await Me();if(d.length>0){let m=new Set,g=new Set,k=!1;for(let b of d)await pe(b,t,!1,g,m)&&(k=!0);if(k){if(t.install)await le(Array.from(g));else{let x=await R(Array.from(g));if(x.length>0){let C=G(),y=C==="npm"?"install":"add";a.info(`Install missing dependencies: ${f.bold(`${C} ${y} ${x.join(" ")}`)}`)}}let b=u.resolve(process.cwd(),t.output);await Ee(b)}}}async function ue(e={}){let t=await I(),s=T(t),i=await $(),r=(i==null?void 0:i.componentsDir)??s.components,p=u.resolve(process.cwd(),r),l=Object.keys(w).sort((d,m)=>w[d].name.localeCompare(w[m].name)).map(d=>{let m=w[d],g=u.join(p,m.name),k=h.existsSync(g);return{key:d,name:m.name,installed:k,dependencies:m.dependencies??[],registryDependencies:m.registryDependencies??[]}}),c=e.installed?l.filter(d=>d.installed):l;if(e.json){console.log(JSON.stringify(c,null,2));return}let n=l.filter(d=>d.installed).length;a.bold(` Dashkit Components Registry `),a.info(`Components directory: ${f.bold(r)}`),a.info(`Total: ${f.bold(String(l.length))} components (${f.green(`${n} installed`)}) -`);for(let d of c){let m=d.installed?f.green("[installed]"):f.dim("[available]"),g=f.bold(d.name.padEnd(20)),x=d.registryDependencies.length>0?f.cyan(` (requires: ${d.registryDependencies.join(", ")})`):"";console.log(` ${m} ${g}${x}`)}console.log(),e.installed||a.info(`Tip: Run ${f.bold("dashkit add ")} to install a component.`)}async function he(e={}){let t=await I(),s=T(t),i=await $(),r=S((i==null?void 0:i.componentsDir)??s.components)||s.components,p=S((i==null?void 0:i.cssDir)??s.css),o=await Y(),l=!!e.json,c;try{let n=e.componentsDir??e.output,d=!!(e.yes||e.json||n!==void 0||e.cssDir!==void 0),m=!!(process.env.CI||process.env.CLAUDECODE||process.env.CURSOR_AGENT||process.env.CODEX_SANDBOX||process.env.ANTIGRAVITY_AGENT),g=d||m||!process.stdin.isTTY||!process.stdout.isTTY,x,b,k,C,y,P=typeof e.aiRules=="string"?e.aiRules:"AGENTS.md";if(g){x=n??r;let D=U(x,r);e.cssDir!==void 0?b=e.cssDir:n!==void 0&&(i==null?void 0:i.cssDir)===void 0?b=D:b=p||".",k=!0,C=!!o,y=e.aiRules!==!1}else{x=await new ce({name:"componentsDir",message:"Where would you like to store your components?",initial:r}).run();let W=U(x,r),ve=(i==null?void 0:i.cssDir)!==void 0?p||".":W;if(b=await new ce({name:"cssDir",message:"Where would you like to store your dashkit.css?",initial:ve}).run(),o){let ie=u.relative(process.cwd(),o).replace(/\\/g,"/");C=await new q({name:"injectCss",message:`Import dashkit.css into ${ie}?`,initial:!0}).run()}else C=!1;e.aiRules===!1?y=!1:typeof e.aiRules=="string"?y=!0:y=await new q({name:"aiRules",message:`Generate AI assistant instructions (${P})?`,initial:!0}).run(),k=await new q({name:"save",message:"Save these settings to dashkit.json?",initial:!0}).run()}let N=U(x,r),A=S(b),H=A?`${A}/dashkit.css`:"dashkit.css";c=ee({text:"Initializing Dashkit...",isSilent:l||!process.stdout.isTTY}).start();let K=u.resolve(process.cwd(),A,"dashkit.css"),be=u.resolve(_,"src","dashkit","dashkit.css"),Ce=await je(K,be,e.force),ye=u.resolve(process.cwd(),N),te=u.join(ye,"utils");await h.ensureDir(te);let De=await de(te,e.force),O="skipped";if(C&&o){let D=await ae(o,K);D.updated?O="imported":D.reason==="already_imported"&&(O="already_imported")}k&&await re({componentsDir:N,cssDir:A});let z=null;y&&(z=await ge(P,{componentsDir:N,cssDir:A})),c.stop();let se=["clsx","tailwind-merge"],E=await R(se);if(E.length>0){let D=await h.pathExists(u.resolve(process.cwd(),"package.json"));e.install!==!1&&D&&(await le(E,l),E=await R(se))}let J=o?u.relative(process.cwd(),o).replace(/\\/g,"/"):null;if(l){console.log(JSON.stringify({initialized:!0,componentsDir:N,cssDir:A,cssFile:H,cssStatus:Ce,mainCssFile:J,cssImportStatus:O,utilsInstalled:De,configFile:k?"dashkit.json":null,aiRulesFile:z,missingDependencies:E},null,2));return}if(a.success("Dashkit initialized successfully."),a.bold(` -Initialization Summary:`),a.info(` Components Dir: ${f.bold(N)}`),a.info(` CSS Dir: ${f.bold(A||"root")}`),J&&o)if(O==="imported"||O==="already_imported")a.info(` Main CSS: ${f.bold(J)} (imported dashkit.css)`);else{let D=X(o,K);a.info(` Main CSS: ${f.bold(J)} (add: @import "${D}";)`)}if(k&&a.info(" Configuration: dashkit.json saved"),z&&a.info(` AI Rules: ${f.bold(z)} (updated)`),E.length>0){let D=G(),W=D==="npm"?"install":"add";a.info(` Base Packages: ${f.bold(`${D} ${W} ${E.join(" ")}`)}`)}}catch(n){n instanceof Error&&n.message==="cancelled"&&process.exit(0),c==null||c.stop(),a.error("Failed to initialize Dashkit."),n instanceof Error&&a.error(n.message),process.exitCode=1}finally{c==null||c.stop()}}async function fe(e,t={}){let s=e.toLowerCase(),i=Object.keys(w).find(k=>k===s||w[k].name.toLowerCase()===s);if(!i){a.error(`Component "${e}" not found in registry.`),process.exitCode=1;return}let r=w[i],p=await I(),o=T(p),l=await $(),c=(l==null?void 0:l.componentsDir)??o.components,n=u.resolve(process.cwd(),c,r.name),d=await h.pathExists(n),m=r.files.filter(k=>!/\.(test|spec)\.(ts|tsx)$/.test(k)),g=[],x=[];for(let k of m){let C=u.resolve(_,k);if(!await h.pathExists(C))continue;let y=await h.readFile(C,"utf8");for(let P of y.matchAll(/export\s+(?:function|const)\s+([A-Za-z0-9_]+)/g))g.includes(P[1])||g.push(P[1]);for(let P of y.matchAll(/export\s+(?:interface|type)\s+[A-Za-z0-9_]*Props\b[\s\S]*?(?=\nexport\s|\nconst\s|\nfunction\s|$)/g))x.push(P[0].trim())}let b={key:i,name:r.name,installed:d,installCommand:`bunx carllosnc/dashkit add ${i}`,files:m,dependencies:r.dependencies??[],registryDependencies:r.registryDependencies??[],exports:g,propsDefinitions:x};if(t.json){console.log(JSON.stringify(b,null,2));return}if(a.bold(` +`);for(let d of c){let m=d.installed?f.green("[installed]"):f.dim("[available]"),g=f.bold(d.name.padEnd(20)),k=d.registryDependencies.length>0?f.cyan(` (requires: ${d.registryDependencies.join(", ")})`):"";console.log(` ${m} ${g}${k}`)}console.log(),e.installed||a.info(`Tip: Run ${f.bold("dashkit add ")} to install a component.`)}async function he(e={}){let t=await I(),s=T(t),i=await $(),r=S((i==null?void 0:i.componentsDir)??s.components)||s.components,p=S((i==null?void 0:i.cssDir)??s.css),o=await Y(),l=!!e.json,c;try{let n=e.componentsDir??e.output,d=!!(e.yes||e.json||n!==void 0||e.cssDir!==void 0),m=!!(process.env.CI||process.env.CLAUDECODE||process.env.CURSOR_AGENT||process.env.CODEX_SANDBOX||process.env.ANTIGRAVITY_AGENT),g=d||m||!process.stdin.isTTY||!process.stdout.isTTY,k,b,x,C,y,P=typeof e.aiRules=="string"?e.aiRules:"AGENTS.md";if(g){k=n??r;let D=U(k,r);e.cssDir!==void 0?b=e.cssDir:n!==void 0&&(i==null?void 0:i.cssDir)===void 0?b=D:b=p||".",x=!0,C=!!o,y=e.aiRules!==!1}else{k=await new ce({name:"componentsDir",message:"Where would you like to store your components?",initial:r}).run();let W=U(k,r),ve=(i==null?void 0:i.cssDir)!==void 0?p||".":W;if(b=await new ce({name:"cssDir",message:"Where would you like to store your dashkit.css?",initial:ve}).run(),o){let ie=u.relative(process.cwd(),o).replace(/\\/g,"/");C=await new V({name:"injectCss",message:`Import dashkit.css into ${ie}?`,initial:!0}).run()}else C=!1;e.aiRules===!1?y=!1:typeof e.aiRules=="string"?y=!0:y=await new V({name:"aiRules",message:`Generate AI assistant instructions (${P})?`,initial:!0}).run(),x=await new V({name:"save",message:"Save these settings to dashkit.json?",initial:!0}).run()}let j=U(k,r),A=S(b),q=A?`${A}/dashkit.css`:"dashkit.css";c=ee({text:"Initializing Dashkit...",isSilent:l||!process.stdout.isTTY}).start();let K=u.resolve(process.cwd(),A,"dashkit.css"),be=u.resolve(_,"src","dashkit","dashkit.css"),Ce=await Ne(K,be,e.force),ye=u.resolve(process.cwd(),j),te=u.join(ye,"utils");await h.ensureDir(te);let De=await de(te,e.force),O="skipped";if(C&&o){let D=await ae(o,K);D.updated?O="imported":D.reason==="already_imported"&&(O="already_imported")}x&&await re({componentsDir:j,cssDir:A});let z=null;y&&(z=await ge(P,{componentsDir:j,cssDir:A})),c.stop();let se=["clsx","tailwind-merge"],E=await R(se);if(E.length>0){let D=await h.pathExists(u.resolve(process.cwd(),"package.json"));e.install!==!1&&D&&(await le(E,l),E=await R(se))}let J=o?u.relative(process.cwd(),o).replace(/\\/g,"/"):null;if(l){console.log(JSON.stringify({initialized:!0,componentsDir:j,cssDir:A,cssFile:q,cssStatus:Ce,mainCssFile:J,cssImportStatus:O,utilsInstalled:De,configFile:x?"dashkit.json":null,aiRulesFile:z,missingDependencies:E},null,2));return}if(a.success("Dashkit initialized successfully."),a.bold(` +Initialization Summary:`),a.info(` Components Dir: ${f.bold(j)}`),a.info(` CSS Dir: ${f.bold(A||"root")}`),J&&o)if(O==="imported"||O==="already_imported")a.info(` Main CSS: ${f.bold(J)} (imported dashkit.css)`);else{let D=X(o,K);a.info(` Main CSS: ${f.bold(J)} (add: @import "${D}";)`)}if(x&&a.info(" Configuration: dashkit.json saved"),z&&a.info(` AI Rules: ${f.bold(z)} (updated)`),E.length>0){let D=G(),W=D==="npm"?"install":"add";a.info(` Base Packages: ${f.bold(`${D} ${W} ${E.join(" ")}`)}`)}}catch(n){n instanceof Error&&n.message==="cancelled"&&process.exit(0),c==null||c.stop(),a.error("Failed to initialize Dashkit."),n instanceof Error&&a.error(n.message),process.exitCode=1}finally{c==null||c.stop()}}async function fe(e,t={}){let s=e.toLowerCase(),i=Object.keys(w).find(x=>x===s||w[x].name.toLowerCase()===s);if(!i){a.error(`Component "${e}" not found in registry.`),process.exitCode=1;return}let r=w[i],p=await I(),o=T(p),l=await $(),c=(l==null?void 0:l.componentsDir)??o.components,n=u.resolve(process.cwd(),c,r.name),d=await h.pathExists(n),m=r.files.filter(x=>!/\.(test|spec)\.(ts|tsx)$/.test(x)),g=[],k=[];for(let x of m){let C=u.resolve(_,x);if(!await h.pathExists(C))continue;let y=await h.readFile(C,"utf8");for(let P of y.matchAll(/export\s+(?:function|const)\s+([A-Za-z0-9_]+)/g))g.includes(P[1])||g.push(P[1]);for(let P of y.matchAll(/export\s+(?:interface|type)\s+[A-Za-z0-9_]*Props\b[\s\S]*?(?=\nexport\s|\nconst\s|\nfunction\s|$)/g))k.push(P[0].trim())}let b={key:i,name:r.name,installed:d,installCommand:`bunx carllosnc/dashkit add ${i}`,files:m,dependencies:r.dependencies??[],registryDependencies:r.registryDependencies??[],exports:g,propsDefinitions:k};if(t.json){console.log(JSON.stringify(b,null,2));return}if(a.bold(` ${r.name} (${i}) -`),a.info(`Status: ${d?f.green("installed"):f.dim("available")}`),a.info(`Install: ${f.bold(b.installCommand)}`),a.info(`Exports: ${g.join(", ")||r.name}`),a.info(`NPM Dependencies: ${b.dependencies.join(", ")||"none"}`),a.info(`Registry Dependencies: ${b.registryDependencies.join(", ")||"none"}`),x.length>0){a.bold(` -Props Definitions:`);for(let k of x)console.log(` -${k}`)}console.log()}async function ge(e="AGENTS.md",t){let s=await I(),i=T(s),r=t??await $(),p=S((r==null?void 0:r.componentsDir)??i.components)||i.components,o=S((r==null?void 0:r.cssDir)??i.css),l=o?`${o}/dashkit.css`:"dashkit.css",c=u.resolve(process.cwd(),e),n=Object.keys(w).sort((m,g)=>m.localeCompare(g)),d=["","## Dashkit UI \u2014 AI Assistant Guidelines","",`- **Components Directory**: \`${p}\` (import from \`${p}/\` or barrel \`${p}\`)`,`- **Theme & Tokens File**: \`${l}\``,"- **Install Components**: `bunx carllosnc/dashkit add `","- **Inspect Component Props**: `bunx carllosnc/dashkit info --json`",`- **Available Components (${n.length})**: ${n.map(m=>`\`${m}\``).join(", ")}`,"","### 3-Tier AI Customization Protocol",`1. **Global Theme (\`${l}\`)**: Edit \`:root\` / \`.dark\` variables (\`--ds-primary\`, \`--ds-bg\`, \`--ds-card\`, \`--radius\`, \`--ds-pill-radius\`, \`--ds-border-width\`, \`--ds-button-border\`, \`--ds-button-shadow\`, \`--ds-card-shadow\`, \`--ds-input-shadow\`, \`--ds-primary-gradient\`) or set \`data-primary\` / \`data-base\` attributes. Never scatter inline theme classes across pages.`,`2. **Component Variants (\`${p}//.tsx\`)**: Edit \`cva(...)\` variants directly inside the component file when changing a component across the app.`,'3. **Instance Overrides (`className` & `data-slot`)**: Use `className` (merged via `cn()`) or `data-slot` selectors (`className="[&_[data-slot=label]]:uppercase"`) for one-off tweaks.',"","### Component API Patterns","- **Compound (`children`)**: `Card` (`CardHeader`, `CardContent`, `CardFooter`), `Tabs` (`TabsList`, `TabsTrigger`, `TabsContent`), `Accordion` (`AccordionItem`, `AccordionTrigger`, `AccordionContent`), `Modal` (`ModalHeader`, `ModalContent`, `ModalFooter`), `Drawer` (`DrawerHeader`, `DrawerContent`, `DrawerFooter`), `Dropdown`, `Popover`, `Table`, `Navbar`, `Breadcrumb`, `Stepper`.","- **Prop-Driven (`options` / props)**: `Select` & `Combobox` use `options={[{ value, label }]}`; `Input`, `Textarea`, `DatePicker`, `DateField`, `ColorPicker`, `CopyField`, `OtpInput`, `Checkbox`, `Radio`, `Switch`, `Slider` take `label`, `description`/`helperText`, `error` as props; `StatsCard` takes `title`, `value`, `trend`, `status`, `chart`.",""].join(` -`);if(await h.pathExists(c)){let m=await h.readFile(c,"utf8"),g=/[\s\S]*?/,x=g.test(m)?m.replace(g,d):`${m.trimEnd()} +`),a.info(`Status: ${d?f.green("installed"):f.dim("available")}`),a.info(`Install: ${f.bold(b.installCommand)}`),a.info(`Exports: ${g.join(", ")||r.name}`),a.info(`NPM Dependencies: ${b.dependencies.join(", ")||"none"}`),a.info(`Registry Dependencies: ${b.registryDependencies.join(", ")||"none"}`),k.length>0){a.bold(` +Props Definitions:`);for(let x of k)console.log(` +${x}`)}console.log()}async function ge(e="AGENTS.md",t){let s=await I(),i=T(s),r=t??await $(),p=S((r==null?void 0:r.componentsDir)??i.components)||i.components,o=S((r==null?void 0:r.cssDir)??i.css),l=o?`${o}/dashkit.css`:"dashkit.css",c=u.resolve(process.cwd(),e),n=Object.keys(w).sort((m,g)=>m.localeCompare(g)),d=["","## Dashkit UI \u2014 AI Assistant Guidelines","",`- **Components Directory**: \`${p}\` (import from \`${p}/\` or barrel \`${p}\`)`,`- **Theme & Tokens File**: \`${l}\``,"- **Install Components**: `bunx carllosnc/dashkit add `","- **Inspect Component Props**: `bunx carllosnc/dashkit info --json`",`- **Available Components (${n.length})**: ${n.map(m=>`\`${m}\``).join(", ")}`,"","### 3-Tier AI Customization Protocol",`1. **Global Theme (\`${l}\`)**: Edit \`:root\` / \`.dark\` variables (\`--ds-primary\`, \`--ds-bg\`, \`--ds-card\`, \`--radius\`, \`--ds-pill-radius\`, \`--ds-border-width\`, \`--ds-button-border\`, \`--ds-button-shadow\`, \`--ds-card-shadow\`, \`--ds-input-shadow\`, \`--ds-primary-gradient\`) or set \`data-primary\` / \`data-base\` attributes. Never scatter inline theme classes across pages.`,`2. **Component Variants (\`${p}//.tsx\`)**: Edit \`cva(...)\` variants directly inside the component file when changing a component across the app.`,'3. **Instance Overrides (`className` & `data-slot`)**: Use `className` (merged via `cn()`) or `data-slot` selectors (`className="[&_[data-slot=label]]:uppercase"`) for one-off tweaks.',"","### Component API Patterns","- **Compound (`children`)**: `Card` (`CardHeader`, `CardTitle`, `CardDescription`, `CardContent`, `CardFooter`), `BentoGrid` (`BentoGridItem`), `Tabs` (`TabsList`, `TabsTrigger`, `TabsContent`), `Accordion` (`AccordionItem`, `AccordionTrigger`, `AccordionContent`), `Modal` (`ModalHeader`, `ModalContent`, `ModalFooter`), `Drawer` (`DrawerHeader`, `DrawerContent`, `DrawerFooter`), `Dropdown`, `Popover`, `Table` (`TableContainer`, `TableHeader`, `TableBody`, `TableRow`, `TableHead`, `TableCell`), `Navbar` (`NavbarBrand`, `NavbarLinks`, `NavbarActions`), `NavigationMenu`, `Sidebar` (`SidebarProvider`, `SidebarHeader`, `SidebarContent`, `SidebarSection`, `SidebarItem`, `SidebarFooter`), `Breadcrumb`, `Stepper` (`Step`), `Dock` (`DockItem`), `ButtonGroup` (`ButtonGroupItem`), `Avatar` (`AvatarGroup`).","- **Prop-Driven (`options` / props)**: `Select` & `Combobox` use `options={[{ value, label }]}`; `Input`, `Textarea`, `DatePicker`, `DateField`, `ColorPicker`, `CopyField`, `OtpInput`, `Checkbox`, `Radio`, `Switch`, `Slider` take `label`, `description`/`helperText`, `error` as props; `StatsCard` takes `title`, `value`, `trend`, `status`, `chart`.",""].join(` +`);if(await h.pathExists(c)){let m=await h.readFile(c,"utf8"),g=/[\s\S]*?/,k=g.test(m)?m.replace(g,d):`${m.trimEnd()} ${d} -`;await h.writeFile(c,x,"utf8")}else await h.ensureDir(u.dirname(c)),await h.writeFile(c,`# Project AI Instructions +`;await h.writeFile(c,k,"utf8")}else await h.ensureDir(u.dirname(c)),await h.writeFile(c,`# Project AI Instructions ${d} -`,"utf8");return e.replace(/\\/g,"/")}async function xe(e={}){let t=e.output||"AGENTS.md";await ge(t),a.success(`AI rules written to ${t}.`)}async function ke(e,t={}){let s=await I(),i=T(s),r=await $(),p=(r==null?void 0:r.componentsDir)??i.components,o=u.resolve(process.cwd(),p),l;if(e){let n=e.toLowerCase(),d=Object.keys(w).find(m=>m===n||w[m].name.toLowerCase()===n);if(!d){a.error(`Component "${e}" not found in registry.`),process.exitCode=1;return}l=[d]}else l=Object.keys(w).filter(n=>h.existsSync(u.join(o,w[n].name))).sort((n,d)=>w[n].name.localeCompare(w[d].name));let c=[];for(let n of l){let d=w[n],m=u.join(o,d.name),g=d.files.filter(C=>!/\.(test|spec)\.(ts|tsx)$/.test(C)),x=[],b=[];for(let C of g){let y=u.basename(C),P=u.resolve(_,C),N=u.join(m,y);if(!await h.pathExists(N)){b.push(y);continue}let[A,H]=await Promise.all([h.readFile(P,"utf8"),h.readFile(N,"utf8")]);A.replace(/\r\n/g,` -`)!==H.replace(/\r\n/g,` -`)&&x.push(y)}let k=b.length===g.length?"missing":x.length>0||b.length>0?"modified":"up-to-date";c.push({key:n,name:d.name,status:k,modifiedFiles:x,missingFiles:b})}if(t.json){console.log(JSON.stringify(c,null,2));return}if(a.bold(` +`,"utf8");return e.replace(/\\/g,"/")}async function ke(e={}){let t=e.output||"AGENTS.md";await ge(t),a.success(`AI rules written to ${t}.`)}async function xe(e,t={}){let s=await I(),i=T(s),r=await $(),p=(r==null?void 0:r.componentsDir)??i.components,o=u.resolve(process.cwd(),p),l;if(e){let n=e.toLowerCase(),d=Object.keys(w).find(m=>m===n||w[m].name.toLowerCase()===n);if(!d){a.error(`Component "${e}" not found in registry.`),process.exitCode=1;return}l=[d]}else l=Object.keys(w).filter(n=>h.existsSync(u.join(o,w[n].name))).sort((n,d)=>w[n].name.localeCompare(w[d].name));let c=[];for(let n of l){let d=w[n],m=u.join(o,d.name),g=d.files.filter(C=>!/\.(test|spec)\.(ts|tsx)$/.test(C)),k=[],b=[];for(let C of g){let y=u.basename(C),P=u.resolve(_,C),j=u.join(m,y);if(!await h.pathExists(j)){b.push(y);continue}let[A,q]=await Promise.all([h.readFile(P,"utf8"),h.readFile(j,"utf8")]);A.replace(/\r\n/g,` +`)!==q.replace(/\r\n/g,` +`)&&k.push(y)}let x=b.length===g.length?"missing":k.length>0||b.length>0?"modified":"up-to-date";c.push({key:n,name:d.name,status:x,modifiedFiles:k,missingFiles:b})}if(t.json){console.log(JSON.stringify(c,null,2));return}if(a.bold(` Dashkit Component Diff -`),c.length===0){a.info("No installed components found to compare.");return}for(let n of c)if(n.status==="up-to-date")console.log(` ${f.green("[up-to-date]")} ${f.bold(n.name)}`);else if(n.status==="missing")console.log(` ${f.red("[not installed]")} ${f.bold(n.name)}`);else{let d=[...n.modifiedFiles.map(m=>`${m} (modified)`),...n.missingFiles.map(m=>`${m} (missing)`)].join(", ");console.log(` ${f.yellow("[modified]")} ${f.bold(n.name.padEnd(20))} ${f.dim(d)}`)}console.log()}async function we(){await oe()}var j=new Re;j.name("dashkit").description("Dashkit CLI - Add premium components to your project").version("1.0.0");j.command("add").description("Add one or more components to your project").argument("[components...]","Components to add").option("-a, --all","Add all available components in the registry").option("-o, --output ","Output directory (defaults to smart detection)").option("--no-install","Do not automatically install dependencies").option("-f, --force","Overwrite existing component files").option("-t, --tests","Include test files for the component (*.test.tsx)").action(me);j.command("diff").description("Compare installed component files with the upstream Dashkit registry").argument("[component]","Optional component slug or name to inspect").option("--json","Output diff report as JSON").action(ke);j.command("info").description("Show component metadata, dependencies, exports, and props").argument("","Component slug or name to inspect").option("--json","Output component metadata as JSON").action(fe);j.command("list").description("List all available components in Dashkit registry").option("--installed","Show only components installed in the current project").option("--json","Output component list as JSON").action(ue);j.command("init").description("Initialize Dashkit in your project (installs dashkit.css, utils, dashkit.json, and AI rules)").option("-y, --yes","Accept all defaults without prompting").option("-c, --components-dir ","Directory to store Dashkit components").option("-o, --output ","Alias for --components-dir").option("--css-dir ","Directory to store dashkit.css").option("--ai-rules [file]","Generate AI assistant instructions (defaults to AGENTS.md)").option("--no-ai-rules","Skip generating AI assistant instructions").option("-f, --force","Overwrite existing dashkit.css and utility files").option("--no-install","Do not automatically install base dependencies").option("--json","Output initialization result as JSON for LLMs and scripts").action(he);j.command("doctor").description("Run diagnostics on the registry and project structure").action(we);j.command("ai-rules").description("Generate AI assistant instructions (AGENTS.md / .cursorrules) for your project").option("-o, --output ","Target file path (defaults to AGENTS.md)").action(xe);j.parseAsync(); +`),c.length===0){a.info("No installed components found to compare.");return}for(let n of c)if(n.status==="up-to-date")console.log(` ${f.green("[up-to-date]")} ${f.bold(n.name)}`);else if(n.status==="missing")console.log(` ${f.red("[not installed]")} ${f.bold(n.name)}`);else{let d=[...n.modifiedFiles.map(m=>`${m} (modified)`),...n.missingFiles.map(m=>`${m} (missing)`)].join(", ");console.log(` ${f.yellow("[modified]")} ${f.bold(n.name.padEnd(20))} ${f.dim(d)}`)}console.log()}async function we(){await oe()}var N=new Re;N.name("dashkit").description("Dashkit CLI - Add premium components to your project").version("1.0.0");N.command("add").description("Add one or more components to your project").argument("[components...]","Components to add").option("-a, --all","Add all available components in the registry").option("-o, --output ","Output directory (defaults to smart detection)").option("--no-install","Do not automatically install dependencies").option("-f, --force","Overwrite existing component files").option("-t, --tests","Include test files for the component (*.test.tsx)").action(me);N.command("diff").description("Compare installed component files with the upstream Dashkit registry").argument("[component]","Optional component slug or name to inspect").option("--json","Output diff report as JSON").action(xe);N.command("info").description("Show component metadata, dependencies, exports, and props").argument("","Component slug or name to inspect").option("--json","Output component metadata as JSON").action(fe);N.command("list").description("List all available components in Dashkit registry").option("--installed","Show only components installed in the current project").option("--json","Output component list as JSON").action(ue);N.command("init").description("Initialize Dashkit in your project (installs dashkit.css, utils, dashkit.json, and AI rules)").option("-y, --yes","Accept all defaults without prompting").option("-c, --components-dir ","Directory to store Dashkit components").option("-o, --output ","Alias for --components-dir").option("--css-dir ","Directory to store dashkit.css").option("--ai-rules [file]","Generate AI assistant instructions (defaults to AGENTS.md)").option("--no-ai-rules","Skip generating AI assistant instructions").option("-f, --force","Overwrite existing dashkit.css and utility files").option("--no-install","Do not automatically install base dependencies").option("--json","Output initialization result as JSON for LLMs and scripts").action(he);N.command("doctor").description("Run diagnostics on the registry and project structure").action(we);N.command("ai-rules").description("Generate AI assistant instructions (AGENTS.md / .cursorrules) for your project").option("-o, --output ","Target file path (defaults to AGENTS.md)").action(ke);N.parseAsync();