@vizejs/musea-mcp-server 0.285.0 → 0.286.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.mjs +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{src-DMeHW2z2.mjs → src-CqGFwjgv.mjs} +86 -18
- package/package.json +4 -3
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-CqGFwjgv.mjs";
|
|
2
2
|
export { createMuseaServer, createMuseaServer as default, startServer };
|
|
@@ -4,6 +4,8 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
|
|
|
4
4
|
import { CallToolRequestSchema, ErrorCode, ListResourcesRequestSchema, ListToolsRequestSchema, McpError, ReadResourceRequestSchema } from "@modelcontextprotocol/sdk/types.js";
|
|
5
5
|
import fs from "node:fs";
|
|
6
6
|
import path from "node:path";
|
|
7
|
+
import { NodeTypes, baseParse } from "@vue/compiler-dom";
|
|
8
|
+
import ts from "typescript";
|
|
7
9
|
//#region src/native.ts
|
|
8
10
|
let native = null;
|
|
9
11
|
function loadNative() {
|
|
@@ -525,6 +527,89 @@ const toolDefinitions = [
|
|
|
525
527
|
}
|
|
526
528
|
];
|
|
527
529
|
//#endregion
|
|
530
|
+
//#region src/markdown-template.ts
|
|
531
|
+
const SELF_TAG_NAME = "Self";
|
|
532
|
+
const TEMPLATE_FENCE_LANGUAGES = new Set([
|
|
533
|
+
"",
|
|
534
|
+
"html",
|
|
535
|
+
"template",
|
|
536
|
+
"vue"
|
|
537
|
+
]);
|
|
538
|
+
function formatGeneratedMarkdown(markdown, componentName) {
|
|
539
|
+
return markdown.replace(/```(\w*)\n([\s\S]*?)```/g, (_match, lang, code) => {
|
|
540
|
+
const normalizedLang = lang.toLowerCase();
|
|
541
|
+
return formatCodeFence(lang, TEMPLATE_FENCE_LANGUAGES.has(normalizedLang) ? rewriteSelfComponentTags(code, componentName) : code);
|
|
542
|
+
});
|
|
543
|
+
}
|
|
544
|
+
function formatCodeFence(lang, code) {
|
|
545
|
+
const lines = code.split("\n");
|
|
546
|
+
let minIndent = Infinity;
|
|
547
|
+
for (const line of lines) if (line.trim()) {
|
|
548
|
+
const indent = line.match(/^(\s*)/)?.[1].length ?? 0;
|
|
549
|
+
minIndent = Math.min(minIndent, indent);
|
|
550
|
+
}
|
|
551
|
+
if (minIndent === Infinity) minIndent = 0;
|
|
552
|
+
return `\`\`\`${lang}\n${(minIndent > 0 ? lines.map((line) => line.slice(minIndent)) : lines).join("\n")}\`\`\``;
|
|
553
|
+
}
|
|
554
|
+
function rewriteSelfComponentTags(code, componentName) {
|
|
555
|
+
const replacements = [];
|
|
556
|
+
try {
|
|
557
|
+
collectSelfTagReplacements(baseParse(code, { comments: true }).children, replacements, componentName);
|
|
558
|
+
} catch {
|
|
559
|
+
return code;
|
|
560
|
+
}
|
|
561
|
+
if (replacements.length === 0) return code;
|
|
562
|
+
let rewritten = code;
|
|
563
|
+
for (const replacement of replacements.sort((left, right) => right.start - left.start)) rewritten = rewritten.slice(0, replacement.start) + replacement.text + rewritten.slice(replacement.end);
|
|
564
|
+
return rewritten;
|
|
565
|
+
}
|
|
566
|
+
function collectSelfTagReplacements(nodes, replacements, componentName) {
|
|
567
|
+
for (const node of nodes) {
|
|
568
|
+
if (node.type !== NodeTypes.ELEMENT) continue;
|
|
569
|
+
if (node.tag === SELF_TAG_NAME) addSelfElementReplacements(node, replacements, componentName);
|
|
570
|
+
collectSelfTagReplacements(node.children, replacements, componentName);
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
function addSelfElementReplacements(node, replacements, componentName) {
|
|
574
|
+
const openStart = node.loc.start.offset + 1;
|
|
575
|
+
const openEnd = openStart + 4;
|
|
576
|
+
replacements.push({
|
|
577
|
+
start: openStart,
|
|
578
|
+
end: openEnd,
|
|
579
|
+
text: componentName
|
|
580
|
+
});
|
|
581
|
+
if (node.isSelfClosing) return;
|
|
582
|
+
const closeTagIndex = node.loc.source.lastIndexOf(`</${SELF_TAG_NAME}>`);
|
|
583
|
+
if (closeTagIndex < 0) return;
|
|
584
|
+
const closeStart = node.loc.start.offset + closeTagIndex + 2;
|
|
585
|
+
replacements.push({
|
|
586
|
+
start: closeStart,
|
|
587
|
+
end: closeStart + 4,
|
|
588
|
+
text: componentName
|
|
589
|
+
});
|
|
590
|
+
}
|
|
591
|
+
//#endregion
|
|
592
|
+
//#region src/palette-typescript.ts
|
|
593
|
+
function buildPaletteTypescript(title, controls) {
|
|
594
|
+
const members = controls.map((control) => ts.factory.createPropertySignature(void 0, propertyNameNode(control.name), control.required ? void 0 : ts.factory.createToken(ts.SyntaxKind.QuestionToken), controlTypeNode(control)));
|
|
595
|
+
const declaration = ts.factory.createInterfaceDeclaration([ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], interfaceNameFromTitle(title), void 0, void 0, members);
|
|
596
|
+
const sourceFile = ts.createSourceFile("palette.ts", "", ts.ScriptTarget.Latest, false, ts.ScriptKind.TS);
|
|
597
|
+
return `${ts.createPrinter({ newLine: ts.NewLineKind.LineFeed }).printNode(ts.EmitHint.Unspecified, declaration, sourceFile)}\n`;
|
|
598
|
+
}
|
|
599
|
+
function interfaceNameFromTitle(title) {
|
|
600
|
+
const candidate = `${title.replace(/\s+/g, "") || "Component"}Props`.replace(/[^A-Za-z0-9_$]/g, "_");
|
|
601
|
+
return /^[A-Za-z_$]/.test(candidate) ? candidate : `_${candidate}`;
|
|
602
|
+
}
|
|
603
|
+
function propertyNameNode(name) {
|
|
604
|
+
return /^[$A-Z_a-z][$\w]*$/.test(name) ? ts.factory.createIdentifier(name) : ts.factory.createStringLiteral(name);
|
|
605
|
+
}
|
|
606
|
+
function controlTypeNode(control) {
|
|
607
|
+
if (control.control === "boolean") return ts.factory.createKeywordTypeNode(ts.SyntaxKind.BooleanKeyword);
|
|
608
|
+
if (control.control === "number") return ts.factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword);
|
|
609
|
+
if (control.control === "select" && control.options.length > 0) return ts.factory.createUnionTypeNode(control.options.map((option) => ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(String(option.value)))));
|
|
610
|
+
return ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword);
|
|
611
|
+
}
|
|
612
|
+
//#endregion
|
|
528
613
|
//#region src/musea.ts
|
|
529
614
|
function normalize(value) {
|
|
530
615
|
return value?.trim().toLowerCase() ?? "";
|
|
@@ -855,10 +940,7 @@ function buildPaletteFromAnalysis(title, analysis) {
|
|
|
855
940
|
title,
|
|
856
941
|
controls
|
|
857
942
|
}, null, 2),
|
|
858
|
-
typescript:
|
|
859
|
-
const type = control.control === "boolean" ? "boolean" : control.control === "number" ? "number" : control.control === "select" && control.options.length > 0 ? control.options.map((option) => `"${String(option.value)}"`).join(" | ") : "string";
|
|
860
|
-
return ` ${control.name}${control.required ? "" : "?"}: ${type};`;
|
|
861
|
-
}).join("\n")}\n}\n`
|
|
943
|
+
typescript: buildPaletteTypescript(title, controls)
|
|
862
944
|
};
|
|
863
945
|
}
|
|
864
946
|
async function analyzeResolvedComponent(ctx, binding, resolved) {
|
|
@@ -890,20 +972,6 @@ async function analyzeResolvedComponent(ctx, binding, resolved) {
|
|
|
890
972
|
}
|
|
891
973
|
};
|
|
892
974
|
}
|
|
893
|
-
function formatGeneratedMarkdown(markdown, componentName) {
|
|
894
|
-
let formatted = markdown.replace(/<Self(\s|>|\/)/g, `<${componentName}$1`).replace(/<\/Self>/g, `</${componentName}>`);
|
|
895
|
-
formatted = formatted.replace(/```(\w*)\n([\s\S]*?)```/g, (_match, lang, code) => {
|
|
896
|
-
const lines = code.split("\n");
|
|
897
|
-
let minIndent = Infinity;
|
|
898
|
-
for (const line of lines) if (line.trim()) {
|
|
899
|
-
const indent = line.match(/^(\s*)/)?.[1].length ?? 0;
|
|
900
|
-
minIndent = Math.min(minIndent, indent);
|
|
901
|
-
}
|
|
902
|
-
if (minIndent === Infinity) minIndent = 0;
|
|
903
|
-
return `\`\`\`${lang}\n${(minIndent > 0 ? lines.map((line) => line.slice(minIndent)) : lines).join("\n")}\`\`\``;
|
|
904
|
-
});
|
|
905
|
-
return formatted;
|
|
906
|
-
}
|
|
907
975
|
async function buildPalette(ctx, binding, resolved, source) {
|
|
908
976
|
let palette = null;
|
|
909
977
|
if (binding.generateArtPalette) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vizejs/musea-mcp-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.286.0",
|
|
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,14 +42,15 @@
|
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"@modelcontextprotocol/sdk": "1.29.0",
|
|
45
|
-
"@vizejs/native": "0.
|
|
45
|
+
"@vizejs/native": "0.286.0",
|
|
46
|
+
"@vue/compiler-dom": "3.5.35",
|
|
47
|
+
"typescript": "6.0.3"
|
|
46
48
|
},
|
|
47
49
|
"devDependencies": {
|
|
48
50
|
"@tsdown/css": "0.22.0",
|
|
49
51
|
"@types/node": "25.9.2",
|
|
50
52
|
"tsdown": "0.22.0",
|
|
51
53
|
"tsx": "4.22.4",
|
|
52
|
-
"typescript": "6.0.3",
|
|
53
54
|
"vite": "npm:@voidzero-dev/vite-plus-core@0.1.21",
|
|
54
55
|
"vite-plus": "0.1.21"
|
|
55
56
|
},
|