@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.
package/dist/server.js CHANGED
@@ -3221,8 +3221,8 @@ var require_utils = __commonJS({
3221
3221
  }
3222
3222
  return ind;
3223
3223
  }
3224
- function removeDotSegments(path8) {
3225
- let input = path8;
3224
+ function removeDotSegments(path11) {
3225
+ let input = path11;
3226
3226
  const output = [];
3227
3227
  let nextSlash = -1;
3228
3228
  let len = 0;
@@ -3421,8 +3421,8 @@ var require_schemes = __commonJS({
3421
3421
  wsComponent.secure = void 0;
3422
3422
  }
3423
3423
  if (wsComponent.resourceName) {
3424
- const [path8, query] = wsComponent.resourceName.split("?");
3425
- wsComponent.path = path8 && path8 !== "/" ? path8 : void 0;
3424
+ const [path11, query] = wsComponent.resourceName.split("?");
3425
+ wsComponent.path = path11 && path11 !== "/" ? path11 : void 0;
3426
3426
  wsComponent.query = query;
3427
3427
  wsComponent.resourceName = void 0;
3428
3428
  }
@@ -6784,12 +6784,12 @@ var require_dist = __commonJS({
6784
6784
  throw new Error(`Unknown format "${name}"`);
6785
6785
  return f;
6786
6786
  };
6787
- function addFormats(ajv, list, fs5, exportName) {
6787
+ function addFormats(ajv, list, fs6, exportName) {
6788
6788
  var _a;
6789
6789
  var _b;
6790
6790
  (_a = (_b = ajv.opts.code).formats) !== null && _a !== void 0 ? _a : _b.formats = (0, codegen_1._)`require("ajv-formats/dist/formats").${exportName}`;
6791
6791
  for (const f of list)
6792
- ajv.addFormat(f, fs5[f]);
6792
+ ajv.addFormat(f, fs6[f]);
6793
6793
  }
6794
6794
  module.exports = exports = formatsPlugin;
6795
6795
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -7275,8 +7275,8 @@ function getErrorMap() {
7275
7275
 
7276
7276
  // ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.js
7277
7277
  var makeIssue = (params) => {
7278
- const { data, path: path8, errorMaps, issueData } = params;
7279
- const fullPath = [...path8, ...issueData.path || []];
7278
+ const { data, path: path11, errorMaps, issueData } = params;
7279
+ const fullPath = [...path11, ...issueData.path || []];
7280
7280
  const fullIssue = {
7281
7281
  ...issueData,
7282
7282
  path: fullPath
@@ -7392,11 +7392,11 @@ var errorUtil;
7392
7392
 
7393
7393
  // ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/types.js
7394
7394
  var ParseInputLazyPath = class {
7395
- constructor(parent, value, path8, key) {
7395
+ constructor(parent, value, path11, key) {
7396
7396
  this._cachedPath = [];
7397
7397
  this.parent = parent;
7398
7398
  this.data = value;
7399
- this._path = path8;
7399
+ this._path = path11;
7400
7400
  this._key = key;
7401
7401
  }
7402
7402
  get path() {
@@ -10827,14 +10827,14 @@ var ostring = () => stringType().optional();
10827
10827
  var onumber = () => numberType().optional();
10828
10828
  var oboolean = () => booleanType().optional();
10829
10829
  var coerce = {
10830
- string: (arg) => ZodString.create({ ...arg, coerce: true }),
10831
- number: (arg) => ZodNumber.create({ ...arg, coerce: true }),
10832
- boolean: (arg) => ZodBoolean.create({
10830
+ string: ((arg) => ZodString.create({ ...arg, coerce: true })),
10831
+ number: ((arg) => ZodNumber.create({ ...arg, coerce: true })),
10832
+ boolean: ((arg) => ZodBoolean.create({
10833
10833
  ...arg,
10834
10834
  coerce: true
10835
- }),
10836
- bigint: (arg) => ZodBigInt.create({ ...arg, coerce: true }),
10837
- date: (arg) => ZodDate.create({ ...arg, coerce: true })
10835
+ })),
10836
+ bigint: ((arg) => ZodBigInt.create({ ...arg, coerce: true })),
10837
+ date: ((arg) => ZodDate.create({ ...arg, coerce: true }))
10838
10838
  };
10839
10839
  var NEVER = INVALID;
10840
10840
 
@@ -11034,10 +11034,10 @@ function assignProp(target, prop, value) {
11034
11034
  configurable: true
11035
11035
  });
11036
11036
  }
11037
- function getElementAtPath(obj, path8) {
11038
- if (!path8)
11037
+ function getElementAtPath(obj, path11) {
11038
+ if (!path11)
11039
11039
  return obj;
11040
- return path8.reduce((acc, key) => acc?.[key], obj);
11040
+ return path11.reduce((acc, key) => acc?.[key], obj);
11041
11041
  }
11042
11042
  function promiseAllObject(promisesObj) {
11043
11043
  const keys = Object.keys(promisesObj);
@@ -11357,11 +11357,11 @@ function aborted(x, startIndex = 0) {
11357
11357
  }
11358
11358
  return false;
11359
11359
  }
11360
- function prefixIssues(path8, issues) {
11360
+ function prefixIssues(path11, issues) {
11361
11361
  return issues.map((iss) => {
11362
11362
  var _a;
11363
11363
  (_a = iss).path ?? (_a.path = []);
11364
- iss.path.unshift(path8);
11364
+ iss.path.unshift(path11);
11365
11365
  return iss;
11366
11366
  });
11367
11367
  }
@@ -14668,10 +14668,10 @@ var ZodMiniType = /* @__PURE__ */ $constructor("ZodMiniType", (inst, def) => {
14668
14668
  };
14669
14669
  inst.clone = (_def, params) => clone(inst, _def, params);
14670
14670
  inst.brand = () => inst;
14671
- inst.register = (reg, meta) => {
14671
+ inst.register = ((reg, meta) => {
14672
14672
  reg.add(inst, meta);
14673
14673
  return inst;
14674
- };
14674
+ });
14675
14675
  });
14676
14676
  var ZodMiniObject = /* @__PURE__ */ $constructor("ZodMiniObject", (inst, def) => {
14677
14677
  $ZodObject.init(inst, def);
@@ -14934,10 +14934,10 @@ var ZodType2 = /* @__PURE__ */ $constructor("ZodType", (inst, def) => {
14934
14934
  };
14935
14935
  inst.clone = (def2, params) => clone(inst, def2, params);
14936
14936
  inst.brand = () => inst;
14937
- inst.register = (reg, meta) => {
14937
+ inst.register = ((reg, meta) => {
14938
14938
  reg.add(inst, meta);
14939
14939
  return inst;
14940
- };
14940
+ });
14941
14941
  inst.parse = (data, params) => parse2(inst, data, params, { callee: inst.parse });
14942
14942
  inst.safeParse = (data, params) => safeParse3(inst, data, params);
14943
14943
  inst.parseAsync = async (data, params) => parseAsync2(inst, data, params, { callee: inst.parseAsync });
@@ -16894,11 +16894,13 @@ function assertCompleteRequestPrompt(request) {
16894
16894
  if (request.params.ref.type !== "ref/prompt") {
16895
16895
  throw new TypeError(`Expected CompleteRequestPrompt, but got ${request.params.ref.type}`);
16896
16896
  }
16897
+ void request;
16897
16898
  }
16898
16899
  function assertCompleteRequestResourceTemplate(request) {
16899
16900
  if (request.params.ref.type !== "ref/resource") {
16900
16901
  throw new TypeError(`Expected CompleteRequestResourceTemplate, but got ${request.params.ref.type}`);
16901
16902
  }
16903
+ void request;
16902
16904
  }
16903
16905
  var CompleteResultSchema = ResultSchema.extend({
16904
16906
  completion: looseObject({
@@ -21074,7 +21076,7 @@ function extractType(text2, startIndex) {
21074
21076
  function parseInterface(content, interfaceName) {
21075
21077
  const props = [];
21076
21078
  const interfaceRegex = new RegExp(
21077
- `(?:export\\s+)?${TYPE_OR_INTERFACE}\\s+${interfaceName}\\s*(?:extends\\s+[^{]+)?(?:=\\s*)?\\{([\\s\\S]*?)\\n\\}`,
21079
+ `(?:export\\s+)?${TYPE_OR_INTERFACE}\\s+${interfaceName}\\s*(?:<(?:\\{[^}]*\\}|[^>])*>)?\\s*(?:extends\\s+[^{]+)?(?:=\\s*)?\\{([\\s\\S]*?)\\n\\}`,
21078
21080
  "m"
21079
21081
  );
21080
21082
  const match = content.match(interfaceRegex);
@@ -21089,7 +21091,10 @@ function parseInterface(content, interfaceName) {
21089
21091
  const propName = propMatch[2];
21090
21092
  const isOptional = !!propMatch[3];
21091
21093
  const typeStartIndex = propMatch.index + propMatch[0].length;
21092
- const { type: propType, endIndex } = extractType(interfaceBody, typeStartIndex);
21094
+ const { type: propType, endIndex } = extractType(
21095
+ interfaceBody,
21096
+ typeStartIndex
21097
+ );
21093
21098
  propStartRegex.lastIndex = endIndex + 1;
21094
21099
  const jsdoc = parseJSDoc(jsdocComment);
21095
21100
  props.push({
@@ -21106,7 +21111,9 @@ function parseInterface(content, interfaceName) {
21106
21111
  function extractComponentDescription(content, interfaceName) {
21107
21112
  const lines = content.split("\n");
21108
21113
  const interfaceLineIndex = lines.findIndex(
21109
- (line) => line.match(new RegExp(`export\\s+${TYPE_OR_INTERFACE}\\s+${interfaceName}`))
21114
+ (line) => line.match(
21115
+ new RegExp(`export\\s+${TYPE_OR_INTERFACE}\\s+${interfaceName}`)
21116
+ )
21110
21117
  );
21111
21118
  if (interfaceLineIndex === -1) {
21112
21119
  return "";
@@ -21132,7 +21139,9 @@ function extractComponentDescription(content, interfaceName) {
21132
21139
  return "";
21133
21140
  }
21134
21141
  function resolveUnionOrIntersectionProps(content, typeName) {
21135
- const typeDefRegex = new RegExp(`export\\s+type\\s+${typeName}\\s*=\\s*([^;]+)`);
21142
+ const typeDefRegex = new RegExp(
21143
+ `export\\s+type\\s+${typeName}\\s*=\\s*([^;]+)`
21144
+ );
21136
21145
  const match = content.match(typeDefRegex);
21137
21146
  if (!match) return [];
21138
21147
  const referencedTypes = match[1].split(/[|&]/).map((t) => t.trim()).filter((t) => t.endsWith("Props"));
@@ -21160,7 +21169,9 @@ function readTypesFile(filePath, componentName) {
21160
21169
  return null;
21161
21170
  }
21162
21171
  const resolvedName = componentName || path.basename(path.dirname(filePath));
21163
- const exactRegex = new RegExp(`export\\s+${TYPE_OR_INTERFACE}\\s+(${resolvedName}Props)\\b`);
21172
+ const exactRegex = new RegExp(
21173
+ `export\\s+${TYPE_OR_INTERFACE}\\s+(${resolvedName}Props)\\b`
21174
+ );
21164
21175
  let propsInterfaceMatch = content.match(exactRegex);
21165
21176
  if (!propsInterfaceMatch) {
21166
21177
  const prefixRegex = new RegExp(
@@ -21204,20 +21215,39 @@ import * as path2 from "node:path";
21204
21215
  import { fileURLToPath } from "node:url";
21205
21216
  var __filename = fileURLToPath(import.meta.url);
21206
21217
  var __dirname = path2.dirname(__filename);
21207
- function findUiLibraryRoot() {
21208
- const possiblePaths = [
21209
- // Monorepo development: from packages/lib-mcp/dist/utils -> packages/ui-library
21210
- path2.resolve(__dirname, "../../../ui-library"),
21211
- // Installed as dependency: from node_modules/@aleph-alpha/lib-mcp/dist/utils -> node_modules/@aleph-alpha/ui-library
21212
- path2.resolve(__dirname, "../../@aleph-alpha/ui-library"),
21213
- // Alternative: resolve from cwd
21214
- path2.join(process.cwd(), "node_modules/@aleph-alpha/ui-library")
21218
+ function findInMonorepo(startDir, packageName) {
21219
+ let current = startDir;
21220
+ for (let i = 0; i < 10; i++) {
21221
+ const candidate = path2.join(current, "packages", packageName);
21222
+ if (fs2.existsSync(path2.join(candidate, "package.json"))) {
21223
+ return candidate;
21224
+ }
21225
+ const parent = path2.dirname(current);
21226
+ if (parent === current) break;
21227
+ current = parent;
21228
+ }
21229
+ return null;
21230
+ }
21231
+ function resolveWorkspacePackage(packageName, scope = "@aleph-alpha") {
21232
+ const fromDirname = findInMonorepo(__dirname, packageName);
21233
+ if (fromDirname) return fromDirname;
21234
+ const fromCwd = findInMonorepo(process.cwd(), packageName);
21235
+ if (fromCwd) return fromCwd;
21236
+ const nodeModulesCandidates = [
21237
+ path2.resolve(__dirname, `../../${scope}/${packageName}`),
21238
+ path2.resolve(__dirname, `../../../${scope}/${packageName}`),
21239
+ path2.join(process.cwd(), `node_modules/${scope}/${packageName}`)
21215
21240
  ];
21216
- for (const pkgPath of possiblePaths) {
21241
+ for (const pkgPath of nodeModulesCandidates) {
21217
21242
  if (fs2.existsSync(path2.join(pkgPath, "package.json"))) {
21218
21243
  return pkgPath;
21219
21244
  }
21220
21245
  }
21246
+ return null;
21247
+ }
21248
+ function findUiLibraryRoot() {
21249
+ const pkgPath = resolveWorkspacePackage("ui-library");
21250
+ if (pkgPath) return pkgPath;
21221
21251
  throw new Error("Could not find @aleph-alpha/ui-library. Is it installed?");
21222
21252
  }
21223
21253
  function getLibraryRootPath() {
@@ -21233,6 +21263,21 @@ function getLibrarySourcePath() {
21233
21263
  "Could not find UI library source directory. Is the package installed correctly?"
21234
21264
  );
21235
21265
  }
21266
+ function findChatKitRoot() {
21267
+ const pkgPath = resolveWorkspacePackage("chat-kit");
21268
+ if (pkgPath) return pkgPath;
21269
+ throw new Error("Could not find @aleph-alpha/chat-kit. Is it installed?");
21270
+ }
21271
+ function getChatKitSourcePath() {
21272
+ const chatKitRoot = findChatKitRoot();
21273
+ const srcPath = path2.join(chatKitRoot, "src");
21274
+ if (fs2.existsSync(srcPath)) {
21275
+ return srcPath;
21276
+ }
21277
+ throw new Error(
21278
+ "Could not find chat-kit source directory. Is the package installed correctly?"
21279
+ );
21280
+ }
21236
21281
  function getMcpDirPath() {
21237
21282
  const possiblePaths = [
21238
21283
  // Bundled: from dist/utils -> package root
@@ -21255,6 +21300,12 @@ function getPackageRoot() {
21255
21300
  return process.cwd();
21256
21301
  }
21257
21302
 
21303
+ // src/utils/constants.ts
21304
+ var COMPONENT_PREFIX = "Ui";
21305
+ var CHAT_KIT_PREFIX = "Ck";
21306
+ var INTERNAL_DIRS = ["shadcn"];
21307
+ var TYPE_SUFFIXES = ["Props", "Variant", "Size"];
21308
+
21258
21309
  // src/constants.ts
21259
21310
  function detectCategoryDirs() {
21260
21311
  const srcPath = getSrcPath();
@@ -21266,7 +21317,7 @@ function detectCategoryDirs() {
21266
21317
  try {
21267
21318
  const dirPath = path3.join(srcPath, entry.name);
21268
21319
  const subEntries = fs3.readdirSync(dirPath, { withFileTypes: true });
21269
- return subEntries.some((sub) => sub.isDirectory() && sub.name.startsWith("Ui"));
21320
+ return subEntries.some((sub) => sub.isDirectory() && sub.name.startsWith(COMPONENT_PREFIX));
21270
21321
  } catch {
21271
21322
  return false;
21272
21323
  }
@@ -21278,6 +21329,47 @@ function getCategoryDirs() {
21278
21329
  cachedCategoryDirs = detectCategoryDirs();
21279
21330
  return cachedCategoryDirs;
21280
21331
  }
21332
+ function detectChatKitCategoryDirs() {
21333
+ const srcPath = getChatKitSrcPath();
21334
+ if (!srcPath || !fs3.existsSync(srcPath)) {
21335
+ return [];
21336
+ }
21337
+ const categories = [];
21338
+ const walk = (dir, relative, depth) => {
21339
+ let entries;
21340
+ try {
21341
+ entries = fs3.readdirSync(dir, { withFileTypes: true });
21342
+ } catch {
21343
+ return;
21344
+ }
21345
+ const hasChatKitSubdirs = entries.some(
21346
+ (sub) => sub.isDirectory() && sub.name.startsWith(CHAT_KIT_PREFIX)
21347
+ );
21348
+ if (hasChatKitSubdirs && relative) {
21349
+ categories.push(relative);
21350
+ return;
21351
+ }
21352
+ if (depth >= 2) return;
21353
+ for (const entry of entries) {
21354
+ if (!entry.isDirectory()) continue;
21355
+ if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
21356
+ if (entry.name.startsWith(CHAT_KIT_PREFIX)) continue;
21357
+ walk(
21358
+ path3.join(dir, entry.name),
21359
+ relative ? path3.join(relative, entry.name) : entry.name,
21360
+ depth + 1
21361
+ );
21362
+ }
21363
+ };
21364
+ walk(srcPath, "", 0);
21365
+ return categories;
21366
+ }
21367
+ var cachedChatKitCategoryDirs = null;
21368
+ function getChatKitCategoryDirs() {
21369
+ if (cachedChatKitCategoryDirs) return cachedChatKitCategoryDirs;
21370
+ cachedChatKitCategoryDirs = detectChatKitCategoryDirs();
21371
+ return cachedChatKitCategoryDirs;
21372
+ }
21281
21373
  function getSrcPath() {
21282
21374
  try {
21283
21375
  return getLibrarySourcePath();
@@ -21285,6 +21377,13 @@ function getSrcPath() {
21285
21377
  return null;
21286
21378
  }
21287
21379
  }
21380
+ function getChatKitSrcPath() {
21381
+ try {
21382
+ return getChatKitSourcePath();
21383
+ } catch {
21384
+ return null;
21385
+ }
21386
+ }
21288
21387
  var cachedMeta = null;
21289
21388
  function loadComponentsMeta() {
21290
21389
  if (cachedMeta) return cachedMeta;
@@ -21293,6 +21392,14 @@ function loadComponentsMeta() {
21293
21392
  cachedMeta = readJsonFile(metaPath) ?? {};
21294
21393
  return cachedMeta;
21295
21394
  }
21395
+ var cachedChatKitMeta = null;
21396
+ function loadChatKitComponentsMeta() {
21397
+ if (cachedChatKitMeta) return cachedChatKitMeta;
21398
+ const mcpDir = getMcpDirPath();
21399
+ const metaPath = path3.join(mcpDir, "chat-kit-components-meta.json");
21400
+ cachedChatKitMeta = readJsonFile(metaPath) ?? {};
21401
+ return cachedChatKitMeta;
21402
+ }
21296
21403
  function getPackageVersion() {
21297
21404
  const pkgRoot = getPackageRoot();
21298
21405
  const pkgPath = path3.join(pkgRoot, "package.json");
@@ -21300,11 +21407,6 @@ function getPackageVersion() {
21300
21407
  return pkg?.version ?? "0.0.0";
21301
21408
  }
21302
21409
 
21303
- // src/utils/constants.ts
21304
- var COMPONENT_PREFIX = "Ui";
21305
- var INTERNAL_DIRS = ["shadcn"];
21306
- var TYPE_SUFFIXES = ["Props", "Variant", "Size"];
21307
-
21308
21410
  // src/utils/component-name.ts
21309
21411
  function normalizeComponentName(name) {
21310
21412
  if (name.startsWith(COMPONENT_PREFIX)) {
@@ -21340,7 +21442,11 @@ function scanCategoryDirectory(categoryDir) {
21340
21442
  return {
21341
21443
  name: componentName,
21342
21444
  category: componentMeta?.category ?? "Uncategorized",
21343
- description: getComponentDescription(componentName, componentMeta, componentDir)
21445
+ description: getComponentDescription(
21446
+ componentName,
21447
+ componentMeta,
21448
+ componentDir
21449
+ )
21344
21450
  };
21345
21451
  });
21346
21452
  }
@@ -21397,7 +21503,9 @@ function extractStories(content) {
21397
21503
  if (storyName === "default") continue;
21398
21504
  const storyStart = match.index;
21399
21505
  const remainingContent = content.substring(storyStart);
21400
- const templateRefMatch = remainingContent.match(/code:\s*(\w+TemplateSource)/);
21506
+ const templateRefMatch = remainingContent.match(
21507
+ /code:\s*(\w+TemplateSource)/
21508
+ );
21401
21509
  if (templateRefMatch) {
21402
21510
  stories.set(storyName, templateRefMatch[1]);
21403
21511
  }
@@ -21670,7 +21778,12 @@ function getComponentDocs(componentName) {
21670
21778
  import * as path7 from "node:path";
21671
21779
  function getSetupGuide() {
21672
21780
  const libraryRoot = getLibraryRootPath();
21673
- const quickStartPath = path7.join(libraryRoot, "docs", "public-docs", "quick-start.md");
21781
+ const quickStartPath = path7.join(
21782
+ libraryRoot,
21783
+ "docs",
21784
+ "public-docs",
21785
+ "quick-start.md"
21786
+ );
21674
21787
  const quickStart = readTextFile(quickStartPath);
21675
21788
  if (quickStart) {
21676
21789
  return quickStart;
@@ -21683,8 +21796,278 @@ function getSetupGuide() {
21683
21796
  return null;
21684
21797
  }
21685
21798
 
21799
+ // src/tools/list-chat-kit-components.ts
21800
+ import * as fs5 from "node:fs";
21801
+ import * as path9 from "node:path";
21802
+
21803
+ // src/readers/chat-kit-types-reader.ts
21804
+ import * as path8 from "node:path";
21805
+ var TYPE_OR_INTERFACE2 = "(?:interface|type)";
21806
+ function parseJSDoc2(comment) {
21807
+ const lines = comment.replace(/\/\*\*|\*\/|\*/g, "").split("\n").map((line) => line.trim()).filter(Boolean);
21808
+ let description = "";
21809
+ let defaultValue;
21810
+ let example;
21811
+ for (const line of lines) {
21812
+ if (line.startsWith("@default")) {
21813
+ defaultValue = line.replace("@default", "").trim().replace(/^['"]|['"]$/g, "");
21814
+ } else if (line.startsWith("@example")) {
21815
+ example = line.replace("@example", "").trim();
21816
+ } else if (!line.startsWith("@")) {
21817
+ description += (description ? " " : "") + line;
21818
+ }
21819
+ }
21820
+ return { description, default: defaultValue, example };
21821
+ }
21822
+ function extractType2(text2, startIndex) {
21823
+ let depth = 0;
21824
+ let i = startIndex;
21825
+ while (i < text2.length) {
21826
+ const char = text2[i];
21827
+ const prevChar = i > 0 ? text2[i - 1] : "";
21828
+ if (char === "<" || char === "{" || char === "(" || char === "[") {
21829
+ depth++;
21830
+ } else if (char === "}" || char === ")" || char === "]") {
21831
+ depth = Math.max(0, depth - 1);
21832
+ } else if (char === ">") {
21833
+ if (prevChar !== "=") {
21834
+ depth = Math.max(0, depth - 1);
21835
+ }
21836
+ } else if (char === ";" && depth === 0) {
21837
+ return { type: text2.slice(startIndex, i).trim(), endIndex: i };
21838
+ }
21839
+ i++;
21840
+ }
21841
+ return { type: text2.slice(startIndex).trim(), endIndex: text2.length };
21842
+ }
21843
+ function parseInterface2(content, interfaceName) {
21844
+ const props = [];
21845
+ const interfaceRegex = new RegExp(
21846
+ `(?:export\\s+)?${TYPE_OR_INTERFACE2}\\s+${interfaceName}\\s*(?:<(?:\\{[^}]*\\}|[^>])*>)?\\s*(?:extends\\s+[^{]+)?(?:=\\s*)?\\{([\\s\\S]*?)\\n\\}`,
21847
+ "m"
21848
+ );
21849
+ const match = content.match(interfaceRegex);
21850
+ if (!match) {
21851
+ return props;
21852
+ }
21853
+ const interfaceBody = match[1];
21854
+ const propStartRegex = /(?:\/\*\*([\s\S]*?)\*\/\s*)?([\w]+)(\?)?:\s*/g;
21855
+ let propMatch;
21856
+ while ((propMatch = propStartRegex.exec(interfaceBody)) !== null) {
21857
+ const jsdocComment = propMatch[1] || "";
21858
+ const propName = propMatch[2];
21859
+ const isOptional = !!propMatch[3];
21860
+ const typeStartIndex = propMatch.index + propMatch[0].length;
21861
+ const { type: propType, endIndex } = extractType2(interfaceBody, typeStartIndex);
21862
+ propStartRegex.lastIndex = endIndex + 1;
21863
+ const jsdoc = parseJSDoc2(jsdocComment);
21864
+ props.push({
21865
+ name: propName,
21866
+ type: propType,
21867
+ required: !isOptional,
21868
+ description: jsdoc.description,
21869
+ default: jsdoc.default,
21870
+ example: jsdoc.example
21871
+ });
21872
+ }
21873
+ return props;
21874
+ }
21875
+ function extractComponentDescription2(content, interfaceName) {
21876
+ const lines = content.split("\n");
21877
+ const interfaceLineIndex = lines.findIndex(
21878
+ (line) => line.match(new RegExp(`export\\s+${TYPE_OR_INTERFACE2}\\s+${interfaceName}`))
21879
+ );
21880
+ if (interfaceLineIndex === -1) {
21881
+ return "";
21882
+ }
21883
+ let jsdocEndIndex = -1;
21884
+ for (let i = interfaceLineIndex - 1; i >= 0; i--) {
21885
+ const line = lines[i].trim();
21886
+ if (line === "" || line === "*/") {
21887
+ if (line === "*/") {
21888
+ jsdocEndIndex = i;
21889
+ }
21890
+ continue;
21891
+ }
21892
+ if (!line.startsWith("*") && !line.startsWith("/**")) {
21893
+ break;
21894
+ }
21895
+ if (line.startsWith("/**")) {
21896
+ const jsdocLines = lines.slice(i, jsdocEndIndex + 1);
21897
+ const jsdocContent = jsdocLines.join("\n");
21898
+ return parseJSDoc2(jsdocContent).description;
21899
+ }
21900
+ }
21901
+ return "";
21902
+ }
21903
+ function resolveUnionOrIntersectionProps2(content, typeName) {
21904
+ const typeDefRegex = new RegExp(`export\\s+type\\s+${typeName}\\s*=\\s*([^;]+)`);
21905
+ const match = content.match(typeDefRegex);
21906
+ if (!match) return [];
21907
+ const referencedTypes = match[1].split(/[|&]/).map((t) => t.trim()).filter((t) => t.endsWith("Props"));
21908
+ if (referencedTypes.length === 0) return [];
21909
+ const firstBranch = referencedTypes[0];
21910
+ const extendsRegex = new RegExp(
21911
+ `(?:export\\s+)?${TYPE_OR_INTERFACE2}\\s+${firstBranch}\\s+extends\\s+(\\w+)`
21912
+ );
21913
+ const extendsMatch = content.match(extendsRegex);
21914
+ const allProps = [];
21915
+ if (extendsMatch) {
21916
+ allProps.push(...parseInterface2(content, extendsMatch[1]));
21917
+ }
21918
+ allProps.push(...parseInterface2(content, firstBranch));
21919
+ const seen = /* @__PURE__ */ new Set();
21920
+ return allProps.filter((p) => {
21921
+ if (seen.has(p.name)) return false;
21922
+ seen.add(p.name);
21923
+ return true;
21924
+ });
21925
+ }
21926
+ function readChatKitTypesFile(filePath, componentName) {
21927
+ const content = readTextFile(filePath);
21928
+ if (!content) {
21929
+ return null;
21930
+ }
21931
+ const resolvedName = componentName || path8.basename(path8.dirname(filePath));
21932
+ const exactRegex = new RegExp(`export\\s+${TYPE_OR_INTERFACE2}\\s+(${resolvedName}Props)\\b`);
21933
+ let propsInterfaceMatch = content.match(exactRegex);
21934
+ if (!propsInterfaceMatch) {
21935
+ const prefixRegex = new RegExp(
21936
+ `export\\s+${TYPE_OR_INTERFACE2}\\s+(${resolvedName}\\w*Props)\\b`
21937
+ );
21938
+ propsInterfaceMatch = content.match(prefixRegex);
21939
+ }
21940
+ if (!propsInterfaceMatch) {
21941
+ propsInterfaceMatch = content.match(
21942
+ new RegExp(`export\\s+${TYPE_OR_INTERFACE2}\\s+(Ck\\w+Props)\\b`)
21943
+ );
21944
+ }
21945
+ if (!propsInterfaceMatch) {
21946
+ return null;
21947
+ }
21948
+ const interfaceName = propsInterfaceMatch[1];
21949
+ const matchedComponentName = interfaceName.replace("Props", "");
21950
+ const description = extractComponentDescription2(content, interfaceName);
21951
+ let props = parseInterface2(content, interfaceName);
21952
+ if (props.length === 0) {
21953
+ props = resolveUnionOrIntersectionProps2(content, interfaceName);
21954
+ }
21955
+ return {
21956
+ name: matchedComponentName,
21957
+ description,
21958
+ props
21959
+ };
21960
+ }
21961
+ function readChatKitComponentTypes(componentDir) {
21962
+ const typesPath = path8.join(componentDir, "types.ts");
21963
+ return readChatKitTypesFile(typesPath, path8.basename(componentDir));
21964
+ }
21965
+
21966
+ // src/tools/list-chat-kit-components.ts
21967
+ function isChatKitComponent(dirName) {
21968
+ return dirName.startsWith(CHAT_KIT_PREFIX);
21969
+ }
21970
+ function getDescription(componentName, componentMeta, componentDir) {
21971
+ if (componentMeta?.description) return componentMeta.description;
21972
+ const typeInfo = readChatKitComponentTypes(componentDir);
21973
+ if (typeInfo?.description) return typeInfo.description;
21974
+ return `${componentName} component`;
21975
+ }
21976
+ function matchesFilter2(component, filter) {
21977
+ const filterLower = filter.toLowerCase();
21978
+ return component.name.toLowerCase().includes(filterLower) || component.category.toLowerCase().includes(filterLower) || component.description.toLowerCase().includes(filterLower);
21979
+ }
21980
+ function listChatKitComponents(filter) {
21981
+ const srcPath = getChatKitSourcePath();
21982
+ const meta = loadChatKitComponentsMeta();
21983
+ const allComponents = getChatKitCategoryDirs().flatMap((category) => {
21984
+ const categoryPath = path9.join(srcPath, category);
21985
+ if (!isDirectory(categoryPath)) return [];
21986
+ return fs5.readdirSync(categoryPath, { withFileTypes: true }).filter((e) => e.isDirectory() && isChatKitComponent(e.name)).map((e) => {
21987
+ const componentDir = path9.join(categoryPath, e.name);
21988
+ const componentMeta = meta[e.name];
21989
+ return {
21990
+ name: e.name,
21991
+ category: componentMeta?.category ?? "Uncategorized",
21992
+ description: getDescription(e.name, componentMeta, componentDir)
21993
+ };
21994
+ });
21995
+ });
21996
+ allComponents.sort((a, b) => a.name.localeCompare(b.name));
21997
+ return filter ? allComponents.filter((c) => matchesFilter2(c, filter)) : allComponents;
21998
+ }
21999
+
22000
+ // src/tools/get-chat-kit-docs.ts
22001
+ import * as path10 from "node:path";
22002
+ function normalizeChatKitName(name) {
22003
+ return name.startsWith(CHAT_KIT_PREFIX) ? name : `${CHAT_KIT_PREFIX}${name}`;
22004
+ }
22005
+ function findChatKitComponentDir(componentName) {
22006
+ const srcPath = getChatKitSourcePath();
22007
+ for (const category of getChatKitCategoryDirs()) {
22008
+ const dir = path10.join(srcPath, category, componentName);
22009
+ if (isDirectory(dir)) return dir;
22010
+ }
22011
+ return null;
22012
+ }
22013
+ function isTypeSuffix2(name) {
22014
+ return TYPE_SUFFIXES.some((suffix) => name.endsWith(suffix));
22015
+ }
22016
+ function extractSubComponents2(indexPath, mainComponentName) {
22017
+ const content = readTextFile(indexPath);
22018
+ if (!content) return [];
22019
+ const subComponents = /* @__PURE__ */ new Set();
22020
+ const exportRegex = /export\s*\{[^}]*(?:default\s+as\s+)?(\w+)[^}]*\}/g;
22021
+ let match;
22022
+ while ((match = exportRegex.exec(content)) !== null) {
22023
+ const exportName = match[1];
22024
+ if (exportName.startsWith(mainComponentName) && exportName !== mainComponentName && !isTypeSuffix2(exportName)) {
22025
+ subComponents.add(exportName);
22026
+ }
22027
+ }
22028
+ return Array.from(subComponents).sort();
22029
+ }
22030
+ function getChatKitComponentDocs(componentName) {
22031
+ const name = normalizeChatKitName(componentName);
22032
+ const componentDir = findChatKitComponentDir(name);
22033
+ if (!componentDir) return null;
22034
+ const typeInfo = readChatKitComponentTypes(componentDir);
22035
+ const props = typeInfo?.props || [];
22036
+ let description = typeInfo?.description || "";
22037
+ const storiesInfo = readComponentStories(componentDir);
22038
+ const examples = storiesInfo?.examples || [];
22039
+ const usageGuidance = storiesInfo?.usageGuidance || [];
22040
+ if (!description && usageGuidance.length > 0) {
22041
+ description = usageGuidance[0];
22042
+ }
22043
+ if (!description) {
22044
+ description = `${name} component from @aleph-alpha/chat-kit`;
22045
+ }
22046
+ const indexPath = path10.join(componentDir, "index.ts");
22047
+ const subComponents = readTextFile(indexPath) ? extractSubComponents2(indexPath, name) : void 0;
22048
+ if (storiesInfo?.argTypes) {
22049
+ for (const argType of storiesInfo.argTypes) {
22050
+ const prop = props.find((p) => p.name === argType.name);
22051
+ if (prop && !prop.description && argType.description) {
22052
+ prop.description = argType.description;
22053
+ }
22054
+ }
22055
+ }
22056
+ return {
22057
+ name,
22058
+ description,
22059
+ props,
22060
+ examples,
22061
+ usageGuidance: [...new Set(usageGuidance)],
22062
+ subComponents: subComponents && subComponents.length > 0 ? subComponents : void 0,
22063
+ defaultArgs: storiesInfo?.defaultArgs
22064
+ };
22065
+ }
22066
+
21686
22067
  // src/server.ts
21687
- var text = (t) => ({ content: [{ type: "text", text: t }] });
22068
+ var text = (t) => ({
22069
+ content: [{ type: "text", text: t }]
22070
+ });
21688
22071
  var error2 = (msg) => ({ ...text(msg), isError: true });
21689
22072
  function handleError(e) {
21690
22073
  const message = e instanceof Error ? e.message : String(e);
@@ -21709,11 +22092,13 @@ function formatComponentDocs(docs) {
21709
22092
  docs.props.forEach((prop) => sections.push(...formatProp(prop)));
21710
22093
  }
21711
22094
  if (docs.defaultArgs && Object.keys(docs.defaultArgs).length > 0) {
21712
- const filteredArgs = Object.entries(docs.defaultArgs).filter(([key, value]) => {
21713
- const prop = docs.props.find((p) => p.name === key);
21714
- if (!prop?.default) return true;
21715
- return String(value) !== prop.default;
21716
- });
22095
+ const filteredArgs = Object.entries(docs.defaultArgs).filter(
22096
+ ([key, value]) => {
22097
+ const prop = docs.props.find((p) => p.name === key);
22098
+ if (!prop?.default) return true;
22099
+ return String(value) !== prop.default;
22100
+ }
22101
+ );
21717
22102
  if (filteredArgs.length > 0) {
21718
22103
  sections.push("## Storybook Defaults", "");
21719
22104
  sections.push(
@@ -21752,11 +22137,16 @@ function formatComponentDocs(docs) {
21752
22137
  return sections.join("\n").trim();
21753
22138
  }
21754
22139
  async function startServer() {
21755
- const server = new McpServer({ name: "ui-library", version: getPackageVersion() });
22140
+ const server = new McpServer({
22141
+ name: "ui-library",
22142
+ version: getPackageVersion()
22143
+ });
21756
22144
  server.tool(
21757
22145
  "list_components",
21758
22146
  "List all UI components. Optionally filter by name, category, or description.",
21759
- { filter: external_exports.string().optional().describe("Filter by name/category/description") },
22147
+ {
22148
+ filter: external_exports.string().optional().describe("Filter by name/category/description")
22149
+ },
21760
22150
  async ({ filter }) => {
21761
22151
  try {
21762
22152
  const components = listComponents(filter);
@@ -21789,7 +22179,9 @@ async function startServer() {
21789
22179
  server.tool(
21790
22180
  "get_component_docs",
21791
22181
  "Get full documentation for a component including props, examples, and usage.",
21792
- { componentName: external_exports.string().describe('Component name (e.g., "UiButton" or "Button")') },
22182
+ {
22183
+ componentName: external_exports.string().describe('Component name (e.g., "UiButton" or "Button")')
22184
+ },
21793
22185
  async ({ componentName }) => {
21794
22186
  try {
21795
22187
  const docs = getComponentDocs(componentName);
@@ -21800,6 +22192,52 @@ async function startServer() {
21800
22192
  }
21801
22193
  }
21802
22194
  );
22195
+ server.tool(
22196
+ "list_chat_kit_components",
22197
+ "List all Chat Kit components. Optionally filter by name, category, or description.",
22198
+ { filter: external_exports.string().optional().describe("Filter by name/category/description") },
22199
+ async ({ filter }) => {
22200
+ try {
22201
+ const components = listChatKitComponents(filter);
22202
+ if (components.length === 0) {
22203
+ const message = filter ? `No chat-kit components matching "${filter}".` : "No chat-kit components found.";
22204
+ return text(message);
22205
+ }
22206
+ const grouped = components.reduce(
22207
+ (acc, component) => {
22208
+ (acc[component.category] ??= []).push(component);
22209
+ return acc;
22210
+ },
22211
+ {}
22212
+ );
22213
+ const sections = [`Found ${components.length} chat-kit component(s):`, ""];
22214
+ Object.entries(grouped).forEach(([category, comps]) => {
22215
+ sections.push(`## ${category}`, "");
22216
+ comps.forEach((comp) => {
22217
+ sections.push(`- **${comp.name}**: ${comp.description}`);
22218
+ });
22219
+ sections.push("");
22220
+ });
22221
+ return text(sections.join("\n").trim());
22222
+ } catch (e) {
22223
+ return handleError(e);
22224
+ }
22225
+ }
22226
+ );
22227
+ server.tool(
22228
+ "get_chat_kit_docs",
22229
+ "Get full documentation for a Chat Kit component including props, examples, and usage.",
22230
+ { componentName: external_exports.string().describe('Component name (e.g., "CkChatBubble" or "ChatBubble")') },
22231
+ async ({ componentName }) => {
22232
+ try {
22233
+ const docs = getChatKitComponentDocs(componentName);
22234
+ if (!docs) return error2(`Chat Kit component "${componentName}" not found.`);
22235
+ return text(formatComponentDocs(docs));
22236
+ } catch (e) {
22237
+ return handleError(e);
22238
+ }
22239
+ }
22240
+ );
21803
22241
  server.tool(
21804
22242
  "get_setup_guide",
21805
22243
  "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.",
@@ -21807,7 +22245,10 @@ async function startServer() {
21807
22245
  async () => {
21808
22246
  try {
21809
22247
  const guide = getSetupGuide();
21810
- if (!guide) return error2("Setup guide not found. Is @aleph-alpha/ui-library installed?");
22248
+ if (!guide)
22249
+ return error2(
22250
+ "Setup guide not found. Is @aleph-alpha/ui-library installed?"
22251
+ );
21811
22252
  return text(guide);
21812
22253
  } catch (e) {
21813
22254
  return handleError(e);