@aleph-alpha/lib-mcp 1.6.1 → 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.
package/dist/cli.js CHANGED
@@ -3222,8 +3222,8 @@ var require_utils = __commonJS({
3222
3222
  }
3223
3223
  return ind;
3224
3224
  }
3225
- function removeDotSegments(path9) {
3226
- let input = path9;
3225
+ function removeDotSegments(path12) {
3226
+ let input = path12;
3227
3227
  const output = [];
3228
3228
  let nextSlash = -1;
3229
3229
  let len = 0;
@@ -3422,8 +3422,8 @@ var require_schemes = __commonJS({
3422
3422
  wsComponent.secure = void 0;
3423
3423
  }
3424
3424
  if (wsComponent.resourceName) {
3425
- const [path9, query] = wsComponent.resourceName.split("?");
3426
- wsComponent.path = path9 && path9 !== "/" ? path9 : void 0;
3425
+ const [path12, query] = wsComponent.resourceName.split("?");
3426
+ wsComponent.path = path12 && path12 !== "/" ? path12 : void 0;
3427
3427
  wsComponent.query = query;
3428
3428
  wsComponent.resourceName = void 0;
3429
3429
  }
@@ -6785,12 +6785,12 @@ var require_dist = __commonJS({
6785
6785
  throw new Error(`Unknown format "${name}"`);
6786
6786
  return f;
6787
6787
  };
6788
- function addFormats(ajv, list, fs6, exportName) {
6788
+ function addFormats(ajv, list, fs7, exportName) {
6789
6789
  var _a;
6790
6790
  var _b;
6791
6791
  (_a = (_b = ajv.opts.code).formats) !== null && _a !== void 0 ? _a : _b.formats = (0, codegen_1._)`require("ajv-formats/dist/formats").${exportName}`;
6792
6792
  for (const f of list)
6793
- ajv.addFormat(f, fs6[f]);
6793
+ ajv.addFormat(f, fs7[f]);
6794
6794
  }
6795
6795
  module.exports = exports = formatsPlugin;
6796
6796
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -6847,8 +6847,18 @@ function findMatchingBrace(text2, openingBraceIndex, openChar = "{", closeChar =
6847
6847
  var __filename = fileURLToPath(import.meta.url);
6848
6848
  var __dirname = path.dirname(__filename);
6849
6849
  var IDE_CONFIG = {
6850
- claude: { dir: null, file: ".mcp.json", name: "Claude Code", rootKey: "mcpServers" },
6851
- cursor: { dir: ".cursor", file: "mcp.json", name: "Cursor", rootKey: "mcpServers" },
6850
+ claude: {
6851
+ dir: null,
6852
+ file: ".mcp.json",
6853
+ name: "Claude Code",
6854
+ rootKey: "mcpServers"
6855
+ },
6856
+ cursor: {
6857
+ dir: ".cursor",
6858
+ file: "mcp.json",
6859
+ name: "Cursor",
6860
+ rootKey: "mcpServers"
6861
+ },
6852
6862
  vscode: {
6853
6863
  dir: ".vscode",
6854
6864
  file: "mcp.json",
@@ -6871,7 +6881,9 @@ function getMcpServerPath(projectRoot) {
6871
6881
  if (fs2.existsSync(nodeModulesPath)) return relativePath;
6872
6882
  const absolutePath = path.resolve(__dirname, "cli.js");
6873
6883
  if (fs2.existsSync(absolutePath)) return absolutePath;
6874
- throw new Error("Could not find lib-mcp. Make sure @aleph-alpha/lib-mcp is installed.");
6884
+ throw new Error(
6885
+ "Could not find lib-mcp. Make sure @aleph-alpha/lib-mcp is installed."
6886
+ );
6875
6887
  }
6876
6888
  function configureIDE(ide, projectRoot, mcpPath) {
6877
6889
  const { dir, file, name, rootKey, extraFields } = IDE_CONFIG[ide];
@@ -6882,7 +6894,11 @@ function configureIDE(ide, projectRoot, mcpPath) {
6882
6894
  }
6883
6895
  const settings = readJsonFile(settingsFile) ?? {};
6884
6896
  const servers = settings[rootKey] ?? {};
6885
- servers["ui-library"] = { command: "node", args: [mcpPath, "serve"], ...extraFields };
6897
+ servers["ui-library"] = {
6898
+ command: "node",
6899
+ args: [mcpPath, "serve"],
6900
+ ...extraFields
6901
+ };
6886
6902
  settings[rootKey] = servers;
6887
6903
  const tempFile = `${settingsFile}.tmp`;
6888
6904
  try {
@@ -7413,8 +7429,8 @@ function getErrorMap() {
7413
7429
 
7414
7430
  // ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.js
7415
7431
  var makeIssue = (params) => {
7416
- const { data, path: path9, errorMaps, issueData } = params;
7417
- const fullPath = [...path9, ...issueData.path || []];
7432
+ const { data, path: path12, errorMaps, issueData } = params;
7433
+ const fullPath = [...path12, ...issueData.path || []];
7418
7434
  const fullIssue = {
7419
7435
  ...issueData,
7420
7436
  path: fullPath
@@ -7530,11 +7546,11 @@ var errorUtil;
7530
7546
 
7531
7547
  // ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/types.js
7532
7548
  var ParseInputLazyPath = class {
7533
- constructor(parent, value, path9, key) {
7549
+ constructor(parent, value, path12, key) {
7534
7550
  this._cachedPath = [];
7535
7551
  this.parent = parent;
7536
7552
  this.data = value;
7537
- this._path = path9;
7553
+ this._path = path12;
7538
7554
  this._key = key;
7539
7555
  }
7540
7556
  get path() {
@@ -10965,14 +10981,14 @@ var ostring = () => stringType().optional();
10965
10981
  var onumber = () => numberType().optional();
10966
10982
  var oboolean = () => booleanType().optional();
10967
10983
  var coerce = {
10968
- string: (arg) => ZodString.create({ ...arg, coerce: true }),
10969
- number: (arg) => ZodNumber.create({ ...arg, coerce: true }),
10970
- boolean: (arg) => ZodBoolean.create({
10984
+ string: ((arg) => ZodString.create({ ...arg, coerce: true })),
10985
+ number: ((arg) => ZodNumber.create({ ...arg, coerce: true })),
10986
+ boolean: ((arg) => ZodBoolean.create({
10971
10987
  ...arg,
10972
10988
  coerce: true
10973
- }),
10974
- bigint: (arg) => ZodBigInt.create({ ...arg, coerce: true }),
10975
- date: (arg) => ZodDate.create({ ...arg, coerce: true })
10989
+ })),
10990
+ bigint: ((arg) => ZodBigInt.create({ ...arg, coerce: true })),
10991
+ date: ((arg) => ZodDate.create({ ...arg, coerce: true }))
10976
10992
  };
10977
10993
  var NEVER = INVALID;
10978
10994
 
@@ -11172,10 +11188,10 @@ function assignProp(target, prop, value) {
11172
11188
  configurable: true
11173
11189
  });
11174
11190
  }
11175
- function getElementAtPath(obj, path9) {
11176
- if (!path9)
11191
+ function getElementAtPath(obj, path12) {
11192
+ if (!path12)
11177
11193
  return obj;
11178
- return path9.reduce((acc, key) => acc?.[key], obj);
11194
+ return path12.reduce((acc, key) => acc?.[key], obj);
11179
11195
  }
11180
11196
  function promiseAllObject(promisesObj) {
11181
11197
  const keys = Object.keys(promisesObj);
@@ -11495,11 +11511,11 @@ function aborted(x, startIndex = 0) {
11495
11511
  }
11496
11512
  return false;
11497
11513
  }
11498
- function prefixIssues(path9, issues) {
11514
+ function prefixIssues(path12, issues) {
11499
11515
  return issues.map((iss) => {
11500
11516
  var _a;
11501
11517
  (_a = iss).path ?? (_a.path = []);
11502
- iss.path.unshift(path9);
11518
+ iss.path.unshift(path12);
11503
11519
  return iss;
11504
11520
  });
11505
11521
  }
@@ -14806,10 +14822,10 @@ var ZodMiniType = /* @__PURE__ */ $constructor("ZodMiniType", (inst, def) => {
14806
14822
  };
14807
14823
  inst.clone = (_def, params) => clone(inst, _def, params);
14808
14824
  inst.brand = () => inst;
14809
- inst.register = (reg, meta) => {
14825
+ inst.register = ((reg, meta) => {
14810
14826
  reg.add(inst, meta);
14811
14827
  return inst;
14812
- };
14828
+ });
14813
14829
  });
14814
14830
  var ZodMiniObject = /* @__PURE__ */ $constructor("ZodMiniObject", (inst, def) => {
14815
14831
  $ZodObject.init(inst, def);
@@ -15072,10 +15088,10 @@ var ZodType2 = /* @__PURE__ */ $constructor("ZodType", (inst, def) => {
15072
15088
  };
15073
15089
  inst.clone = (def2, params) => clone(inst, def2, params);
15074
15090
  inst.brand = () => inst;
15075
- inst.register = (reg, meta) => {
15091
+ inst.register = ((reg, meta) => {
15076
15092
  reg.add(inst, meta);
15077
15093
  return inst;
15078
- };
15094
+ });
15079
15095
  inst.parse = (data, params) => parse2(inst, data, params, { callee: inst.parse });
15080
15096
  inst.safeParse = (data, params) => safeParse3(inst, data, params);
15081
15097
  inst.parseAsync = async (data, params) => parseAsync2(inst, data, params, { callee: inst.parseAsync });
@@ -17032,11 +17048,13 @@ function assertCompleteRequestPrompt(request) {
17032
17048
  if (request.params.ref.type !== "ref/prompt") {
17033
17049
  throw new TypeError(`Expected CompleteRequestPrompt, but got ${request.params.ref.type}`);
17034
17050
  }
17051
+ void request;
17035
17052
  }
17036
17053
  function assertCompleteRequestResourceTemplate(request) {
17037
17054
  if (request.params.ref.type !== "ref/resource") {
17038
17055
  throw new TypeError(`Expected CompleteRequestResourceTemplate, but got ${request.params.ref.type}`);
17039
17056
  }
17057
+ void request;
17040
17058
  }
17041
17059
  var CompleteResultSchema = ResultSchema.extend({
17042
17060
  completion: looseObject({
@@ -21170,7 +21188,7 @@ function extractType(text2, startIndex) {
21170
21188
  function parseInterface(content, interfaceName) {
21171
21189
  const props = [];
21172
21190
  const interfaceRegex = new RegExp(
21173
- `(?:export\\s+)?${TYPE_OR_INTERFACE}\\s+${interfaceName}\\s*(?:extends\\s+[^{]+)?(?:=\\s*)?\\{([\\s\\S]*?)\\n\\}`,
21191
+ `(?:export\\s+)?${TYPE_OR_INTERFACE}\\s+${interfaceName}\\s*(?:<(?:\\{[^}]*\\}|[^>])*>)?\\s*(?:extends\\s+[^{]+)?(?:=\\s*)?\\{([\\s\\S]*?)\\n\\}`,
21174
21192
  "m"
21175
21193
  );
21176
21194
  const match = content.match(interfaceRegex);
@@ -21185,7 +21203,10 @@ function parseInterface(content, interfaceName) {
21185
21203
  const propName = propMatch[2];
21186
21204
  const isOptional = !!propMatch[3];
21187
21205
  const typeStartIndex = propMatch.index + propMatch[0].length;
21188
- const { type: propType, endIndex } = extractType(interfaceBody, typeStartIndex);
21206
+ const { type: propType, endIndex } = extractType(
21207
+ interfaceBody,
21208
+ typeStartIndex
21209
+ );
21189
21210
  propStartRegex.lastIndex = endIndex + 1;
21190
21211
  const jsdoc = parseJSDoc(jsdocComment);
21191
21212
  props.push({
@@ -21202,7 +21223,9 @@ function parseInterface(content, interfaceName) {
21202
21223
  function extractComponentDescription(content, interfaceName) {
21203
21224
  const lines = content.split("\n");
21204
21225
  const interfaceLineIndex = lines.findIndex(
21205
- (line) => line.match(new RegExp(`export\\s+${TYPE_OR_INTERFACE}\\s+${interfaceName}`))
21226
+ (line) => line.match(
21227
+ new RegExp(`export\\s+${TYPE_OR_INTERFACE}\\s+${interfaceName}`)
21228
+ )
21206
21229
  );
21207
21230
  if (interfaceLineIndex === -1) {
21208
21231
  return "";
@@ -21228,7 +21251,9 @@ function extractComponentDescription(content, interfaceName) {
21228
21251
  return "";
21229
21252
  }
21230
21253
  function resolveUnionOrIntersectionProps(content, typeName) {
21231
- const typeDefRegex = new RegExp(`export\\s+type\\s+${typeName}\\s*=\\s*([^;]+)`);
21254
+ const typeDefRegex = new RegExp(
21255
+ `export\\s+type\\s+${typeName}\\s*=\\s*([^;]+)`
21256
+ );
21232
21257
  const match = content.match(typeDefRegex);
21233
21258
  if (!match) return [];
21234
21259
  const referencedTypes = match[1].split(/[|&]/).map((t) => t.trim()).filter((t) => t.endsWith("Props"));
@@ -21256,7 +21281,9 @@ function readTypesFile(filePath, componentName) {
21256
21281
  return null;
21257
21282
  }
21258
21283
  const resolvedName = componentName || path2.basename(path2.dirname(filePath));
21259
- const exactRegex = new RegExp(`export\\s+${TYPE_OR_INTERFACE}\\s+(${resolvedName}Props)\\b`);
21284
+ const exactRegex = new RegExp(
21285
+ `export\\s+${TYPE_OR_INTERFACE}\\s+(${resolvedName}Props)\\b`
21286
+ );
21260
21287
  let propsInterfaceMatch = content.match(exactRegex);
21261
21288
  if (!propsInterfaceMatch) {
21262
21289
  const prefixRegex = new RegExp(
@@ -21300,20 +21327,39 @@ import * as path3 from "node:path";
21300
21327
  import { fileURLToPath as fileURLToPath2 } from "node:url";
21301
21328
  var __filename2 = fileURLToPath2(import.meta.url);
21302
21329
  var __dirname2 = path3.dirname(__filename2);
21303
- function findUiLibraryRoot() {
21304
- const possiblePaths = [
21305
- // Monorepo development: from packages/lib-mcp/dist/utils -> packages/ui-library
21306
- path3.resolve(__dirname2, "../../../ui-library"),
21307
- // Installed as dependency: from node_modules/@aleph-alpha/lib-mcp/dist/utils -> node_modules/@aleph-alpha/ui-library
21308
- path3.resolve(__dirname2, "../../@aleph-alpha/ui-library"),
21309
- // Alternative: resolve from cwd
21310
- path3.join(process.cwd(), "node_modules/@aleph-alpha/ui-library")
21330
+ function findInMonorepo(startDir, packageName) {
21331
+ let current = startDir;
21332
+ for (let i = 0; i < 10; i++) {
21333
+ const candidate = path3.join(current, "packages", packageName);
21334
+ if (fs3.existsSync(path3.join(candidate, "package.json"))) {
21335
+ return candidate;
21336
+ }
21337
+ const parent = path3.dirname(current);
21338
+ if (parent === current) break;
21339
+ current = parent;
21340
+ }
21341
+ return null;
21342
+ }
21343
+ function resolveWorkspacePackage(packageName, scope = "@aleph-alpha") {
21344
+ const fromDirname = findInMonorepo(__dirname2, packageName);
21345
+ if (fromDirname) return fromDirname;
21346
+ const fromCwd = findInMonorepo(process.cwd(), packageName);
21347
+ if (fromCwd) return fromCwd;
21348
+ const nodeModulesCandidates = [
21349
+ path3.resolve(__dirname2, `../../${scope}/${packageName}`),
21350
+ path3.resolve(__dirname2, `../../../${scope}/${packageName}`),
21351
+ path3.join(process.cwd(), `node_modules/${scope}/${packageName}`)
21311
21352
  ];
21312
- for (const pkgPath of possiblePaths) {
21353
+ for (const pkgPath of nodeModulesCandidates) {
21313
21354
  if (fs3.existsSync(path3.join(pkgPath, "package.json"))) {
21314
21355
  return pkgPath;
21315
21356
  }
21316
21357
  }
21358
+ return null;
21359
+ }
21360
+ function findUiLibraryRoot() {
21361
+ const pkgPath = resolveWorkspacePackage("ui-library");
21362
+ if (pkgPath) return pkgPath;
21317
21363
  throw new Error("Could not find @aleph-alpha/ui-library. Is it installed?");
21318
21364
  }
21319
21365
  function getLibraryRootPath() {
@@ -21329,6 +21375,21 @@ function getLibrarySourcePath() {
21329
21375
  "Could not find UI library source directory. Is the package installed correctly?"
21330
21376
  );
21331
21377
  }
21378
+ function findChatKitRoot() {
21379
+ const pkgPath = resolveWorkspacePackage("chat-kit");
21380
+ if (pkgPath) return pkgPath;
21381
+ throw new Error("Could not find @aleph-alpha/chat-kit. Is it installed?");
21382
+ }
21383
+ function getChatKitSourcePath() {
21384
+ const chatKitRoot = findChatKitRoot();
21385
+ const srcPath = path3.join(chatKitRoot, "src");
21386
+ if (fs3.existsSync(srcPath)) {
21387
+ return srcPath;
21388
+ }
21389
+ throw new Error(
21390
+ "Could not find chat-kit source directory. Is the package installed correctly?"
21391
+ );
21392
+ }
21332
21393
  function getMcpDirPath() {
21333
21394
  const possiblePaths = [
21334
21395
  // Bundled: from dist/utils -> package root
@@ -21351,6 +21412,12 @@ function getPackageRoot() {
21351
21412
  return process.cwd();
21352
21413
  }
21353
21414
 
21415
+ // src/utils/constants.ts
21416
+ var COMPONENT_PREFIX = "Ui";
21417
+ var CHAT_KIT_PREFIX = "Ck";
21418
+ var INTERNAL_DIRS = ["shadcn"];
21419
+ var TYPE_SUFFIXES = ["Props", "Variant", "Size"];
21420
+
21354
21421
  // src/constants.ts
21355
21422
  function detectCategoryDirs() {
21356
21423
  const srcPath = getSrcPath();
@@ -21362,7 +21429,7 @@ function detectCategoryDirs() {
21362
21429
  try {
21363
21430
  const dirPath = path4.join(srcPath, entry.name);
21364
21431
  const subEntries = fs4.readdirSync(dirPath, { withFileTypes: true });
21365
- return subEntries.some((sub) => sub.isDirectory() && sub.name.startsWith("Ui"));
21432
+ return subEntries.some((sub) => sub.isDirectory() && sub.name.startsWith(COMPONENT_PREFIX));
21366
21433
  } catch {
21367
21434
  return false;
21368
21435
  }
@@ -21374,6 +21441,47 @@ function getCategoryDirs() {
21374
21441
  cachedCategoryDirs = detectCategoryDirs();
21375
21442
  return cachedCategoryDirs;
21376
21443
  }
21444
+ function detectChatKitCategoryDirs() {
21445
+ const srcPath = getChatKitSrcPath();
21446
+ if (!srcPath || !fs4.existsSync(srcPath)) {
21447
+ return [];
21448
+ }
21449
+ const categories = [];
21450
+ const walk = (dir, relative, depth) => {
21451
+ let entries;
21452
+ try {
21453
+ entries = fs4.readdirSync(dir, { withFileTypes: true });
21454
+ } catch {
21455
+ return;
21456
+ }
21457
+ const hasChatKitSubdirs = entries.some(
21458
+ (sub) => sub.isDirectory() && sub.name.startsWith(CHAT_KIT_PREFIX)
21459
+ );
21460
+ if (hasChatKitSubdirs && relative) {
21461
+ categories.push(relative);
21462
+ return;
21463
+ }
21464
+ if (depth >= 2) return;
21465
+ for (const entry of entries) {
21466
+ if (!entry.isDirectory()) continue;
21467
+ if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
21468
+ if (entry.name.startsWith(CHAT_KIT_PREFIX)) continue;
21469
+ walk(
21470
+ path4.join(dir, entry.name),
21471
+ relative ? path4.join(relative, entry.name) : entry.name,
21472
+ depth + 1
21473
+ );
21474
+ }
21475
+ };
21476
+ walk(srcPath, "", 0);
21477
+ return categories;
21478
+ }
21479
+ var cachedChatKitCategoryDirs = null;
21480
+ function getChatKitCategoryDirs() {
21481
+ if (cachedChatKitCategoryDirs) return cachedChatKitCategoryDirs;
21482
+ cachedChatKitCategoryDirs = detectChatKitCategoryDirs();
21483
+ return cachedChatKitCategoryDirs;
21484
+ }
21377
21485
  function getSrcPath() {
21378
21486
  try {
21379
21487
  return getLibrarySourcePath();
@@ -21381,6 +21489,13 @@ function getSrcPath() {
21381
21489
  return null;
21382
21490
  }
21383
21491
  }
21492
+ function getChatKitSrcPath() {
21493
+ try {
21494
+ return getChatKitSourcePath();
21495
+ } catch {
21496
+ return null;
21497
+ }
21498
+ }
21384
21499
  var cachedMeta = null;
21385
21500
  function loadComponentsMeta() {
21386
21501
  if (cachedMeta) return cachedMeta;
@@ -21389,6 +21504,14 @@ function loadComponentsMeta() {
21389
21504
  cachedMeta = readJsonFile(metaPath) ?? {};
21390
21505
  return cachedMeta;
21391
21506
  }
21507
+ var cachedChatKitMeta = null;
21508
+ function loadChatKitComponentsMeta() {
21509
+ if (cachedChatKitMeta) return cachedChatKitMeta;
21510
+ const mcpDir = getMcpDirPath();
21511
+ const metaPath = path4.join(mcpDir, "chat-kit-components-meta.json");
21512
+ cachedChatKitMeta = readJsonFile(metaPath) ?? {};
21513
+ return cachedChatKitMeta;
21514
+ }
21392
21515
  function getPackageVersion() {
21393
21516
  const pkgRoot = getPackageRoot();
21394
21517
  const pkgPath = path4.join(pkgRoot, "package.json");
@@ -21396,11 +21519,6 @@ function getPackageVersion() {
21396
21519
  return pkg?.version ?? "0.0.0";
21397
21520
  }
21398
21521
 
21399
- // src/utils/constants.ts
21400
- var COMPONENT_PREFIX = "Ui";
21401
- var INTERNAL_DIRS = ["shadcn"];
21402
- var TYPE_SUFFIXES = ["Props", "Variant", "Size"];
21403
-
21404
21522
  // src/utils/component-name.ts
21405
21523
  function normalizeComponentName(name) {
21406
21524
  if (name.startsWith(COMPONENT_PREFIX)) {
@@ -21436,7 +21554,11 @@ function scanCategoryDirectory(categoryDir) {
21436
21554
  return {
21437
21555
  name: componentName,
21438
21556
  category: componentMeta?.category ?? "Uncategorized",
21439
- description: getComponentDescription(componentName, componentMeta, componentDir)
21557
+ description: getComponentDescription(
21558
+ componentName,
21559
+ componentMeta,
21560
+ componentDir
21561
+ )
21440
21562
  };
21441
21563
  });
21442
21564
  }
@@ -21493,7 +21615,9 @@ function extractStories(content) {
21493
21615
  if (storyName === "default") continue;
21494
21616
  const storyStart = match.index;
21495
21617
  const remainingContent = content.substring(storyStart);
21496
- const templateRefMatch = remainingContent.match(/code:\s*(\w+TemplateSource)/);
21618
+ const templateRefMatch = remainingContent.match(
21619
+ /code:\s*(\w+TemplateSource)/
21620
+ );
21497
21621
  if (templateRefMatch) {
21498
21622
  stories.set(storyName, templateRefMatch[1]);
21499
21623
  }
@@ -21766,7 +21890,12 @@ function getComponentDocs(componentName) {
21766
21890
  import * as path8 from "node:path";
21767
21891
  function getSetupGuide() {
21768
21892
  const libraryRoot = getLibraryRootPath();
21769
- const quickStartPath = path8.join(libraryRoot, "docs", "public-docs", "quick-start.md");
21893
+ const quickStartPath = path8.join(
21894
+ libraryRoot,
21895
+ "docs",
21896
+ "public-docs",
21897
+ "quick-start.md"
21898
+ );
21770
21899
  const quickStart = readTextFile(quickStartPath);
21771
21900
  if (quickStart) {
21772
21901
  return quickStart;
@@ -21779,8 +21908,278 @@ function getSetupGuide() {
21779
21908
  return null;
21780
21909
  }
21781
21910
 
21911
+ // src/tools/list-chat-kit-components.ts
21912
+ import * as fs6 from "node:fs";
21913
+ import * as path10 from "node:path";
21914
+
21915
+ // src/readers/chat-kit-types-reader.ts
21916
+ import * as path9 from "node:path";
21917
+ var TYPE_OR_INTERFACE2 = "(?:interface|type)";
21918
+ function parseJSDoc2(comment) {
21919
+ const lines = comment.replace(/\/\*\*|\*\/|\*/g, "").split("\n").map((line) => line.trim()).filter(Boolean);
21920
+ let description = "";
21921
+ let defaultValue;
21922
+ let example;
21923
+ for (const line of lines) {
21924
+ if (line.startsWith("@default")) {
21925
+ defaultValue = line.replace("@default", "").trim().replace(/^['"]|['"]$/g, "");
21926
+ } else if (line.startsWith("@example")) {
21927
+ example = line.replace("@example", "").trim();
21928
+ } else if (!line.startsWith("@")) {
21929
+ description += (description ? " " : "") + line;
21930
+ }
21931
+ }
21932
+ return { description, default: defaultValue, example };
21933
+ }
21934
+ function extractType2(text2, startIndex) {
21935
+ let depth = 0;
21936
+ let i = startIndex;
21937
+ while (i < text2.length) {
21938
+ const char = text2[i];
21939
+ const prevChar = i > 0 ? text2[i - 1] : "";
21940
+ if (char === "<" || char === "{" || char === "(" || char === "[") {
21941
+ depth++;
21942
+ } else if (char === "}" || char === ")" || char === "]") {
21943
+ depth = Math.max(0, depth - 1);
21944
+ } else if (char === ">") {
21945
+ if (prevChar !== "=") {
21946
+ depth = Math.max(0, depth - 1);
21947
+ }
21948
+ } else if (char === ";" && depth === 0) {
21949
+ return { type: text2.slice(startIndex, i).trim(), endIndex: i };
21950
+ }
21951
+ i++;
21952
+ }
21953
+ return { type: text2.slice(startIndex).trim(), endIndex: text2.length };
21954
+ }
21955
+ function parseInterface2(content, interfaceName) {
21956
+ const props = [];
21957
+ const interfaceRegex = new RegExp(
21958
+ `(?:export\\s+)?${TYPE_OR_INTERFACE2}\\s+${interfaceName}\\s*(?:<(?:\\{[^}]*\\}|[^>])*>)?\\s*(?:extends\\s+[^{]+)?(?:=\\s*)?\\{([\\s\\S]*?)\\n\\}`,
21959
+ "m"
21960
+ );
21961
+ const match = content.match(interfaceRegex);
21962
+ if (!match) {
21963
+ return props;
21964
+ }
21965
+ const interfaceBody = match[1];
21966
+ const propStartRegex = /(?:\/\*\*([\s\S]*?)\*\/\s*)?([\w]+)(\?)?:\s*/g;
21967
+ let propMatch;
21968
+ while ((propMatch = propStartRegex.exec(interfaceBody)) !== null) {
21969
+ const jsdocComment = propMatch[1] || "";
21970
+ const propName = propMatch[2];
21971
+ const isOptional = !!propMatch[3];
21972
+ const typeStartIndex = propMatch.index + propMatch[0].length;
21973
+ const { type: propType, endIndex } = extractType2(interfaceBody, typeStartIndex);
21974
+ propStartRegex.lastIndex = endIndex + 1;
21975
+ const jsdoc = parseJSDoc2(jsdocComment);
21976
+ props.push({
21977
+ name: propName,
21978
+ type: propType,
21979
+ required: !isOptional,
21980
+ description: jsdoc.description,
21981
+ default: jsdoc.default,
21982
+ example: jsdoc.example
21983
+ });
21984
+ }
21985
+ return props;
21986
+ }
21987
+ function extractComponentDescription2(content, interfaceName) {
21988
+ const lines = content.split("\n");
21989
+ const interfaceLineIndex = lines.findIndex(
21990
+ (line) => line.match(new RegExp(`export\\s+${TYPE_OR_INTERFACE2}\\s+${interfaceName}`))
21991
+ );
21992
+ if (interfaceLineIndex === -1) {
21993
+ return "";
21994
+ }
21995
+ let jsdocEndIndex = -1;
21996
+ for (let i = interfaceLineIndex - 1; i >= 0; i--) {
21997
+ const line = lines[i].trim();
21998
+ if (line === "" || line === "*/") {
21999
+ if (line === "*/") {
22000
+ jsdocEndIndex = i;
22001
+ }
22002
+ continue;
22003
+ }
22004
+ if (!line.startsWith("*") && !line.startsWith("/**")) {
22005
+ break;
22006
+ }
22007
+ if (line.startsWith("/**")) {
22008
+ const jsdocLines = lines.slice(i, jsdocEndIndex + 1);
22009
+ const jsdocContent = jsdocLines.join("\n");
22010
+ return parseJSDoc2(jsdocContent).description;
22011
+ }
22012
+ }
22013
+ return "";
22014
+ }
22015
+ function resolveUnionOrIntersectionProps2(content, typeName) {
22016
+ const typeDefRegex = new RegExp(`export\\s+type\\s+${typeName}\\s*=\\s*([^;]+)`);
22017
+ const match = content.match(typeDefRegex);
22018
+ if (!match) return [];
22019
+ const referencedTypes = match[1].split(/[|&]/).map((t) => t.trim()).filter((t) => t.endsWith("Props"));
22020
+ if (referencedTypes.length === 0) return [];
22021
+ const firstBranch = referencedTypes[0];
22022
+ const extendsRegex = new RegExp(
22023
+ `(?:export\\s+)?${TYPE_OR_INTERFACE2}\\s+${firstBranch}\\s+extends\\s+(\\w+)`
22024
+ );
22025
+ const extendsMatch = content.match(extendsRegex);
22026
+ const allProps = [];
22027
+ if (extendsMatch) {
22028
+ allProps.push(...parseInterface2(content, extendsMatch[1]));
22029
+ }
22030
+ allProps.push(...parseInterface2(content, firstBranch));
22031
+ const seen = /* @__PURE__ */ new Set();
22032
+ return allProps.filter((p) => {
22033
+ if (seen.has(p.name)) return false;
22034
+ seen.add(p.name);
22035
+ return true;
22036
+ });
22037
+ }
22038
+ function readChatKitTypesFile(filePath, componentName) {
22039
+ const content = readTextFile(filePath);
22040
+ if (!content) {
22041
+ return null;
22042
+ }
22043
+ const resolvedName = componentName || path9.basename(path9.dirname(filePath));
22044
+ const exactRegex = new RegExp(`export\\s+${TYPE_OR_INTERFACE2}\\s+(${resolvedName}Props)\\b`);
22045
+ let propsInterfaceMatch = content.match(exactRegex);
22046
+ if (!propsInterfaceMatch) {
22047
+ const prefixRegex = new RegExp(
22048
+ `export\\s+${TYPE_OR_INTERFACE2}\\s+(${resolvedName}\\w*Props)\\b`
22049
+ );
22050
+ propsInterfaceMatch = content.match(prefixRegex);
22051
+ }
22052
+ if (!propsInterfaceMatch) {
22053
+ propsInterfaceMatch = content.match(
22054
+ new RegExp(`export\\s+${TYPE_OR_INTERFACE2}\\s+(Ck\\w+Props)\\b`)
22055
+ );
22056
+ }
22057
+ if (!propsInterfaceMatch) {
22058
+ return null;
22059
+ }
22060
+ const interfaceName = propsInterfaceMatch[1];
22061
+ const matchedComponentName = interfaceName.replace("Props", "");
22062
+ const description = extractComponentDescription2(content, interfaceName);
22063
+ let props = parseInterface2(content, interfaceName);
22064
+ if (props.length === 0) {
22065
+ props = resolveUnionOrIntersectionProps2(content, interfaceName);
22066
+ }
22067
+ return {
22068
+ name: matchedComponentName,
22069
+ description,
22070
+ props
22071
+ };
22072
+ }
22073
+ function readChatKitComponentTypes(componentDir) {
22074
+ const typesPath = path9.join(componentDir, "types.ts");
22075
+ return readChatKitTypesFile(typesPath, path9.basename(componentDir));
22076
+ }
22077
+
22078
+ // src/tools/list-chat-kit-components.ts
22079
+ function isChatKitComponent(dirName) {
22080
+ return dirName.startsWith(CHAT_KIT_PREFIX);
22081
+ }
22082
+ function getDescription(componentName, componentMeta, componentDir) {
22083
+ if (componentMeta?.description) return componentMeta.description;
22084
+ const typeInfo = readChatKitComponentTypes(componentDir);
22085
+ if (typeInfo?.description) return typeInfo.description;
22086
+ return `${componentName} component`;
22087
+ }
22088
+ function matchesFilter2(component, filter) {
22089
+ const filterLower = filter.toLowerCase();
22090
+ return component.name.toLowerCase().includes(filterLower) || component.category.toLowerCase().includes(filterLower) || component.description.toLowerCase().includes(filterLower);
22091
+ }
22092
+ function listChatKitComponents(filter) {
22093
+ const srcPath = getChatKitSourcePath();
22094
+ const meta = loadChatKitComponentsMeta();
22095
+ const allComponents = getChatKitCategoryDirs().flatMap((category) => {
22096
+ const categoryPath = path10.join(srcPath, category);
22097
+ if (!isDirectory(categoryPath)) return [];
22098
+ return fs6.readdirSync(categoryPath, { withFileTypes: true }).filter((e) => e.isDirectory() && isChatKitComponent(e.name)).map((e) => {
22099
+ const componentDir = path10.join(categoryPath, e.name);
22100
+ const componentMeta = meta[e.name];
22101
+ return {
22102
+ name: e.name,
22103
+ category: componentMeta?.category ?? "Uncategorized",
22104
+ description: getDescription(e.name, componentMeta, componentDir)
22105
+ };
22106
+ });
22107
+ });
22108
+ allComponents.sort((a, b) => a.name.localeCompare(b.name));
22109
+ return filter ? allComponents.filter((c) => matchesFilter2(c, filter)) : allComponents;
22110
+ }
22111
+
22112
+ // src/tools/get-chat-kit-docs.ts
22113
+ import * as path11 from "node:path";
22114
+ function normalizeChatKitName(name) {
22115
+ return name.startsWith(CHAT_KIT_PREFIX) ? name : `${CHAT_KIT_PREFIX}${name}`;
22116
+ }
22117
+ function findChatKitComponentDir(componentName) {
22118
+ const srcPath = getChatKitSourcePath();
22119
+ for (const category of getChatKitCategoryDirs()) {
22120
+ const dir = path11.join(srcPath, category, componentName);
22121
+ if (isDirectory(dir)) return dir;
22122
+ }
22123
+ return null;
22124
+ }
22125
+ function isTypeSuffix2(name) {
22126
+ return TYPE_SUFFIXES.some((suffix) => name.endsWith(suffix));
22127
+ }
22128
+ function extractSubComponents2(indexPath, mainComponentName) {
22129
+ const content = readTextFile(indexPath);
22130
+ if (!content) return [];
22131
+ const subComponents = /* @__PURE__ */ new Set();
22132
+ const exportRegex = /export\s*\{[^}]*(?:default\s+as\s+)?(\w+)[^}]*\}/g;
22133
+ let match;
22134
+ while ((match = exportRegex.exec(content)) !== null) {
22135
+ const exportName = match[1];
22136
+ if (exportName.startsWith(mainComponentName) && exportName !== mainComponentName && !isTypeSuffix2(exportName)) {
22137
+ subComponents.add(exportName);
22138
+ }
22139
+ }
22140
+ return Array.from(subComponents).sort();
22141
+ }
22142
+ function getChatKitComponentDocs(componentName) {
22143
+ const name = normalizeChatKitName(componentName);
22144
+ const componentDir = findChatKitComponentDir(name);
22145
+ if (!componentDir) return null;
22146
+ const typeInfo = readChatKitComponentTypes(componentDir);
22147
+ const props = typeInfo?.props || [];
22148
+ let description = typeInfo?.description || "";
22149
+ const storiesInfo = readComponentStories(componentDir);
22150
+ const examples = storiesInfo?.examples || [];
22151
+ const usageGuidance = storiesInfo?.usageGuidance || [];
22152
+ if (!description && usageGuidance.length > 0) {
22153
+ description = usageGuidance[0];
22154
+ }
22155
+ if (!description) {
22156
+ description = `${name} component from @aleph-alpha/chat-kit`;
22157
+ }
22158
+ const indexPath = path11.join(componentDir, "index.ts");
22159
+ const subComponents = readTextFile(indexPath) ? extractSubComponents2(indexPath, name) : void 0;
22160
+ if (storiesInfo?.argTypes) {
22161
+ for (const argType of storiesInfo.argTypes) {
22162
+ const prop = props.find((p) => p.name === argType.name);
22163
+ if (prop && !prop.description && argType.description) {
22164
+ prop.description = argType.description;
22165
+ }
22166
+ }
22167
+ }
22168
+ return {
22169
+ name,
22170
+ description,
22171
+ props,
22172
+ examples,
22173
+ usageGuidance: [...new Set(usageGuidance)],
22174
+ subComponents: subComponents && subComponents.length > 0 ? subComponents : void 0,
22175
+ defaultArgs: storiesInfo?.defaultArgs
22176
+ };
22177
+ }
22178
+
21782
22179
  // src/server.ts
21783
- var text = (t) => ({ content: [{ type: "text", text: t }] });
22180
+ var text = (t) => ({
22181
+ content: [{ type: "text", text: t }]
22182
+ });
21784
22183
  var error2 = (msg) => ({ ...text(msg), isError: true });
21785
22184
  function handleError(e) {
21786
22185
  const message = e instanceof Error ? e.message : String(e);
@@ -21805,11 +22204,13 @@ function formatComponentDocs(docs) {
21805
22204
  docs.props.forEach((prop) => sections.push(...formatProp(prop)));
21806
22205
  }
21807
22206
  if (docs.defaultArgs && Object.keys(docs.defaultArgs).length > 0) {
21808
- const filteredArgs = Object.entries(docs.defaultArgs).filter(([key, value]) => {
21809
- const prop = docs.props.find((p) => p.name === key);
21810
- if (!prop?.default) return true;
21811
- return String(value) !== prop.default;
21812
- });
22207
+ const filteredArgs = Object.entries(docs.defaultArgs).filter(
22208
+ ([key, value]) => {
22209
+ const prop = docs.props.find((p) => p.name === key);
22210
+ if (!prop?.default) return true;
22211
+ return String(value) !== prop.default;
22212
+ }
22213
+ );
21813
22214
  if (filteredArgs.length > 0) {
21814
22215
  sections.push("## Storybook Defaults", "");
21815
22216
  sections.push(
@@ -21848,11 +22249,16 @@ function formatComponentDocs(docs) {
21848
22249
  return sections.join("\n").trim();
21849
22250
  }
21850
22251
  async function startServer() {
21851
- const server = new McpServer({ name: "ui-library", version: getPackageVersion() });
22252
+ const server = new McpServer({
22253
+ name: "ui-library",
22254
+ version: getPackageVersion()
22255
+ });
21852
22256
  server.tool(
21853
22257
  "list_components",
21854
22258
  "List all UI components. Optionally filter by name, category, or description.",
21855
- { filter: external_exports.string().optional().describe("Filter by name/category/description") },
22259
+ {
22260
+ filter: external_exports.string().optional().describe("Filter by name/category/description")
22261
+ },
21856
22262
  async ({ filter }) => {
21857
22263
  try {
21858
22264
  const components = listComponents(filter);
@@ -21885,7 +22291,9 @@ async function startServer() {
21885
22291
  server.tool(
21886
22292
  "get_component_docs",
21887
22293
  "Get full documentation for a component including props, examples, and usage.",
21888
- { componentName: external_exports.string().describe('Component name (e.g., "UiButton" or "Button")') },
22294
+ {
22295
+ componentName: external_exports.string().describe('Component name (e.g., "UiButton" or "Button")')
22296
+ },
21889
22297
  async ({ componentName }) => {
21890
22298
  try {
21891
22299
  const docs = getComponentDocs(componentName);
@@ -21896,6 +22304,52 @@ async function startServer() {
21896
22304
  }
21897
22305
  }
21898
22306
  );
22307
+ server.tool(
22308
+ "list_chat_kit_components",
22309
+ "List all Chat Kit components. Optionally filter by name, category, or description.",
22310
+ { filter: external_exports.string().optional().describe("Filter by name/category/description") },
22311
+ async ({ filter }) => {
22312
+ try {
22313
+ const components = listChatKitComponents(filter);
22314
+ if (components.length === 0) {
22315
+ const message = filter ? `No chat-kit components matching "${filter}".` : "No chat-kit components found.";
22316
+ return text(message);
22317
+ }
22318
+ const grouped = components.reduce(
22319
+ (acc, component) => {
22320
+ (acc[component.category] ??= []).push(component);
22321
+ return acc;
22322
+ },
22323
+ {}
22324
+ );
22325
+ const sections = [`Found ${components.length} chat-kit component(s):`, ""];
22326
+ Object.entries(grouped).forEach(([category, comps]) => {
22327
+ sections.push(`## ${category}`, "");
22328
+ comps.forEach((comp) => {
22329
+ sections.push(`- **${comp.name}**: ${comp.description}`);
22330
+ });
22331
+ sections.push("");
22332
+ });
22333
+ return text(sections.join("\n").trim());
22334
+ } catch (e) {
22335
+ return handleError(e);
22336
+ }
22337
+ }
22338
+ );
22339
+ server.tool(
22340
+ "get_chat_kit_docs",
22341
+ "Get full documentation for a Chat Kit component including props, examples, and usage.",
22342
+ { componentName: external_exports.string().describe('Component name (e.g., "CkChatBubble" or "ChatBubble")') },
22343
+ async ({ componentName }) => {
22344
+ try {
22345
+ const docs = getChatKitComponentDocs(componentName);
22346
+ if (!docs) return error2(`Chat Kit component "${componentName}" not found.`);
22347
+ return text(formatComponentDocs(docs));
22348
+ } catch (e) {
22349
+ return handleError(e);
22350
+ }
22351
+ }
22352
+ );
21899
22353
  server.tool(
21900
22354
  "get_setup_guide",
21901
22355
  "Get the setup and installation guide for integrating the UI library into a project. Returns UnoCSS config, Vite config, required dependencies, and MCP setup instructions.",
@@ -21903,7 +22357,10 @@ async function startServer() {
21903
22357
  async () => {
21904
22358
  try {
21905
22359
  const guide = getSetupGuide();
21906
- if (!guide) return error2("Setup guide not found. Is @aleph-alpha/ui-library installed?");
22360
+ if (!guide)
22361
+ return error2(
22362
+ "Setup guide not found. Is @aleph-alpha/ui-library installed?"
22363
+ );
21907
22364
  return text(guide);
21908
22365
  } catch (e) {
21909
22366
  return handleError(e);