@buoy-design/mcp 0.1.1 → 0.3.16
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/bin.js
CHANGED
|
@@ -57,7 +57,9 @@ function parseTokenFile(content) {
|
|
|
57
57
|
if ("tokens" in content) {
|
|
58
58
|
const tokenObj = content.tokens;
|
|
59
59
|
for (const [category, categoryTokens] of Object.entries(tokenObj)) {
|
|
60
|
-
for (const [name, tokenData] of Object.entries(
|
|
60
|
+
for (const [name, tokenData] of Object.entries(
|
|
61
|
+
categoryTokens
|
|
62
|
+
)) {
|
|
61
63
|
const data = tokenData;
|
|
62
64
|
tokens.push({
|
|
63
65
|
name,
|
|
@@ -74,7 +76,9 @@ function parseTokenFile(content) {
|
|
|
74
76
|
return tokens;
|
|
75
77
|
}
|
|
76
78
|
if (typeof content === "object") {
|
|
77
|
-
for (const [key, value] of Object.entries(
|
|
79
|
+
for (const [key, value] of Object.entries(
|
|
80
|
+
content
|
|
81
|
+
)) {
|
|
78
82
|
if (value && typeof value === "object" && "$value" in value) {
|
|
79
83
|
const v = value;
|
|
80
84
|
tokens.push({
|
|
@@ -122,7 +126,10 @@ async function loadComponents(cwd) {
|
|
|
122
126
|
} catch {
|
|
123
127
|
}
|
|
124
128
|
}
|
|
125
|
-
const skillInventory = join(
|
|
129
|
+
const skillInventory = join(
|
|
130
|
+
cwd,
|
|
131
|
+
".claude/skills/design-system/components/_inventory.md"
|
|
132
|
+
);
|
|
126
133
|
if (existsSync(skillInventory)) {
|
|
127
134
|
const content = readFileSync(skillInventory, "utf-8");
|
|
128
135
|
components.push(...parseInventoryMarkdown(content));
|
|
@@ -134,7 +141,7 @@ function parseInventoryMarkdown(content) {
|
|
|
134
141
|
const lines = content.split("\n");
|
|
135
142
|
for (const line of lines) {
|
|
136
143
|
const match = line.match(/^\|\s*`?(\w+)`?\s*\|([^|]*)\|([^|]*)\|/);
|
|
137
|
-
if (match && match[1] !== "Component") {
|
|
144
|
+
if (match && match[1] && match[2] && match[3] && match[1] !== "Component") {
|
|
138
145
|
components.push({
|
|
139
146
|
name: match[1],
|
|
140
147
|
framework: "react",
|
|
@@ -187,7 +194,9 @@ function detectPatterns(components) {
|
|
|
187
194
|
});
|
|
188
195
|
}
|
|
189
196
|
const modalComponents = components.filter(
|
|
190
|
-
(c) => ["Modal", "Dialog", "Drawer", "Sheet", "Popover"].some(
|
|
197
|
+
(c) => ["Modal", "Dialog", "Drawer", "Sheet", "Popover"].some(
|
|
198
|
+
(n) => c.name.includes(n)
|
|
199
|
+
)
|
|
191
200
|
);
|
|
192
201
|
if (modalComponents.length > 0) {
|
|
193
202
|
patterns.push({
|
|
@@ -502,6 +511,11 @@ function createServer(cwd = process.cwd()) {
|
|
|
502
511
|
const { name, arguments: args } = request.params;
|
|
503
512
|
switch (name) {
|
|
504
513
|
case "find_component": {
|
|
514
|
+
if (!args || typeof args !== "object" || !("useCase" in args) || typeof args.useCase !== "string") {
|
|
515
|
+
throw new Error(
|
|
516
|
+
'Invalid find_component request: missing required "useCase" parameter'
|
|
517
|
+
);
|
|
518
|
+
}
|
|
505
519
|
const { useCase, constraints } = args;
|
|
506
520
|
const result = handleFindComponent(ctx, useCase, constraints);
|
|
507
521
|
return {
|
|
@@ -514,6 +528,11 @@ function createServer(cwd = process.cwd()) {
|
|
|
514
528
|
};
|
|
515
529
|
}
|
|
516
530
|
case "validate_code": {
|
|
531
|
+
if (!args || typeof args !== "object" || !("code" in args) || typeof args.code !== "string") {
|
|
532
|
+
throw new Error(
|
|
533
|
+
'Invalid validate_code request: missing required "code" parameter'
|
|
534
|
+
);
|
|
535
|
+
}
|
|
517
536
|
const { code, filePath } = args;
|
|
518
537
|
const result = handleValidateCode(ctx, code, filePath);
|
|
519
538
|
return {
|
|
@@ -526,6 +545,11 @@ function createServer(cwd = process.cwd()) {
|
|
|
526
545
|
};
|
|
527
546
|
}
|
|
528
547
|
case "resolve_token": {
|
|
548
|
+
if (!args || typeof args !== "object" || !("value" in args) || typeof args.value !== "string") {
|
|
549
|
+
throw new Error(
|
|
550
|
+
'Invalid resolve_token request: missing required "value" parameter'
|
|
551
|
+
);
|
|
552
|
+
}
|
|
529
553
|
const { value, context: tokenContext } = args;
|
|
530
554
|
const result = handleResolveToken(ctx, value, tokenContext);
|
|
531
555
|
return {
|
|
@@ -565,8 +589,14 @@ function handleFindComponent(ctx, useCase, constraints) {
|
|
|
565
589
|
reasoning: `No existing component found for "${useCase}".`,
|
|
566
590
|
guidance: {
|
|
567
591
|
suggestion: "Consider creating a new component or composing existing ones.",
|
|
568
|
-
availableComponents: availableComponents.length > 0 ? `Available components include: ${availableComponents.join(", ")}` : "No components in inventory. Run `buoy
|
|
569
|
-
nextSteps: ctx.components.length === 0 ? [
|
|
592
|
+
availableComponents: availableComponents.length > 0 ? `Available components include: ${availableComponents.join(", ")}` : "No components in inventory. Run `buoy sweep` to discover components.",
|
|
593
|
+
nextSteps: ctx.components.length === 0 ? [
|
|
594
|
+
"Run `buoy sweep` to discover components",
|
|
595
|
+
"Run `buoy skill spill` to populate component inventory"
|
|
596
|
+
] : [
|
|
597
|
+
"Check component naming - try broader search terms",
|
|
598
|
+
"View full inventory with components://inventory"
|
|
599
|
+
]
|
|
570
600
|
}
|
|
571
601
|
};
|
|
572
602
|
}
|
|
@@ -575,6 +605,13 @@ function handleFindComponent(ctx, useCase, constraints) {
|
|
|
575
605
|
score: calculateMatchScore(c, useCase, constraints)
|
|
576
606
|
}));
|
|
577
607
|
scored.sort((a, b) => b.score - a.score);
|
|
608
|
+
if (scored.length === 0) {
|
|
609
|
+
return {
|
|
610
|
+
recommended: null,
|
|
611
|
+
alternatives: [],
|
|
612
|
+
reasoning: "No matches found"
|
|
613
|
+
};
|
|
614
|
+
}
|
|
578
615
|
const recommended = scored[0].component;
|
|
579
616
|
const alternatives = scored.slice(1, 4).map((s) => s.component);
|
|
580
617
|
return {
|
|
@@ -610,7 +647,9 @@ function handleValidateCode(ctx, code, _filePath) {
|
|
|
610
647
|
const hexColors = code.match(/#[0-9A-Fa-f]{3,8}\b/g) || [];
|
|
611
648
|
const rgbColors = code.match(/rgb\([^)]+\)/g) || [];
|
|
612
649
|
for (const color of [...hexColors, ...rgbColors]) {
|
|
613
|
-
const isToken = ctx.tokens.some(
|
|
650
|
+
const isToken = ctx.tokens.some(
|
|
651
|
+
(t) => t.value.toLowerCase() === color.toLowerCase()
|
|
652
|
+
);
|
|
614
653
|
if (!isToken) {
|
|
615
654
|
const match = findClosestToken(ctx, color, "color");
|
|
616
655
|
issues.push({
|
|
@@ -668,7 +707,7 @@ function handleValidateCode(ctx, code, _filePath) {
|
|
|
668
707
|
checksPerformed,
|
|
669
708
|
tokensAvailable: ctx.tokens.length,
|
|
670
709
|
componentsKnown: ctx.components.length,
|
|
671
|
-
guidance: issues.length === 0 ? "Code follows design system rules. Run `buoy check` for comprehensive analysis." : "Fix issues above, then re-validate. Run `buoy fix --dry-run` for automated suggestions."
|
|
710
|
+
guidance: issues.length === 0 ? "Code follows design system rules. Run `buoy drift check` for comprehensive analysis." : "Fix issues above, then re-validate. Run `buoy drift fix --dry-run` for automated suggestions."
|
|
672
711
|
}
|
|
673
712
|
};
|
|
674
713
|
}
|
|
@@ -701,9 +740,9 @@ function handleResolveToken(ctx, value, tokenContext) {
|
|
|
701
740
|
tokenCount: ctx.tokens.length,
|
|
702
741
|
availableCategories: availableCategories.length > 0 ? availableCategories : ["No tokens loaded"],
|
|
703
742
|
nextSteps: ctx.tokens.length === 0 ? [
|
|
704
|
-
"Run `buoy tokens` to extract tokens from hardcoded values",
|
|
743
|
+
"Run `buoy dock tokens` to extract tokens from hardcoded values",
|
|
705
744
|
"Add a design-tokens.json file",
|
|
706
|
-
"Run `buoy
|
|
745
|
+
"Run `buoy sweep` to discover tokens from CSS"
|
|
707
746
|
] : [
|
|
708
747
|
"Consider adding a new token for this value",
|
|
709
748
|
"Use the closest available value from the scale",
|
|
@@ -740,7 +779,8 @@ function handleSuggestFix(ctx, type, value, location) {
|
|
|
740
779
|
let category;
|
|
741
780
|
if (type.includes("color")) category = "color";
|
|
742
781
|
else if (type.includes("spacing")) category = "spacing";
|
|
743
|
-
else if (type.includes("font") || type.includes("typography"))
|
|
782
|
+
else if (type.includes("font") || type.includes("typography"))
|
|
783
|
+
category = "typography";
|
|
744
784
|
const closest = findClosestToken(ctx, value, category);
|
|
745
785
|
if (!closest) {
|
|
746
786
|
return {
|
|
@@ -751,12 +791,12 @@ function handleSuggestFix(ctx, type, value, location) {
|
|
|
751
791
|
tokenCount: ctx.tokens.length,
|
|
752
792
|
categorySearched: category || "all",
|
|
753
793
|
nextSteps: ctx.tokens.length === 0 ? [
|
|
754
|
-
"Run `buoy tokens` to extract tokens from codebase",
|
|
794
|
+
"Run `buoy dock tokens` to extract tokens from codebase",
|
|
755
795
|
"Add a design-tokens.json file",
|
|
756
796
|
"Manual fix: replace with CSS variable or theme token"
|
|
757
797
|
] : [
|
|
758
798
|
"Value may be intentionally one-off (consider documenting)",
|
|
759
|
-
"Run `buoy fix --confidence low` to see all suggestions",
|
|
799
|
+
"Run `buoy drift fix --confidence low` to see all suggestions",
|
|
760
800
|
"Create a new token for this value if it will be reused"
|
|
761
801
|
]
|
|
762
802
|
}
|
|
@@ -793,4 +833,4 @@ export {
|
|
|
793
833
|
createServer,
|
|
794
834
|
startServer
|
|
795
835
|
};
|
|
796
|
-
//# sourceMappingURL=chunk-
|
|
836
|
+
//# sourceMappingURL=chunk-ATK6XDWX.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/context-loader.ts","../src/server.ts"],"sourcesContent":["/**\n * Context loader - gathers design system information from the codebase\n */\n\nimport { readFileSync, existsSync } from \"fs\";\nimport { join } from \"path\";\nimport type {\n DesignSystemContext,\n TokenWithIntent,\n ComponentSummary,\n Pattern,\n AntiPattern,\n} from \"./types.js\";\n\n/**\n * Load design system context from the project\n */\nexport async function loadDesignSystemContext(\n cwd: string,\n): Promise<DesignSystemContext> {\n const projectName = getProjectName(cwd);\n const tokens = await loadTokens(cwd);\n const components = await loadComponents(cwd);\n const patterns = detectPatterns(components);\n const antiPatterns = getAntiPatterns();\n\n return {\n tokens,\n components,\n patterns,\n antiPatterns,\n projectName,\n lastUpdated: new Date().toISOString(),\n };\n}\n\n/**\n * Get project name from package.json\n */\nfunction getProjectName(cwd: string): string {\n const pkgPath = join(cwd, \"package.json\");\n if (existsSync(pkgPath)) {\n try {\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf-8\"));\n return pkg.name || \"Design System\";\n } catch {\n // Ignore parse errors\n }\n }\n return \"Design System\";\n}\n\n/**\n * Load tokens from various sources\n */\nasync function loadTokens(cwd: string): Promise<TokenWithIntent[]> {\n const tokens: TokenWithIntent[] = [];\n\n // Try to load from exported tokens file\n const tokenPaths = [\n \"design-tokens.json\",\n \"tokens.json\",\n \".buoy/tokens.json\",\n \"tokens-ai-context.json\",\n ];\n\n for (const tokenPath of tokenPaths) {\n const fullPath = join(cwd, tokenPath);\n if (existsSync(fullPath)) {\n try {\n const content = JSON.parse(readFileSync(fullPath, \"utf-8\"));\n tokens.push(...parseTokenFile(content));\n break;\n } catch {\n // Continue to next path\n }\n }\n }\n\n // If no token file found, try to scan CSS files\n if (tokens.length === 0) {\n tokens.push(...(await scanCssTokens(cwd)));\n }\n\n return tokens;\n}\n\n/**\n * Parse token file (supports multiple formats)\n */\nfunction parseTokenFile(content: unknown): TokenWithIntent[] {\n const tokens: TokenWithIntent[] = [];\n\n if (!content || typeof content !== \"object\") return tokens;\n\n // AI context format\n if (\"tokens\" in (content as Record<string, unknown>)) {\n const tokenObj = (\n content as { tokens: Record<string, Record<string, unknown>> }\n ).tokens;\n for (const [category, categoryTokens] of Object.entries(tokenObj)) {\n for (const [name, tokenData] of Object.entries(\n categoryTokens as Record<string, unknown>,\n )) {\n const data = tokenData as Record<string, unknown>;\n tokens.push({\n name,\n value: String(data.$value || data.value || \"\"),\n category: category as TokenWithIntent[\"category\"],\n intent: data.$intent as TokenWithIntent[\"intent\"],\n usage: data.$usage as string | undefined,\n avoid: data.$avoid as string | undefined,\n examples: data.$examples as string[] | undefined,\n deprecated: data.$deprecated as boolean | undefined,\n });\n }\n }\n return tokens;\n }\n\n // W3C DTCG format\n if (typeof content === \"object\") {\n for (const [key, value] of Object.entries(\n content as Record<string, unknown>,\n )) {\n if (value && typeof value === \"object\" && \"$value\" in value) {\n const v = value as Record<string, unknown>;\n tokens.push({\n name: key,\n value: String(v.$value),\n category: inferCategory(key, String(v.$value)),\n usage: v.$description as string | undefined,\n });\n }\n }\n }\n\n return tokens;\n}\n\n/**\n * Infer token category from name and value\n */\nfunction inferCategory(\n name: string,\n value: string,\n): TokenWithIntent[\"category\"] {\n const lower = name.toLowerCase();\n if (\n lower.includes(\"color\") ||\n value.startsWith(\"#\") ||\n value.startsWith(\"rgb\")\n ) {\n return \"color\";\n }\n if (\n lower.includes(\"spacing\") ||\n lower.includes(\"space\") ||\n lower.includes(\"gap\")\n ) {\n return \"spacing\";\n }\n if (\n lower.includes(\"font\") ||\n lower.includes(\"text\") ||\n lower.includes(\"typography\")\n ) {\n return \"typography\";\n }\n if (lower.includes(\"radius\") || lower.includes(\"rounded\")) {\n return \"radius\";\n }\n if (lower.includes(\"shadow\")) {\n return \"shadow\";\n }\n return \"color\"; // Default\n}\n\n/**\n * Scan CSS files for tokens (fallback)\n */\nasync function scanCssTokens(_cwd: string): Promise<TokenWithIntent[]> {\n // This would scan CSS files for custom properties\n // Simplified for now - real implementation would use the scanners package\n return [];\n}\n\n/**\n * Load components from the codebase\n */\nasync function loadComponents(cwd: string): Promise<ComponentSummary[]> {\n const components: ComponentSummary[] = [];\n\n // Try to load from cached component inventory\n const inventoryPath = join(cwd, \".buoy/components.json\");\n if (existsSync(inventoryPath)) {\n try {\n const content = JSON.parse(readFileSync(inventoryPath, \"utf-8\"));\n if (Array.isArray(content)) {\n return content as ComponentSummary[];\n }\n } catch {\n // Continue to scanning\n }\n }\n\n // Check for skill-generated inventory\n const skillInventory = join(\n cwd,\n \".claude/skills/design-system/components/_inventory.md\",\n );\n if (existsSync(skillInventory)) {\n const content = readFileSync(skillInventory, \"utf-8\");\n components.push(...parseInventoryMarkdown(content));\n }\n\n return components;\n}\n\n/**\n * Parse component inventory from markdown\n */\nfunction parseInventoryMarkdown(content: string): ComponentSummary[] {\n const components: ComponentSummary[] = [];\n const lines = content.split(\"\\n\");\n\n for (const line of lines) {\n // Parse table rows: | ComponentName | Description | Props |\n const match = line.match(/^\\|\\s*`?(\\w+)`?\\s*\\|([^|]*)\\|([^|]*)\\|/);\n if (match && match[1] && match[2] && match[3] && match[1] !== \"Component\") {\n components.push({\n name: match[1],\n framework: \"react\", // Default assumption\n props: match[3]\n .split(\",\")\n .map((p) => p.trim())\n .filter(Boolean),\n description: match[2].trim(),\n path: \"\",\n });\n }\n }\n\n return components;\n}\n\n/**\n * Detect patterns from component usage\n */\nfunction detectPatterns(components: ComponentSummary[]): Pattern[] {\n const patterns: Pattern[] = [];\n\n // Form pattern\n const formComponents = components.filter((c) =>\n [\"Input\", \"Select\", \"Checkbox\", \"Radio\", \"Form\", \"Label\"].some((n) =>\n c.name.includes(n),\n ),\n );\n if (formComponents.length > 0) {\n patterns.push({\n name: \"Forms\",\n description: \"Form input and validation patterns\",\n components: formComponents.map((c) => c.name),\n usage:\n \"Use for user input collection with consistent styling and validation\",\n });\n }\n\n // Navigation pattern\n const navComponents = components.filter((c) =>\n [\"Nav\", \"Menu\", \"Sidebar\", \"Header\", \"Footer\", \"Tab\", \"Breadcrumb\"].some(\n (n) => c.name.includes(n),\n ),\n );\n if (navComponents.length > 0) {\n patterns.push({\n name: \"Navigation\",\n description: \"Navigation and menu patterns\",\n components: navComponents.map((c) => c.name),\n usage: \"Use for site navigation with consistent structure\",\n });\n }\n\n // Card pattern\n const cardComponents = components.filter((c) =>\n [\"Card\", \"Panel\", \"Box\", \"Container\"].some((n) => c.name.includes(n)),\n );\n if (cardComponents.length > 0) {\n patterns.push({\n name: \"Cards\",\n description: \"Content container patterns\",\n components: cardComponents.map((c) => c.name),\n usage: \"Use for grouping related content\",\n });\n }\n\n // Modal pattern\n const modalComponents = components.filter((c) =>\n [\"Modal\", \"Dialog\", \"Drawer\", \"Sheet\", \"Popover\"].some((n) =>\n c.name.includes(n),\n ),\n );\n if (modalComponents.length > 0) {\n patterns.push({\n name: \"Modals\",\n description: \"Overlay and dialog patterns\",\n components: modalComponents.map((c) => c.name),\n usage: \"Use for focused interactions that require attention\",\n });\n }\n\n return patterns;\n}\n\n/**\n * Get common anti-patterns to avoid\n */\nfunction getAntiPatterns(): AntiPattern[] {\n return [\n {\n name: \"Hardcoded Colors\",\n description: \"Using hex/rgb values directly instead of design tokens\",\n avoid: 'style={{ color: \"#2563EB\" }} or color: #2563EB',\n instead:\n 'Use color tokens: className=\"text-primary\" or color={tokens.primary}',\n severity: \"warning\",\n },\n {\n name: \"Arbitrary Spacing\",\n description: \"Using pixel values not in the spacing scale\",\n avoid: \"padding: 13px or p-[13px]\",\n instead: \"Use spacing scale: p-4 (16px) or p-3 (12px)\",\n severity: \"warning\",\n },\n {\n name: \"Inline onClick Handlers\",\n description: \"Using div/span with onClick instead of semantic elements\",\n avoid: \"<div onClick={handleClick}>Click me</div>\",\n instead: \"Use <Button> or <button> for clickable elements\",\n severity: \"critical\",\n },\n {\n name: \"Missing Alt Text\",\n description: \"Images without alt attributes\",\n avoid: '<img src=\"logo.png\" />',\n instead: '<img src=\"logo.png\" alt=\"Company logo\" />',\n severity: \"critical\",\n },\n {\n name: \"Custom Component Creation\",\n description: \"Creating new components when existing ones would work\",\n avoid: \"Creating MyButton.tsx when Button component exists\",\n instead: \"Check component inventory first, extend existing if needed\",\n severity: \"info\",\n },\n {\n name: \"Inconsistent Naming\",\n description: \"Component names that dont follow project conventions\",\n avoid: \"my-component.tsx or MyComponent.jsx\",\n instead: \"Follow project naming: ComponentName.tsx\",\n severity: \"info\",\n },\n ];\n}\n\n/**\n * Get tokens by category\n */\nexport function getTokensByCategory(\n context: DesignSystemContext,\n category: string,\n): TokenWithIntent[] {\n return context.tokens.filter((t) => t.category === category);\n}\n\n/**\n * Find component by name\n */\nexport function findComponent(\n context: DesignSystemContext,\n name: string,\n): ComponentSummary | undefined {\n return context.components.find(\n (c) => c.name.toLowerCase() === name.toLowerCase(),\n );\n}\n\n/**\n * Search components by use case\n */\nexport function searchComponents(\n context: DesignSystemContext,\n useCase: string,\n): ComponentSummary[] {\n const keywords = useCase.toLowerCase().split(/\\s+/);\n\n return context.components.filter((c) => {\n const searchText =\n `${c.name} ${c.description || \"\"} ${c.props.join(\" \")}`.toLowerCase();\n return keywords.some((kw) => searchText.includes(kw));\n });\n}\n","/**\n * Buoy MCP Server\n *\n * Provides design system context to AI agents via Model Context Protocol.\n *\n * Resources:\n * - tokens://all - All design tokens\n * - tokens://{category} - Tokens by category (color, spacing, typography)\n * - components://inventory - Component catalog\n * - components://{name} - Component details\n * - patterns://all - Pattern library\n * - antipatterns://all - Anti-patterns to avoid\n *\n * Tools:\n * - find_component - Find best component for a use case\n * - validate_code - Check code against design system\n * - resolve_token - Find token for a hardcoded value\n * - suggest_fix - Get fix suggestion for drift\n */\n\nimport { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport {\n CallToolRequestSchema,\n ListResourcesRequestSchema,\n ListToolsRequestSchema,\n ReadResourceRequestSchema,\n} from \"@modelcontextprotocol/sdk/types.js\";\n\nimport {\n loadDesignSystemContext,\n getTokensByCategory,\n findComponent,\n searchComponents,\n} from \"./context-loader.js\";\nimport type {\n DesignSystemContext,\n FindComponentRequest,\n FindComponentResponse,\n ValidateCodeRequest,\n ValidateCodeResponse,\n ResolveTokenRequest,\n ResolveTokenResponse,\n TokenWithIntent,\n} from \"./types.js\";\n\n/**\n * Create and configure the Buoy MCP server\n */\nexport function createServer(cwd: string = process.cwd()): Server {\n const server = new Server(\n {\n name: \"buoy-design-system\",\n version: \"0.1.0\",\n },\n {\n capabilities: {\n resources: {},\n tools: {},\n },\n },\n );\n\n let context: DesignSystemContext | null = null;\n\n /**\n * Load context on demand\n */\n async function getContext(): Promise<DesignSystemContext> {\n if (!context) {\n context = await loadDesignSystemContext(cwd);\n }\n return context;\n }\n\n /**\n * List available resources\n */\n server.setRequestHandler(ListResourcesRequestSchema, async () => {\n return {\n resources: [\n {\n uri: \"tokens://all\",\n name: \"All Design Tokens\",\n description: \"Complete list of design tokens with usage guidance\",\n mimeType: \"application/json\",\n },\n {\n uri: \"tokens://color\",\n name: \"Color Tokens\",\n description: \"Color tokens with semantic meaning\",\n mimeType: \"application/json\",\n },\n {\n uri: \"tokens://spacing\",\n name: \"Spacing Tokens\",\n description: \"Spacing scale for consistent layouts\",\n mimeType: \"application/json\",\n },\n {\n uri: \"tokens://typography\",\n name: \"Typography Tokens\",\n description: \"Font sizes, weights, and families\",\n mimeType: \"application/json\",\n },\n {\n uri: \"components://inventory\",\n name: \"Component Inventory\",\n description: \"All available UI components\",\n mimeType: \"application/json\",\n },\n {\n uri: \"patterns://all\",\n name: \"Pattern Library\",\n description: \"Common UI patterns and compositions\",\n mimeType: \"application/json\",\n },\n {\n uri: \"antipatterns://all\",\n name: \"Anti-Patterns\",\n description: \"Things to avoid in this design system\",\n mimeType: \"application/json\",\n },\n ],\n };\n });\n\n /**\n * Read resource content\n */\n server.setRequestHandler(ReadResourceRequestSchema, async (request) => {\n const ctx = await getContext();\n const uri = request.params.uri;\n\n // Tokens resources\n if (uri === \"tokens://all\") {\n return {\n contents: [\n {\n uri,\n mimeType: \"application/json\",\n text: JSON.stringify(ctx.tokens, null, 2),\n },\n ],\n };\n }\n\n if (uri.startsWith(\"tokens://\")) {\n const category = uri.replace(\"tokens://\", \"\");\n const tokens = getTokensByCategory(ctx, category);\n return {\n contents: [\n {\n uri,\n mimeType: \"application/json\",\n text: JSON.stringify(tokens, null, 2),\n },\n ],\n };\n }\n\n // Components resources\n if (uri === \"components://inventory\") {\n return {\n contents: [\n {\n uri,\n mimeType: \"application/json\",\n text: JSON.stringify(ctx.components, null, 2),\n },\n ],\n };\n }\n\n if (uri.startsWith(\"components://\")) {\n const name = uri.replace(\"components://\", \"\");\n const component = findComponent(ctx, name);\n return {\n contents: [\n {\n uri,\n mimeType: \"application/json\",\n text: component\n ? JSON.stringify(component, null, 2)\n : JSON.stringify({ error: `Component \"${name}\" not found` }),\n },\n ],\n };\n }\n\n // Patterns resources\n if (uri === \"patterns://all\") {\n return {\n contents: [\n {\n uri,\n mimeType: \"application/json\",\n text: JSON.stringify(ctx.patterns, null, 2),\n },\n ],\n };\n }\n\n // Anti-patterns resources\n if (uri === \"antipatterns://all\") {\n return {\n contents: [\n {\n uri,\n mimeType: \"application/json\",\n text: JSON.stringify(ctx.antiPatterns, null, 2),\n },\n ],\n };\n }\n\n throw new Error(`Unknown resource: ${uri}`);\n });\n\n /**\n * List available tools\n */\n server.setRequestHandler(ListToolsRequestSchema, async () => {\n return {\n tools: [\n {\n name: \"find_component\",\n description:\n \"Find the best component for a use case. Returns recommended component with alternatives.\",\n inputSchema: {\n type: \"object\",\n properties: {\n useCase: {\n type: \"string\",\n description:\n 'Description of what you want to build (e.g., \"submit button\", \"form input\")',\n },\n constraints: {\n type: \"array\",\n items: { type: \"string\" },\n description:\n 'Optional constraints (e.g., \"accessible\", \"responsive\")',\n },\n },\n required: [\"useCase\"],\n },\n },\n {\n name: \"validate_code\",\n description:\n \"Validate code against design system rules. Returns issues and suggestions.\",\n inputSchema: {\n type: \"object\",\n properties: {\n code: {\n type: \"string\",\n description: \"The code to validate\",\n },\n filePath: {\n type: \"string\",\n description: \"Optional file path for context\",\n },\n },\n required: [\"code\"],\n },\n },\n {\n name: \"resolve_token\",\n description:\n \"Find the design token that matches a hardcoded value. Returns exact or closest match.\",\n inputSchema: {\n type: \"object\",\n properties: {\n value: {\n type: \"string\",\n description: 'The hardcoded value (e.g., \"#2563EB\", \"16px\")',\n },\n context: {\n type: \"string\",\n enum: [\"color\", \"spacing\", \"typography\"],\n description: \"Optional hint about value type\",\n },\n },\n required: [\"value\"],\n },\n },\n {\n name: \"suggest_fix\",\n description: \"Get a fix suggestion for a design system violation.\",\n inputSchema: {\n type: \"object\",\n properties: {\n type: {\n type: \"string\",\n description:\n 'Type of violation (e.g., \"hardcoded-color\", \"arbitrary-spacing\")',\n },\n value: {\n type: \"string\",\n description: \"The problematic value\",\n },\n location: {\n type: \"string\",\n description: \"Where the violation occurs (file:line)\",\n },\n },\n required: [\"type\", \"value\"],\n },\n },\n ],\n };\n });\n\n /**\n * Handle tool calls\n */\n server.setRequestHandler(CallToolRequestSchema, async (request) => {\n const ctx = await getContext();\n const { name, arguments: args } = request.params;\n\n switch (name) {\n case \"find_component\": {\n if (\n !args ||\n typeof args !== \"object\" ||\n !(\"useCase\" in args) ||\n typeof args.useCase !== \"string\"\n ) {\n throw new Error(\n 'Invalid find_component request: missing required \"useCase\" parameter',\n );\n }\n const { useCase, constraints } =\n args as unknown as FindComponentRequest;\n const result = handleFindComponent(ctx, useCase, constraints);\n return {\n content: [\n {\n type: \"text\",\n text: JSON.stringify(result, null, 2),\n },\n ],\n };\n }\n\n case \"validate_code\": {\n if (\n !args ||\n typeof args !== \"object\" ||\n !(\"code\" in args) ||\n typeof args.code !== \"string\"\n ) {\n throw new Error(\n 'Invalid validate_code request: missing required \"code\" parameter',\n );\n }\n const { code, filePath } = args as unknown as ValidateCodeRequest;\n const result = handleValidateCode(ctx, code, filePath);\n return {\n content: [\n {\n type: \"text\",\n text: JSON.stringify(result, null, 2),\n },\n ],\n };\n }\n\n case \"resolve_token\": {\n if (\n !args ||\n typeof args !== \"object\" ||\n !(\"value\" in args) ||\n typeof args.value !== \"string\"\n ) {\n throw new Error(\n 'Invalid resolve_token request: missing required \"value\" parameter',\n );\n }\n const { value, context: tokenContext } =\n args as unknown as ResolveTokenRequest;\n const result = handleResolveToken(ctx, value, tokenContext);\n return {\n content: [\n {\n type: \"text\",\n text: JSON.stringify(result, null, 2),\n },\n ],\n };\n }\n\n case \"suggest_fix\": {\n const { type, value, location } = args as {\n type: string;\n value: string;\n location?: string;\n };\n const result = handleSuggestFix(ctx, type, value, location);\n return {\n content: [\n {\n type: \"text\",\n text: JSON.stringify(result, null, 2),\n },\n ],\n };\n }\n\n default:\n throw new Error(`Unknown tool: ${name}`);\n }\n });\n\n return server;\n}\n\n/**\n * Find component handler\n */\nfunction handleFindComponent(\n ctx: DesignSystemContext,\n useCase: string,\n constraints?: string[],\n): FindComponentResponse {\n const matches = searchComponents(ctx, useCase);\n\n if (matches.length === 0) {\n // No Dead Ends: Provide guidance when no components found\n const availableComponents = ctx.components.slice(0, 5).map((c) => c.name);\n return {\n recommended: null,\n alternatives: [],\n reasoning: `No existing component found for \"${useCase}\".`,\n guidance: {\n suggestion:\n \"Consider creating a new component or composing existing ones.\",\n availableComponents:\n availableComponents.length > 0\n ? `Available components include: ${availableComponents.join(\", \")}`\n : \"No components in inventory. Run `buoy sweep` to discover components.\",\n nextSteps:\n ctx.components.length === 0\n ? [\n \"Run `buoy sweep` to discover components\",\n \"Run `buoy skill spill` to populate component inventory\",\n ]\n : [\n \"Check component naming - try broader search terms\",\n \"View full inventory with components://inventory\",\n ],\n },\n };\n }\n\n // Score matches (simple scoring for now)\n const scored = matches.map((c) => ({\n component: c,\n score: calculateMatchScore(c, useCase, constraints),\n }));\n\n scored.sort((a, b) => b.score - a.score);\n\n if (scored.length === 0) {\n // This should never happen due to early return above, but just in case\n return {\n recommended: null,\n alternatives: [],\n reasoning: \"No matches found\",\n };\n }\n\n const recommended = scored[0]!.component;\n const alternatives = scored.slice(1, 4).map((s) => s.component);\n\n return {\n recommended,\n alternatives,\n reasoning: `\"${recommended.name}\" is the best match for \"${useCase}\". ${\n recommended.description || \"\"\n }`,\n };\n}\n\n/**\n * Calculate match score for a component\n */\nfunction calculateMatchScore(\n component: { name: string; description?: string; props: string[] },\n useCase: string,\n constraints?: string[],\n): number {\n let score = 0;\n const searchText =\n `${component.name} ${component.description || \"\"} ${component.props.join(\" \")}`.toLowerCase();\n const useCaseLower = useCase.toLowerCase();\n\n // Name match\n if (component.name.toLowerCase().includes(useCaseLower)) {\n score += 10;\n }\n\n // Keyword matches\n const keywords = useCaseLower.split(/\\s+/);\n for (const keyword of keywords) {\n if (searchText.includes(keyword)) {\n score += 2;\n }\n }\n\n // Constraint matches\n if (constraints) {\n for (const constraint of constraints) {\n if (searchText.includes(constraint.toLowerCase())) {\n score += 3;\n }\n }\n }\n\n return score;\n}\n\n/**\n * Validate code handler\n */\nfunction handleValidateCode(\n ctx: DesignSystemContext,\n code: string,\n _filePath?: string,\n): ValidateCodeResponse {\n const issues: ValidateCodeResponse[\"issues\"] = [];\n\n // Check for hardcoded colors\n const hexColors = code.match(/#[0-9A-Fa-f]{3,8}\\b/g) || [];\n const rgbColors = code.match(/rgb\\([^)]+\\)/g) || [];\n\n for (const color of [...hexColors, ...rgbColors]) {\n // Check if it's a token value\n const isToken = ctx.tokens.some(\n (t) => t.value.toLowerCase() === color.toLowerCase(),\n );\n if (!isToken) {\n const match = findClosestToken(ctx, color, \"color\");\n issues.push({\n type: \"hardcoded-color\",\n severity: \"warning\",\n message: `Hardcoded color \"${color}\" - use design token instead`,\n suggestion: match\n ? `Use token: ${match.name} (${match.value})`\n : undefined,\n });\n }\n }\n\n // Check for arbitrary spacing\n const arbitrarySpacing = code.match(/\\b\\d+px\\b/g) || [];\n const spacingScale = ctx.tokens\n .filter((t) => t.category === \"spacing\")\n .map((t) => t.value);\n\n for (const spacing of arbitrarySpacing) {\n if (!spacingScale.includes(spacing)) {\n const match = findClosestToken(ctx, spacing, \"spacing\");\n issues.push({\n type: \"arbitrary-spacing\",\n severity: \"warning\",\n message: `Arbitrary spacing \"${spacing}\" - use spacing scale`,\n suggestion: match\n ? `Use token: ${match.name} (${match.value})`\n : undefined,\n });\n }\n }\n\n // Check for div onClick (accessibility anti-pattern)\n if (/<div[^>]*onClick/i.test(code)) {\n issues.push({\n type: \"accessibility\",\n severity: \"critical\",\n message: \"Using div with onClick - use button or Button component\",\n suggestion: \"Replace <div onClick> with <Button onClick>\",\n });\n }\n\n // Check for img without alt\n if (/<img[^>]*(?!alt)[^>]*>/i.test(code) && !/<img[^>]*alt=/i.test(code)) {\n issues.push({\n type: \"accessibility\",\n severity: \"critical\",\n message: \"Image missing alt attribute\",\n suggestion: 'Add alt=\"description\" to img element',\n });\n }\n\n // No Dead Ends: Provide context about what was checked\n const checksPerformed = [\n \"Hardcoded colors\",\n \"Arbitrary spacing values\",\n \"Accessibility anti-patterns (div onClick, img alt)\",\n ];\n\n return {\n valid: issues.length === 0,\n issues,\n summary: {\n total: issues.length,\n critical: issues.filter((i) => i.severity === \"critical\").length,\n warning: issues.filter((i) => i.severity === \"warning\").length,\n info: issues.filter((i) => i.severity === \"info\").length,\n },\n context: {\n checksPerformed,\n tokensAvailable: ctx.tokens.length,\n componentsKnown: ctx.components.length,\n guidance:\n issues.length === 0\n ? \"Code follows design system rules. Run `buoy drift check` for comprehensive analysis.\"\n : \"Fix issues above, then re-validate. Run `buoy drift fix --dry-run` for automated suggestions.\",\n },\n };\n}\n\n/**\n * Resolve token handler\n */\nfunction handleResolveToken(\n ctx: DesignSystemContext,\n value: string,\n tokenContext?: \"color\" | \"spacing\" | \"typography\",\n): ResolveTokenResponse {\n // Filter tokens by context if provided\n const candidates = tokenContext\n ? ctx.tokens.filter((t) => t.category === tokenContext)\n : ctx.tokens;\n\n // Look for exact match\n const exactMatch = candidates.find(\n (t) => t.value.toLowerCase() === value.toLowerCase(),\n );\n\n if (exactMatch) {\n return {\n exactMatch,\n closestMatches: [],\n suggestion: `Use token: ${exactMatch.name}`,\n };\n }\n\n // Find closest matches\n const closest = findClosestToken(ctx, value, tokenContext);\n\n if (closest) {\n return {\n exactMatch: null,\n closestMatches: [{ token: closest, similarity: 0.8 }],\n suggestion: `Closest token: ${closest.name} (${closest.value})`,\n };\n }\n\n // No Dead Ends: Explain why no match and suggest next steps\n const availableCategories = [...new Set(ctx.tokens.map((t) => t.category))];\n return {\n exactMatch: null,\n closestMatches: [],\n suggestion: `No matching token found for \"${value}\".`,\n guidance: {\n tokenCount: ctx.tokens.length,\n availableCategories:\n availableCategories.length > 0\n ? availableCategories\n : [\"No tokens loaded\"],\n nextSteps:\n ctx.tokens.length === 0\n ? [\n \"Run `buoy dock tokens` to extract tokens from hardcoded values\",\n \"Add a design-tokens.json file\",\n \"Run `buoy sweep` to discover tokens from CSS\",\n ]\n : [\n \"Consider adding a new token for this value\",\n \"Use the closest available value from the scale\",\n `View available tokens: tokens://${tokenContext || \"all\"}`,\n ],\n },\n };\n}\n\n/**\n * Find closest matching token\n */\nfunction findClosestToken(\n ctx: DesignSystemContext,\n value: string,\n category?: string,\n): TokenWithIntent | null {\n const candidates = category\n ? ctx.tokens.filter((t) => t.category === category)\n : ctx.tokens;\n\n if (candidates.length === 0) return null;\n\n // For colors, try to find similar hue\n if (value.startsWith(\"#\") || value.startsWith(\"rgb\")) {\n return candidates[0]!; // We know candidates is not empty\n }\n\n // For spacing, find closest numeric value\n const numericValue = parseFloat(value);\n if (!isNaN(numericValue)) {\n let closest = candidates[0]!;\n let closestDiff = Infinity;\n\n for (const token of candidates) {\n const tokenValue = parseFloat(token.value);\n if (!isNaN(tokenValue)) {\n const diff = Math.abs(tokenValue - numericValue);\n if (diff < closestDiff) {\n closestDiff = diff;\n closest = token;\n }\n }\n }\n\n return closest;\n }\n\n return candidates[0]!;\n}\n\n/**\n * Suggest fix handler\n */\nfunction handleSuggestFix(\n ctx: DesignSystemContext,\n type: string,\n value: string,\n location?: string,\n) {\n // Determine category from type\n let category: \"color\" | \"spacing\" | \"typography\" | undefined;\n if (type.includes(\"color\")) category = \"color\";\n else if (type.includes(\"spacing\")) category = \"spacing\";\n else if (type.includes(\"font\") || type.includes(\"typography\"))\n category = \"typography\";\n\n const closest = findClosestToken(ctx, value, category);\n\n if (!closest) {\n // No Dead Ends: Explain why no fix and suggest next steps\n return {\n fix: null,\n explanation: `No suitable token found for \"${value}\"`,\n alternatives: [],\n guidance: {\n tokenCount: ctx.tokens.length,\n categorySearched: category || \"all\",\n nextSteps:\n ctx.tokens.length === 0\n ? [\n \"Run `buoy dock tokens` to extract tokens from codebase\",\n \"Add a design-tokens.json file\",\n \"Manual fix: replace with CSS variable or theme token\",\n ]\n : [\n \"Value may be intentionally one-off (consider documenting)\",\n \"Run `buoy drift fix --confidence low` to see all suggestions\",\n \"Create a new token for this value if it will be reused\",\n ],\n },\n };\n }\n\n // Generate fix based on type\n let replacement = closest.name;\n if (type.includes(\"color\")) {\n replacement = `var(--${closest.name})`;\n } else if (type.includes(\"class\")) {\n replacement = closest.name.replace(/^(color|spacing|font)-/, \"\");\n }\n\n return {\n fix: {\n type: \"replace\" as const,\n original: value,\n replacement,\n confidence: 0.85,\n },\n explanation: `Replace hardcoded value with design token \"${closest.name}\"${\n location ? ` at ${location}` : \"\"\n }`,\n alternatives: ctx.tokens\n .filter((t) => t.category === category && t.name !== closest.name)\n .slice(0, 3)\n .map((t) => t.name),\n };\n}\n\n/**\n * Start the MCP server\n */\nexport async function startServer(cwd: string = process.cwd()): Promise<void> {\n const server = createServer(cwd);\n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@buoy-design/mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.16",
|
|
4
4
|
"description": "MCP server for Buoy design system context",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
],
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
23
|
-
"@buoy-design/
|
|
24
|
-
"@buoy-design/
|
|
23
|
+
"@buoy-design/scanners": "0.3.16",
|
|
24
|
+
"@buoy-design/core": "0.3.16"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"tsup": "^8.0.0",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/context-loader.ts","../src/server.ts"],"sourcesContent":["/**\n * Context loader - gathers design system information from the codebase\n */\n\nimport { readFileSync, existsSync } from 'fs';\nimport { join } from 'path';\nimport type {\n DesignSystemContext,\n TokenWithIntent,\n ComponentSummary,\n Pattern,\n AntiPattern,\n} from './types.js';\n\n/**\n * Load design system context from the project\n */\nexport async function loadDesignSystemContext(\n cwd: string\n): Promise<DesignSystemContext> {\n const projectName = getProjectName(cwd);\n const tokens = await loadTokens(cwd);\n const components = await loadComponents(cwd);\n const patterns = detectPatterns(components);\n const antiPatterns = getAntiPatterns();\n\n return {\n tokens,\n components,\n patterns,\n antiPatterns,\n projectName,\n lastUpdated: new Date().toISOString(),\n };\n}\n\n/**\n * Get project name from package.json\n */\nfunction getProjectName(cwd: string): string {\n const pkgPath = join(cwd, 'package.json');\n if (existsSync(pkgPath)) {\n try {\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));\n return pkg.name || 'Design System';\n } catch {\n // Ignore parse errors\n }\n }\n return 'Design System';\n}\n\n/**\n * Load tokens from various sources\n */\nasync function loadTokens(cwd: string): Promise<TokenWithIntent[]> {\n const tokens: TokenWithIntent[] = [];\n\n // Try to load from exported tokens file\n const tokenPaths = [\n 'design-tokens.json',\n 'tokens.json',\n '.buoy/tokens.json',\n 'tokens-ai-context.json',\n ];\n\n for (const tokenPath of tokenPaths) {\n const fullPath = join(cwd, tokenPath);\n if (existsSync(fullPath)) {\n try {\n const content = JSON.parse(readFileSync(fullPath, 'utf-8'));\n tokens.push(...parseTokenFile(content));\n break;\n } catch {\n // Continue to next path\n }\n }\n }\n\n // If no token file found, try to scan CSS files\n if (tokens.length === 0) {\n tokens.push(...(await scanCssTokens(cwd)));\n }\n\n return tokens;\n}\n\n/**\n * Parse token file (supports multiple formats)\n */\nfunction parseTokenFile(content: unknown): TokenWithIntent[] {\n const tokens: TokenWithIntent[] = [];\n\n if (!content || typeof content !== 'object') return tokens;\n\n // AI context format\n if ('tokens' in (content as Record<string, unknown>)) {\n const tokenObj = (content as { tokens: Record<string, Record<string, unknown>> }).tokens;\n for (const [category, categoryTokens] of Object.entries(tokenObj)) {\n for (const [name, tokenData] of Object.entries(categoryTokens as Record<string, unknown>)) {\n const data = tokenData as Record<string, unknown>;\n tokens.push({\n name,\n value: String(data.$value || data.value || ''),\n category: category as TokenWithIntent['category'],\n intent: data.$intent as TokenWithIntent['intent'],\n usage: data.$usage as string | undefined,\n avoid: data.$avoid as string | undefined,\n examples: data.$examples as string[] | undefined,\n deprecated: data.$deprecated as boolean | undefined,\n });\n }\n }\n return tokens;\n }\n\n // W3C DTCG format\n if (typeof content === 'object') {\n for (const [key, value] of Object.entries(content as Record<string, unknown>)) {\n if (value && typeof value === 'object' && '$value' in value) {\n const v = value as Record<string, unknown>;\n tokens.push({\n name: key,\n value: String(v.$value),\n category: inferCategory(key, String(v.$value)),\n usage: v.$description as string | undefined,\n });\n }\n }\n }\n\n return tokens;\n}\n\n/**\n * Infer token category from name and value\n */\nfunction inferCategory(name: string, value: string): TokenWithIntent['category'] {\n const lower = name.toLowerCase();\n if (lower.includes('color') || value.startsWith('#') || value.startsWith('rgb')) {\n return 'color';\n }\n if (lower.includes('spacing') || lower.includes('space') || lower.includes('gap')) {\n return 'spacing';\n }\n if (lower.includes('font') || lower.includes('text') || lower.includes('typography')) {\n return 'typography';\n }\n if (lower.includes('radius') || lower.includes('rounded')) {\n return 'radius';\n }\n if (lower.includes('shadow')) {\n return 'shadow';\n }\n return 'color'; // Default\n}\n\n/**\n * Scan CSS files for tokens (fallback)\n */\nasync function scanCssTokens(_cwd: string): Promise<TokenWithIntent[]> {\n // This would scan CSS files for custom properties\n // Simplified for now - real implementation would use the scanners package\n return [];\n}\n\n/**\n * Load components from the codebase\n */\nasync function loadComponents(cwd: string): Promise<ComponentSummary[]> {\n const components: ComponentSummary[] = [];\n\n // Try to load from cached component inventory\n const inventoryPath = join(cwd, '.buoy/components.json');\n if (existsSync(inventoryPath)) {\n try {\n const content = JSON.parse(readFileSync(inventoryPath, 'utf-8'));\n if (Array.isArray(content)) {\n return content as ComponentSummary[];\n }\n } catch {\n // Continue to scanning\n }\n }\n\n // Check for skill-generated inventory\n const skillInventory = join(cwd, '.claude/skills/design-system/components/_inventory.md');\n if (existsSync(skillInventory)) {\n const content = readFileSync(skillInventory, 'utf-8');\n components.push(...parseInventoryMarkdown(content));\n }\n\n return components;\n}\n\n/**\n * Parse component inventory from markdown\n */\nfunction parseInventoryMarkdown(content: string): ComponentSummary[] {\n const components: ComponentSummary[] = [];\n const lines = content.split('\\n');\n\n for (const line of lines) {\n // Parse table rows: | ComponentName | Description | Props |\n const match = line.match(/^\\|\\s*`?(\\w+)`?\\s*\\|([^|]*)\\|([^|]*)\\|/);\n if (match && match[1] !== 'Component') {\n components.push({\n name: match[1],\n framework: 'react', // Default assumption\n props: match[3].split(',').map(p => p.trim()).filter(Boolean),\n description: match[2].trim(),\n path: '',\n });\n }\n }\n\n return components;\n}\n\n/**\n * Detect patterns from component usage\n */\nfunction detectPatterns(components: ComponentSummary[]): Pattern[] {\n const patterns: Pattern[] = [];\n\n // Form pattern\n const formComponents = components.filter(c =>\n ['Input', 'Select', 'Checkbox', 'Radio', 'Form', 'Label'].some(n =>\n c.name.includes(n)\n )\n );\n if (formComponents.length > 0) {\n patterns.push({\n name: 'Forms',\n description: 'Form input and validation patterns',\n components: formComponents.map(c => c.name),\n usage: 'Use for user input collection with consistent styling and validation',\n });\n }\n\n // Navigation pattern\n const navComponents = components.filter(c =>\n ['Nav', 'Menu', 'Sidebar', 'Header', 'Footer', 'Tab', 'Breadcrumb'].some(n =>\n c.name.includes(n)\n )\n );\n if (navComponents.length > 0) {\n patterns.push({\n name: 'Navigation',\n description: 'Navigation and menu patterns',\n components: navComponents.map(c => c.name),\n usage: 'Use for site navigation with consistent structure',\n });\n }\n\n // Card pattern\n const cardComponents = components.filter(c =>\n ['Card', 'Panel', 'Box', 'Container'].some(n => c.name.includes(n))\n );\n if (cardComponents.length > 0) {\n patterns.push({\n name: 'Cards',\n description: 'Content container patterns',\n components: cardComponents.map(c => c.name),\n usage: 'Use for grouping related content',\n });\n }\n\n // Modal pattern\n const modalComponents = components.filter(c =>\n ['Modal', 'Dialog', 'Drawer', 'Sheet', 'Popover'].some(n => c.name.includes(n))\n );\n if (modalComponents.length > 0) {\n patterns.push({\n name: 'Modals',\n description: 'Overlay and dialog patterns',\n components: modalComponents.map(c => c.name),\n usage: 'Use for focused interactions that require attention',\n });\n }\n\n return patterns;\n}\n\n/**\n * Get common anti-patterns to avoid\n */\nfunction getAntiPatterns(): AntiPattern[] {\n return [\n {\n name: 'Hardcoded Colors',\n description: 'Using hex/rgb values directly instead of design tokens',\n avoid: 'style={{ color: \"#2563EB\" }} or color: #2563EB',\n instead: 'Use color tokens: className=\"text-primary\" or color={tokens.primary}',\n severity: 'warning',\n },\n {\n name: 'Arbitrary Spacing',\n description: 'Using pixel values not in the spacing scale',\n avoid: 'padding: 13px or p-[13px]',\n instead: 'Use spacing scale: p-4 (16px) or p-3 (12px)',\n severity: 'warning',\n },\n {\n name: 'Inline onClick Handlers',\n description: 'Using div/span with onClick instead of semantic elements',\n avoid: '<div onClick={handleClick}>Click me</div>',\n instead: 'Use <Button> or <button> for clickable elements',\n severity: 'critical',\n },\n {\n name: 'Missing Alt Text',\n description: 'Images without alt attributes',\n avoid: '<img src=\"logo.png\" />',\n instead: '<img src=\"logo.png\" alt=\"Company logo\" />',\n severity: 'critical',\n },\n {\n name: 'Custom Component Creation',\n description: 'Creating new components when existing ones would work',\n avoid: 'Creating MyButton.tsx when Button component exists',\n instead: 'Check component inventory first, extend existing if needed',\n severity: 'info',\n },\n {\n name: 'Inconsistent Naming',\n description: 'Component names that dont follow project conventions',\n avoid: 'my-component.tsx or MyComponent.jsx',\n instead: 'Follow project naming: ComponentName.tsx',\n severity: 'info',\n },\n ];\n}\n\n/**\n * Get tokens by category\n */\nexport function getTokensByCategory(\n context: DesignSystemContext,\n category: string\n): TokenWithIntent[] {\n return context.tokens.filter(t => t.category === category);\n}\n\n/**\n * Find component by name\n */\nexport function findComponent(\n context: DesignSystemContext,\n name: string\n): ComponentSummary | undefined {\n return context.components.find(\n c => c.name.toLowerCase() === name.toLowerCase()\n );\n}\n\n/**\n * Search components by use case\n */\nexport function searchComponents(\n context: DesignSystemContext,\n useCase: string\n): ComponentSummary[] {\n const keywords = useCase.toLowerCase().split(/\\s+/);\n\n return context.components.filter(c => {\n const searchText = `${c.name} ${c.description || ''} ${c.props.join(' ')}`.toLowerCase();\n return keywords.some(kw => searchText.includes(kw));\n });\n}\n","/**\n * Buoy MCP Server\n *\n * Provides design system context to AI agents via Model Context Protocol.\n *\n * Resources:\n * - tokens://all - All design tokens\n * - tokens://{category} - Tokens by category (color, spacing, typography)\n * - components://inventory - Component catalog\n * - components://{name} - Component details\n * - patterns://all - Pattern library\n * - antipatterns://all - Anti-patterns to avoid\n *\n * Tools:\n * - find_component - Find best component for a use case\n * - validate_code - Check code against design system\n * - resolve_token - Find token for a hardcoded value\n * - suggest_fix - Get fix suggestion for drift\n */\n\nimport { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport {\n CallToolRequestSchema,\n ListResourcesRequestSchema,\n ListToolsRequestSchema,\n ReadResourceRequestSchema,\n} from '@modelcontextprotocol/sdk/types.js';\n\nimport {\n loadDesignSystemContext,\n getTokensByCategory,\n findComponent,\n searchComponents,\n} from './context-loader.js';\nimport type {\n DesignSystemContext,\n FindComponentRequest,\n FindComponentResponse,\n ValidateCodeRequest,\n ValidateCodeResponse,\n ResolveTokenRequest,\n ResolveTokenResponse,\n} from './types.js';\n\n/**\n * Create and configure the Buoy MCP server\n */\nexport function createServer(cwd: string = process.cwd()): Server {\n const server = new Server(\n {\n name: 'buoy-design-system',\n version: '0.1.0',\n },\n {\n capabilities: {\n resources: {},\n tools: {},\n },\n }\n );\n\n let context: DesignSystemContext | null = null;\n\n /**\n * Load context on demand\n */\n async function getContext(): Promise<DesignSystemContext> {\n if (!context) {\n context = await loadDesignSystemContext(cwd);\n }\n return context;\n }\n\n /**\n * List available resources\n */\n server.setRequestHandler(ListResourcesRequestSchema, async () => {\n return {\n resources: [\n {\n uri: 'tokens://all',\n name: 'All Design Tokens',\n description: 'Complete list of design tokens with usage guidance',\n mimeType: 'application/json',\n },\n {\n uri: 'tokens://color',\n name: 'Color Tokens',\n description: 'Color tokens with semantic meaning',\n mimeType: 'application/json',\n },\n {\n uri: 'tokens://spacing',\n name: 'Spacing Tokens',\n description: 'Spacing scale for consistent layouts',\n mimeType: 'application/json',\n },\n {\n uri: 'tokens://typography',\n name: 'Typography Tokens',\n description: 'Font sizes, weights, and families',\n mimeType: 'application/json',\n },\n {\n uri: 'components://inventory',\n name: 'Component Inventory',\n description: 'All available UI components',\n mimeType: 'application/json',\n },\n {\n uri: 'patterns://all',\n name: 'Pattern Library',\n description: 'Common UI patterns and compositions',\n mimeType: 'application/json',\n },\n {\n uri: 'antipatterns://all',\n name: 'Anti-Patterns',\n description: 'Things to avoid in this design system',\n mimeType: 'application/json',\n },\n ],\n };\n });\n\n /**\n * Read resource content\n */\n server.setRequestHandler(ReadResourceRequestSchema, async (request) => {\n const ctx = await getContext();\n const uri = request.params.uri;\n\n // Tokens resources\n if (uri === 'tokens://all') {\n return {\n contents: [\n {\n uri,\n mimeType: 'application/json',\n text: JSON.stringify(ctx.tokens, null, 2),\n },\n ],\n };\n }\n\n if (uri.startsWith('tokens://')) {\n const category = uri.replace('tokens://', '');\n const tokens = getTokensByCategory(ctx, category);\n return {\n contents: [\n {\n uri,\n mimeType: 'application/json',\n text: JSON.stringify(tokens, null, 2),\n },\n ],\n };\n }\n\n // Components resources\n if (uri === 'components://inventory') {\n return {\n contents: [\n {\n uri,\n mimeType: 'application/json',\n text: JSON.stringify(ctx.components, null, 2),\n },\n ],\n };\n }\n\n if (uri.startsWith('components://')) {\n const name = uri.replace('components://', '');\n const component = findComponent(ctx, name);\n return {\n contents: [\n {\n uri,\n mimeType: 'application/json',\n text: component\n ? JSON.stringify(component, null, 2)\n : JSON.stringify({ error: `Component \"${name}\" not found` }),\n },\n ],\n };\n }\n\n // Patterns resources\n if (uri === 'patterns://all') {\n return {\n contents: [\n {\n uri,\n mimeType: 'application/json',\n text: JSON.stringify(ctx.patterns, null, 2),\n },\n ],\n };\n }\n\n // Anti-patterns resources\n if (uri === 'antipatterns://all') {\n return {\n contents: [\n {\n uri,\n mimeType: 'application/json',\n text: JSON.stringify(ctx.antiPatterns, null, 2),\n },\n ],\n };\n }\n\n throw new Error(`Unknown resource: ${uri}`);\n });\n\n /**\n * List available tools\n */\n server.setRequestHandler(ListToolsRequestSchema, async () => {\n return {\n tools: [\n {\n name: 'find_component',\n description:\n 'Find the best component for a use case. Returns recommended component with alternatives.',\n inputSchema: {\n type: 'object',\n properties: {\n useCase: {\n type: 'string',\n description: 'Description of what you want to build (e.g., \"submit button\", \"form input\")',\n },\n constraints: {\n type: 'array',\n items: { type: 'string' },\n description: 'Optional constraints (e.g., \"accessible\", \"responsive\")',\n },\n },\n required: ['useCase'],\n },\n },\n {\n name: 'validate_code',\n description:\n 'Validate code against design system rules. Returns issues and suggestions.',\n inputSchema: {\n type: 'object',\n properties: {\n code: {\n type: 'string',\n description: 'The code to validate',\n },\n filePath: {\n type: 'string',\n description: 'Optional file path for context',\n },\n },\n required: ['code'],\n },\n },\n {\n name: 'resolve_token',\n description:\n 'Find the design token that matches a hardcoded value. Returns exact or closest match.',\n inputSchema: {\n type: 'object',\n properties: {\n value: {\n type: 'string',\n description: 'The hardcoded value (e.g., \"#2563EB\", \"16px\")',\n },\n context: {\n type: 'string',\n enum: ['color', 'spacing', 'typography'],\n description: 'Optional hint about value type',\n },\n },\n required: ['value'],\n },\n },\n {\n name: 'suggest_fix',\n description:\n 'Get a fix suggestion for a design system violation.',\n inputSchema: {\n type: 'object',\n properties: {\n type: {\n type: 'string',\n description: 'Type of violation (e.g., \"hardcoded-color\", \"arbitrary-spacing\")',\n },\n value: {\n type: 'string',\n description: 'The problematic value',\n },\n location: {\n type: 'string',\n description: 'Where the violation occurs (file:line)',\n },\n },\n required: ['type', 'value'],\n },\n },\n ],\n };\n });\n\n /**\n * Handle tool calls\n */\n server.setRequestHandler(CallToolRequestSchema, async (request) => {\n const ctx = await getContext();\n const { name, arguments: args } = request.params;\n\n switch (name) {\n case 'find_component': {\n const { useCase, constraints } = args as FindComponentRequest;\n const result = handleFindComponent(ctx, useCase, constraints);\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(result, null, 2),\n },\n ],\n };\n }\n\n case 'validate_code': {\n const { code, filePath } = args as ValidateCodeRequest;\n const result = handleValidateCode(ctx, code, filePath);\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(result, null, 2),\n },\n ],\n };\n }\n\n case 'resolve_token': {\n const { value, context: tokenContext } = args as ResolveTokenRequest;\n const result = handleResolveToken(ctx, value, tokenContext);\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(result, null, 2),\n },\n ],\n };\n }\n\n case 'suggest_fix': {\n const { type, value, location } = args as {\n type: string;\n value: string;\n location?: string;\n };\n const result = handleSuggestFix(ctx, type, value, location);\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(result, null, 2),\n },\n ],\n };\n }\n\n default:\n throw new Error(`Unknown tool: ${name}`);\n }\n });\n\n return server;\n}\n\n/**\n * Find component handler\n */\nfunction handleFindComponent(\n ctx: DesignSystemContext,\n useCase: string,\n constraints?: string[]\n): FindComponentResponse {\n const matches = searchComponents(ctx, useCase);\n\n if (matches.length === 0) {\n // No Dead Ends: Provide guidance when no components found\n const availableComponents = ctx.components.slice(0, 5).map(c => c.name);\n return {\n recommended: null,\n alternatives: [],\n reasoning: `No existing component found for \"${useCase}\".`,\n guidance: {\n suggestion: 'Consider creating a new component or composing existing ones.',\n availableComponents: availableComponents.length > 0\n ? `Available components include: ${availableComponents.join(', ')}`\n : 'No components in inventory. Run `buoy scan` to discover components.',\n nextSteps: ctx.components.length === 0\n ? ['Run `buoy scan` to discover components', 'Run `buoy skill spill` to populate component inventory']\n : ['Check component naming - try broader search terms', 'View full inventory with components://inventory'],\n },\n };\n }\n\n // Score matches (simple scoring for now)\n const scored = matches.map(c => ({\n component: c,\n score: calculateMatchScore(c, useCase, constraints),\n }));\n\n scored.sort((a, b) => b.score - a.score);\n\n const recommended = scored[0].component;\n const alternatives = scored.slice(1, 4).map(s => s.component);\n\n return {\n recommended,\n alternatives,\n reasoning: `\"${recommended.name}\" is the best match for \"${useCase}\". ${\n recommended.description || ''\n }`,\n };\n}\n\n/**\n * Calculate match score for a component\n */\nfunction calculateMatchScore(\n component: { name: string; description?: string; props: string[] },\n useCase: string,\n constraints?: string[]\n): number {\n let score = 0;\n const searchText = `${component.name} ${component.description || ''} ${component.props.join(' ')}`.toLowerCase();\n const useCaseLower = useCase.toLowerCase();\n\n // Name match\n if (component.name.toLowerCase().includes(useCaseLower)) {\n score += 10;\n }\n\n // Keyword matches\n const keywords = useCaseLower.split(/\\s+/);\n for (const keyword of keywords) {\n if (searchText.includes(keyword)) {\n score += 2;\n }\n }\n\n // Constraint matches\n if (constraints) {\n for (const constraint of constraints) {\n if (searchText.includes(constraint.toLowerCase())) {\n score += 3;\n }\n }\n }\n\n return score;\n}\n\n/**\n * Validate code handler\n */\nfunction handleValidateCode(\n ctx: DesignSystemContext,\n code: string,\n _filePath?: string\n): ValidateCodeResponse {\n const issues: ValidateCodeResponse['issues'] = [];\n\n // Check for hardcoded colors\n const hexColors = code.match(/#[0-9A-Fa-f]{3,8}\\b/g) || [];\n const rgbColors = code.match(/rgb\\([^)]+\\)/g) || [];\n\n for (const color of [...hexColors, ...rgbColors]) {\n // Check if it's a token value\n const isToken = ctx.tokens.some(t => t.value.toLowerCase() === color.toLowerCase());\n if (!isToken) {\n const match = findClosestToken(ctx, color, 'color');\n issues.push({\n type: 'hardcoded-color',\n severity: 'warning',\n message: `Hardcoded color \"${color}\" - use design token instead`,\n suggestion: match ? `Use token: ${match.name} (${match.value})` : undefined,\n });\n }\n }\n\n // Check for arbitrary spacing\n const arbitrarySpacing = code.match(/\\b\\d+px\\b/g) || [];\n const spacingScale = ctx.tokens\n .filter(t => t.category === 'spacing')\n .map(t => t.value);\n\n for (const spacing of arbitrarySpacing) {\n if (!spacingScale.includes(spacing)) {\n const match = findClosestToken(ctx, spacing, 'spacing');\n issues.push({\n type: 'arbitrary-spacing',\n severity: 'warning',\n message: `Arbitrary spacing \"${spacing}\" - use spacing scale`,\n suggestion: match ? `Use token: ${match.name} (${match.value})` : undefined,\n });\n }\n }\n\n // Check for div onClick (accessibility anti-pattern)\n if (/<div[^>]*onClick/i.test(code)) {\n issues.push({\n type: 'accessibility',\n severity: 'critical',\n message: 'Using div with onClick - use button or Button component',\n suggestion: 'Replace <div onClick> with <Button onClick>',\n });\n }\n\n // Check for img without alt\n if (/<img[^>]*(?!alt)[^>]*>/i.test(code) && !/<img[^>]*alt=/i.test(code)) {\n issues.push({\n type: 'accessibility',\n severity: 'critical',\n message: 'Image missing alt attribute',\n suggestion: 'Add alt=\"description\" to img element',\n });\n }\n\n // No Dead Ends: Provide context about what was checked\n const checksPerformed = [\n 'Hardcoded colors',\n 'Arbitrary spacing values',\n 'Accessibility anti-patterns (div onClick, img alt)',\n ];\n\n return {\n valid: issues.length === 0,\n issues,\n summary: {\n total: issues.length,\n critical: issues.filter(i => i.severity === 'critical').length,\n warning: issues.filter(i => i.severity === 'warning').length,\n info: issues.filter(i => i.severity === 'info').length,\n },\n context: {\n checksPerformed,\n tokensAvailable: ctx.tokens.length,\n componentsKnown: ctx.components.length,\n guidance: issues.length === 0\n ? 'Code follows design system rules. Run `buoy check` for comprehensive analysis.'\n : 'Fix issues above, then re-validate. Run `buoy fix --dry-run` for automated suggestions.',\n },\n };\n}\n\n/**\n * Resolve token handler\n */\nfunction handleResolveToken(\n ctx: DesignSystemContext,\n value: string,\n tokenContext?: 'color' | 'spacing' | 'typography'\n): ResolveTokenResponse {\n // Filter tokens by context if provided\n const candidates = tokenContext\n ? ctx.tokens.filter(t => t.category === tokenContext)\n : ctx.tokens;\n\n // Look for exact match\n const exactMatch = candidates.find(\n t => t.value.toLowerCase() === value.toLowerCase()\n );\n\n if (exactMatch) {\n return {\n exactMatch,\n closestMatches: [],\n suggestion: `Use token: ${exactMatch.name}`,\n };\n }\n\n // Find closest matches\n const closest = findClosestToken(ctx, value, tokenContext);\n\n if (closest) {\n return {\n exactMatch: null,\n closestMatches: [{ token: closest, similarity: 0.8 }],\n suggestion: `Closest token: ${closest.name} (${closest.value})`,\n };\n }\n\n // No Dead Ends: Explain why no match and suggest next steps\n const availableCategories = [...new Set(ctx.tokens.map(t => t.category))];\n return {\n exactMatch: null,\n closestMatches: [],\n suggestion: `No matching token found for \"${value}\".`,\n guidance: {\n tokenCount: ctx.tokens.length,\n availableCategories: availableCategories.length > 0\n ? availableCategories\n : ['No tokens loaded'],\n nextSteps: ctx.tokens.length === 0\n ? [\n 'Run `buoy tokens` to extract tokens from hardcoded values',\n 'Add a design-tokens.json file',\n 'Run `buoy scan` to discover tokens from CSS',\n ]\n : [\n 'Consider adding a new token for this value',\n 'Use the closest available value from the scale',\n `View available tokens: tokens://${tokenContext || 'all'}`,\n ],\n },\n };\n}\n\n/**\n * Find closest matching token\n */\nfunction findClosestToken(\n ctx: DesignSystemContext,\n value: string,\n category?: string\n): DesignSystemContext['tokens'][0] | null {\n const candidates = category\n ? ctx.tokens.filter(t => t.category === category)\n : ctx.tokens;\n\n if (candidates.length === 0) return null;\n\n // For colors, try to find similar hue\n if (value.startsWith('#') || value.startsWith('rgb')) {\n return candidates[0]; // Simplified - return first token\n }\n\n // For spacing, find closest numeric value\n const numericValue = parseFloat(value);\n if (!isNaN(numericValue)) {\n let closest = candidates[0];\n let closestDiff = Infinity;\n\n for (const token of candidates) {\n const tokenValue = parseFloat(token.value);\n if (!isNaN(tokenValue)) {\n const diff = Math.abs(tokenValue - numericValue);\n if (diff < closestDiff) {\n closestDiff = diff;\n closest = token;\n }\n }\n }\n\n return closest;\n }\n\n return candidates[0];\n}\n\n/**\n * Suggest fix handler\n */\nfunction handleSuggestFix(\n ctx: DesignSystemContext,\n type: string,\n value: string,\n location?: string\n) {\n // Determine category from type\n let category: 'color' | 'spacing' | 'typography' | undefined;\n if (type.includes('color')) category = 'color';\n else if (type.includes('spacing')) category = 'spacing';\n else if (type.includes('font') || type.includes('typography')) category = 'typography';\n\n const closest = findClosestToken(ctx, value, category);\n\n if (!closest) {\n // No Dead Ends: Explain why no fix and suggest next steps\n return {\n fix: null,\n explanation: `No suitable token found for \"${value}\"`,\n alternatives: [],\n guidance: {\n tokenCount: ctx.tokens.length,\n categorySearched: category || 'all',\n nextSteps: ctx.tokens.length === 0\n ? [\n 'Run `buoy tokens` to extract tokens from codebase',\n 'Add a design-tokens.json file',\n 'Manual fix: replace with CSS variable or theme token',\n ]\n : [\n 'Value may be intentionally one-off (consider documenting)',\n 'Run `buoy fix --confidence low` to see all suggestions',\n 'Create a new token for this value if it will be reused',\n ],\n },\n };\n }\n\n // Generate fix based on type\n let replacement = closest.name;\n if (type.includes('color')) {\n replacement = `var(--${closest.name})`;\n } else if (type.includes('class')) {\n replacement = closest.name.replace(/^(color|spacing|font)-/, '');\n }\n\n return {\n fix: {\n type: 'replace' as const,\n original: value,\n replacement,\n confidence: 0.85,\n },\n explanation: `Replace hardcoded value with design token \"${closest.name}\"${\n location ? ` at ${location}` : ''\n }`,\n alternatives: ctx.tokens\n .filter(t => t.category === category && t.name !== closest.name)\n .slice(0, 3)\n .map(t => t.name),\n };\n}\n\n/**\n * Start the MCP server\n */\nexport async function startServer(cwd: string = process.cwd()): Promise<void> {\n const server = createServer(cwd);\n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n"],"mappings":"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","names":[]}
|