docsui-cli 0.0.59

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/README.md +279 -0
  2. package/dist/commands/add.d.ts +5 -0
  3. package/dist/commands/add.js +254 -0
  4. package/dist/commands/doctor.d.ts +5 -0
  5. package/dist/commands/doctor.js +250 -0
  6. package/dist/commands/init.d.ts +5 -0
  7. package/dist/commands/init.js +548 -0
  8. package/dist/commands/list.d.ts +5 -0
  9. package/dist/commands/list.js +84 -0
  10. package/dist/commands/mcp.d.ts +3 -0
  11. package/dist/commands/mcp.js +1562 -0
  12. package/dist/commands/new.d.ts +5 -0
  13. package/dist/commands/new.js +113 -0
  14. package/dist/commands/remove.d.ts +5 -0
  15. package/dist/commands/remove.js +134 -0
  16. package/dist/commands/save.d.ts +5 -0
  17. package/dist/commands/save.js +60 -0
  18. package/dist/commands/update.d.ts +5 -0
  19. package/dist/commands/update.js +247 -0
  20. package/dist/index.d.ts +1 -0
  21. package/dist/index.js +88 -0
  22. package/dist/latex-to-primitives.d.ts +59 -0
  23. package/dist/latex-to-primitives.js +1019 -0
  24. package/dist/lib/component-registry.d.ts +33 -0
  25. package/dist/lib/component-registry.js +843 -0
  26. package/dist/lib/css-tokens.d.ts +8 -0
  27. package/dist/lib/css-tokens.js +294 -0
  28. package/dist/metadata.d.ts +1 -0
  29. package/dist/metadata.js +4 -0
  30. package/dist/symbol-map.d.ts +30 -0
  31. package/dist/symbol-map.js +1607 -0
  32. package/dist/utils/detect-structure.d.ts +16 -0
  33. package/dist/utils/detect-structure.js +58 -0
  34. package/dist/utils/fetch-component.d.ts +13 -0
  35. package/dist/utils/fetch-component.js +81 -0
  36. package/dist/utils/get-config.d.ts +14 -0
  37. package/dist/utils/get-config.js +19 -0
  38. package/dist/utils/install-deps.d.ts +3 -0
  39. package/dist/utils/install-deps.js +23 -0
  40. package/dist/utils/save-mdx-page.d.ts +35 -0
  41. package/dist/utils/save-mdx-page.js +44 -0
  42. package/dist/utils/scan-mdx.d.ts +20 -0
  43. package/dist/utils/scan-mdx.js +106 -0
  44. package/dist/utils/telemetry.d.ts +3 -0
  45. package/dist/utils/telemetry.js +42 -0
  46. package/dist/utils/write-component.d.ts +7 -0
  47. package/dist/utils/write-component.js +25 -0
  48. package/dist/webview-bundle.js +3478 -0
  49. package/package.json +94 -0
package/README.md ADDED
@@ -0,0 +1,279 @@
1
+ # docsui
2
+
3
+ Copy-paste MDX components for documentation sites. 52+ components including 150+ math primitives, data structures, tables, diagrams, and more — built with React, TypeScript, and Tailwind CSS. CLI, MCP server, and remark plugin included.
4
+
5
+ Follows the [shadcn/ui](https://ui.shadcn.com) philosophy — components are added directly to your project, not installed as a dependency. You own the code.
6
+
7
+ ## Quick Start
8
+
9
+ ```bash
10
+ # Initialize your project
11
+ npx docsui-cli@latest init
12
+
13
+ # Add components
14
+ npx docsui-cli@latest add callout tabs code-block
15
+
16
+ # Or use the interactive menu
17
+ npx docsui-cli@latest
18
+ ```
19
+
20
+ ## Commands
21
+
22
+ ### `init`
23
+
24
+ Sets up mdx-ui in your project:
25
+
26
+ - Creates `docsui.json` config
27
+ - Injects shadcn-compatible CSS variables into your `globals.css`
28
+ - Patches `tailwind.config` with color tokens (Tailwind v3) or adds `@theme inline` block (Tailwind v4)
29
+ - Injects Shiki dual-theme CSS for syntax highlighting
30
+ - Works with Next.js, Vite React, Astro, and any other framework
31
+
32
+ ```bash
33
+ npx docsui-cli@latest init
34
+ ```
35
+
36
+ ### `add`
37
+
38
+ Adds one or more components to your project:
39
+
40
+ ```bash
41
+ # Add specific components
42
+ npx docsui-cli@latest add callout
43
+
44
+ # Add multiple at once
45
+ npx docsui-cli@latest add tabs steps accordion
46
+
47
+ # Interactive picker (no args)
48
+ npx docsui-cli@latest add
49
+ ```
50
+
51
+ Each component is written to your `componentsDir`, its npm dependencies are installed, and your `mdx-components.tsx` is patched with the correct static imports.
52
+
53
+ ### `update`
54
+
55
+ Re-fetches and overwrites installed components with the latest versions:
56
+
57
+ ```bash
58
+ # Update all installed components
59
+ npx docsui-cli@latest update
60
+
61
+ # Update specific components
62
+ npx docsui-cli@latest update callout tabs
63
+ ```
64
+
65
+ ### `list`
66
+
67
+ ```bash
68
+ # Show all available components
69
+ npx docsui-cli@latest list
70
+
71
+ # Show only installed components
72
+ npx docsui-cli@latest list --installed
73
+ ```
74
+
75
+ ## Available Components (52)
76
+
77
+ ### Content & Layout
78
+
79
+ | Component | Description |
80
+ | ----------------- | ------------------------------------------------------------------- |
81
+ | `alert` | Semantic `role="alert"` boxes — info, warning, destructive, success |
82
+ | `accordion` | Collapsible sections — single or multiple open |
83
+ | `annotation` | Inline text annotation — click to reveal explanation popover |
84
+ | `badge` | Status labels with 7 variants |
85
+ | `blockquote` | Styled blockquote |
86
+ | `callout` | Alert boxes — info, warning, danger, success |
87
+ | `card` | Card + header/title/description/content/footer + LinkCard |
88
+ | `changelog` | Versioned entries with timeline and typed change badges |
89
+ | `definition` | Formal term definition in structured format |
90
+ | `emphasis` | Bold (`<strong>`) and italic (`<em>`) |
91
+ | `glossary` | Context-based inline glossary with popovers via `<Term>` |
92
+ | `heading` | H1–H6 with auto-generated anchor links |
93
+ | `headings` | Markdown h1–h6 overrides with anchor links |
94
+ | `highlight` | Marker-style inline highlight — yellow, blue, green, pink, purple |
95
+ | `horizontal-rule` | Divider — default, dashed, dotted, gradient |
96
+ | `illustration` | Single diagram or responsive 1–3 column image grid |
97
+ | `image` | Image with optional caption |
98
+ | `inline-code` | Inline code snippets |
99
+ | `invariant` | Formal invariant statement with optional complexity annotation |
100
+ | `kbd` | Keyboard shortcut display (`Ctrl+K`, `⌘+S`) |
101
+ | `link` | Styled anchor — auto-detects external URLs, adds open-in-new-tab |
102
+ | `list` | Ordered and unordered lists |
103
+ | `paragraph` | Paragraph with Lead, Intro, Large, Small, Muted variants |
104
+ | `preview` | Tabbed component preview — rendered output + source with copy |
105
+ | `reveal` | Animated click-to-reveal panel for answers, hints, and spoilers |
106
+ | `security-note` | Security callout with severity levels — info, warning, critical |
107
+ | `spoiler` | Collapsible `<details>`/`<summary>` disclosure |
108
+ | `steps` | Numbered step-by-step guide |
109
+ | `tabs` | Tabbed content with keyboard navigation |
110
+
111
+ ### Code & Terminal
112
+
113
+ | Component | Description |
114
+ | ------------ | --------------------------------------------------------------- |
115
+ | `code-block` | Syntax-highlighted code blocks via rehype-pretty-code |
116
+ | `code-group` | Tabbed code blocks — npm/pnpm/yarn or multi-language examples |
117
+ | `diff-block` | Code diff block — highlights `+` additions and `-` removals |
118
+ | `terminal` | macOS-style terminal window with traffic lights and typed lines |
119
+
120
+ ### Math
121
+
122
+ | Component | Description |
123
+ | ----------------- | ----------------------------------------------------------------------------------------------------------- |
124
+ | `math` | LaTeX math via KaTeX — block and inline |
125
+ | `math-primitives` | 150+ JSX math primitives — Frac, Pow, Integral, Sum, Greek, trig, logic and more. No LaTeX engine required. |
126
+ | `math-equation` | Display equation containers — centered block with optional equation number |
127
+ | `math-solution` | Step-by-step solution blocks — SolutionStep, SolutionAnswer, SolutionNote |
128
+
129
+ ### Data & Tables
130
+
131
+ | Component | Description |
132
+ | ------------------ | --------------------------------------------------------------------- |
133
+ | `complexity-table` | Time and space complexity table for algorithm operations |
134
+ | `data-table` | Dynamic table — accepts columns and data as props |
135
+ | `data-type-table` | AI/ML numeric data type and tensor specification table |
136
+ | `hardware-spec` | Hardware interface spec card — type, version, speed, voltage, pins |
137
+ | `pin-table` | Hardware pinout table — signal name, direction, voltage, alt function |
138
+ | `privacy-table` | Personal data documentation — purpose, legal basis, retention |
139
+ | `register-map` | Hardware register/OTP fuse map — address, bits, access type, reset |
140
+ | `table` | Table with header, body, footer, caption |
141
+
142
+ ### Diagrams & Visualization
143
+
144
+ | Component | Description |
145
+ | --------- | ---------------------------------------------------------------------------------- |
146
+ | `ds` | Data structure visualizations — Array, LinkedList, Stack, Queue, Tree, Graph, etc. |
147
+ | `ds-tree` | SVG tree visualizer — BST, AVL, Heap, N-ary with traversal animations |
148
+ | `mermaid` | Mermaid diagrams — flowcharts, sequences, etc. |
149
+
150
+ ### SEO & Metadata
151
+
152
+ | Component | Description |
153
+ | --------- | ---------------------------------------------------------- |
154
+ | `json-ld` | JSON-LD structured data — Article, BreadcrumbList, FAQPage |
155
+
156
+ ### Navigation
157
+
158
+ | Component | Description |
159
+ | ----------- | ------------------------------------ |
160
+ | `file-tree` | Simple string-based file/folder tree |
161
+ | `tree` | Interactive file/folder tree |
162
+
163
+ ### Certification & Compliance
164
+
165
+ | Component | Description |
166
+ | --------------------- | ------------------------------------------------------------ |
167
+ | `certification-badge` | ISO, TISAX, SOC 2 certification chips with status indicators |
168
+
169
+ ### Media
170
+
171
+ | Component | Description |
172
+ | --------- | ----------------------------------------------------------------- |
173
+ | `video` | Video embed — auto-detects YouTube, Vimeo, and HTML5 with caption |
174
+
175
+ ### Utilities
176
+
177
+ | Component | Description |
178
+ | ---------------- | -------------------------------------- |
179
+ | `mdx-components` | Auto-wired MDX component mapper |
180
+ | `utils` | `cn()` utility (clsx + tailwind-merge) |
181
+
182
+ ## Math Primitives
183
+
184
+ `math-primitives` is the single math system in mdx-ui — 150+ JSX components with no LaTeX engine required:
185
+
186
+ ```bash
187
+ npx docsui-cli@latest add math-primitives
188
+ ```
189
+
190
+ ```mdx
191
+ {/* Fraction */}
192
+
193
+ <Frac num="a" den="b" />
194
+
195
+ {/* Integral with bounds */}
196
+
197
+ <Integral from="a" to="b">
198
+ f(x) dx
199
+ </Integral>
200
+
201
+ {/* Compose multiple elements */}
202
+
203
+ <Frac
204
+ num={
205
+ <Expr>
206
+ x <Pow exp="2">dx</Pow>
207
+ </Expr>
208
+ }
209
+ den={<Pow exp="2">dy</Pow>}
210
+ />
211
+ ```
212
+
213
+ Key components: `Expr` (composition), `Frac`, `Pow`, `Sub`, `Sqrt`, `Integral`, `Sum`, `Prod`, `Lim`, `Deriv`, `PDeriv`, `Brace`, `Paren`, full Greek alphabet, trig functions, logic symbols, and more.
214
+
215
+ ## Syntax Highlighting
216
+
217
+ `code-block` integrates with `rehype-pretty-code` and Shiki for accurate, dual-theme syntax highlighting.
218
+
219
+ ```bash
220
+ npm install rehype-pretty-code shiki
221
+ ```
222
+
223
+ ```ts
224
+ // next.config.ts
225
+ import rehypePrettyCode from "rehype-pretty-code";
226
+
227
+ const withMDX = createMDX({
228
+ options: {
229
+ rehypePlugins: [
230
+ [
231
+ rehypePrettyCode,
232
+ {
233
+ theme: { light: "github-light-default", dark: "github-dark-default" },
234
+ defaultColor: false,
235
+ },
236
+ ],
237
+ ],
238
+ },
239
+ });
240
+ ```
241
+
242
+ Map `pre` to `CodeBlock` in your MDX components:
243
+
244
+ ```tsx
245
+ import { CodeBlock } from "@/components/mdx/code-block";
246
+ const components = { pre: CodeBlock };
247
+ ```
248
+
249
+ The required CSS is automatically injected by `npx docsui-cli@latest init`.
250
+
251
+ ## Framework Support
252
+
253
+ | Framework | Status |
254
+ | ---------------------- | ------ |
255
+ | Next.js (App Router) | ✓ |
256
+ | Next.js (Pages Router) | ✓ |
257
+ | Vite React | ✓ |
258
+ | Astro | ✓ |
259
+ | Tailwind v3 | ✓ |
260
+ | Tailwind v4 | ✓ |
261
+
262
+ ## Example `docsui.json`
263
+
264
+ ```json
265
+ {
266
+ "componentsDir": "src/components/mdx",
267
+ "framework": "nextjs"
268
+ }
269
+ ```
270
+
271
+ ## Links
272
+
273
+ - **Documentation**: [GitHub](https://github.com/suryaravikumar-space/mdx-ui)
274
+ - **Issues**: [GitHub Issues](https://github.com/suryaravikumar-space/mdx-ui/issues)
275
+ - **npm**: [docsui](https://www.npmjs.com/package/docsui-cli)
276
+
277
+ ## License
278
+
279
+ MIT
@@ -0,0 +1,5 @@
1
+ import { Command } from 'commander';
2
+
3
+ declare const add: Command;
4
+
5
+ export { add };
@@ -0,0 +1,254 @@
1
+ import { Command } from "commander";
2
+ import prompts from "prompts";
3
+ import chalk from "chalk";
4
+ import ora from "ora";
5
+ import fs from "fs-extra";
6
+ import path from "path";
7
+ import { getConfig } from "../utils/get-config.js";
8
+ import {
9
+ fetchComponent
10
+ } from "../utils/fetch-component.js";
11
+ import { installDependencies } from "../utils/install-deps.js";
12
+ import { COMPONENT_MDX_MAP, REGISTRY } from "../lib/component-registry.js";
13
+ import { scanMdxComponents, printScanWarnings } from "../utils/scan-mdx.js";
14
+ import { ping } from "../utils/telemetry.js";
15
+ async function findMdxComponentsFile(componentsDir, cwd) {
16
+ const candidates = [
17
+ path.join(cwd, componentsDir, "mdx-components.tsx"),
18
+ path.join(cwd, componentsDir, "mdx-components.jsx"),
19
+ // common fallbacks in case init used a different dir than the actual file
20
+ path.join(cwd, "src/components/mdx-components.tsx"),
21
+ path.join(cwd, "src/components/mdx-components.jsx"),
22
+ path.join(cwd, "components/mdx-components.tsx"),
23
+ path.join(cwd, "components/mdx-components.jsx"),
24
+ path.join(cwd, "src/mdx-components.tsx"),
25
+ path.join(cwd, "src/mdx-components.jsx")
26
+ ];
27
+ for (const p of candidates) {
28
+ if (await fs.pathExists(p)) return p;
29
+ }
30
+ return null;
31
+ }
32
+ async function patchMdxComponents(componentName, componentsDir, cwd) {
33
+ const mapping = COMPONENT_MDX_MAP[componentName];
34
+ if (!mapping) return { patched: false, mdxPath: "" };
35
+ if (mapping.imports.length === 0 && Object.keys(mapping.elementMappings).length === 0)
36
+ return { patched: false, mdxPath: "" };
37
+ let mdxPath = await findMdxComponentsFile(componentsDir, cwd);
38
+ if (!mdxPath) {
39
+ mdxPath = path.join(cwd, componentsDir, "mdx-components.tsx");
40
+ await fs.ensureDir(path.dirname(mdxPath));
41
+ await fs.writeFile(mdxPath, `export const mdxComponents = {
42
+ }
43
+ `);
44
+ }
45
+ let content = await fs.readFile(mdxPath, "utf-8");
46
+ if (!content.includes(mapping.importFile)) {
47
+ const importLine = `import { ${mapping.imports.join(", ")} } from "${mapping.importFile}"
48
+ `;
49
+ const exportIdx = content.indexOf("export const mdxComponents");
50
+ if (exportIdx !== -1) {
51
+ content = content.slice(0, exportIdx) + importLine + content.slice(exportIdx);
52
+ } else {
53
+ content = importLine + content;
54
+ }
55
+ }
56
+ const ANCHOR = "export const mdxComponents";
57
+ const anchorIdx = content.indexOf(ANCHOR);
58
+ const openBrace = anchorIdx !== -1 ? content.indexOf("{", anchorIdx) : -1;
59
+ let closeIdx = -1;
60
+ if (openBrace !== -1) {
61
+ let depth = 0;
62
+ for (let i = openBrace; i < content.length; i++) {
63
+ if (content[i] === "{") depth++;
64
+ else if (content[i] === "}") {
65
+ depth--;
66
+ if (depth === 0) {
67
+ closeIdx = i;
68
+ break;
69
+ }
70
+ }
71
+ }
72
+ }
73
+ const objectBody = openBrace !== -1 && closeIdx !== -1 ? content.slice(openBrace + 1, closeIdx) : "";
74
+ const additions = [];
75
+ for (const [element, component] of Object.entries(mapping.elementMappings)) {
76
+ if (!objectBody.includes(`${element}:`) && !objectBody.includes(`${element} :`)) {
77
+ additions.push(` ${element}: ${component},`);
78
+ }
79
+ }
80
+ for (const exportName of mapping.imports) {
81
+ const alreadyMapped = Object.values(mapping.elementMappings).includes(
82
+ exportName
83
+ );
84
+ if (!alreadyMapped && !objectBody.includes(`${exportName},`) && !objectBody.includes(`${exportName}:`)) {
85
+ additions.push(` ${exportName},`);
86
+ }
87
+ }
88
+ if (additions.length > 0 && closeIdx !== -1) {
89
+ content = content.slice(0, closeIdx) + additions.join("\n") + "\n" + content.slice(closeIdx);
90
+ }
91
+ await fs.writeFile(mdxPath, content);
92
+ return { patched: true, mdxPath };
93
+ }
94
+ function loadRegistry() {
95
+ return {
96
+ components: Object.entries(REGISTRY).filter(([name]) => name !== "utils").map(([name, entry]) => ({
97
+ name,
98
+ type: "mdx",
99
+ description: entry.description,
100
+ files: entry.files
101
+ }))
102
+ };
103
+ }
104
+ const add = new Command().name("add").description("Add components to your project").argument("[components...]", "components to add").option(
105
+ "-o, --overwrite",
106
+ "overwrite existing files without prompting",
107
+ false
108
+ ).option("-a, --all", "add all available components", false).action(
109
+ async (components, opts) => {
110
+ console.log();
111
+ const config = await getConfig();
112
+ if (!config) {
113
+ console.log(chalk.red("\u2717 No docsui.json found"));
114
+ console.log(chalk.yellow("Run 'npx docsui-cli@latest init' first"));
115
+ process.exit(1);
116
+ }
117
+ if (opts.all) {
118
+ const registry = loadRegistry();
119
+ components = registry.components.filter((c) => c.type === "mdx").map((c) => c.name);
120
+ console.log(
121
+ chalk.dim(`Adding all ${components.length} components...
122
+ `)
123
+ );
124
+ } else if (components.length === 0) {
125
+ const registry = loadRegistry();
126
+ const mdxComponents = registry.components.filter(
127
+ (c) => c.type === "mdx"
128
+ );
129
+ const { selected } = await prompts({
130
+ type: "multiselect",
131
+ name: "selected",
132
+ message: "Which components would you like to add?",
133
+ choices: mdxComponents.map((c) => ({
134
+ title: c.name.split("-").map(
135
+ (word) => word.charAt(0).toUpperCase() + word.slice(1)
136
+ ).join(" "),
137
+ value: c.name,
138
+ description: c.description
139
+ }))
140
+ });
141
+ components = selected;
142
+ }
143
+ if (!components || components.length === 0) {
144
+ console.log(chalk.yellow("No components selected"));
145
+ process.exit(0);
146
+ }
147
+ const spinner = ora("Fetching components...").start();
148
+ try {
149
+ const componentsData = [];
150
+ const processedComponents = /* @__PURE__ */ new Set();
151
+ async function fetchComponentRecursive(componentName) {
152
+ if (processedComponents.has(componentName)) return;
153
+ processedComponents.add(componentName);
154
+ const data = await fetchComponent(componentName);
155
+ if (data.registryDependencies && data.registryDependencies.length > 0) {
156
+ for (const depName of data.registryDependencies) {
157
+ await fetchComponentRecursive(depName);
158
+ }
159
+ }
160
+ componentsData.push(data);
161
+ }
162
+ for (const component of components) {
163
+ await fetchComponentRecursive(component);
164
+ }
165
+ spinner.text = "Installing dependencies...";
166
+ const allDeps = /* @__PURE__ */ new Set();
167
+ for (const data of componentsData) {
168
+ data.dependencies?.forEach((dep) => allDeps.add(dep));
169
+ }
170
+ if (allDeps.size > 0) {
171
+ await installDependencies(Array.from(allDeps));
172
+ }
173
+ spinner.stop();
174
+ const cwd = process.cwd();
175
+ const framework = config.framework ?? "unknown";
176
+ const written = [];
177
+ const skipped = [];
178
+ for (const data of componentsData) {
179
+ for (const file of data.files) {
180
+ const libRoot = config.componentsDir.startsWith("src/") ? path.join(cwd, "src") : cwd;
181
+ const filePath = file.path.startsWith("lib/") ? path.join(libRoot, file.path) : path.join(cwd, config.componentsDir, file.path);
182
+ if (!path.resolve(filePath).startsWith(path.resolve(cwd) + path.sep)) {
183
+ throw new Error(
184
+ `Refusing to write outside project root: ${file.path}`
185
+ );
186
+ }
187
+ let incoming = file.content;
188
+ if (framework === "react") {
189
+ incoming = incoming.replace(/^["']use client["']\n\n?/m, "");
190
+ }
191
+ const exists = await fs.pathExists(filePath);
192
+ if (exists) {
193
+ const existing = await fs.readFile(filePath, "utf-8");
194
+ if (existing.trim() === incoming.trim()) {
195
+ skipped.push(file.path);
196
+ continue;
197
+ }
198
+ if (!opts.overwrite) {
199
+ const { overwrite } = await prompts({
200
+ type: "confirm",
201
+ name: "overwrite",
202
+ message: `${chalk.yellow(file.path)} already exists and has local changes. Overwrite?`,
203
+ initial: false
204
+ });
205
+ if (!overwrite) {
206
+ skipped.push(file.path);
207
+ continue;
208
+ }
209
+ }
210
+ }
211
+ await fs.ensureDir(path.dirname(filePath));
212
+ await fs.writeFile(filePath, incoming, "utf-8");
213
+ written.push(file.path);
214
+ }
215
+ }
216
+ let patchedFile = "";
217
+ for (const data of componentsData) {
218
+ const result = await patchMdxComponents(
219
+ data.name,
220
+ config.componentsDir,
221
+ cwd
222
+ );
223
+ if (result.patched && !patchedFile) {
224
+ patchedFile = path.relative(cwd, result.mdxPath);
225
+ }
226
+ }
227
+ console.log();
228
+ for (const component of components) {
229
+ console.log(chalk.green(`\u2713 ${component}`));
230
+ }
231
+ if (skipped.length > 0) {
232
+ console.log(chalk.dim(` skipped: ${skipped.join(", ")}`));
233
+ }
234
+ if (patchedFile) {
235
+ console.log(chalk.dim(` updated: ${patchedFile}`));
236
+ }
237
+ console.log();
238
+ console.log(chalk.bold("Done! \u{1F389}"));
239
+ console.log();
240
+ ping("add", { components });
241
+ const pm = await fs.pathExists(path.join(cwd, "pnpm-lock.yaml")) ? "pnpm" : await fs.pathExists(path.join(cwd, "yarn.lock")) ? "yarn" : "npm";
242
+ const scanResults = await scanMdxComponents(cwd);
243
+ printScanWarnings(scanResults, pm);
244
+ } catch (error) {
245
+ spinner.fail("Failed to add components");
246
+ const msg = error instanceof Error ? error.message : String(error);
247
+ console.error(chalk.red(msg));
248
+ process.exit(1);
249
+ }
250
+ }
251
+ );
252
+ export {
253
+ add
254
+ };
@@ -0,0 +1,5 @@
1
+ import { Command } from 'commander';
2
+
3
+ declare const doctor: Command;
4
+
5
+ export { doctor };