@aleph-alpha/lib-mcp 2.2.0 → 4.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(path11) {
3225
- let input = path11;
3224
+ function removeDotSegments(path12) {
3225
+ let input = path12;
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 [path11, query] = wsComponent.resourceName.split("?");
3425
- wsComponent.path = path11 && path11 !== "/" ? path11 : void 0;
3424
+ const [path12, query] = wsComponent.resourceName.split("?");
3425
+ wsComponent.path = path12 && path12 !== "/" ? path12 : void 0;
3426
3426
  wsComponent.query = query;
3427
3427
  wsComponent.resourceName = void 0;
3428
3428
  }
@@ -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: path11, errorMaps, issueData } = params;
7279
- const fullPath = [...path11, ...issueData.path || []];
7278
+ const { data, path: path12, errorMaps, issueData } = params;
7279
+ const fullPath = [...path12, ...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, path11, key) {
7395
+ constructor(parent, value, path12, key) {
7396
7396
  this._cachedPath = [];
7397
7397
  this.parent = parent;
7398
7398
  this.data = value;
7399
- this._path = path11;
7399
+ this._path = path12;
7400
7400
  this._key = key;
7401
7401
  }
7402
7402
  get path() {
@@ -11034,10 +11034,10 @@ function assignProp(target, prop, value) {
11034
11034
  configurable: true
11035
11035
  });
11036
11036
  }
11037
- function getElementAtPath(obj, path11) {
11038
- if (!path11)
11037
+ function getElementAtPath(obj, path12) {
11038
+ if (!path12)
11039
11039
  return obj;
11040
- return path11.reduce((acc, key) => acc?.[key], obj);
11040
+ return path12.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(path11, issues) {
11360
+ function prefixIssues(path12, issues) {
11361
11361
  return issues.map((iss) => {
11362
11362
  var _a;
11363
11363
  (_a = iss).path ?? (_a.path = []);
11364
- iss.path.unshift(path11);
11364
+ iss.path.unshift(path12);
11365
11365
  return iss;
11366
11366
  });
11367
11367
  }
@@ -20989,9 +20989,9 @@ var StdioServerTransport = class {
20989
20989
 
20990
20990
  // src/tools/list-components.ts
20991
20991
  import * as fs4 from "node:fs";
20992
- import * as path4 from "node:path";
20992
+ import * as path5 from "node:path";
20993
20993
 
20994
- // src/readers/types-reader.ts
20994
+ // src/readers/stories-reader.ts
20995
20995
  import * as path from "node:path";
20996
20996
 
20997
20997
  // src/utils/file-utils.ts
@@ -21034,7 +21034,264 @@ function findMatchingBrace(text2, openingBraceIndex, openChar = "{", closeChar =
21034
21034
  return depth === 0 ? i - 1 : -1;
21035
21035
  }
21036
21036
 
21037
+ // src/readers/stories-reader.ts
21038
+ function extractStoryJSDoc(content, storyName) {
21039
+ const exportRegex = new RegExp(`export\\s+const\\s+${storyName}\\s*:`);
21040
+ const exportMatch = content.match(exportRegex);
21041
+ if (!exportMatch || exportMatch.index === void 0) return "";
21042
+ const beforeExport = content.substring(0, exportMatch.index);
21043
+ const lastJsDocEnd = beforeExport.lastIndexOf("*/");
21044
+ if (lastJsDocEnd === -1) return "";
21045
+ const between = beforeExport.substring(lastJsDocEnd + 2);
21046
+ if (between.trim() !== "") return "";
21047
+ const lastJsDocStart = beforeExport.lastIndexOf("/**");
21048
+ if (lastJsDocStart === -1 || lastJsDocStart > lastJsDocEnd) return "";
21049
+ const jsdoc = beforeExport.substring(lastJsDocStart + 3, lastJsDocEnd);
21050
+ return jsdoc.split("\n").map((line) => line.replace(/^\s*\*\s?/, "").trim()).filter((line) => line && !line.startsWith("@")).join(" ").trim();
21051
+ }
21052
+ function extractTemplateSource(content) {
21053
+ const templates = /* @__PURE__ */ new Map();
21054
+ const templateRegex = /const\s+(\w+TemplateSource)\s*=\s*`([\s\S]*?)`;/g;
21055
+ let match;
21056
+ while ((match = templateRegex.exec(content)) !== null) {
21057
+ const varName = match[1];
21058
+ const code = match[2].trim();
21059
+ templates.set(varName, code);
21060
+ }
21061
+ return templates;
21062
+ }
21063
+ function extractStories(content) {
21064
+ const stories = /* @__PURE__ */ new Map();
21065
+ const storyExportRegex = /export\s+const\s+(\w+):\s*Story\s*=/g;
21066
+ let match;
21067
+ while ((match = storyExportRegex.exec(content)) !== null) {
21068
+ const storyName = match[1];
21069
+ if (storyName === "default") continue;
21070
+ const storyStart = match.index;
21071
+ const remainingContent = content.substring(storyStart);
21072
+ const templateRefMatch = remainingContent.match(
21073
+ /code:\s*(\w+TemplateSource)/
21074
+ );
21075
+ if (templateRefMatch) {
21076
+ stories.set(storyName, templateRefMatch[1]);
21077
+ }
21078
+ }
21079
+ return stories;
21080
+ }
21081
+ function extractInlineRenderTemplates(content) {
21082
+ const examples = [];
21083
+ const storyExportRegex = /export\s+const\s+(\w+):\s*Story\s*=/g;
21084
+ let match;
21085
+ while ((match = storyExportRegex.exec(content)) !== null) {
21086
+ const storyName = match[1];
21087
+ if (storyName === "default") continue;
21088
+ const afterEquals = content.indexOf("{", match.index + match[0].length);
21089
+ if (afterEquals === -1) continue;
21090
+ const closingBrace = findMatchingBrace(content, afterEquals);
21091
+ if (closingBrace === -1) continue;
21092
+ const storyBlock = content.slice(afterEquals, closingBrace + 1);
21093
+ if (!storyBlock.includes("template:")) continue;
21094
+ if (/sourceState:\s*['"]none['"]/.test(storyBlock)) continue;
21095
+ const templateMatch = storyBlock.match(/template:\s*`([\s\S]*?)`/);
21096
+ if (!templateMatch) continue;
21097
+ const template = templateMatch[1].trim();
21098
+ if (!template) continue;
21099
+ const componentsMatch = storyBlock.match(/components:\s*\{([^}]+)\}/);
21100
+ const componentNames = componentsMatch ? componentsMatch[1].split(",").map((c) => c.trim()).filter(Boolean) : [];
21101
+ const imports = componentNames.length > 0 ? `<script setup>
21102
+ // Components: ${componentNames.join(", ")}
21103
+ </script>
21104
+
21105
+ ` : "";
21106
+ examples.push({
21107
+ name: storyName,
21108
+ description: "",
21109
+ code: `${imports}<template>
21110
+ ${template}
21111
+ </template>`
21112
+ });
21113
+ }
21114
+ return examples;
21115
+ }
21116
+ function extractArgTypes(content) {
21117
+ const argTypes = [];
21118
+ const argTypesKeyIndex = content.indexOf("argTypes");
21119
+ if (argTypesKeyIndex === -1) {
21120
+ return argTypes;
21121
+ }
21122
+ const colonIndex = content.indexOf(":", argTypesKeyIndex);
21123
+ if (colonIndex === -1) {
21124
+ return argTypes;
21125
+ }
21126
+ const openingBraceIndex = content.indexOf("{", colonIndex);
21127
+ if (openingBraceIndex === -1) {
21128
+ return argTypes;
21129
+ }
21130
+ const closingBraceIndex = findMatchingBrace(content, openingBraceIndex);
21131
+ if (closingBraceIndex === -1) {
21132
+ return argTypes;
21133
+ }
21134
+ const argTypesBlock = content.slice(openingBraceIndex + 1, closingBraceIndex);
21135
+ let index = 0;
21136
+ while (index < argTypesBlock.length) {
21137
+ const propNameMatch = argTypesBlock.slice(index).match(/^\s*(\w+)\s*:\s*\{/);
21138
+ if (!propNameMatch) {
21139
+ const nextComma = argTypesBlock.indexOf(",", index);
21140
+ if (nextComma === -1) break;
21141
+ index = nextComma + 1;
21142
+ continue;
21143
+ }
21144
+ const propName = propNameMatch[1];
21145
+ const propStartIndex = index + propNameMatch[0].length - 1;
21146
+ const propEndIndex = findMatchingBrace(argTypesBlock, propStartIndex);
21147
+ if (propEndIndex === -1) break;
21148
+ const propBlock = argTypesBlock.slice(propStartIndex + 1, propEndIndex);
21149
+ const descMatch = propBlock.match(/description:\s*['"](.+?)['"]\s*[,}]/s);
21150
+ const description = descMatch ? descMatch[1].replace(/\\(['"])/g, "$1") : "";
21151
+ const controlMatch = propBlock.match(/control:\s*['"]?(\w+)['"]?/);
21152
+ const control = controlMatch ? controlMatch[1] : void 0;
21153
+ const optionsMatch = propBlock.match(/options:\s*\[([\s\S]*?)\]/);
21154
+ let options;
21155
+ if (optionsMatch) {
21156
+ options = optionsMatch[1].split(",").map((opt) => opt.trim().replace(/['"]/g, "")).filter(Boolean);
21157
+ }
21158
+ argTypes.push({
21159
+ name: propName,
21160
+ description,
21161
+ control,
21162
+ options
21163
+ });
21164
+ index = propEndIndex + 1;
21165
+ }
21166
+ return argTypes;
21167
+ }
21168
+ function extractTitle(content) {
21169
+ const titleMatch = content.match(/title:\s*['"]([^'"]+)['"]/);
21170
+ return titleMatch ? titleMatch[1] : "";
21171
+ }
21172
+ function extractLabels(content) {
21173
+ const tagsKeyIndex = content.indexOf("tags:");
21174
+ if (tagsKeyIndex === -1) return [];
21175
+ const openingBracketIndex = content.indexOf("[", tagsKeyIndex);
21176
+ if (openingBracketIndex === -1) return [];
21177
+ const closingBracketIndex = content.indexOf("]", openingBracketIndex);
21178
+ if (closingBracketIndex === -1) return [];
21179
+ const tagsBlock = content.slice(openingBracketIndex + 1, closingBracketIndex);
21180
+ const labels = /* @__PURE__ */ new Set();
21181
+ const tagRegex = /['"`]([^'"`]+)['"`]/g;
21182
+ let match;
21183
+ while ((match = tagRegex.exec(tagsBlock)) !== null) {
21184
+ const label = match[1].trim();
21185
+ if (label) labels.add(label);
21186
+ }
21187
+ return Array.from(labels);
21188
+ }
21189
+ function extractMetaArgs(content) {
21190
+ const metaDefaultIndex = content.indexOf("export default");
21191
+ if (metaDefaultIndex === -1) return void 0;
21192
+ const metaSection = content.slice(0, metaDefaultIndex);
21193
+ const argsKeyIndex = metaSection.lastIndexOf("args:");
21194
+ if (argsKeyIndex !== -1) {
21195
+ return extractArgsFromPosition(content, argsKeyIndex);
21196
+ }
21197
+ const afterExport = content.slice(metaDefaultIndex + "export default".length);
21198
+ const trimmed = afterExport.trimStart();
21199
+ if (!trimmed.startsWith("{")) return void 0;
21200
+ const blockStart = content.indexOf("{", metaDefaultIndex);
21201
+ const blockEnd = findMatchingBrace(content, blockStart);
21202
+ if (blockEnd === -1) return void 0;
21203
+ const metaBlock = content.slice(blockStart + 1, blockEnd);
21204
+ const inlineArgsIndex = metaBlock.indexOf("args:");
21205
+ if (inlineArgsIndex === -1) return void 0;
21206
+ return extractArgsFromPosition(content, blockStart + 1 + inlineArgsIndex);
21207
+ }
21208
+ function extractArgsFromPosition(content, argsKeyIndex) {
21209
+ const colonIndex = content.indexOf(":", argsKeyIndex + 4);
21210
+ if (colonIndex === -1) {
21211
+ return void 0;
21212
+ }
21213
+ const openingBraceIndex = content.indexOf("{", colonIndex);
21214
+ if (openingBraceIndex === -1) {
21215
+ return void 0;
21216
+ }
21217
+ const closingBraceIndex = findMatchingBrace(content, openingBraceIndex);
21218
+ if (closingBraceIndex === -1) {
21219
+ return void 0;
21220
+ }
21221
+ const argsBlock = content.slice(openingBraceIndex + 1, closingBraceIndex);
21222
+ const args = {};
21223
+ const kvRegex = /(\w+)\s*:\s*(?:'([^']*)'|"([^"]*)"|(\d+(?:\.\d+)?)|(\btrue\b|\bfalse\b))/g;
21224
+ let match;
21225
+ while ((match = kvRegex.exec(argsBlock)) !== null) {
21226
+ const key = match[1];
21227
+ if (match[2] !== void 0) {
21228
+ args[key] = match[2];
21229
+ } else if (match[3] !== void 0) {
21230
+ args[key] = match[3];
21231
+ } else if (match[4] !== void 0) {
21232
+ args[key] = Number(match[4]);
21233
+ } else if (match[5] !== void 0) {
21234
+ args[key] = match[5] === "true";
21235
+ }
21236
+ }
21237
+ return Object.keys(args).length > 0 ? args : void 0;
21238
+ }
21239
+ function readStoriesFile(filePath) {
21240
+ const content = readTextFile(filePath);
21241
+ if (!content) {
21242
+ return null;
21243
+ }
21244
+ const title = extractTitle(content);
21245
+ const labels = extractLabels(content);
21246
+ const argTypes = extractArgTypes(content);
21247
+ const templateSources = extractTemplateSource(content);
21248
+ const storyTemplateMap = extractStories(content);
21249
+ const examples = [];
21250
+ const usageGuidance = [];
21251
+ const coveredStories = /* @__PURE__ */ new Set();
21252
+ for (const [storyName, templateVar] of storyTemplateMap) {
21253
+ const code = templateSources.get(templateVar);
21254
+ const description = extractStoryJSDoc(content, storyName);
21255
+ if (code) {
21256
+ examples.push({
21257
+ name: storyName,
21258
+ description,
21259
+ code
21260
+ });
21261
+ coveredStories.add(storyName);
21262
+ }
21263
+ if (description) {
21264
+ usageGuidance.push(description);
21265
+ }
21266
+ }
21267
+ const inlineExamples = extractInlineRenderTemplates(content);
21268
+ for (const example of inlineExamples) {
21269
+ if (!coveredStories.has(example.name)) {
21270
+ const description = extractStoryJSDoc(content, example.name);
21271
+ examples.push({ ...example, description });
21272
+ if (description) {
21273
+ usageGuidance.push(description);
21274
+ }
21275
+ }
21276
+ }
21277
+ const defaultArgs = extractMetaArgs(content);
21278
+ return {
21279
+ title,
21280
+ labels,
21281
+ examples,
21282
+ argTypes,
21283
+ usageGuidance,
21284
+ defaultArgs
21285
+ };
21286
+ }
21287
+ function readComponentStories(componentDir) {
21288
+ const componentName = path.basename(componentDir);
21289
+ const storiesPath = path.join(componentDir, `${componentName}.stories.ts`);
21290
+ return readStoriesFile(storiesPath);
21291
+ }
21292
+
21037
21293
  // src/readers/types-reader.ts
21294
+ import * as path2 from "node:path";
21038
21295
  var TYPE_OR_INTERFACE = "(?:interface|type)";
21039
21296
  function parseJSDoc(comment) {
21040
21297
  const lines = comment.replace(/\/\*\*|\*\/|\*/g, "").split("\n").map((line) => line.trim()).filter(Boolean);
@@ -21168,7 +21425,7 @@ function readTypesFile(filePath, componentName) {
21168
21425
  if (!content) {
21169
21426
  return null;
21170
21427
  }
21171
- const resolvedName = componentName || path.basename(path.dirname(filePath));
21428
+ const resolvedName = componentName || path2.basename(path2.dirname(filePath));
21172
21429
  const exactRegex = new RegExp(
21173
21430
  `export\\s+${TYPE_OR_INTERFACE}\\s+(${resolvedName}Props)\\b`
21174
21431
  );
@@ -21201,28 +21458,28 @@ function readTypesFile(filePath, componentName) {
21201
21458
  };
21202
21459
  }
21203
21460
  function readComponentTypes(componentDir) {
21204
- const typesPath = path.join(componentDir, "types.ts");
21205
- return readTypesFile(typesPath, path.basename(componentDir));
21461
+ const typesPath = path2.join(componentDir, "types.ts");
21462
+ return readTypesFile(typesPath, path2.basename(componentDir));
21206
21463
  }
21207
21464
 
21208
21465
  // src/constants.ts
21209
21466
  import * as fs3 from "node:fs";
21210
- import * as path3 from "node:path";
21467
+ import * as path4 from "node:path";
21211
21468
 
21212
21469
  // src/utils/paths.ts
21213
21470
  import * as fs2 from "node:fs";
21214
- import * as path2 from "node:path";
21471
+ import * as path3 from "node:path";
21215
21472
  import { fileURLToPath } from "node:url";
21216
21473
  var __filename = fileURLToPath(import.meta.url);
21217
- var __dirname = path2.dirname(__filename);
21474
+ var __dirname = path3.dirname(__filename);
21218
21475
  function findInMonorepo(startDir, packageName) {
21219
21476
  let current = startDir;
21220
21477
  for (let i = 0; i < 10; i++) {
21221
- const candidate = path2.join(current, "packages", packageName);
21222
- if (fs2.existsSync(path2.join(candidate, "package.json"))) {
21478
+ const candidate = path3.join(current, "packages", packageName);
21479
+ if (fs2.existsSync(path3.join(candidate, "package.json"))) {
21223
21480
  return candidate;
21224
21481
  }
21225
- const parent = path2.dirname(current);
21482
+ const parent = path3.dirname(current);
21226
21483
  if (parent === current) break;
21227
21484
  current = parent;
21228
21485
  }
@@ -21234,12 +21491,12 @@ function resolveWorkspacePackage(packageName, scope = "@aleph-alpha") {
21234
21491
  const fromCwd = findInMonorepo(process.cwd(), packageName);
21235
21492
  if (fromCwd) return fromCwd;
21236
21493
  const nodeModulesCandidates = [
21237
- path2.resolve(__dirname, `../../${scope}/${packageName}`),
21238
- path2.resolve(__dirname, `../../../${scope}/${packageName}`),
21239
- path2.join(process.cwd(), `node_modules/${scope}/${packageName}`)
21494
+ path3.resolve(__dirname, `../../${scope}/${packageName}`),
21495
+ path3.resolve(__dirname, `../../../${scope}/${packageName}`),
21496
+ path3.join(process.cwd(), `node_modules/${scope}/${packageName}`)
21240
21497
  ];
21241
21498
  for (const pkgPath of nodeModulesCandidates) {
21242
- if (fs2.existsSync(path2.join(pkgPath, "package.json"))) {
21499
+ if (fs2.existsSync(path3.join(pkgPath, "package.json"))) {
21243
21500
  return pkgPath;
21244
21501
  }
21245
21502
  }
@@ -21255,7 +21512,7 @@ function getLibraryRootPath() {
21255
21512
  }
21256
21513
  function getLibrarySourcePath() {
21257
21514
  const uiLibraryRoot = findUiLibraryRoot();
21258
- const srcPath = path2.join(uiLibraryRoot, "src");
21515
+ const srcPath = path3.join(uiLibraryRoot, "src");
21259
21516
  if (fs2.existsSync(srcPath)) {
21260
21517
  return srcPath;
21261
21518
  }
@@ -21270,7 +21527,7 @@ function findChatKitRoot() {
21270
21527
  }
21271
21528
  function getChatKitSourcePath() {
21272
21529
  const chatKitRoot = findChatKitRoot();
21273
- const srcPath = path2.join(chatKitRoot, "src");
21530
+ const srcPath = path3.join(chatKitRoot, "src");
21274
21531
  if (fs2.existsSync(srcPath)) {
21275
21532
  return srcPath;
21276
21533
  }
@@ -21281,20 +21538,20 @@ function getChatKitSourcePath() {
21281
21538
  function getMcpDirPath() {
21282
21539
  const possiblePaths = [
21283
21540
  // Bundled: from dist/utils -> package root
21284
- path2.resolve(__dirname, "../.."),
21541
+ path3.resolve(__dirname, "../.."),
21285
21542
  // Fallback: current directory
21286
21543
  __dirname
21287
21544
  ];
21288
21545
  for (const mcpPath of possiblePaths) {
21289
- if (fs2.existsSync(path2.join(mcpPath, "components-meta.json"))) {
21546
+ if (fs2.existsSync(path3.join(mcpPath, "components-meta.json"))) {
21290
21547
  return mcpPath;
21291
21548
  }
21292
21549
  }
21293
- return path2.resolve(__dirname, "../..");
21550
+ return path3.resolve(__dirname, "../..");
21294
21551
  }
21295
21552
  function getPackageRoot() {
21296
- const pkgRoot = path2.resolve(__dirname, "../..");
21297
- if (fs2.existsSync(path2.join(pkgRoot, "package.json"))) {
21553
+ const pkgRoot = path3.resolve(__dirname, "../..");
21554
+ if (fs2.existsSync(path3.join(pkgRoot, "package.json"))) {
21298
21555
  return pkgRoot;
21299
21556
  }
21300
21557
  return process.cwd();
@@ -21317,7 +21574,7 @@ function detectCategoryDirs() {
21317
21574
  (entry) => !entry.name.startsWith(".") && entry.name !== "node_modules"
21318
21575
  ).filter((entry) => {
21319
21576
  try {
21320
- const dirPath = path3.join(srcPath, entry.name);
21577
+ const dirPath = path4.join(srcPath, entry.name);
21321
21578
  const subEntries = fs3.readdirSync(dirPath, { withFileTypes: true });
21322
21579
  return subEntries.some(
21323
21580
  (sub) => sub.isDirectory() && sub.name.startsWith(COMPONENT_PREFIX)
@@ -21359,8 +21616,8 @@ function detectChatKitCategoryDirs() {
21359
21616
  if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
21360
21617
  if (entry.name.startsWith(CHAT_KIT_PREFIX)) continue;
21361
21618
  walk(
21362
- path3.join(dir, entry.name),
21363
- relative ? path3.join(relative, entry.name) : entry.name,
21619
+ path4.join(dir, entry.name),
21620
+ relative ? path4.join(relative, entry.name) : entry.name,
21364
21621
  depth + 1
21365
21622
  );
21366
21623
  }
@@ -21392,7 +21649,7 @@ var cachedMeta = null;
21392
21649
  function loadComponentsMeta() {
21393
21650
  if (cachedMeta) return cachedMeta;
21394
21651
  const mcpDir = getMcpDirPath();
21395
- const metaPath = path3.join(mcpDir, "components-meta.json");
21652
+ const metaPath = path4.join(mcpDir, "components-meta.json");
21396
21653
  cachedMeta = readJsonFile(metaPath) ?? {};
21397
21654
  return cachedMeta;
21398
21655
  }
@@ -21400,13 +21657,13 @@ var cachedChatKitMeta = null;
21400
21657
  function loadChatKitComponentsMeta() {
21401
21658
  if (cachedChatKitMeta) return cachedChatKitMeta;
21402
21659
  const mcpDir = getMcpDirPath();
21403
- const metaPath = path3.join(mcpDir, "chat-kit-components-meta.json");
21660
+ const metaPath = path4.join(mcpDir, "chat-kit-components-meta.json");
21404
21661
  cachedChatKitMeta = readJsonFile(metaPath) ?? {};
21405
21662
  return cachedChatKitMeta;
21406
21663
  }
21407
21664
  function getPackageVersion() {
21408
21665
  const pkgRoot = getPackageRoot();
21409
- const pkgPath = path3.join(pkgRoot, "package.json");
21666
+ const pkgPath = path4.join(pkgRoot, "package.json");
21410
21667
  const pkg = readJsonFile(pkgPath);
21411
21668
  return pkg?.version ?? "0.0.0";
21412
21669
  }
@@ -21442,7 +21699,7 @@ function scanCategoryDirectory(categoryDir) {
21442
21699
  return entries.filter((entry) => entry.isDirectory()).filter((entry) => isComponentDirectory(entry.name)).filter((entry) => !INTERNAL_DIRS.includes(entry.name)).map((entry) => {
21443
21700
  const componentName = entry.name;
21444
21701
  const componentMeta = meta[componentName];
21445
- const componentDir = path4.join(categoryDir, componentName);
21702
+ const componentDir = path5.join(categoryDir, componentName);
21446
21703
  return {
21447
21704
  name: componentName,
21448
21705
  category: componentMeta?.category ?? "Uncategorized",
@@ -21450,18 +21707,19 @@ function scanCategoryDirectory(categoryDir) {
21450
21707
  componentName,
21451
21708
  componentMeta,
21452
21709
  componentDir
21453
- )
21710
+ ),
21711
+ labels: readComponentStories(componentDir)?.labels || []
21454
21712
  };
21455
21713
  });
21456
21714
  }
21457
21715
  function matchesFilter(component, filter) {
21458
21716
  const filterLower = filter.toLowerCase();
21459
- return component.name.toLowerCase().includes(filterLower) || component.category.toLowerCase().includes(filterLower) || component.description.toLowerCase().includes(filterLower);
21717
+ return component.name.toLowerCase().includes(filterLower) || component.category.toLowerCase().includes(filterLower) || component.description.toLowerCase().includes(filterLower) || component.labels.some((label) => label.toLowerCase().includes(filterLower));
21460
21718
  }
21461
21719
  function listComponents(filter) {
21462
21720
  const srcPath = getLibrarySourcePath();
21463
21721
  const allComponents = getCategoryDirs().flatMap((category) => {
21464
- const categoryPath = path4.join(srcPath, category);
21722
+ const categoryPath = path5.join(srcPath, category);
21465
21723
  return scanCategoryDirectory(categoryPath);
21466
21724
  });
21467
21725
  allComponents.sort((a, b) => a.name.localeCompare(b.name));
@@ -21469,250 +21727,21 @@ function listComponents(filter) {
21469
21727
  }
21470
21728
 
21471
21729
  // src/tools/get-docs.ts
21472
- import * as path6 from "node:path";
21473
-
21474
- // src/readers/stories-reader.ts
21475
- import * as path5 from "node:path";
21476
- function extractStoryJSDoc(content, storyName) {
21477
- const exportRegex = new RegExp(`export\\s+const\\s+${storyName}\\s*:`);
21478
- const exportMatch = content.match(exportRegex);
21479
- if (!exportMatch || exportMatch.index === void 0) return "";
21480
- const beforeExport = content.substring(0, exportMatch.index);
21481
- const lastJsDocEnd = beforeExport.lastIndexOf("*/");
21482
- if (lastJsDocEnd === -1) return "";
21483
- const between = beforeExport.substring(lastJsDocEnd + 2);
21484
- if (between.trim() !== "") return "";
21485
- const lastJsDocStart = beforeExport.lastIndexOf("/**");
21486
- if (lastJsDocStart === -1 || lastJsDocStart > lastJsDocEnd) return "";
21487
- const jsdoc = beforeExport.substring(lastJsDocStart + 3, lastJsDocEnd);
21488
- return jsdoc.split("\n").map((line) => line.replace(/^\s*\*\s?/, "").trim()).filter((line) => line && !line.startsWith("@")).join(" ").trim();
21489
- }
21490
- function extractTemplateSource(content) {
21491
- const templates = /* @__PURE__ */ new Map();
21492
- const templateRegex = /const\s+(\w+TemplateSource)\s*=\s*`([\s\S]*?)`;/g;
21493
- let match;
21494
- while ((match = templateRegex.exec(content)) !== null) {
21495
- const varName = match[1];
21496
- const code = match[2].trim();
21497
- templates.set(varName, code);
21498
- }
21499
- return templates;
21500
- }
21501
- function extractStories(content) {
21502
- const stories = /* @__PURE__ */ new Map();
21503
- const storyExportRegex = /export\s+const\s+(\w+):\s*Story\s*=/g;
21504
- let match;
21505
- while ((match = storyExportRegex.exec(content)) !== null) {
21506
- const storyName = match[1];
21507
- if (storyName === "default") continue;
21508
- const storyStart = match.index;
21509
- const remainingContent = content.substring(storyStart);
21510
- const templateRefMatch = remainingContent.match(
21511
- /code:\s*(\w+TemplateSource)/
21512
- );
21513
- if (templateRefMatch) {
21514
- stories.set(storyName, templateRefMatch[1]);
21515
- }
21516
- }
21517
- return stories;
21518
- }
21519
- function extractInlineRenderTemplates(content) {
21520
- const examples = [];
21521
- const storyExportRegex = /export\s+const\s+(\w+):\s*Story\s*=/g;
21522
- let match;
21523
- while ((match = storyExportRegex.exec(content)) !== null) {
21524
- const storyName = match[1];
21525
- if (storyName === "default") continue;
21526
- const afterEquals = content.indexOf("{", match.index + match[0].length);
21527
- if (afterEquals === -1) continue;
21528
- const closingBrace = findMatchingBrace(content, afterEquals);
21529
- if (closingBrace === -1) continue;
21530
- const storyBlock = content.slice(afterEquals, closingBrace + 1);
21531
- if (!storyBlock.includes("template:")) continue;
21532
- const templateMatch = storyBlock.match(/template:\s*`([\s\S]*?)`/);
21533
- if (!templateMatch) continue;
21534
- const template = templateMatch[1].trim();
21535
- if (!template) continue;
21536
- const componentsMatch = storyBlock.match(/components:\s*\{([^}]+)\}/);
21537
- const componentNames = componentsMatch ? componentsMatch[1].split(",").map((c) => c.trim()).filter(Boolean) : [];
21538
- const imports = componentNames.length > 0 ? `<script setup>
21539
- // Components: ${componentNames.join(", ")}
21540
- </script>
21730
+ import * as path7 from "node:path";
21541
21731
 
21542
- ` : "";
21543
- examples.push({
21544
- name: storyName,
21545
- description: "",
21546
- code: `${imports}<template>
21547
- ${template}
21548
- </template>`
21549
- });
21550
- }
21551
- return examples;
21552
- }
21553
- function extractArgTypes(content) {
21554
- const argTypes = [];
21555
- const argTypesKeyIndex = content.indexOf("argTypes");
21556
- if (argTypesKeyIndex === -1) {
21557
- return argTypes;
21558
- }
21559
- const colonIndex = content.indexOf(":", argTypesKeyIndex);
21560
- if (colonIndex === -1) {
21561
- return argTypes;
21562
- }
21563
- const openingBraceIndex = content.indexOf("{", colonIndex);
21564
- if (openingBraceIndex === -1) {
21565
- return argTypes;
21566
- }
21567
- const closingBraceIndex = findMatchingBrace(content, openingBraceIndex);
21568
- if (closingBraceIndex === -1) {
21569
- return argTypes;
21570
- }
21571
- const argTypesBlock = content.slice(openingBraceIndex + 1, closingBraceIndex);
21572
- let index = 0;
21573
- while (index < argTypesBlock.length) {
21574
- const propNameMatch = argTypesBlock.slice(index).match(/^\s*(\w+)\s*:\s*\{/);
21575
- if (!propNameMatch) {
21576
- const nextComma = argTypesBlock.indexOf(",", index);
21577
- if (nextComma === -1) break;
21578
- index = nextComma + 1;
21579
- continue;
21580
- }
21581
- const propName = propNameMatch[1];
21582
- const propStartIndex = index + propNameMatch[0].length - 1;
21583
- const propEndIndex = findMatchingBrace(argTypesBlock, propStartIndex);
21584
- if (propEndIndex === -1) break;
21585
- const propBlock = argTypesBlock.slice(propStartIndex + 1, propEndIndex);
21586
- const descMatch = propBlock.match(/description:\s*['"](.+?)['"]\s*[,}]/s);
21587
- const description = descMatch ? descMatch[1].replace(/\\(['"])/g, "$1") : "";
21588
- const controlMatch = propBlock.match(/control:\s*['"]?(\w+)['"]?/);
21589
- const control = controlMatch ? controlMatch[1] : void 0;
21590
- const optionsMatch = propBlock.match(/options:\s*\[([\s\S]*?)\]/);
21591
- let options;
21592
- if (optionsMatch) {
21593
- options = optionsMatch[1].split(",").map((opt) => opt.trim().replace(/['"]/g, "")).filter(Boolean);
21594
- }
21595
- argTypes.push({
21596
- name: propName,
21597
- description,
21598
- control,
21599
- options
21600
- });
21601
- index = propEndIndex + 1;
21602
- }
21603
- return argTypes;
21604
- }
21605
- function extractTitle(content) {
21606
- const titleMatch = content.match(/title:\s*['"]([^'"]+)['"]/);
21607
- return titleMatch ? titleMatch[1] : "";
21608
- }
21609
- function extractMetaArgs(content) {
21610
- const metaDefaultIndex = content.indexOf("export default");
21611
- if (metaDefaultIndex === -1) return void 0;
21612
- const metaSection = content.slice(0, metaDefaultIndex);
21613
- const argsKeyIndex = metaSection.lastIndexOf("args:");
21614
- if (argsKeyIndex !== -1) {
21615
- return extractArgsFromPosition(content, argsKeyIndex);
21616
- }
21617
- const afterExport = content.slice(metaDefaultIndex + "export default".length);
21618
- const trimmed = afterExport.trimStart();
21619
- if (!trimmed.startsWith("{")) return void 0;
21620
- const blockStart = content.indexOf("{", metaDefaultIndex);
21621
- const blockEnd = findMatchingBrace(content, blockStart);
21622
- if (blockEnd === -1) return void 0;
21623
- const metaBlock = content.slice(blockStart + 1, blockEnd);
21624
- const inlineArgsIndex = metaBlock.indexOf("args:");
21625
- if (inlineArgsIndex === -1) return void 0;
21626
- return extractArgsFromPosition(content, blockStart + 1 + inlineArgsIndex);
21627
- }
21628
- function extractArgsFromPosition(content, argsKeyIndex) {
21629
- const colonIndex = content.indexOf(":", argsKeyIndex + 4);
21630
- if (colonIndex === -1) {
21631
- return void 0;
21632
- }
21633
- const openingBraceIndex = content.indexOf("{", colonIndex);
21634
- if (openingBraceIndex === -1) {
21635
- return void 0;
21636
- }
21637
- const closingBraceIndex = findMatchingBrace(content, openingBraceIndex);
21638
- if (closingBraceIndex === -1) {
21639
- return void 0;
21640
- }
21641
- const argsBlock = content.slice(openingBraceIndex + 1, closingBraceIndex);
21642
- const args = {};
21643
- const kvRegex = /(\w+)\s*:\s*(?:'([^']*)'|"([^"]*)"|(\d+(?:\.\d+)?)|(\btrue\b|\bfalse\b))/g;
21644
- let match;
21645
- while ((match = kvRegex.exec(argsBlock)) !== null) {
21646
- const key = match[1];
21647
- if (match[2] !== void 0) {
21648
- args[key] = match[2];
21649
- } else if (match[3] !== void 0) {
21650
- args[key] = match[3];
21651
- } else if (match[4] !== void 0) {
21652
- args[key] = Number(match[4]);
21653
- } else if (match[5] !== void 0) {
21654
- args[key] = match[5] === "true";
21655
- }
21656
- }
21657
- return Object.keys(args).length > 0 ? args : void 0;
21658
- }
21659
- function readStoriesFile(filePath) {
21660
- const content = readTextFile(filePath);
21661
- if (!content) {
21662
- return null;
21663
- }
21664
- const title = extractTitle(content);
21665
- const argTypes = extractArgTypes(content);
21666
- const templateSources = extractTemplateSource(content);
21667
- const storyTemplateMap = extractStories(content);
21668
- const examples = [];
21669
- const usageGuidance = [];
21670
- const coveredStories = /* @__PURE__ */ new Set();
21671
- for (const [storyName, templateVar] of storyTemplateMap) {
21672
- const code = templateSources.get(templateVar);
21673
- const description = extractStoryJSDoc(content, storyName);
21674
- if (code) {
21675
- examples.push({
21676
- name: storyName,
21677
- description,
21678
- code
21679
- });
21680
- coveredStories.add(storyName);
21681
- }
21682
- if (description) {
21683
- usageGuidance.push(description);
21684
- }
21685
- }
21686
- const inlineExamples = extractInlineRenderTemplates(content);
21687
- for (const example of inlineExamples) {
21688
- if (!coveredStories.has(example.name)) {
21689
- const description = extractStoryJSDoc(content, example.name);
21690
- examples.push({ ...example, description });
21691
- if (description) {
21692
- usageGuidance.push(description);
21693
- }
21694
- }
21695
- }
21696
- const defaultArgs = extractMetaArgs(content);
21697
- return {
21698
- title,
21699
- examples,
21700
- argTypes,
21701
- usageGuidance,
21702
- defaultArgs
21703
- };
21704
- }
21705
- function readComponentStories(componentDir) {
21706
- const componentName = path5.basename(componentDir);
21707
- const storiesPath = path5.join(componentDir, `${componentName}.stories.ts`);
21708
- return readStoriesFile(storiesPath);
21732
+ // src/readers/component-docs-reader.ts
21733
+ import * as path6 from "node:path";
21734
+ function readComponentSupplementalDocs(componentDir) {
21735
+ return readJsonFile(
21736
+ path6.join(componentDir, "mcp-docs.json")
21737
+ );
21709
21738
  }
21710
21739
 
21711
21740
  // src/tools/get-docs.ts
21712
21741
  function findComponentDirectory(componentName) {
21713
21742
  const srcPath = getLibrarySourcePath();
21714
21743
  for (const category of getCategoryDirs()) {
21715
- const componentDir = path6.join(srcPath, category, componentName);
21744
+ const componentDir = path7.join(srcPath, category, componentName);
21716
21745
  if (isDirectory(componentDir)) {
21717
21746
  return componentDir;
21718
21747
  }
@@ -21748,15 +21777,17 @@ function getComponentDocs(componentName) {
21748
21777
  const props = typeInfo?.props || [];
21749
21778
  let description = typeInfo?.description || "";
21750
21779
  const storiesInfo = readComponentStories(componentDir);
21780
+ const labels = storiesInfo?.labels || [];
21751
21781
  const examples = storiesInfo?.examples || [];
21752
21782
  const usageGuidance = storiesInfo?.usageGuidance || [];
21783
+ const supplementalDocs = readComponentSupplementalDocs(componentDir);
21753
21784
  if (!description && usageGuidance.length > 0) {
21754
21785
  description = usageGuidance[0];
21755
21786
  }
21756
21787
  if (!description) {
21757
21788
  description = `${normalizedName} component from @aleph-alpha/ui-library`;
21758
21789
  }
21759
- const indexPath = path6.join(componentDir, "index.ts");
21790
+ const indexPath = path7.join(componentDir, "index.ts");
21760
21791
  const subComponents = readTextFile(indexPath) ? extractSubComponents(indexPath, normalizedName) : void 0;
21761
21792
  if (storiesInfo?.argTypes) {
21762
21793
  for (const argType of storiesInfo.argTypes) {
@@ -21769,20 +21800,22 @@ function getComponentDocs(componentName) {
21769
21800
  return {
21770
21801
  name: normalizedName,
21771
21802
  description,
21803
+ labels,
21772
21804
  props,
21773
21805
  examples,
21774
21806
  usageGuidance: [...new Set(usageGuidance)],
21775
21807
  // Remove duplicates
21808
+ supplementalDocs: supplementalDocs ?? void 0,
21776
21809
  subComponents: subComponents && subComponents.length > 0 ? subComponents : void 0,
21777
21810
  defaultArgs: storiesInfo?.defaultArgs
21778
21811
  };
21779
21812
  }
21780
21813
 
21781
21814
  // src/tools/get-setup.ts
21782
- import * as path7 from "node:path";
21815
+ import * as path8 from "node:path";
21783
21816
  function getSetupGuide() {
21784
21817
  const libraryRoot = getLibraryRootPath();
21785
- const quickStartPath = path7.join(
21818
+ const quickStartPath = path8.join(
21786
21819
  libraryRoot,
21787
21820
  "docs",
21788
21821
  "public-docs",
@@ -21792,7 +21825,7 @@ function getSetupGuide() {
21792
21825
  if (quickStart) {
21793
21826
  return quickStart;
21794
21827
  }
21795
- const readmePath = path7.join(libraryRoot, "README.md");
21828
+ const readmePath = path8.join(libraryRoot, "README.md");
21796
21829
  const readme = readTextFile(readmePath);
21797
21830
  if (readme) {
21798
21831
  return readme;
@@ -21802,10 +21835,10 @@ function getSetupGuide() {
21802
21835
 
21803
21836
  // src/tools/list-chat-kit-components.ts
21804
21837
  import * as fs5 from "node:fs";
21805
- import * as path9 from "node:path";
21838
+ import * as path10 from "node:path";
21806
21839
 
21807
21840
  // src/readers/chat-kit-types-reader.ts
21808
- import * as path8 from "node:path";
21841
+ import * as path9 from "node:path";
21809
21842
  var TYPE_OR_INTERFACE2 = "(?:interface|type)";
21810
21843
  function parseJSDoc2(comment) {
21811
21844
  const lines = comment.replace(/\/\*\*|\*\/|\*/g, "").split("\n").map((line) => line.trim()).filter(Boolean);
@@ -21939,7 +21972,7 @@ function readChatKitTypesFile(filePath, componentName) {
21939
21972
  if (!content) {
21940
21973
  return null;
21941
21974
  }
21942
- const resolvedName = componentName || path8.basename(path8.dirname(filePath));
21975
+ const resolvedName = componentName || path9.basename(path9.dirname(filePath));
21943
21976
  const exactRegex = new RegExp(
21944
21977
  `export\\s+${TYPE_OR_INTERFACE2}\\s+(${resolvedName}Props)\\b`
21945
21978
  );
@@ -21972,8 +22005,8 @@ function readChatKitTypesFile(filePath, componentName) {
21972
22005
  };
21973
22006
  }
21974
22007
  function readChatKitComponentTypes(componentDir) {
21975
- const typesPath = path8.join(componentDir, "types.ts");
21976
- return readChatKitTypesFile(typesPath, path8.basename(componentDir));
22008
+ const typesPath = path9.join(componentDir, "types.ts");
22009
+ return readChatKitTypesFile(typesPath, path9.basename(componentDir));
21977
22010
  }
21978
22011
 
21979
22012
  // src/tools/list-chat-kit-components.ts
@@ -21994,10 +22027,10 @@ function listChatKitComponents(filter) {
21994
22027
  const srcPath = getChatKitSourcePath();
21995
22028
  const meta = loadChatKitComponentsMeta();
21996
22029
  const allComponents = getChatKitCategoryDirs().flatMap((category) => {
21997
- const categoryPath = path9.join(srcPath, category);
22030
+ const categoryPath = path10.join(srcPath, category);
21998
22031
  if (!isDirectory(categoryPath)) return [];
21999
22032
  return fs5.readdirSync(categoryPath, { withFileTypes: true }).filter((e) => e.isDirectory() && isChatKitComponent(e.name)).map((e) => {
22000
- const componentDir = path9.join(categoryPath, e.name);
22033
+ const componentDir = path10.join(categoryPath, e.name);
22001
22034
  const componentMeta = meta[e.name];
22002
22035
  return {
22003
22036
  name: e.name,
@@ -22011,14 +22044,14 @@ function listChatKitComponents(filter) {
22011
22044
  }
22012
22045
 
22013
22046
  // src/tools/get-chat-kit-docs.ts
22014
- import * as path10 from "node:path";
22047
+ import * as path11 from "node:path";
22015
22048
  function normalizeChatKitName(name) {
22016
22049
  return name.startsWith(CHAT_KIT_PREFIX) ? name : `${CHAT_KIT_PREFIX}${name}`;
22017
22050
  }
22018
22051
  function findChatKitComponentDir(componentName) {
22019
22052
  const srcPath = getChatKitSourcePath();
22020
22053
  for (const category of getChatKitCategoryDirs()) {
22021
- const dir = path10.join(srcPath, category, componentName);
22054
+ const dir = path11.join(srcPath, category, componentName);
22022
22055
  if (isDirectory(dir)) return dir;
22023
22056
  }
22024
22057
  return null;
@@ -22056,7 +22089,7 @@ function getChatKitComponentDocs(componentName) {
22056
22089
  if (!description) {
22057
22090
  description = `${name} component from @aleph-alpha/chat-kit`;
22058
22091
  }
22059
- const indexPath = path10.join(componentDir, "index.ts");
22092
+ const indexPath = path11.join(componentDir, "index.ts");
22060
22093
  const subComponents = readTextFile(indexPath) ? extractSubComponents2(indexPath, name) : void 0;
22061
22094
  if (storiesInfo?.argTypes) {
22062
22095
  for (const argType of storiesInfo.argTypes) {
@@ -22069,6 +22102,7 @@ function getChatKitComponentDocs(componentName) {
22069
22102
  return {
22070
22103
  name,
22071
22104
  description,
22105
+ labels: [],
22072
22106
  props,
22073
22107
  examples,
22074
22108
  usageGuidance: [...new Set(usageGuidance)],
@@ -22100,6 +22134,12 @@ function formatProp(prop) {
22100
22134
  }
22101
22135
  function formatComponentDocs(docs) {
22102
22136
  const sections = [`# ${docs.name}`, docs.description, ""];
22137
+ if (docs.labels.length > 0) {
22138
+ sections.push(
22139
+ `**Labels:** ${docs.labels.map((label) => `\`${label}\``).join(", ")}`,
22140
+ ""
22141
+ );
22142
+ }
22103
22143
  if (docs.props.length > 0) {
22104
22144
  sections.push("## Props", "");
22105
22145
  docs.props.forEach((prop) => sections.push(...formatProp(prop)));
@@ -22137,6 +22177,22 @@ function formatComponentDocs(docs) {
22137
22177
  docs.usageGuidance.forEach((guidance) => sections.push(`- ${guidance}`));
22138
22178
  sections.push("");
22139
22179
  }
22180
+ if (docs.supplementalDocs?.designNotes) {
22181
+ sections.push(
22182
+ ...formatSupplementalDocsSection(
22183
+ "Design Notes",
22184
+ docs.supplementalDocs.designNotes
22185
+ )
22186
+ );
22187
+ }
22188
+ if (docs.supplementalDocs?.accessibility) {
22189
+ sections.push(
22190
+ ...formatSupplementalDocsSection(
22191
+ "Accessibility",
22192
+ docs.supplementalDocs.accessibility
22193
+ )
22194
+ );
22195
+ }
22140
22196
  if (docs.examples.length > 0) {
22141
22197
  sections.push("## Examples", "");
22142
22198
  docs.examples.forEach((example) => {
@@ -22149,6 +22205,37 @@ function formatComponentDocs(docs) {
22149
22205
  }
22150
22206
  return sections.join("\n").trim();
22151
22207
  }
22208
+ function formatSupplementalDocsSection(heading, section) {
22209
+ if (!section) return [];
22210
+ const lines = [`## ${heading}`, ""];
22211
+ lines.push(`### ${section.title}`, "");
22212
+ if (section.summary) {
22213
+ lines.push(section.summary, "");
22214
+ }
22215
+ for (const block of section.sections ?? []) {
22216
+ lines.push(`#### ${block.title}`, "");
22217
+ if (block.content) {
22218
+ lines.push(block.content, "");
22219
+ }
22220
+ for (const item of block.items ?? []) {
22221
+ lines.push(`- ${item}`);
22222
+ }
22223
+ if (block.items?.length) {
22224
+ lines.push("");
22225
+ }
22226
+ }
22227
+ if (section.do?.length) {
22228
+ lines.push("#### Do", "");
22229
+ section.do.forEach((item) => lines.push(`- ${item}`));
22230
+ lines.push("");
22231
+ }
22232
+ if (section.dont?.length) {
22233
+ lines.push("#### Don't", "");
22234
+ section.dont.forEach((item) => lines.push(`- ${item}`));
22235
+ lines.push("");
22236
+ }
22237
+ return lines;
22238
+ }
22152
22239
  async function startServer() {
22153
22240
  const server = new McpServer({
22154
22241
  name: "ui-library",
@@ -22179,7 +22266,8 @@ async function startServer() {
22179
22266
  Object.entries(grouped).forEach(([category, comps]) => {
22180
22267
  sections.push(`## ${category}`, "");
22181
22268
  comps.forEach((comp) => {
22182
- sections.push(`- **${comp.name}**: ${comp.description}`);
22269
+ const labels = comp.labels.length > 0 ? ` [${comp.labels.join(", ")}]` : "";
22270
+ sections.push(`- **${comp.name}**${labels}: ${comp.description}`);
22183
22271
  });
22184
22272
  sections.push("");
22185
22273
  });