@testgorilla/tgo-ui 11.12.2 → 11.13.1

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/mcp/server.mjs CHANGED
@@ -3228,8 +3228,8 @@ var require_utils = __commonJS({
3228
3228
  }
3229
3229
  return ind;
3230
3230
  }
3231
- function removeDotSegments(path2) {
3232
- let input = path2;
3231
+ function removeDotSegments(path3) {
3232
+ let input = path3;
3233
3233
  const output = [];
3234
3234
  let nextSlash = -1;
3235
3235
  let len = 0;
@@ -3481,8 +3481,8 @@ var require_schemes = __commonJS({
3481
3481
  wsComponent.secure = void 0;
3482
3482
  }
3483
3483
  if (wsComponent.resourceName) {
3484
- const [path2, query] = wsComponent.resourceName.split("?");
3485
- wsComponent.path = path2 && path2 !== "/" ? path2 : void 0;
3484
+ const [path3, query] = wsComponent.resourceName.split("?");
3485
+ wsComponent.path = path3 && path3 !== "/" ? path3 : void 0;
3486
3486
  wsComponent.query = query;
3487
3487
  wsComponent.resourceName = void 0;
3488
3488
  }
@@ -7392,8 +7392,8 @@ function getErrorMap() {
7392
7392
 
7393
7393
  // node_modules/zod/v3/helpers/parseUtil.js
7394
7394
  var makeIssue = (params) => {
7395
- const { data, path: path2, errorMaps, issueData } = params;
7396
- const fullPath = [...path2, ...issueData.path || []];
7395
+ const { data, path: path3, errorMaps, issueData } = params;
7396
+ const fullPath = [...path3, ...issueData.path || []];
7397
7397
  const fullIssue = {
7398
7398
  ...issueData,
7399
7399
  path: fullPath
@@ -7509,11 +7509,11 @@ var errorUtil;
7509
7509
 
7510
7510
  // node_modules/zod/v3/types.js
7511
7511
  var ParseInputLazyPath = class {
7512
- constructor(parent, value, path2, key) {
7512
+ constructor(parent, value, path3, key) {
7513
7513
  this._cachedPath = [];
7514
7514
  this.parent = parent;
7515
7515
  this.data = value;
7516
- this._path = path2;
7516
+ this._path = path3;
7517
7517
  this._key = key;
7518
7518
  }
7519
7519
  get path() {
@@ -11150,10 +11150,10 @@ function assignProp(target, prop, value) {
11150
11150
  configurable: true
11151
11151
  });
11152
11152
  }
11153
- function getElementAtPath(obj, path2) {
11154
- if (!path2)
11153
+ function getElementAtPath(obj, path3) {
11154
+ if (!path3)
11155
11155
  return obj;
11156
- return path2.reduce((acc, key) => acc?.[key], obj);
11156
+ return path3.reduce((acc, key) => acc?.[key], obj);
11157
11157
  }
11158
11158
  function promiseAllObject(promisesObj) {
11159
11159
  const keys = Object.keys(promisesObj);
@@ -11473,11 +11473,11 @@ function aborted(x, startIndex = 0) {
11473
11473
  }
11474
11474
  return false;
11475
11475
  }
11476
- function prefixIssues(path2, issues) {
11476
+ function prefixIssues(path3, issues) {
11477
11477
  return issues.map((iss) => {
11478
11478
  var _a;
11479
11479
  (_a = iss).path ?? (_a.path = []);
11480
- iss.path.unshift(path2);
11480
+ iss.path.unshift(path3);
11481
11481
  return iss;
11482
11482
  });
11483
11483
  }
@@ -21102,8 +21102,8 @@ var StdioServerTransport = class {
21102
21102
  };
21103
21103
 
21104
21104
  // src/server-lite.ts
21105
- import { readFileSync } from "node:fs";
21106
- import path from "node:path";
21105
+ import { readFileSync as readFileSync2 } from "node:fs";
21106
+ import path2 from "node:path";
21107
21107
 
21108
21108
  // src/catalog/store.ts
21109
21109
  var CatalogStore = class {
@@ -21144,6 +21144,7 @@ var CatalogStore = class {
21144
21144
  description: c.description,
21145
21145
  importPath: c.importPath,
21146
21146
  moduleName: c.moduleName,
21147
+ standalone: c.standalone,
21147
21148
  inputCount: c.inputs.length,
21148
21149
  outputCount: c.outputs.length,
21149
21150
  supportsTheme: c.supportsTheme,
@@ -21188,12 +21189,22 @@ function registerListComponentsTool(server, store) {
21188
21189
 
21189
21190
  // src/tools/get-component.ts
21190
21191
  var NOT_FOUND = (name) => `Component "${name}" not found. Use list_components to see available components.`;
21192
+ function trimComponent(component, params) {
21193
+ const { template, documentation, ...rest } = component;
21194
+ return {
21195
+ ...rest,
21196
+ ...params.includeTemplate ? { template } : {},
21197
+ ...params.includeDocs ? { documentation } : {}
21198
+ };
21199
+ }
21191
21200
  function registerGetComponentTool(server, store) {
21192
21201
  server.tool(
21193
21202
  "get_component",
21194
- 'Get full metadata for a tgo-canopy-ui component including all inputs, outputs, types, module info, usage examples, documentation, and (where applicable) resolved color swatches \u2014 e.g. badge exposes background/text hex per rebrandColor value so a Figma fill can be matched mechanically. Accepts component directory name (e.g., "button"), selector (e.g., "ui-button"), or class name (e.g., "ButtonComponent").',
21203
+ 'Get full metadata for a tgo-canopy-ui component including all inputs, outputs, types, module info, usage examples, and (where applicable) resolved color swatches \u2014 e.g. badge exposes background/text hex per rebrandColor value so a Figma fill can be matched mechanically. Accepts component directory name (e.g., "button"), selector (e.g., "ui-button"), or class name (e.g., "ButtonComponent"). The raw HTML template and full docs markdown are omitted by default \u2014 pass includeTemplate / includeDocs to get them.',
21195
21204
  {
21196
- name: external_exports.string().describe("Component name, selector, or class name")
21205
+ name: external_exports.string().describe("Component name, selector, or class name"),
21206
+ includeTemplate: external_exports.boolean().optional().describe("Include the raw HTML template (large; queryGuide already summarizes it). Default false."),
21207
+ includeDocs: external_exports.boolean().optional().describe("Include the full docs markdown (large; get_usage_guide covers most needs). Default false.")
21197
21208
  },
21198
21209
  async (params) => {
21199
21210
  const component = store.find(params.name);
@@ -21204,7 +21215,7 @@ function registerGetComponentTool(server, store) {
21204
21215
  };
21205
21216
  }
21206
21217
  return {
21207
- content: [{ type: "text", text: JSON.stringify(component, null, 2) }]
21218
+ content: [{ type: "text", text: JSON.stringify(trimComponent(component, params), null, 2) }]
21208
21219
  };
21209
21220
  }
21210
21221
  );
@@ -21270,6 +21281,7 @@ function registerSearchComponentsTool(server, store) {
21270
21281
  description: c.description,
21271
21282
  importPath: c.importPath,
21272
21283
  moduleName: c.moduleName,
21284
+ standalone: c.standalone,
21273
21285
  inputCount: c.inputs.length,
21274
21286
  outputCount: c.outputs.length,
21275
21287
  supportsTheme: c.supportsTheme,
@@ -21309,14 +21321,21 @@ function generateUsageGuide(c) {
21309
21321
  }
21310
21322
  lines.push("");
21311
21323
  }
21312
- lines.push("## Import");
21313
- lines.push("");
21314
- lines.push("```typescript");
21315
- lines.push(`import { ${c.moduleName} } from '${c.importPath}';`);
21316
- lines.push("```");
21317
- lines.push("");
21318
- lines.push(`Add \`${c.moduleName}\` to the \`imports\` array of your NgModule.`);
21319
- lines.push("");
21324
+ const importSymbol = c.moduleName || (c.name !== "UnknownComponent" ? c.name : "");
21325
+ if (importSymbol) {
21326
+ lines.push("## Import");
21327
+ lines.push("");
21328
+ lines.push("```typescript");
21329
+ lines.push(`import { ${importSymbol} } from '${c.importPath}';`);
21330
+ lines.push("```");
21331
+ lines.push("");
21332
+ if (!c.moduleName && c.standalone) {
21333
+ lines.push(`This is a standalone component \u2014 add \`${importSymbol}\` to the \`imports\` array of your standalone component or NgModule.`);
21334
+ } else {
21335
+ lines.push(`Add \`${importSymbol}\` to the \`imports\` array of your NgModule or standalone component.`);
21336
+ }
21337
+ lines.push("");
21338
+ }
21320
21339
  if (c.inputs.length > 0) {
21321
21340
  lines.push("## Inputs");
21322
21341
  lines.push("");
@@ -21377,14 +21396,13 @@ function generateUsageGuide(c) {
21377
21396
  lines.push("## Basic Usage");
21378
21397
  lines.push("");
21379
21398
  lines.push("```html");
21380
- const requiredAttrs = c.inputs.filter((i) => i.required).map((i) => `[${i.alias ?? i.name}]="value"`).join(" ");
21381
- const optionalAttrs = c.inputs.filter((i) => !i.required).slice(0, 3).map((i) => {
21382
- const attrName = i.alias ?? i.name;
21383
- return i.defaultValue ? `${attrName}="${i.defaultValue.replace(/'/g, "")}"` : `[${attrName}]="value"`;
21384
- }).join(" ");
21385
- const outputBindings = c.outputs.map((o) => `(${o.alias ?? o.name})="onEvent($event)"`).join(" ");
21386
- const attrs = [requiredAttrs, optionalAttrs, outputBindings].filter(Boolean).join(" ");
21387
- lines.push(`<${c.selector} ${attrs}></${c.selector}>`);
21399
+ const requiredInputs = c.inputs.filter((i) => i.required);
21400
+ const shownInputs = requiredInputs.length > 0 ? requiredInputs : representativeInputs(c);
21401
+ const requiredAttrs = shownInputs.map((i) => renderInputPlaceholder(i.alias ?? i.name, i.type, c)).join(" ");
21402
+ const primaryOutput = c.outputs[0];
21403
+ const outputBinding = primaryOutput ? `(${primaryOutput.alias ?? primaryOutput.name})="on${capitalize(primaryOutput.alias ?? primaryOutput.name)}($event)"` : "";
21404
+ const attrs = [requiredAttrs, outputBinding].filter(Boolean).join(" ");
21405
+ lines.push(`<${c.selector}${attrs ? " " + attrs : ""}></${c.selector}>`);
21388
21406
  lines.push("```");
21389
21407
  lines.push("");
21390
21408
  if (c.examples.length > 0) {
@@ -21401,6 +21419,31 @@ function generateUsageGuide(c) {
21401
21419
  }
21402
21420
  return lines.join("\n");
21403
21421
  }
21422
+ function representativeInputs(c) {
21423
+ const labelLike = c.inputs.find(
21424
+ (i) => i.type === "string" && /^(label|title|text|placeholder)$/.test(i.alias ?? i.name)
21425
+ );
21426
+ const unionLike = c.inputs.find(
21427
+ (i) => i !== labelLike && firstUnionLiteral(i.type, c) !== null
21428
+ );
21429
+ return [labelLike, unionLike].filter((i) => i !== void 0);
21430
+ }
21431
+ function renderInputPlaceholder(attrName, type, c) {
21432
+ const unionLiteral = firstUnionLiteral(type, c);
21433
+ if (unionLiteral !== null) return `${attrName}="${unionLiteral}"`;
21434
+ if (type === "boolean") return `[${attrName}]="true"`;
21435
+ if (type === "number") return `[${attrName}]="0"`;
21436
+ if (type === "string") return `${attrName}="value"`;
21437
+ return `[${attrName}]="value"`;
21438
+ }
21439
+ function firstUnionLiteral(type, c) {
21440
+ const aliased = c.types.typeAliases.find((t) => t.name === type)?.value ?? type;
21441
+ const match = aliased.match(/^\s*\|?\s*'([^']+)'/);
21442
+ return match ? match[1] : null;
21443
+ }
21444
+ function capitalize(name) {
21445
+ return name.charAt(0).toUpperCase() + name.slice(1);
21446
+ }
21404
21447
  function registerGetUsageGuideTool(server, store) {
21405
21448
  server.tool(
21406
21449
  "get_usage_guide",
@@ -21791,6 +21834,87 @@ function registerListColorPalettesTool(server, palettes) {
21791
21834
  );
21792
21835
  }
21793
21836
 
21837
+ // src/tools/check-version.ts
21838
+ import { existsSync, readFileSync } from "node:fs";
21839
+ import path from "node:path";
21840
+ var PACKAGE_NAME = "@testgorilla/tgo-ui";
21841
+ function readJson(filePath) {
21842
+ try {
21843
+ return JSON.parse(readFileSync(filePath, "utf-8"));
21844
+ } catch {
21845
+ return null;
21846
+ }
21847
+ }
21848
+ function* ancestors(startDir) {
21849
+ let dir = path.resolve(startDir);
21850
+ for (; ; ) {
21851
+ yield dir;
21852
+ const parent = path.dirname(dir);
21853
+ if (parent === dir) return;
21854
+ dir = parent;
21855
+ }
21856
+ }
21857
+ function findInstalledPackage(startDir) {
21858
+ for (const dir of ancestors(startDir)) {
21859
+ const pkgPath = path.join(dir, "node_modules", ...PACKAGE_NAME.split("/"), "package.json");
21860
+ if (!existsSync(pkgPath)) continue;
21861
+ const version2 = readJson(pkgPath)?.version;
21862
+ if (typeof version2 === "string") return { version: version2, path: pkgPath };
21863
+ }
21864
+ return null;
21865
+ }
21866
+ function findDeclaredRange(startDir) {
21867
+ for (const dir of ancestors(startDir)) {
21868
+ const pkg = readJson(path.join(dir, "package.json"));
21869
+ if (!pkg) continue;
21870
+ const range = pkg.dependencies?.[PACKAGE_NAME] ?? pkg.devDependencies?.[PACKAGE_NAME] ?? pkg.peerDependencies?.[PACKAGE_NAME];
21871
+ return typeof range === "string" ? range : null;
21872
+ }
21873
+ return null;
21874
+ }
21875
+ function handleCheckVersion(serverVersion, params, cwd = process.cwd()) {
21876
+ const projectDir = params.projectDir ? path.resolve(cwd, params.projectDir) : cwd;
21877
+ const declaredRange = findDeclaredRange(projectDir);
21878
+ let installedVersion = null;
21879
+ let installedSource = null;
21880
+ if (params.installedVersion) {
21881
+ installedVersion = params.installedVersion.trim().replace(/^v/, "");
21882
+ installedSource = "installedVersion parameter";
21883
+ } else {
21884
+ const installed = findInstalledPackage(projectDir);
21885
+ if (installed) {
21886
+ installedVersion = installed.version;
21887
+ installedSource = installed.path;
21888
+ }
21889
+ }
21890
+ if (installedVersion === null) {
21891
+ return {
21892
+ serverVersion,
21893
+ installedVersion,
21894
+ installedSource,
21895
+ declaredRange,
21896
+ match: null,
21897
+ message: `Could not find ${PACKAGE_NAME} in node_modules above ${projectDir}. Pass the version from your project's node_modules/${PACKAGE_NAME}/package.json as \`installedVersion\`, or point \`projectDir\` at the consumer project root.`
21898
+ };
21899
+ }
21900
+ const match = installedVersion === serverVersion;
21901
+ const message = match ? `OK: the MCP catalog (v${serverVersion}) matches the installed ${PACKAGE_NAME} (v${installedVersion}).` : `MISMATCH: the MCP catalog was built from ${PACKAGE_NAME} v${serverVersion} but the project has v${installedVersion} installed. Component inputs, outputs and examples reported by this server may not exist in the installed version. Point the MCP server at node_modules/${PACKAGE_NAME}/mcp/server.mjs inside this project, or update the dependency so both versions agree.`;
21902
+ return { serverVersion, installedVersion, installedSource, declaredRange, match, message };
21903
+ }
21904
+ function registerCheckVersionTool(server, serverVersion) {
21905
+ server.tool(
21906
+ "check_version",
21907
+ `Verify that this MCP server's catalog matches the ${PACKAGE_NAME} version installed in the consumer project. The installed version is resolved from node_modules (walking up from the server's working directory or \`projectDir\`); pass \`installedVersion\` to override. Call this first when component metadata looks out of sync with the code you are working on. Returns \`{ serverVersion, installedVersion, installedSource, declaredRange, match, message }\`.`,
21908
+ {
21909
+ installedVersion: external_exports.string().optional().describe(`Installed ${PACKAGE_NAME} version to compare against (e.g. "11.12.2"). Overrides node_modules resolution.`),
21910
+ projectDir: external_exports.string().optional().describe("Consumer project directory to resolve node_modules from. Defaults to the server's working directory.")
21911
+ },
21912
+ async ({ installedVersion, projectDir }) => ({
21913
+ content: [{ type: "text", text: JSON.stringify(handleCheckVersion(serverVersion, { installedVersion, projectDir }), null, 2) }]
21914
+ })
21915
+ );
21916
+ }
21917
+
21794
21918
  // src/icons/icon-resolver.ts
21795
21919
  var MIN_FUZZY_QUERY_LENGTH = 4;
21796
21920
  var IconResolver = class {
@@ -22010,14 +22134,15 @@ function createStaticMcpServer(catalog) {
22010
22134
  registerGetDesignTokensTool(server, catalog.tokens ?? []);
22011
22135
  registerListTypographyClassesTool(server, catalog.typography ?? []);
22012
22136
  registerListColorPalettesTool(server, catalog.colorPalettes ?? []);
22137
+ registerCheckVersionTool(server, catalog.version);
22013
22138
  return server;
22014
22139
  }
22015
22140
  var isMainScript = import.meta.url === `file://${process.argv[1]}` || process.argv[1]?.endsWith("server-lite.js") || process.argv[1]?.endsWith("server.mjs");
22016
22141
  if (isMainScript) {
22017
- const catalogPath = path.join(import.meta.dirname, "catalog.json");
22142
+ const catalogPath = path2.join(import.meta.dirname, "catalog.json");
22018
22143
  let raw;
22019
22144
  try {
22020
- raw = readFileSync(catalogPath, "utf-8");
22145
+ raw = readFileSync2(catalogPath, "utf-8");
22021
22146
  } catch {
22022
22147
  console.error(`[mcp] Fatal: catalog.json not found at ${catalogPath}`);
22023
22148
  console.error("[mcp] The catalog must be adjacent to server.mjs");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@testgorilla/tgo-ui",
3
- "version": "11.12.2",
3
+ "version": "11.13.1",
4
4
  "license": "proprietary-license",
5
5
  "lint-staged": {
6
6
  "{projects,components}/**/*.ts": [