@aleph-alpha/lib-mcp 1.7.0 → 2.0.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.
@@ -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 findUiLibraryRoot() {
19
- const possiblePaths = [
20
- // Monorepo development: from packages/lib-mcp/dist/utils -> packages/ui-library
21
- path.resolve(__dirname, "../../../ui-library"),
22
- // Installed as dependency: from node_modules/@aleph-alpha/lib-mcp/dist/utils -> node_modules/@aleph-alpha/ui-library
23
- path.resolve(__dirname, "../../@aleph-alpha/ui-library"),
24
- // Alternative: resolve from cwd
25
- path.join(process.cwd(), "node_modules/@aleph-alpha/ui-library")
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 possiblePaths) {
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();
@@ -63,7 +101,7 @@ function detectCategoryDirs() {
63
101
  try {
64
102
  const dirPath = path2.join(srcPath, entry.name);
65
103
  const subEntries = fs3.readdirSync(dirPath, { withFileTypes: true });
66
- return subEntries.some((sub) => sub.isDirectory() && sub.name.startsWith("Ui"));
104
+ return subEntries.some((sub) => sub.isDirectory() && sub.name.startsWith(COMPONENT_PREFIX));
67
105
  } catch {
68
106
  return false;
69
107
  }
@@ -75,6 +113,47 @@ function getCategoryDirs() {
75
113
  cachedCategoryDirs = detectCategoryDirs();
76
114
  return cachedCategoryDirs;
77
115
  }
116
+ function detectChatKitCategoryDirs() {
117
+ const srcPath = getChatKitSrcPath();
118
+ if (!srcPath || !fs3.existsSync(srcPath)) {
119
+ return [];
120
+ }
121
+ const categories = [];
122
+ const walk = (dir, relative, depth) => {
123
+ let entries;
124
+ try {
125
+ entries = fs3.readdirSync(dir, { withFileTypes: true });
126
+ } catch {
127
+ return;
128
+ }
129
+ const hasChatKitSubdirs = entries.some(
130
+ (sub) => sub.isDirectory() && sub.name.startsWith(CHAT_KIT_PREFIX)
131
+ );
132
+ if (hasChatKitSubdirs && relative) {
133
+ categories.push(relative);
134
+ return;
135
+ }
136
+ if (depth >= 2) return;
137
+ for (const entry of entries) {
138
+ if (!entry.isDirectory()) continue;
139
+ if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
140
+ if (entry.name.startsWith(CHAT_KIT_PREFIX)) continue;
141
+ walk(
142
+ path2.join(dir, entry.name),
143
+ relative ? path2.join(relative, entry.name) : entry.name,
144
+ depth + 1
145
+ );
146
+ }
147
+ };
148
+ walk(srcPath, "", 0);
149
+ return categories;
150
+ }
151
+ var cachedChatKitCategoryDirs = null;
152
+ function getChatKitCategoryDirs() {
153
+ if (cachedChatKitCategoryDirs) return cachedChatKitCategoryDirs;
154
+ cachedChatKitCategoryDirs = detectChatKitCategoryDirs();
155
+ return cachedChatKitCategoryDirs;
156
+ }
78
157
  function getSrcPath() {
79
158
  try {
80
159
  return getLibrarySourcePath();
@@ -82,6 +161,13 @@ function getSrcPath() {
82
161
  return null;
83
162
  }
84
163
  }
164
+ function getChatKitSrcPath() {
165
+ try {
166
+ return getChatKitSourcePath();
167
+ } catch {
168
+ return null;
169
+ }
170
+ }
85
171
 
86
172
  // src/scripts/generate-component-meta.ts
87
173
  function escapeRegex(str) {
@@ -91,6 +177,7 @@ var __filename2 = fileURLToPath2(import.meta.url);
91
177
  var __dirname2 = path3.dirname(__filename2);
92
178
  var PACKAGE_ROOT = getPackageRoot();
93
179
  var OUTPUT_PATH = path3.join(PACKAGE_ROOT, "components-meta.json");
180
+ var CHAT_KIT_OUTPUT_PATH = path3.join(PACKAGE_ROOT, "chat-kit-components-meta.json");
94
181
  function extractJSDocTags(content, interfaceName) {
95
182
  const declarationRegex = new RegExp(
96
183
  `export\\s+(?:interface|type)\\s+${escapeRegex(interfaceName)}\\b`
@@ -138,12 +225,12 @@ function extractJSDocTags(content, interfaceName) {
138
225
  return { description, useCases, keywords, related, category };
139
226
  }
140
227
  function extractKeywordsFromName(componentName) {
141
- const name = componentName.replace(/^Ui/, "");
228
+ const name = componentName.replace(/^(?:Ui|Ck)/, "");
142
229
  return name.replace(/([a-z])([A-Z])/g, "$1 $2").toLowerCase().split(/\s+/).filter((word) => word.length > 2);
143
230
  }
144
231
  function extractProps(content, interfaceName) {
145
232
  const regex = new RegExp(
146
- `export\\s+interface\\s+${escapeRegex(interfaceName)}\\s*\\{([\\s\\S]*?)\\n\\}`,
233
+ `export\\s+interface\\s+${escapeRegex(interfaceName)}\\s*(?:<(?:\\{[^}]*\\}|[^>])*>)?\\s*\\{([\\s\\S]*?)\\n\\}`,
147
234
  "m"
148
235
  );
149
236
  const match = content.match(regex);
@@ -184,7 +271,7 @@ function processComponent(componentDir, componentName) {
184
271
  `export\\s+(?:interface|type)\\s+(${escapedName}\\w*Props)\\b`
185
272
  );
186
273
  const subComponentMatch = typesContent.match(subComponentPropsRegex);
187
- const anyPropsMatch = typesContent.match(/export\s+(?:interface|type)\s+(Ui\w+Props)/);
274
+ const anyPropsMatch = typesContent.match(/export\s+(?:interface|type)\s+((?:Ui|Ck)\w+Props)/);
188
275
  const interfaceName = exactMatch?.[1] || subComponentMatch?.[1] || anyPropsMatch?.[1] || `${componentName}Props`;
189
276
  const jsdocData = extractJSDocTags(typesContent, interfaceName);
190
277
  const nameKeywords = extractKeywordsFromName(componentName);
@@ -217,7 +304,7 @@ function scanComponents() {
217
304
  const entries = fs4.readdirSync(categoryPath, { withFileTypes: true });
218
305
  for (const entry of entries) {
219
306
  if (!entry.isDirectory()) continue;
220
- if (!entry.name.startsWith("Ui")) continue;
307
+ if (!entry.name.startsWith(COMPONENT_PREFIX)) continue;
221
308
  if (entry.name === "shadcn") continue;
222
309
  const componentDir = path3.join(categoryPath, entry.name);
223
310
  const componentMeta = processComponent(componentDir, entry.name);
@@ -228,19 +315,54 @@ function scanComponents() {
228
315
  }
229
316
  return meta;
230
317
  }
318
+ function scanChatKitComponents() {
319
+ const meta = {};
320
+ let srcPath;
321
+ try {
322
+ srcPath = getChatKitSourcePath();
323
+ } catch (e) {
324
+ console.warn(` \u26A0\uFE0F Skipping chat-kit scan: ${e.message}`);
325
+ return meta;
326
+ }
327
+ for (const category of getChatKitCategoryDirs()) {
328
+ const categoryPath = path3.join(srcPath, category);
329
+ if (!fs4.existsSync(categoryPath)) continue;
330
+ const entries = fs4.readdirSync(categoryPath, { withFileTypes: true });
331
+ for (const entry of entries) {
332
+ if (!entry.isDirectory()) continue;
333
+ if (!entry.name.startsWith(CHAT_KIT_PREFIX)) continue;
334
+ const componentDir = path3.join(categoryPath, entry.name);
335
+ const componentMeta = processComponent(componentDir, entry.name);
336
+ if (componentMeta) {
337
+ meta[entry.name] = componentMeta;
338
+ }
339
+ }
340
+ }
341
+ return meta;
342
+ }
343
+ function summarize(label, meta) {
344
+ const total = Object.keys(meta).length;
345
+ const withUseCases = Object.values(meta).filter((m) => m.useCases.length > 0).length;
346
+ const withKeywords = Object.values(meta).filter((m) => m.keywords.length > 0).length;
347
+ console.log(`
348
+ ${label} summary:`);
349
+ console.log(` Components with @useCases: ${withUseCases}/${total}`);
350
+ console.log(` Components with keywords: ${withKeywords}/${total}`);
351
+ }
231
352
  function main() {
232
- console.log("Scanning components...");
353
+ console.log("Scanning ui-library components...");
233
354
  const meta = scanComponents();
234
- console.log(`Found ${Object.keys(meta).length} components`);
355
+ console.log(`Found ${Object.keys(meta).length} ui-library components`);
235
356
  console.log(`Writing to ${OUTPUT_PATH}...`);
236
357
  fs4.writeFileSync(OUTPUT_PATH, JSON.stringify(meta, null, 2));
237
- console.log("Done!");
238
- const withUseCases = Object.values(meta).filter((m) => m.useCases.length > 0).length;
239
- const withKeywords = Object.values(meta).filter((m) => m.keywords.length > 0).length;
240
- console.log(`
241
- Summary:`);
242
- console.log(` Components with @useCases: ${withUseCases}/${Object.keys(meta).length}`);
243
- console.log(` Components with keywords: ${withKeywords}/${Object.keys(meta).length}`);
358
+ console.log("\nScanning chat-kit components...");
359
+ const chatKitMeta = scanChatKitComponents();
360
+ console.log(`Found ${Object.keys(chatKitMeta).length} chat-kit components`);
361
+ console.log(`Writing to ${CHAT_KIT_OUTPUT_PATH}...`);
362
+ fs4.writeFileSync(CHAT_KIT_OUTPUT_PATH, JSON.stringify(chatKitMeta, null, 2));
363
+ console.log("\nDone!");
364
+ summarize("ui-library", meta);
365
+ summarize("chat-kit", chatKitMeta);
244
366
  }
245
367
  var isMain = import.meta.url === `file://${process.argv[1]}`;
246
368
  if (isMain) {