@aleph-alpha/lib-mcp 1.7.0 → 2.1.0
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 +75 -14
- package/chat-kit-components-meta.json +546 -0
- package/components-meta.json +79 -77
- package/dist/cli.js +541 -63
- package/dist/scripts/generate-component-meta.js +162 -25
- package/dist/server.js +521 -59
- package/package.json +14 -5
|
@@ -15,20 +15,39 @@ import * as path from "node:path";
|
|
|
15
15
|
import { fileURLToPath } from "node:url";
|
|
16
16
|
var __filename = fileURLToPath(import.meta.url);
|
|
17
17
|
var __dirname = path.dirname(__filename);
|
|
18
|
-
function
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
path.
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
path.
|
|
18
|
+
function findInMonorepo(startDir, packageName) {
|
|
19
|
+
let current = startDir;
|
|
20
|
+
for (let i = 0; i < 10; i++) {
|
|
21
|
+
const candidate = path.join(current, "packages", packageName);
|
|
22
|
+
if (fs.existsSync(path.join(candidate, "package.json"))) {
|
|
23
|
+
return candidate;
|
|
24
|
+
}
|
|
25
|
+
const parent = path.dirname(current);
|
|
26
|
+
if (parent === current) break;
|
|
27
|
+
current = parent;
|
|
28
|
+
}
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
function resolveWorkspacePackage(packageName, scope = "@aleph-alpha") {
|
|
32
|
+
const fromDirname = findInMonorepo(__dirname, packageName);
|
|
33
|
+
if (fromDirname) return fromDirname;
|
|
34
|
+
const fromCwd = findInMonorepo(process.cwd(), packageName);
|
|
35
|
+
if (fromCwd) return fromCwd;
|
|
36
|
+
const nodeModulesCandidates = [
|
|
37
|
+
path.resolve(__dirname, `../../${scope}/${packageName}`),
|
|
38
|
+
path.resolve(__dirname, `../../../${scope}/${packageName}`),
|
|
39
|
+
path.join(process.cwd(), `node_modules/${scope}/${packageName}`)
|
|
26
40
|
];
|
|
27
|
-
for (const pkgPath of
|
|
41
|
+
for (const pkgPath of nodeModulesCandidates) {
|
|
28
42
|
if (fs.existsSync(path.join(pkgPath, "package.json"))) {
|
|
29
43
|
return pkgPath;
|
|
30
44
|
}
|
|
31
45
|
}
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
function findUiLibraryRoot() {
|
|
49
|
+
const pkgPath = resolveWorkspacePackage("ui-library");
|
|
50
|
+
if (pkgPath) return pkgPath;
|
|
32
51
|
throw new Error("Could not find @aleph-alpha/ui-library. Is it installed?");
|
|
33
52
|
}
|
|
34
53
|
function getLibrarySourcePath() {
|
|
@@ -41,6 +60,21 @@ function getLibrarySourcePath() {
|
|
|
41
60
|
"Could not find UI library source directory. Is the package installed correctly?"
|
|
42
61
|
);
|
|
43
62
|
}
|
|
63
|
+
function findChatKitRoot() {
|
|
64
|
+
const pkgPath = resolveWorkspacePackage("chat-kit");
|
|
65
|
+
if (pkgPath) return pkgPath;
|
|
66
|
+
throw new Error("Could not find @aleph-alpha/chat-kit. Is it installed?");
|
|
67
|
+
}
|
|
68
|
+
function getChatKitSourcePath() {
|
|
69
|
+
const chatKitRoot = findChatKitRoot();
|
|
70
|
+
const srcPath = path.join(chatKitRoot, "src");
|
|
71
|
+
if (fs.existsSync(srcPath)) {
|
|
72
|
+
return srcPath;
|
|
73
|
+
}
|
|
74
|
+
throw new Error(
|
|
75
|
+
"Could not find chat-kit source directory. Is the package installed correctly?"
|
|
76
|
+
);
|
|
77
|
+
}
|
|
44
78
|
function getPackageRoot() {
|
|
45
79
|
const pkgRoot = path.resolve(__dirname, "../..");
|
|
46
80
|
if (fs.existsSync(path.join(pkgRoot, "package.json"))) {
|
|
@@ -52,6 +86,10 @@ function getPackageRoot() {
|
|
|
52
86
|
// src/utils/file-utils.ts
|
|
53
87
|
import * as fs2 from "node:fs";
|
|
54
88
|
|
|
89
|
+
// src/utils/constants.ts
|
|
90
|
+
var COMPONENT_PREFIX = "Ui";
|
|
91
|
+
var CHAT_KIT_PREFIX = "Ck";
|
|
92
|
+
|
|
55
93
|
// src/constants.ts
|
|
56
94
|
function detectCategoryDirs() {
|
|
57
95
|
const srcPath = getSrcPath();
|
|
@@ -59,11 +97,15 @@ function detectCategoryDirs() {
|
|
|
59
97
|
return [];
|
|
60
98
|
}
|
|
61
99
|
const entries = fs3.readdirSync(srcPath, { withFileTypes: true });
|
|
62
|
-
return entries.filter((entry) => entry.isDirectory()).filter(
|
|
100
|
+
return entries.filter((entry) => entry.isDirectory()).filter(
|
|
101
|
+
(entry) => !entry.name.startsWith(".") && entry.name !== "node_modules"
|
|
102
|
+
).filter((entry) => {
|
|
63
103
|
try {
|
|
64
104
|
const dirPath = path2.join(srcPath, entry.name);
|
|
65
105
|
const subEntries = fs3.readdirSync(dirPath, { withFileTypes: true });
|
|
66
|
-
return subEntries.some(
|
|
106
|
+
return subEntries.some(
|
|
107
|
+
(sub) => sub.isDirectory() && sub.name.startsWith(COMPONENT_PREFIX)
|
|
108
|
+
);
|
|
67
109
|
} catch {
|
|
68
110
|
return false;
|
|
69
111
|
}
|
|
@@ -75,6 +117,47 @@ function getCategoryDirs() {
|
|
|
75
117
|
cachedCategoryDirs = detectCategoryDirs();
|
|
76
118
|
return cachedCategoryDirs;
|
|
77
119
|
}
|
|
120
|
+
function detectChatKitCategoryDirs() {
|
|
121
|
+
const srcPath = getChatKitSrcPath();
|
|
122
|
+
if (!srcPath || !fs3.existsSync(srcPath)) {
|
|
123
|
+
return [];
|
|
124
|
+
}
|
|
125
|
+
const categories = [];
|
|
126
|
+
const walk = (dir, relative, depth) => {
|
|
127
|
+
let entries;
|
|
128
|
+
try {
|
|
129
|
+
entries = fs3.readdirSync(dir, { withFileTypes: true });
|
|
130
|
+
} catch {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
const hasChatKitSubdirs = entries.some(
|
|
134
|
+
(sub) => sub.isDirectory() && sub.name.startsWith(CHAT_KIT_PREFIX)
|
|
135
|
+
);
|
|
136
|
+
if (hasChatKitSubdirs && relative) {
|
|
137
|
+
categories.push(relative);
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
if (depth >= 2) return;
|
|
141
|
+
for (const entry of entries) {
|
|
142
|
+
if (!entry.isDirectory()) continue;
|
|
143
|
+
if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
|
|
144
|
+
if (entry.name.startsWith(CHAT_KIT_PREFIX)) continue;
|
|
145
|
+
walk(
|
|
146
|
+
path2.join(dir, entry.name),
|
|
147
|
+
relative ? path2.join(relative, entry.name) : entry.name,
|
|
148
|
+
depth + 1
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
walk(srcPath, "", 0);
|
|
153
|
+
return categories;
|
|
154
|
+
}
|
|
155
|
+
var cachedChatKitCategoryDirs = null;
|
|
156
|
+
function getChatKitCategoryDirs() {
|
|
157
|
+
if (cachedChatKitCategoryDirs) return cachedChatKitCategoryDirs;
|
|
158
|
+
cachedChatKitCategoryDirs = detectChatKitCategoryDirs();
|
|
159
|
+
return cachedChatKitCategoryDirs;
|
|
160
|
+
}
|
|
78
161
|
function getSrcPath() {
|
|
79
162
|
try {
|
|
80
163
|
return getLibrarySourcePath();
|
|
@@ -82,6 +165,13 @@ function getSrcPath() {
|
|
|
82
165
|
return null;
|
|
83
166
|
}
|
|
84
167
|
}
|
|
168
|
+
function getChatKitSrcPath() {
|
|
169
|
+
try {
|
|
170
|
+
return getChatKitSourcePath();
|
|
171
|
+
} catch {
|
|
172
|
+
return null;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
85
175
|
|
|
86
176
|
// src/scripts/generate-component-meta.ts
|
|
87
177
|
function escapeRegex(str) {
|
|
@@ -91,6 +181,10 @@ var __filename2 = fileURLToPath2(import.meta.url);
|
|
|
91
181
|
var __dirname2 = path3.dirname(__filename2);
|
|
92
182
|
var PACKAGE_ROOT = getPackageRoot();
|
|
93
183
|
var OUTPUT_PATH = path3.join(PACKAGE_ROOT, "components-meta.json");
|
|
184
|
+
var CHAT_KIT_OUTPUT_PATH = path3.join(
|
|
185
|
+
PACKAGE_ROOT,
|
|
186
|
+
"chat-kit-components-meta.json"
|
|
187
|
+
);
|
|
94
188
|
function extractJSDocTags(content, interfaceName) {
|
|
95
189
|
const declarationRegex = new RegExp(
|
|
96
190
|
`export\\s+(?:interface|type)\\s+${escapeRegex(interfaceName)}\\b`
|
|
@@ -138,12 +232,12 @@ function extractJSDocTags(content, interfaceName) {
|
|
|
138
232
|
return { description, useCases, keywords, related, category };
|
|
139
233
|
}
|
|
140
234
|
function extractKeywordsFromName(componentName) {
|
|
141
|
-
const name = componentName.replace(/^Ui/, "");
|
|
235
|
+
const name = componentName.replace(/^(?:Ui|Ck)/, "");
|
|
142
236
|
return name.replace(/([a-z])([A-Z])/g, "$1 $2").toLowerCase().split(/\s+/).filter((word) => word.length > 2);
|
|
143
237
|
}
|
|
144
238
|
function extractProps(content, interfaceName) {
|
|
145
239
|
const regex = new RegExp(
|
|
146
|
-
`export\\s+interface\\s+${escapeRegex(interfaceName)}\\s*\\{([\\s\\S]*?)\\n\\}`,
|
|
240
|
+
`export\\s+interface\\s+${escapeRegex(interfaceName)}\\s*(?:<(?:\\{[^}]*\\}|[^>])*>)?\\s*\\{([\\s\\S]*?)\\n\\}`,
|
|
147
241
|
"m"
|
|
148
242
|
);
|
|
149
243
|
const match = content.match(regex);
|
|
@@ -178,13 +272,17 @@ function processComponent(componentDir, componentName) {
|
|
|
178
272
|
typesContent = fs4.readFileSync(typesPath, "utf-8");
|
|
179
273
|
}
|
|
180
274
|
const escapedName = escapeRegex(componentName);
|
|
181
|
-
const exactPropsRegex = new RegExp(
|
|
275
|
+
const exactPropsRegex = new RegExp(
|
|
276
|
+
`export\\s+(?:interface|type)\\s+(${escapedName}Props)\\b`
|
|
277
|
+
);
|
|
182
278
|
const exactMatch = typesContent.match(exactPropsRegex);
|
|
183
279
|
const subComponentPropsRegex = new RegExp(
|
|
184
280
|
`export\\s+(?:interface|type)\\s+(${escapedName}\\w*Props)\\b`
|
|
185
281
|
);
|
|
186
282
|
const subComponentMatch = typesContent.match(subComponentPropsRegex);
|
|
187
|
-
const anyPropsMatch = typesContent.match(
|
|
283
|
+
const anyPropsMatch = typesContent.match(
|
|
284
|
+
/export\s+(?:interface|type)\s+((?:Ui|Ck)\w+Props)/
|
|
285
|
+
);
|
|
188
286
|
const interfaceName = exactMatch?.[1] || subComponentMatch?.[1] || anyPropsMatch?.[1] || `${componentName}Props`;
|
|
189
287
|
const jsdocData = extractJSDocTags(typesContent, interfaceName);
|
|
190
288
|
const nameKeywords = extractKeywordsFromName(componentName);
|
|
@@ -217,7 +315,7 @@ function scanComponents() {
|
|
|
217
315
|
const entries = fs4.readdirSync(categoryPath, { withFileTypes: true });
|
|
218
316
|
for (const entry of entries) {
|
|
219
317
|
if (!entry.isDirectory()) continue;
|
|
220
|
-
if (!entry.name.startsWith(
|
|
318
|
+
if (!entry.name.startsWith(COMPONENT_PREFIX)) continue;
|
|
221
319
|
if (entry.name === "shadcn") continue;
|
|
222
320
|
const componentDir = path3.join(categoryPath, entry.name);
|
|
223
321
|
const componentMeta = processComponent(componentDir, entry.name);
|
|
@@ -228,19 +326,58 @@ function scanComponents() {
|
|
|
228
326
|
}
|
|
229
327
|
return meta;
|
|
230
328
|
}
|
|
329
|
+
function scanChatKitComponents() {
|
|
330
|
+
const meta = {};
|
|
331
|
+
let srcPath;
|
|
332
|
+
try {
|
|
333
|
+
srcPath = getChatKitSourcePath();
|
|
334
|
+
} catch (e) {
|
|
335
|
+
console.warn(` \u26A0\uFE0F Skipping chat-kit scan: ${e.message}`);
|
|
336
|
+
return meta;
|
|
337
|
+
}
|
|
338
|
+
for (const category of getChatKitCategoryDirs()) {
|
|
339
|
+
const categoryPath = path3.join(srcPath, category);
|
|
340
|
+
if (!fs4.existsSync(categoryPath)) continue;
|
|
341
|
+
const entries = fs4.readdirSync(categoryPath, { withFileTypes: true });
|
|
342
|
+
for (const entry of entries) {
|
|
343
|
+
if (!entry.isDirectory()) continue;
|
|
344
|
+
if (!entry.name.startsWith(CHAT_KIT_PREFIX)) continue;
|
|
345
|
+
const componentDir = path3.join(categoryPath, entry.name);
|
|
346
|
+
const componentMeta = processComponent(componentDir, entry.name);
|
|
347
|
+
if (componentMeta) {
|
|
348
|
+
meta[entry.name] = componentMeta;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
return meta;
|
|
353
|
+
}
|
|
354
|
+
function summarize(label, meta) {
|
|
355
|
+
const total = Object.keys(meta).length;
|
|
356
|
+
const withUseCases = Object.values(meta).filter(
|
|
357
|
+
(m) => m.useCases.length > 0
|
|
358
|
+
).length;
|
|
359
|
+
const withKeywords = Object.values(meta).filter(
|
|
360
|
+
(m) => m.keywords.length > 0
|
|
361
|
+
).length;
|
|
362
|
+
console.log(`
|
|
363
|
+
${label} summary:`);
|
|
364
|
+
console.log(` Components with @useCases: ${withUseCases}/${total}`);
|
|
365
|
+
console.log(` Components with keywords: ${withKeywords}/${total}`);
|
|
366
|
+
}
|
|
231
367
|
function main() {
|
|
232
|
-
console.log("Scanning components...");
|
|
368
|
+
console.log("Scanning ui-library components...");
|
|
233
369
|
const meta = scanComponents();
|
|
234
|
-
console.log(`Found ${Object.keys(meta).length} components`);
|
|
370
|
+
console.log(`Found ${Object.keys(meta).length} ui-library components`);
|
|
235
371
|
console.log(`Writing to ${OUTPUT_PATH}...`);
|
|
236
372
|
fs4.writeFileSync(OUTPUT_PATH, JSON.stringify(meta, null, 2));
|
|
237
|
-
console.log("
|
|
238
|
-
const
|
|
239
|
-
|
|
240
|
-
console.log(`
|
|
241
|
-
|
|
242
|
-
console.log(
|
|
243
|
-
|
|
373
|
+
console.log("\nScanning chat-kit components...");
|
|
374
|
+
const chatKitMeta = scanChatKitComponents();
|
|
375
|
+
console.log(`Found ${Object.keys(chatKitMeta).length} chat-kit components`);
|
|
376
|
+
console.log(`Writing to ${CHAT_KIT_OUTPUT_PATH}...`);
|
|
377
|
+
fs4.writeFileSync(CHAT_KIT_OUTPUT_PATH, JSON.stringify(chatKitMeta, null, 2));
|
|
378
|
+
console.log("\nDone!");
|
|
379
|
+
summarize("ui-library", meta);
|
|
380
|
+
summarize("chat-kit", chatKitMeta);
|
|
244
381
|
}
|
|
245
382
|
var isMain = import.meta.url === `file://${process.argv[1]}`;
|
|
246
383
|
if (isMain) {
|