@vizejs/musea-mcp-server 0.429.0 → 0.429.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.mjs +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{src-BB93rq2Q.mjs → src-BlrFYjvC.mjs} +164 -3
- package/package.json +2 -2
package/dist/cli.mjs
CHANGED
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as startServer, t as createMuseaServer } from "./src-
|
|
1
|
+
import { n as startServer, t as createMuseaServer } from "./src-BlrFYjvC.mjs";
|
|
2
2
|
export { createMuseaServer, createMuseaServer as default, startServer };
|
|
@@ -1433,15 +1433,176 @@ async function handleRecommendComponents(ctx, args) {
|
|
|
1433
1433
|
}] };
|
|
1434
1434
|
}
|
|
1435
1435
|
//#endregion
|
|
1436
|
+
//#region src/css-tokens.ts
|
|
1437
|
+
const CSS_EXTENSIONS = new Set([
|
|
1438
|
+
".css",
|
|
1439
|
+
".pcss",
|
|
1440
|
+
".postcss"
|
|
1441
|
+
]);
|
|
1442
|
+
const VARIABLE_DECLARATION_RE = /(--[A-Za-z0-9_-]+)\s*:\s*([^;{}]+);/g;
|
|
1443
|
+
const CSS_COMMENT_RE = /\/\*[\s\S]*?\*\//g;
|
|
1444
|
+
const VARIABLE_REFERENCE_RE = /^var\(\s*(--[A-Za-z0-9_-]+)\s*(?:,[^)]+)?\)$/;
|
|
1445
|
+
const NAMESPACE_MAPPINGS = [
|
|
1446
|
+
{
|
|
1447
|
+
prefix: "color",
|
|
1448
|
+
category: "color",
|
|
1449
|
+
type: "color"
|
|
1450
|
+
},
|
|
1451
|
+
{
|
|
1452
|
+
prefix: "spacing",
|
|
1453
|
+
category: "spacing",
|
|
1454
|
+
type: "dimension"
|
|
1455
|
+
},
|
|
1456
|
+
{
|
|
1457
|
+
prefix: "font-weight",
|
|
1458
|
+
category: "typography",
|
|
1459
|
+
pathPrefix: ["fontWeight"],
|
|
1460
|
+
type: "fontWeight"
|
|
1461
|
+
},
|
|
1462
|
+
{
|
|
1463
|
+
prefix: "font",
|
|
1464
|
+
category: "typography",
|
|
1465
|
+
pathPrefix: ["font"],
|
|
1466
|
+
type: "fontFamily"
|
|
1467
|
+
},
|
|
1468
|
+
{
|
|
1469
|
+
prefix: "text",
|
|
1470
|
+
category: "typography",
|
|
1471
|
+
pathPrefix: ["fontSize"],
|
|
1472
|
+
type: "dimension"
|
|
1473
|
+
},
|
|
1474
|
+
{
|
|
1475
|
+
prefix: "radius",
|
|
1476
|
+
category: "radius",
|
|
1477
|
+
type: "dimension"
|
|
1478
|
+
},
|
|
1479
|
+
{
|
|
1480
|
+
prefix: "shadow",
|
|
1481
|
+
category: "shadow",
|
|
1482
|
+
type: "shadow"
|
|
1483
|
+
}
|
|
1484
|
+
];
|
|
1485
|
+
async function isCssTokenPath(tokensPath) {
|
|
1486
|
+
const stat = await fs.promises.stat(tokensPath).catch(() => null);
|
|
1487
|
+
if (!stat) return false;
|
|
1488
|
+
if (stat.isFile()) return CSS_EXTENSIONS.has(path.extname(tokensPath).toLowerCase());
|
|
1489
|
+
if (!stat.isDirectory()) return false;
|
|
1490
|
+
return (await fs.promises.readdir(tokensPath, { withFileTypes: true })).some((entry) => entry.isFile() && CSS_EXTENSIONS.has(path.extname(entry.name).toLowerCase()));
|
|
1491
|
+
}
|
|
1492
|
+
async function parseCssTokenFiles(tokensPath) {
|
|
1493
|
+
const files = (await fs.promises.stat(tokensPath)).isDirectory() ? (await fs.promises.readdir(tokensPath)).filter((name) => CSS_EXTENSIONS.has(path.extname(name).toLowerCase())).sort().map((name) => path.join(tokensPath, name)) : [tokensPath];
|
|
1494
|
+
return parseCssTokenSource((await Promise.all(files.map((file) => fs.promises.readFile(file, "utf8")))).join("\n"));
|
|
1495
|
+
}
|
|
1496
|
+
function parseCssTokenSource(css) {
|
|
1497
|
+
const source = css.replace(CSS_COMMENT_RE, "");
|
|
1498
|
+
const declarations = [];
|
|
1499
|
+
let match;
|
|
1500
|
+
VARIABLE_DECLARATION_RE.lastIndex = 0;
|
|
1501
|
+
while ((match = VARIABLE_DECLARATION_RE.exec(source)) !== null) {
|
|
1502
|
+
const value = match[2]?.trim();
|
|
1503
|
+
if (match[1] && value) declarations.push({
|
|
1504
|
+
variable: match[1],
|
|
1505
|
+
value
|
|
1506
|
+
});
|
|
1507
|
+
}
|
|
1508
|
+
const paths = /* @__PURE__ */ new Map();
|
|
1509
|
+
const mapped = declarations.map((declaration) => {
|
|
1510
|
+
const token = mapDeclaration(declaration.variable, declaration.value);
|
|
1511
|
+
paths.set(declaration.variable, [token.category, ...token.path].join("."));
|
|
1512
|
+
return {
|
|
1513
|
+
...declaration,
|
|
1514
|
+
...token
|
|
1515
|
+
};
|
|
1516
|
+
});
|
|
1517
|
+
const categories = /* @__PURE__ */ new Map();
|
|
1518
|
+
for (const declaration of mapped) {
|
|
1519
|
+
const category = categories.get(declaration.category) ?? {
|
|
1520
|
+
name: declaration.category,
|
|
1521
|
+
tokens: Object.create(null)
|
|
1522
|
+
};
|
|
1523
|
+
categories.set(declaration.category, category);
|
|
1524
|
+
const referenceVariable = declaration.value.match(VARIABLE_REFERENCE_RE)?.[1];
|
|
1525
|
+
const reference = referenceVariable ? paths.get(referenceVariable) : void 0;
|
|
1526
|
+
const token = {
|
|
1527
|
+
value: reference ? `{${reference}}` : declaration.value,
|
|
1528
|
+
type: declaration.type,
|
|
1529
|
+
description: declaration.description,
|
|
1530
|
+
$tier: reference ? "semantic" : "primitive",
|
|
1531
|
+
...reference ? { $reference: reference } : {}
|
|
1532
|
+
};
|
|
1533
|
+
setToken(category, declaration.path, token);
|
|
1534
|
+
}
|
|
1535
|
+
return [...categories.values()];
|
|
1536
|
+
}
|
|
1537
|
+
function mapDeclaration(variable, value) {
|
|
1538
|
+
const name = variable.slice(2);
|
|
1539
|
+
const mapping = NAMESPACE_MAPPINGS.find((candidate) => name === candidate.prefix || name.startsWith(`${candidate.prefix}-`));
|
|
1540
|
+
if (mapping) {
|
|
1541
|
+
const rest = name === mapping.prefix ? "DEFAULT" : name.slice(mapping.prefix.length + 1);
|
|
1542
|
+
const pathParts = [...mapping.pathPrefix ?? [], rest].filter(Boolean);
|
|
1543
|
+
return {
|
|
1544
|
+
category: mapping.category,
|
|
1545
|
+
path: pathParts.length > 0 ? pathParts : ["DEFAULT"],
|
|
1546
|
+
type: mapping.type,
|
|
1547
|
+
description: `Tailwind theme variable ${variable}`
|
|
1548
|
+
};
|
|
1549
|
+
}
|
|
1550
|
+
const segments = name.split("-").filter(Boolean);
|
|
1551
|
+
const category = segments[0] ?? "token";
|
|
1552
|
+
const rest = segments.slice(1).join("-");
|
|
1553
|
+
return {
|
|
1554
|
+
category,
|
|
1555
|
+
path: rest ? [rest] : ["DEFAULT"],
|
|
1556
|
+
type: inferType(value),
|
|
1557
|
+
description: `Custom property ${variable}`
|
|
1558
|
+
};
|
|
1559
|
+
}
|
|
1560
|
+
function inferType(value) {
|
|
1561
|
+
if (/^(?:#|rgba?\(|hsla?\(|oklch\(|oklab\(|color-mix\(|color\()/i.test(value)) return "color";
|
|
1562
|
+
if (/^-?(?:\d+\.\d+|\d+)(?:px|rem|em|vh|vw|vmin|vmax|%)$/i.test(value)) return "dimension";
|
|
1563
|
+
if (/^-?(?:\d+\.\d+|\d+)$/.test(value)) return "number";
|
|
1564
|
+
return "other";
|
|
1565
|
+
}
|
|
1566
|
+
function setToken(category, pathParts, token) {
|
|
1567
|
+
if (pathParts.length === 1) {
|
|
1568
|
+
category.tokens[pathParts[0]] = token;
|
|
1569
|
+
return;
|
|
1570
|
+
}
|
|
1571
|
+
let current = category;
|
|
1572
|
+
for (const part of pathParts.slice(0, -1)) {
|
|
1573
|
+
current.subcategories ??= [];
|
|
1574
|
+
let next = current.subcategories.find((subcategory) => subcategory.name === part);
|
|
1575
|
+
if (!next) {
|
|
1576
|
+
next = {
|
|
1577
|
+
name: part,
|
|
1578
|
+
tokens: Object.create(null)
|
|
1579
|
+
};
|
|
1580
|
+
current.subcategories.push(next);
|
|
1581
|
+
}
|
|
1582
|
+
current = next;
|
|
1583
|
+
}
|
|
1584
|
+
current.tokens[pathParts[pathParts.length - 1]] = token;
|
|
1585
|
+
}
|
|
1586
|
+
//#endregion
|
|
1436
1587
|
//#region src/tokens.ts
|
|
1437
1588
|
async function parseTokensFromPath(tokensPath) {
|
|
1438
|
-
return normalizeCategories(
|
|
1589
|
+
if (await isCssTokenPath(tokensPath)) return normalizeCategories(await parseCssTokenFiles(tokensPath));
|
|
1590
|
+
return categoriesFromNativeResult(loadNative().parseDesignTokensFromPath(tokensPath));
|
|
1591
|
+
}
|
|
1592
|
+
function categoriesFromNativeResult(value) {
|
|
1593
|
+
const parsed = parseJsonResult(value);
|
|
1594
|
+
if (!Array.isArray(parsed)) throw new TypeError("Design token parser did not return a category array");
|
|
1595
|
+
return normalizeCategories(parsed);
|
|
1439
1596
|
}
|
|
1440
1597
|
function generateTokensMarkdown(categories) {
|
|
1441
|
-
return loadNative().generateDesignTokensMarkdown(categories);
|
|
1598
|
+
return String(loadNative().generateDesignTokensMarkdown(JSON.stringify(categories)));
|
|
1442
1599
|
}
|
|
1443
1600
|
function flattenTokenCategories(categories) {
|
|
1444
|
-
return loadNative().flattenDesignTokenCategories(categories);
|
|
1601
|
+
return parseJsonResult(loadNative().flattenDesignTokenCategories(JSON.stringify(categories)));
|
|
1602
|
+
}
|
|
1603
|
+
function parseJsonResult(value) {
|
|
1604
|
+
if (typeof value === "string") return JSON.parse(value);
|
|
1605
|
+
return value;
|
|
1445
1606
|
}
|
|
1446
1607
|
function normalizeCategories(categories) {
|
|
1447
1608
|
for (const category of categories) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vizejs/musea-mcp-server",
|
|
3
|
-
"version": "0.429.
|
|
3
|
+
"version": "0.429.2",
|
|
4
4
|
"description": "MCP server for building Vue.js design systems - component analysis, documentation, variant generation, and design tokens",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"@modelcontextprotocol/sdk": "1.30.0",
|
|
45
|
-
"@vizejs/native": "0.429.
|
|
45
|
+
"@vizejs/native": "0.429.2",
|
|
46
46
|
"@vue/compiler-dom": "3.5.35",
|
|
47
47
|
"typescript": "6.0.3"
|
|
48
48
|
},
|