inai-react-components 0.1.7 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +80 -0
- package/dist/commands/add.d.ts +38 -5
- package/dist/commands/add.d.ts.map +1 -1
- package/dist/commands/add.js +391 -80
- package/dist/commands/diff.d.ts +6 -0
- package/dist/commands/diff.d.ts.map +1 -1
- package/dist/commands/diff.js +92 -20
- package/dist/commands/init.d.ts +6 -3
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +33 -36
- package/dist/commands/mcp.d.ts +123 -0
- package/dist/commands/mcp.d.ts.map +1 -0
- package/dist/commands/mcp.js +289 -0
- package/dist/commands/migrate.d.ts +41 -0
- package/dist/commands/migrate.d.ts.map +1 -0
- package/dist/commands/migrate.js +139 -0
- package/dist/commands/registries.d.ts +46 -0
- package/dist/commands/registries.d.ts.map +1 -0
- package/dist/commands/registries.js +152 -0
- package/dist/commands/remove.d.ts +11 -0
- package/dist/commands/remove.d.ts.map +1 -0
- package/dist/commands/remove.js +170 -0
- package/dist/commands/schema.d.ts +16 -0
- package/dist/commands/schema.d.ts.map +1 -0
- package/dist/commands/schema.js +32 -0
- package/dist/commands/status.d.ts +32 -3
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +148 -25
- package/dist/commands/theme.d.ts.map +1 -1
- package/dist/commands/theme.js +3 -37
- package/dist/commands/update.d.ts +18 -1
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +195 -5
- package/dist/index.js +76 -5
- package/dist/schemas/registry-config.schema.json +62 -0
- package/dist/schemas/registry-item.schema.json +63 -0
- package/dist/schemas/registry.schema.json +15 -0
- package/dist/types/registry.d.ts +50 -0
- package/dist/types/registry.d.ts.map +1 -0
- package/dist/types/registry.js +10 -0
- package/dist/utils/auto-install.d.ts +11 -0
- package/dist/utils/auto-install.d.ts.map +1 -0
- package/dist/utils/auto-install.js +29 -0
- package/dist/utils/framework-detect.d.ts +15 -0
- package/dist/utils/framework-detect.d.ts.map +1 -0
- package/dist/utils/framework-detect.js +90 -0
- package/dist/utils/fuzzy-search.d.ts +16 -0
- package/dist/utils/fuzzy-search.d.ts.map +1 -0
- package/dist/utils/fuzzy-search.js +67 -0
- package/dist/utils/registry-config.d.ts +27 -0
- package/dist/utils/registry-config.d.ts.map +1 -0
- package/dist/utils/registry-config.js +94 -0
- package/dist/utils/registry-resolver.d.ts +26 -0
- package/dist/utils/registry-resolver.d.ts.map +1 -1
- package/dist/utils/registry-resolver.js +134 -10
- package/dist/utils/snapshot.d.ts +20 -0
- package/dist/utils/snapshot.d.ts.map +1 -0
- package/dist/utils/snapshot.js +32 -0
- package/dist/utils/themes.d.ts +17 -0
- package/dist/utils/themes.d.ts.map +1 -0
- package/dist/utils/themes.js +49 -0
- package/package.json +9 -3
package/dist/commands/diff.js
CHANGED
|
@@ -2,33 +2,80 @@ import fs from "node:fs";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import chalk from "chalk";
|
|
4
4
|
import ora from "ora";
|
|
5
|
+
import { diffLines } from "diff";
|
|
5
6
|
import { readComponentsJson, readRegistryJson, } from "./status.js";
|
|
6
7
|
import { resolveRegistryDir } from "../utils/registry-resolver.js";
|
|
8
|
+
const CONTEXT_LINES = 2;
|
|
9
|
+
/**
|
|
10
|
+
* Render a unified-style colored diff between two strings using a real
|
|
11
|
+
* LCS-based algorithm (`diffLines` from the `diff` package). Lines that
|
|
12
|
+
* changed are shown in red/green; unchanged lines are only shown as dim
|
|
13
|
+
* context within `CONTEXT_LINES` of a change.
|
|
14
|
+
*/
|
|
7
15
|
export function computeDiff(localContent, registryContent) {
|
|
8
|
-
|
|
9
|
-
|
|
16
|
+
// `diffLines` reports hunks: each has `value` (the text), and flags
|
|
17
|
+
// `added` (present only in the second arg) or `removed` (present only in
|
|
18
|
+
// the first arg). Neither flag means unchanged.
|
|
19
|
+
// We pass (registryContent, localContent) so that "added" means the
|
|
20
|
+
// local file added a line vs the registry (green +), and "removed" means
|
|
21
|
+
// the line was removed from the registry in the local file (red -).
|
|
22
|
+
const hunks = diffLines(registryContent, localContent);
|
|
23
|
+
const hasChanges = hunks.some((h) => h.added || h.removed);
|
|
24
|
+
if (!hasChanges) {
|
|
25
|
+
return chalk.green("No differences found. Component is up to date.");
|
|
26
|
+
}
|
|
10
27
|
const output = [];
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
28
|
+
for (let i = 0; i < hunks.length; i++) {
|
|
29
|
+
const hunk = hunks[i];
|
|
30
|
+
const lines = hunk.value.replace(/\n$/, "").split("\n");
|
|
31
|
+
if (hunk.added) {
|
|
32
|
+
for (const line of lines) {
|
|
33
|
+
output.push(chalk.green(`+ ${line}`));
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
else if (hunk.removed) {
|
|
37
|
+
for (const line of lines) {
|
|
38
|
+
output.push(chalk.red(`- ${line}`));
|
|
39
|
+
}
|
|
18
40
|
}
|
|
19
41
|
else {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
42
|
+
// Unchanged hunk — keep only CONTEXT_LINES around neighboring changes.
|
|
43
|
+
const prevChanged = i > 0 && (hunks[i - 1].added || hunks[i - 1].removed);
|
|
44
|
+
const nextChanged = i < hunks.length - 1 && (hunks[i + 1].added || hunks[i + 1].removed);
|
|
45
|
+
if (!prevChanged && !nextChanged) {
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
if (prevChanged && nextChanged && lines.length > CONTEXT_LINES * 2) {
|
|
49
|
+
// Show trailing context from previous change, a separator, then
|
|
50
|
+
// leading context for next change.
|
|
51
|
+
for (let j = 0; j < CONTEXT_LINES; j++) {
|
|
52
|
+
output.push(chalk.dim(` ${lines[j]}`));
|
|
53
|
+
}
|
|
54
|
+
output.push(chalk.dim(" ..."));
|
|
55
|
+
for (let j = lines.length - CONTEXT_LINES; j < lines.length; j++) {
|
|
56
|
+
output.push(chalk.dim(` ${lines[j]}`));
|
|
57
|
+
}
|
|
23
58
|
}
|
|
24
|
-
if (
|
|
25
|
-
|
|
59
|
+
else if (prevChanged) {
|
|
60
|
+
const end = Math.min(lines.length, CONTEXT_LINES);
|
|
61
|
+
for (let j = 0; j < end; j++) {
|
|
62
|
+
output.push(chalk.dim(` ${lines[j]}`));
|
|
63
|
+
}
|
|
64
|
+
if (lines.length > CONTEXT_LINES) {
|
|
65
|
+
output.push(chalk.dim(" ..."));
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
else if (nextChanged) {
|
|
69
|
+
const start = Math.max(0, lines.length - CONTEXT_LINES);
|
|
70
|
+
if (start > 0) {
|
|
71
|
+
output.push(chalk.dim(" ..."));
|
|
72
|
+
}
|
|
73
|
+
for (let j = start; j < lines.length; j++) {
|
|
74
|
+
output.push(chalk.dim(` ${lines[j]}`));
|
|
75
|
+
}
|
|
26
76
|
}
|
|
27
77
|
}
|
|
28
78
|
}
|
|
29
|
-
if (!hasChanges) {
|
|
30
|
-
return chalk.green("No differences found. Component is up to date.");
|
|
31
|
-
}
|
|
32
79
|
return output.join("\n");
|
|
33
80
|
}
|
|
34
81
|
export function findComponentInRegistry(registryPath, componentName) {
|
|
@@ -42,6 +89,29 @@ export function findComponentInRegistry(registryPath, componentName) {
|
|
|
42
89
|
];
|
|
43
90
|
return allItems.find((c) => c.name === componentName) ?? null;
|
|
44
91
|
}
|
|
92
|
+
/**
|
|
93
|
+
* Map a registry component to the alias slot that should hold its local copy.
|
|
94
|
+
* Fixes the earlier bug where `diff` always assumed `aliases.components`.
|
|
95
|
+
*/
|
|
96
|
+
function getLocalAliasDir(component, componentsJson) {
|
|
97
|
+
const type = component.type.toLowerCase();
|
|
98
|
+
if (type === "block") {
|
|
99
|
+
return componentsJson.aliases.blocks.replace(/^@\//, "src/");
|
|
100
|
+
}
|
|
101
|
+
if (type === "template") {
|
|
102
|
+
// ComponentsJsonFile doesn't officially type `aliases.templates`, but
|
|
103
|
+
// it may be present in user config — fall back to blocks/templates.
|
|
104
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
105
|
+
const templatesAlias = componentsJson.aliases.templates;
|
|
106
|
+
if (templatesAlias) {
|
|
107
|
+
return templatesAlias.replace(/^@\//, "src/");
|
|
108
|
+
}
|
|
109
|
+
const blocksDir = componentsJson.aliases.blocks.replace(/^@\//, "src/");
|
|
110
|
+
const parent = path.dirname(blocksDir);
|
|
111
|
+
return path.join(parent, "templates");
|
|
112
|
+
}
|
|
113
|
+
return componentsJson.aliases.components.replace(/^@\//, "src/");
|
|
114
|
+
}
|
|
45
115
|
export async function runDiff(componentName, rootDir) {
|
|
46
116
|
const componentsJson = readComponentsJson(rootDir);
|
|
47
117
|
if (!componentsJson) {
|
|
@@ -57,11 +127,14 @@ export async function runDiff(componentName, rootDir) {
|
|
|
57
127
|
return chalk.yellow(`Component "${componentName}" has no files in the registry.`);
|
|
58
128
|
}
|
|
59
129
|
const results = [];
|
|
130
|
+
const localComponentDir = getLocalAliasDir(registryComponent, componentsJson);
|
|
131
|
+
const isMultiFile = registryComponent.type === "block" || registryComponent.type === "template";
|
|
60
132
|
for (const filePath of registryComponent.files) {
|
|
61
133
|
const registryFilePath = path.join(registryDir, filePath);
|
|
62
|
-
const localComponentDir = componentsJson.aliases.components.replace(/^@\//, "src/");
|
|
63
134
|
const fileName = path.basename(filePath);
|
|
64
|
-
const localFilePath =
|
|
135
|
+
const localFilePath = isMultiFile
|
|
136
|
+
? path.join(rootDir, localComponentDir, componentName, fileName)
|
|
137
|
+
: path.join(rootDir, localComponentDir, fileName);
|
|
65
138
|
results.push(chalk.bold(`\nDiff for ${fileName}:`));
|
|
66
139
|
results.push(chalk.dim("─".repeat(60)));
|
|
67
140
|
if (!fs.existsSync(registryFilePath)) {
|
|
@@ -71,7 +144,6 @@ export async function runDiff(componentName, rootDir) {
|
|
|
71
144
|
const registryContent = fs.readFileSync(registryFilePath, "utf-8");
|
|
72
145
|
if (!fs.existsSync(localFilePath)) {
|
|
73
146
|
results.push(chalk.yellow(`Local file not found at ${localComponentDir}/${fileName}. Component may not be installed.`));
|
|
74
|
-
// Show what registry has as all additions
|
|
75
147
|
const lines = registryContent.split("\n");
|
|
76
148
|
for (const line of lines) {
|
|
77
149
|
results.push(chalk.green(`+ ${line}`));
|
package/dist/commands/init.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
type Theme =
|
|
1
|
+
import { type Framework } from "../utils/framework-detect.js";
|
|
2
|
+
type Theme = string;
|
|
3
3
|
declare const FONT_PRESETS: readonly [{
|
|
4
4
|
readonly name: "outfit";
|
|
5
5
|
readonly label: "Outfit";
|
|
@@ -227,11 +227,14 @@ export interface InitConfig {
|
|
|
227
227
|
tanstackQuery: boolean;
|
|
228
228
|
tanstackForm: boolean;
|
|
229
229
|
tanstackTable: boolean;
|
|
230
|
+
framework?: Framework;
|
|
231
|
+
cssEntryPoint?: string;
|
|
230
232
|
}
|
|
231
233
|
export interface ComponentsJson {
|
|
232
234
|
$schema: string;
|
|
233
235
|
registrySource?: string;
|
|
234
236
|
style: string;
|
|
237
|
+
framework?: Framework;
|
|
235
238
|
tailwind: {
|
|
236
239
|
config: string;
|
|
237
240
|
css: string;
|
|
@@ -254,7 +257,7 @@ export interface ComponentsJson {
|
|
|
254
257
|
table: boolean;
|
|
255
258
|
};
|
|
256
259
|
}
|
|
257
|
-
export declare function promptInitConfig(registryDir?: string): Promise<InitConfig | null>;
|
|
260
|
+
export declare function promptInitConfig(registryDir?: string, framework?: Framework): Promise<InitConfig | null>;
|
|
258
261
|
export declare function buildComponentsJson(config: InitConfig, repoUrl?: string): ComponentsJson;
|
|
259
262
|
export declare function getCnTemplate(): string;
|
|
260
263
|
export declare function getLocalTailwindCssTemplate(theme: Theme, fontBody: FontPreset, fontHeading: FontPreset, radius: number): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAOA,
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/init.js
CHANGED
|
@@ -4,32 +4,9 @@ import chalk from "chalk";
|
|
|
4
4
|
import ora from "ora";
|
|
5
5
|
import prompts from "prompts";
|
|
6
6
|
import { cloneRegistry, getCacheDir } from "../utils/registry-resolver.js";
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
"linear",
|
|
11
|
-
"notion",
|
|
12
|
-
"vercel",
|
|
13
|
-
"anthropic",
|
|
14
|
-
"shadcn-default",
|
|
15
|
-
"shadcn-blue",
|
|
16
|
-
"shadcn-green",
|
|
17
|
-
"shadcn-orange",
|
|
18
|
-
"shadcn-red",
|
|
19
|
-
"shadcn-rose",
|
|
20
|
-
"shadcn-violet",
|
|
21
|
-
"shadcn-yellow",
|
|
22
|
-
"shadcn-amber",
|
|
23
|
-
"shadcn-lime",
|
|
24
|
-
"shadcn-emerald",
|
|
25
|
-
"shadcn-teal",
|
|
26
|
-
"shadcn-cyan",
|
|
27
|
-
"shadcn-sky",
|
|
28
|
-
"shadcn-indigo",
|
|
29
|
-
"shadcn-purple",
|
|
30
|
-
"shadcn-fuchsia",
|
|
31
|
-
"shadcn-pink",
|
|
32
|
-
];
|
|
7
|
+
import { THEME_NAMES } from "../utils/themes.js";
|
|
8
|
+
import { detectFramework, frameworkLabel, getCssEntryPoint, } from "../utils/framework-detect.js";
|
|
9
|
+
const AVAILABLE_THEMES = THEME_NAMES;
|
|
33
10
|
const FONT_PRESETS = [
|
|
34
11
|
// Sans-serif — geometric & modern
|
|
35
12
|
{ name: "outfit", label: "Outfit", family: "'Outfit', system-ui, sans-serif" },
|
|
@@ -111,8 +88,11 @@ function discoverThemes(registryDir) {
|
|
|
111
88
|
}
|
|
112
89
|
return [...AVAILABLE_THEMES];
|
|
113
90
|
}
|
|
114
|
-
export async function promptInitConfig(registryDir) {
|
|
91
|
+
export async function promptInitConfig(registryDir, framework) {
|
|
115
92
|
const themes = discoverThemes(registryDir);
|
|
93
|
+
const defaultCssEntry = framework
|
|
94
|
+
? getCssEntryPoint(framework)
|
|
95
|
+
: "src/index.css";
|
|
116
96
|
const response = await prompts([
|
|
117
97
|
{
|
|
118
98
|
type: "text",
|
|
@@ -198,15 +178,19 @@ export async function promptInitConfig(registryDir) {
|
|
|
198
178
|
if (!response.componentPath) {
|
|
199
179
|
return null;
|
|
200
180
|
}
|
|
201
|
-
|
|
181
|
+
const config = response;
|
|
182
|
+
config.framework = framework;
|
|
183
|
+
config.cssEntryPoint = defaultCssEntry;
|
|
184
|
+
return config;
|
|
202
185
|
}
|
|
203
186
|
export function buildComponentsJson(config, repoUrl) {
|
|
204
187
|
const json = {
|
|
205
188
|
$schema: "https://inai-ui.dev/schema.json",
|
|
206
189
|
style: "default",
|
|
190
|
+
framework: config.framework,
|
|
207
191
|
tailwind: {
|
|
208
192
|
config: "tailwind.config.ts",
|
|
209
|
-
css: "src/index.css",
|
|
193
|
+
css: config.cssEntryPoint ?? "src/index.css",
|
|
210
194
|
},
|
|
211
195
|
aliases: {
|
|
212
196
|
components: config.importAlias,
|
|
@@ -248,7 +232,8 @@ function getFontFamily(font) {
|
|
|
248
232
|
}
|
|
249
233
|
export function getLocalTailwindCssTemplate(theme, fontBody, fontHeading, radius) {
|
|
250
234
|
return `@import "tailwindcss";
|
|
251
|
-
@import "./styles/tokens/
|
|
235
|
+
@import "./styles/tokens/primitives/colors.css";
|
|
236
|
+
@import "./styles/tokens/base.css";
|
|
252
237
|
@import "./styles/tokens/themes/${theme}.css";
|
|
253
238
|
@import "./styles/tokens/presets/typography.css";
|
|
254
239
|
@import "./styles/tokens/presets/animations.css";
|
|
@@ -318,13 +303,23 @@ function copyTokensToProject(registryDir, targetDir, theme) {
|
|
|
318
303
|
return copied;
|
|
319
304
|
fs.mkdirSync(tokensDest, { recursive: true });
|
|
320
305
|
// Copy base files
|
|
321
|
-
for (const file of ["base.css"
|
|
306
|
+
for (const file of ["base.css"]) {
|
|
322
307
|
const src = path.join(tokensSrc, file);
|
|
323
308
|
if (fs.existsSync(src)) {
|
|
324
309
|
fs.copyFileSync(src, path.join(tokensDest, file));
|
|
325
310
|
copied.push(`src/styles/tokens/${file}`);
|
|
326
311
|
}
|
|
327
312
|
}
|
|
313
|
+
// Copy primitives (color scales referenced by all themes)
|
|
314
|
+
const primitivesSrc = path.join(tokensSrc, "primitives");
|
|
315
|
+
const primitivesDest = path.join(tokensDest, "primitives");
|
|
316
|
+
if (fs.existsSync(primitivesSrc)) {
|
|
317
|
+
const primitiveCopied = copyDirRecursive(primitivesSrc, primitivesDest);
|
|
318
|
+
for (const file of primitiveCopied) {
|
|
319
|
+
const rel = path.relative(targetDir, file);
|
|
320
|
+
copied.push(rel);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
328
323
|
// Copy selected theme (normalized so it applies without data-theme attribute)
|
|
329
324
|
const themesSrc = path.join(tokensSrc, "themes");
|
|
330
325
|
const themesDest = path.join(tokensDest, "themes");
|
|
@@ -373,9 +368,9 @@ export async function runInit(config, targetDir, repoUrl) {
|
|
|
373
368
|
fs.writeFileSync(cnPath, getCnTemplate());
|
|
374
369
|
filesCreated.push("src/lib/cn.ts");
|
|
375
370
|
// 4. Copy tokens and create CSS
|
|
376
|
-
const
|
|
377
|
-
|
|
378
|
-
|
|
371
|
+
const cssRelPath = config.cssEntryPoint ?? "src/index.css";
|
|
372
|
+
const cssPath = path.join(targetDir, cssRelPath);
|
|
373
|
+
fs.mkdirSync(path.dirname(cssPath), { recursive: true });
|
|
379
374
|
if (repoUrl) {
|
|
380
375
|
// Remote mode: copy tokens from cached registry
|
|
381
376
|
const registryDir = getCacheDir();
|
|
@@ -387,11 +382,13 @@ export async function runInit(config, targetDir, repoUrl) {
|
|
|
387
382
|
// Local mode: reference @company/tokens package
|
|
388
383
|
fs.writeFileSync(cssPath, getLegacyTailwindCssTemplate(config.theme, config.fontBody, config.fontHeading, config.radius));
|
|
389
384
|
}
|
|
390
|
-
filesCreated.push(
|
|
385
|
+
filesCreated.push(cssRelPath);
|
|
391
386
|
return { success: true, filesCreated };
|
|
392
387
|
}
|
|
393
388
|
export async function initCommand(repoUrl) {
|
|
394
389
|
console.log(chalk.bold("\nInAI UI - Project Initialization\n"));
|
|
390
|
+
const detectedFramework = detectFramework(process.cwd());
|
|
391
|
+
console.log(chalk.dim(`Detected framework: ${frameworkLabel(detectedFramework)}`));
|
|
395
392
|
if (repoUrl) {
|
|
396
393
|
const spinner = ora("Cloning component registry...").start();
|
|
397
394
|
try {
|
|
@@ -407,7 +404,7 @@ export async function initCommand(repoUrl) {
|
|
|
407
404
|
}
|
|
408
405
|
}
|
|
409
406
|
const registryDir = repoUrl ? getCacheDir() : undefined;
|
|
410
|
-
const config = await promptInitConfig(registryDir);
|
|
407
|
+
const config = await promptInitConfig(registryDir, detectedFramework);
|
|
411
408
|
if (!config) {
|
|
412
409
|
console.log(chalk.yellow("\nInitialization cancelled."));
|
|
413
410
|
process.exit(0);
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Print the JSON config fragment that users must drop into their Claude
|
|
3
|
+
* Desktop or Cursor `mcpServers` block. Invoked from `inai-ui mcp init`.
|
|
4
|
+
*/
|
|
5
|
+
export declare function printMcpConfig(): void;
|
|
6
|
+
export interface ToolTextResult {
|
|
7
|
+
content: Array<{
|
|
8
|
+
type: "text";
|
|
9
|
+
text: string;
|
|
10
|
+
}>;
|
|
11
|
+
isError?: boolean;
|
|
12
|
+
}
|
|
13
|
+
export declare function handleListComponents(args: {
|
|
14
|
+
category?: string;
|
|
15
|
+
} | undefined, cwd: string): Promise<ToolTextResult>;
|
|
16
|
+
export declare function handleViewComponent(args: {
|
|
17
|
+
name?: string;
|
|
18
|
+
} | undefined, cwd: string): Promise<ToolTextResult>;
|
|
19
|
+
export declare function handleAddComponent(args: {
|
|
20
|
+
name?: string;
|
|
21
|
+
force?: boolean;
|
|
22
|
+
} | undefined, cwd: string): Promise<ToolTextResult>;
|
|
23
|
+
export declare function handleDiffComponent(args: {
|
|
24
|
+
name?: string;
|
|
25
|
+
} | undefined, cwd: string): Promise<ToolTextResult>;
|
|
26
|
+
export declare function handleUpdateComponent(args: {
|
|
27
|
+
name?: string;
|
|
28
|
+
} | undefined, cwd: string): Promise<ToolTextResult>;
|
|
29
|
+
export declare function handleListThemes(): Promise<ToolTextResult>;
|
|
30
|
+
export declare function handleStatus(args: {
|
|
31
|
+
json?: boolean;
|
|
32
|
+
} | undefined, cwd: string): Promise<ToolTextResult>;
|
|
33
|
+
export declare const MCP_TOOLS: readonly [{
|
|
34
|
+
readonly name: "list_components";
|
|
35
|
+
readonly description: "List all available components, blocks and templates in the InAI UI registry.";
|
|
36
|
+
readonly inputSchema: {
|
|
37
|
+
readonly type: "object";
|
|
38
|
+
readonly properties: {
|
|
39
|
+
readonly category: {
|
|
40
|
+
readonly type: "string";
|
|
41
|
+
readonly description: "Optional type filter (e.g. 'component', 'form', 'block').";
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
}, {
|
|
46
|
+
readonly name: "view_component";
|
|
47
|
+
readonly description: "View the source code of a component from the registry.";
|
|
48
|
+
readonly inputSchema: {
|
|
49
|
+
readonly type: "object";
|
|
50
|
+
readonly properties: {
|
|
51
|
+
readonly name: {
|
|
52
|
+
readonly type: "string";
|
|
53
|
+
readonly description: "Component name";
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
readonly required: readonly ["name"];
|
|
57
|
+
};
|
|
58
|
+
}, {
|
|
59
|
+
readonly name: "add_component";
|
|
60
|
+
readonly description: "Install a component (and its transitive registry dependencies) into the current project.";
|
|
61
|
+
readonly inputSchema: {
|
|
62
|
+
readonly type: "object";
|
|
63
|
+
readonly properties: {
|
|
64
|
+
readonly name: {
|
|
65
|
+
readonly type: "string";
|
|
66
|
+
readonly description: "Component name";
|
|
67
|
+
};
|
|
68
|
+
readonly force: {
|
|
69
|
+
readonly type: "boolean";
|
|
70
|
+
readonly description: "Overwrite existing files without prompting.";
|
|
71
|
+
};
|
|
72
|
+
};
|
|
73
|
+
readonly required: readonly ["name"];
|
|
74
|
+
};
|
|
75
|
+
}, {
|
|
76
|
+
readonly name: "diff_component";
|
|
77
|
+
readonly description: "Show a unified diff between the locally-installed component and the registry version.";
|
|
78
|
+
readonly inputSchema: {
|
|
79
|
+
readonly type: "object";
|
|
80
|
+
readonly properties: {
|
|
81
|
+
readonly name: {
|
|
82
|
+
readonly type: "string";
|
|
83
|
+
readonly description: "Component name";
|
|
84
|
+
};
|
|
85
|
+
};
|
|
86
|
+
readonly required: readonly ["name"];
|
|
87
|
+
};
|
|
88
|
+
}, {
|
|
89
|
+
readonly name: "update_component";
|
|
90
|
+
readonly description: "Update an installed component to the latest registry version using a 3-way merge against the snapshot captured at install time. Emits conflict markers when local and registry edits overlap.";
|
|
91
|
+
readonly inputSchema: {
|
|
92
|
+
readonly type: "object";
|
|
93
|
+
readonly properties: {
|
|
94
|
+
readonly name: {
|
|
95
|
+
readonly type: "string";
|
|
96
|
+
readonly description: "Component name";
|
|
97
|
+
};
|
|
98
|
+
};
|
|
99
|
+
readonly required: readonly ["name"];
|
|
100
|
+
};
|
|
101
|
+
}, {
|
|
102
|
+
readonly name: "list_themes";
|
|
103
|
+
readonly description: "List the available InAI UI themes with their categories and descriptions.";
|
|
104
|
+
readonly inputSchema: {
|
|
105
|
+
readonly type: "object";
|
|
106
|
+
readonly properties: {};
|
|
107
|
+
};
|
|
108
|
+
}, {
|
|
109
|
+
readonly name: "project_status";
|
|
110
|
+
readonly description: "Return the InAI UI project status (HEALTHY / DRIFT / OUTDATED / MISSING per component).";
|
|
111
|
+
readonly inputSchema: {
|
|
112
|
+
readonly type: "object";
|
|
113
|
+
readonly properties: {
|
|
114
|
+
readonly json: {
|
|
115
|
+
readonly type: "boolean";
|
|
116
|
+
readonly description: "Return JSON payload (default true).";
|
|
117
|
+
};
|
|
118
|
+
};
|
|
119
|
+
};
|
|
120
|
+
}];
|
|
121
|
+
export declare function runMcp(cwd?: string): Promise<void>;
|
|
122
|
+
export declare function mcpCommand(subcommand?: "init"): Promise<void>;
|
|
123
|
+
//# sourceMappingURL=mcp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../src/commands/mcp.ts"],"names":[],"mappings":"AAgCA;;;GAGG;AACH,wBAAgB,cAAc,IAAI,IAAI,CAErC;AAID,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AASD,wBAAsB,oBAAoB,CACxC,IAAI,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,EACvC,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,cAAc,CAAC,CAKzB;AAED,wBAAsB,mBAAmB,CACvC,IAAI,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,EACnC,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,cAAc,CAAC,CA8BzB;AAED,wBAAsB,kBAAkB,CACtC,IAAI,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,SAAS,EACpD,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,cAAc,CAAC,CAkBzB;AAED,wBAAsB,mBAAmB,CACvC,IAAI,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,EACnC,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,cAAc,CAAC,CAmCzB;AAED,wBAAsB,qBAAqB,CACzC,IAAI,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,EACnC,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,cAAc,CAAC,CAgBzB;AAED,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,cAAc,CAAC,CAEhE;AAED,wBAAsB,YAAY,CAChC,IAAI,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,SAAS,EACpC,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,cAAc,CAAC,CAGzB;AAID,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoFZ,CAAC;AAEX,wBAAsB,MAAM,CAAC,GAAG,GAAE,MAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiEvE;AAED,wBAAsB,UAAU,CAC9B,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CAMf"}
|