@fragments-sdk/mcp 0.6.2 → 0.7.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.
@@ -1,3 +1,8 @@
1
+ import {
2
+ getGuidanceWhen,
3
+ getGuidanceWhenNot
4
+ } from "./chunk-YSRGQDEB.js";
5
+
1
6
  // src/rules.ts
2
7
  import { join } from "path";
3
8
  import { writeFileSync, mkdirSync, existsSync } from "fs";
@@ -49,9 +54,9 @@ function buildRulesContent(data, brandName) {
49
54
  sections.push("## Components\n");
50
55
  const byCategory = /* @__PURE__ */ new Map();
51
56
  for (const c of components) {
52
- const cat = c.meta.category || "uncategorized";
57
+ const cat = c.category || "uncategorized";
53
58
  if (!byCategory.has(cat)) byCategory.set(cat, []);
54
- byCategory.get(cat).push(c.meta.name);
59
+ byCategory.get(cat).push(c.name);
55
60
  }
56
61
  for (const [cat, names] of byCategory) {
57
62
  sections.push(`### ${cat}
@@ -65,7 +70,7 @@ function buildRulesContent(data, brandName) {
65
70
  sections.push(`Import components from \`${data.defaultPackageName}\`:
66
71
  `);
67
72
  sections.push("```typescript");
68
- const exampleNames = components.slice(0, 3).map((c) => c.meta.name);
73
+ const exampleNames = components.slice(0, 3).map((c) => c.name);
69
74
  sections.push(`import { ${exampleNames.join(", ")} } from '${data.defaultPackageName}';`);
70
75
  sections.push("```\n");
71
76
  }
@@ -82,8 +87,8 @@ function buildRulesContent(data, brandName) {
82
87
  const allDos = [];
83
88
  const allDonts = [];
84
89
  for (const c of components) {
85
- if (c.usage?.when) allDos.push(...c.usage.when.slice(0, 1).map((w) => `${c.meta.name}: ${w}`));
86
- if (c.usage?.whenNot) allDonts.push(...c.usage.whenNot.slice(0, 1).map((w) => `${c.meta.name}: ${w}`));
90
+ allDos.push(...getGuidanceWhen(c).slice(0, 1).map((w) => `${c.name}: ${w}`));
91
+ allDonts.push(...getGuidanceWhenNot(c).slice(0, 1).map((w) => `${c.name}: ${w}`));
87
92
  }
88
93
  if (allDos.length > 0 || allDonts.length > 0) {
89
94
  sections.push("## Usage Guidelines\n");
@@ -104,4 +109,4 @@ function buildRulesContent(data, brandName) {
104
109
  export {
105
110
  generateRulesFiles
106
111
  };
107
- //# sourceMappingURL=chunk-2W7DAUUS.js.map
112
+ //# sourceMappingURL=chunk-VV2PJ75X.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/rules.ts"],"sourcesContent":["import { join } from 'node:path';\nimport { writeFileSync, mkdirSync, existsSync } from 'node:fs';\nimport type { McpComponent } from '@fragments-sdk/core';\nimport type { DesignSystemData } from './types.js';\nimport { getGuidanceWhen, getGuidanceWhenNot } from './snapshot-helpers.js';\n\nexport type RulesFormat = 'cursor' | 'claude' | 'copilot';\n\nexport interface RulesGeneratorOptions {\n data: DesignSystemData;\n brandName: string;\n outputDir: string;\n formats: RulesFormat[];\n /** Overwrite existing files (default: false — skip and warn) */\n force?: boolean;\n}\n\n/**\n * Generate IDE rules files from design system data.\n * Returns list of files written. Skips existing files unless force is true.\n */\nexport function generateRulesFiles(options: RulesGeneratorOptions): string[] {\n const { data, brandName, outputDir, formats, force = false } = options;\n const content = buildRulesContent(data, brandName);\n const files: string[] = [];\n\n for (const format of formats) {\n let filePath: string;\n let fileContent: string;\n\n switch (format) {\n case 'cursor':\n filePath = join(outputDir, '.cursorrules');\n fileContent = content;\n break;\n case 'claude':\n filePath = join(outputDir, 'CLAUDE.md');\n fileContent = `# CLAUDE.md\\n\\nThis file provides guidance to Claude Code when working with code in this repository.\\n\\n${content}`;\n break;\n case 'copilot': {\n const dir = join(outputDir, '.github');\n if (!existsSync(dir)) mkdirSync(dir, { recursive: true });\n filePath = join(dir, 'copilot-instructions.md');\n fileContent = content;\n break;\n }\n }\n\n if (!force && existsSync(filePath)) {\n console.error(` Skipped ${filePath} (already exists, use --force to overwrite)`);\n continue;\n }\n\n writeFileSync(filePath, fileContent, 'utf-8');\n files.push(filePath);\n }\n\n return files;\n}\n\nfunction buildRulesContent(data: DesignSystemData, brandName: string): string {\n const sections: string[] = [];\n\n // Header\n sections.push(`# ${brandName} Design System Rules\\n`);\n sections.push(`Always use ${brandName} components and design tokens when building UI. Do not use raw HTML elements, Tailwind classes, or hardcoded CSS values when a design system component or token exists.\\n`);\n\n // Component inventory\n const components: McpComponent[] = Object.values(data.components);\n if (components.length > 0) {\n sections.push('## Components\\n');\n const byCategory = new Map<string, string[]>();\n for (const c of components) {\n const cat = c.category || 'uncategorized';\n if (!byCategory.has(cat)) byCategory.set(cat, []);\n byCategory.get(cat)!.push(c.name);\n }\n for (const [cat, names] of byCategory) {\n sections.push(`### ${cat}\\n`);\n sections.push(names.map(n => `- ${n}`).join('\\n'));\n sections.push('');\n }\n }\n\n // Import pattern\n if (data.defaultPackageName) {\n sections.push('## Imports\\n');\n sections.push(`Import components from \\`${data.defaultPackageName}\\`:\\n`);\n sections.push('```typescript');\n const exampleNames = components.slice(0, 3).map(c => c.name);\n sections.push(`import { ${exampleNames.join(', ')} } from '${data.defaultPackageName}';`);\n sections.push('```\\n');\n }\n\n // Tokens\n if (data.tokens && data.tokens.total > 0) {\n sections.push('## Design Tokens\\n');\n sections.push(`Prefix: \\`${data.tokens.prefix}\\`. Use \\`var(--token-name)\\` in CSS/styles.\\n`);\n sections.push('Available categories:');\n for (const [cat, tokens] of Object.entries(data.tokens.categories) as Array<\n [string, typeof data.tokens.categories[string]]\n >) {\n sections.push(`- **${cat}** (${tokens.length} tokens)`);\n }\n sections.push('');\n }\n\n // Usage guidelines (aggregated from all components)\n const allDos: string[] = [];\n const allDonts: string[] = [];\n for (const c of components) {\n allDos.push(...getGuidanceWhen(c).slice(0, 1).map(w => `${c.name}: ${w}`));\n allDonts.push(...getGuidanceWhenNot(c).slice(0, 1).map(w => `${c.name}: ${w}`));\n }\n if (allDos.length > 0 || allDonts.length > 0) {\n sections.push('## Usage Guidelines\\n');\n if (allDos.length > 0) {\n sections.push('**Do:**');\n sections.push(allDos.slice(0, 10).map(d => `- ${d}`).join('\\n'));\n sections.push('');\n }\n if (allDonts.length > 0) {\n sections.push('**Don\\'t:**');\n sections.push(allDonts.slice(0, 10).map(d => `- ${d}`).join('\\n'));\n sections.push('');\n }\n }\n\n return sections.join('\\n');\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,93 @@
1
+ // src/snapshot-helpers.ts
2
+ function listComponents(snapshot) {
3
+ return Object.values(snapshot.components);
4
+ }
5
+ function componentNames(snapshot) {
6
+ return listComponents(snapshot).map((component) => component.name);
7
+ }
8
+ function listBlocks(snapshot) {
9
+ return Object.values(snapshot.blocks ?? {});
10
+ }
11
+ function findComponentByName(snapshot, name) {
12
+ const query = name.toLowerCase();
13
+ return listComponents(snapshot).find(
14
+ (component) => component.name.toLowerCase() === query
15
+ );
16
+ }
17
+ function normalizeComponentRef(value) {
18
+ return value.trim().toLowerCase();
19
+ }
20
+ function buildCompoundComponent(parent, childName) {
21
+ const child = parent.compoundChildren.find(
22
+ (entry) => normalizeComponentRef(entry.name) === normalizeComponentRef(childName)
23
+ );
24
+ if (!child) return void 0;
25
+ const fullName = child.name.includes(".") ? child.name : `${parent.name}.${child.name}`;
26
+ return {
27
+ ...parent,
28
+ id: child.componentId ?? `${parent.id}::${fullName}`,
29
+ name: fullName,
30
+ description: child.description ?? "",
31
+ props: {},
32
+ propsSummary: [],
33
+ examples: [],
34
+ relations: [],
35
+ compoundChildren: [],
36
+ publicRef: child.componentId ?? fullName,
37
+ publicSlug: null,
38
+ parentComponentId: parent.id,
39
+ parentComponentName: parent.name
40
+ };
41
+ }
42
+ function findComponent(snapshot, reference) {
43
+ const query = normalizeComponentRef(reference);
44
+ const components = listComponents(snapshot);
45
+ const exact = components.find((component) => {
46
+ return normalizeComponentRef(component.name) === query || normalizeComponentRef(component.id) === query || normalizeComponentRef(component.publicRef ?? "") === query;
47
+ });
48
+ if (exact) return exact;
49
+ if (reference.includes(".")) {
50
+ const [parentName, ...childParts] = reference.split(".");
51
+ const childName = childParts.join(".");
52
+ const parent = components.find((component) => {
53
+ return normalizeComponentRef(component.name) === normalizeComponentRef(parentName) || normalizeComponentRef(component.publicRef ?? "") === normalizeComponentRef(parentName) || normalizeComponentRef(component.id) === normalizeComponentRef(parentName);
54
+ });
55
+ if (parent) {
56
+ const child = buildCompoundComponent(parent, childName);
57
+ if (child) return child;
58
+ }
59
+ }
60
+ return void 0;
61
+ }
62
+ function getGuidanceWhen(component) {
63
+ if (component.guidance.when.length > 0) {
64
+ return component.guidance.when;
65
+ }
66
+ if (component.guidance.usageGuidance) {
67
+ return [component.guidance.usageGuidance];
68
+ }
69
+ if (component.guidance.dos.length > 0) {
70
+ return component.guidance.dos;
71
+ }
72
+ return [];
73
+ }
74
+ function getGuidanceWhenNot(component) {
75
+ if (component.guidance.whenNot.length > 0) {
76
+ return component.guidance.whenNot;
77
+ }
78
+ if (component.guidance.donts.length > 0) {
79
+ return component.guidance.donts;
80
+ }
81
+ return [];
82
+ }
83
+
84
+ export {
85
+ listComponents,
86
+ componentNames,
87
+ listBlocks,
88
+ findComponentByName,
89
+ findComponent,
90
+ getGuidanceWhen,
91
+ getGuidanceWhenNot
92
+ };
93
+ //# sourceMappingURL=chunk-YSRGQDEB.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/snapshot-helpers.ts"],"sourcesContent":["import type { McpBlock, McpComponent, McpSnapshot } from '@fragments-sdk/core';\n\nexport type ResolvedMcpComponent = McpComponent & {\n isCanonical?: boolean;\n};\n\nexport function listComponents(\n snapshot: Pick<McpSnapshot, 'components'>,\n): ResolvedMcpComponent[] {\n return Object.values(snapshot.components);\n}\n\nexport function componentNames(snapshot: Pick<McpSnapshot, 'components'>): string[] {\n return listComponents(snapshot).map((component) => component.name);\n}\n\nexport function listBlocks(snapshot: Pick<McpSnapshot, 'blocks'>): McpBlock[] {\n return Object.values(snapshot.blocks ?? {});\n}\n\nexport function findComponentByName(\n snapshot: Pick<McpSnapshot, 'components'>,\n name: string,\n): ResolvedMcpComponent | undefined {\n const query = name.toLowerCase();\n return listComponents(snapshot).find(\n (component) => component.name.toLowerCase() === query,\n );\n}\n\nfunction normalizeComponentRef(value: string): string {\n return value.trim().toLowerCase();\n}\n\nfunction buildCompoundComponent(\n parent: ResolvedMcpComponent,\n childName: string,\n): ResolvedMcpComponent | undefined {\n const child = parent.compoundChildren.find(\n (entry) => normalizeComponentRef(entry.name) === normalizeComponentRef(childName),\n );\n if (!child) return undefined;\n\n const fullName = child.name.includes('.')\n ? child.name\n : `${parent.name}.${child.name}`;\n\n return {\n ...parent,\n id: child.componentId ?? `${parent.id}::${fullName}`,\n name: fullName,\n description: child.description ?? '',\n props: {},\n propsSummary: [],\n examples: [],\n relations: [],\n compoundChildren: [],\n publicRef: child.componentId ?? fullName,\n publicSlug: null,\n parentComponentId: parent.id,\n parentComponentName: parent.name,\n };\n}\n\nexport function findComponent(\n snapshot: Pick<McpSnapshot, 'components'>,\n reference: string,\n): ResolvedMcpComponent | undefined {\n const query = normalizeComponentRef(reference);\n const components = listComponents(snapshot);\n\n const exact = components.find((component) => {\n return (\n normalizeComponentRef(component.name) === query ||\n normalizeComponentRef(component.id) === query ||\n normalizeComponentRef(component.publicRef ?? '') === query\n );\n });\n if (exact) return exact;\n\n if (reference.includes('.')) {\n const [parentName, ...childParts] = reference.split('.');\n const childName = childParts.join('.');\n const parent = components.find((component) => {\n return (\n normalizeComponentRef(component.name) === normalizeComponentRef(parentName) ||\n normalizeComponentRef(component.publicRef ?? '') ===\n normalizeComponentRef(parentName) ||\n normalizeComponentRef(component.id) === normalizeComponentRef(parentName)\n );\n });\n\n if (parent) {\n const child = buildCompoundComponent(parent, childName);\n if (child) return child;\n }\n }\n\n return undefined;\n}\n\nexport function getGuidanceWhen(component: ResolvedMcpComponent): string[] {\n if (component.guidance.when.length > 0) {\n return component.guidance.when;\n }\n if (component.guidance.usageGuidance) {\n return [component.guidance.usageGuidance];\n }\n if (component.guidance.dos.length > 0) {\n return component.guidance.dos;\n }\n return [];\n}\n\nexport function getGuidanceWhenNot(component: ResolvedMcpComponent): string[] {\n if (component.guidance.whenNot.length > 0) {\n return component.guidance.whenNot;\n }\n if (component.guidance.donts.length > 0) {\n return component.guidance.donts;\n }\n return [];\n}\n"],"mappings":"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","names":[]}
package/dist/index.js CHANGED
@@ -1,10 +1,5 @@
1
1
  import {
2
- generateRulesFiles
3
- } from "./chunk-2W7DAUUS.js";
4
- import {
5
- AutoExtractionAdapter
6
- } from "./chunk-NVHGG7GW.js";
7
- import {
2
+ AutoExtractionAdapter,
8
3
  BLOCK_BOOST_PER_OCCURRENCE,
9
4
  BUILTIN_TOOLS,
10
5
  CORE_TOOLS,
@@ -16,22 +11,30 @@ import {
16
11
  ToolRegistry,
17
12
  USE_CASE_TOKEN_CATEGORIES,
18
13
  VIEWER_TOOLS,
14
+ blockFromCompiledBlock,
15
+ buildCapabilities,
16
+ componentFromCompiledFragment,
19
17
  createMcpServer,
20
18
  createSandboxServer,
21
19
  executeWithMiddleware,
20
+ loadConfigFile,
22
21
  startMcpServer,
23
- telemetryMiddleware
24
- } from "./chunk-WBOVO43F.js";
22
+ telemetryMiddleware,
23
+ tokensFromCompiledTokenData,
24
+ validateSnapshot
25
+ } from "./chunk-HGGAXLRO.js";
25
26
  import {
26
27
  BRAND
27
28
  } from "./chunk-4SVS3AA3.js";
28
29
  import {
29
- loadConfigFile
30
- } from "./chunk-FGIBLPSU.js";
30
+ generateRulesFiles
31
+ } from "./chunk-VV2PJ75X.js";
32
+ import "./chunk-YSRGQDEB.js";
31
33
 
32
34
  // src/adapters/custom-json.ts
33
35
  import { readFile } from "fs/promises";
34
36
  import { existsSync } from "fs";
37
+ import { mcpSnapshotSchema } from "@fragments-sdk/core";
35
38
  var CustomJsonAdapter = class {
36
39
  constructor(filePath) {
37
40
  this.filePath = filePath;
@@ -46,21 +49,80 @@ var CustomJsonAdapter = class {
46
49
  }
47
50
  const content = await readFile(this.filePath, "utf-8");
48
51
  const raw = JSON.parse(content);
52
+ if (raw.schemaVersion === 1 && typeof raw.sourceType === "string" && raw.components && typeof raw.components === "object") {
53
+ const snapshot2 = mcpSnapshotSchema.parse(raw);
54
+ return {
55
+ snapshot: snapshot2,
56
+ components: snapshot2.components,
57
+ blocks: snapshot2.blocks,
58
+ tokens: snapshot2.tokens,
59
+ graph: snapshot2.graph,
60
+ performanceSummary: snapshot2.performanceSummary,
61
+ packageMap: snapshot2.packageMap,
62
+ defaultPackageName: snapshot2.defaultPackageName,
63
+ capabilities: new Set(snapshot2.capabilities)
64
+ };
65
+ }
49
66
  if (!raw.components || typeof raw.components !== "object") {
50
67
  throw new Error(
51
68
  `Invalid design system data: "components" field is required and must be an object. File: ${this.filePath}`
52
69
  );
53
70
  }
54
- return {
55
- components: raw.components,
56
- blocks: raw.blocks,
57
- tokens: raw.tokens,
71
+ const packageMap = raw.packageMap ?? {};
72
+ const defaultPackageName = raw.defaultPackageName;
73
+ const components = Object.fromEntries(
74
+ Object.entries(raw.components).map(
75
+ ([key, fragment]) => [
76
+ key,
77
+ componentFromCompiledFragment({
78
+ id: key,
79
+ fragment,
80
+ sourceType: "custom-json",
81
+ packageName: packageMap[fragment.meta.name] ?? defaultPackageName,
82
+ importPath: packageMap[fragment.meta.name] ?? defaultPackageName
83
+ })
84
+ ]
85
+ )
86
+ );
87
+ const blocks = raw.blocks ? Object.fromEntries(
88
+ Object.entries(raw.blocks).map(
89
+ ([key, block]) => [key, blockFromCompiledBlock(key, block)]
90
+ )
91
+ ) : void 0;
92
+ const tokens = raw.tokens ? tokensFromCompiledTokenData(raw.tokens) : void 0;
93
+ const snapshot = validateSnapshot({
94
+ schemaVersion: 1,
95
+ sourceType: "custom-json",
96
+ sourceLabel: this.filePath,
97
+ capabilities: buildCapabilities({
98
+ components,
99
+ blocks,
100
+ tokens,
101
+ graph: raw.graph,
102
+ performanceSummary: raw.performanceSummary
103
+ }),
104
+ metadata: {
105
+ packageName: defaultPackageName,
106
+ importPath: defaultPackageName
107
+ },
108
+ components,
109
+ blocks,
110
+ tokens,
58
111
  graph: raw.graph,
59
112
  performanceSummary: raw.performanceSummary,
60
- packageMap: new Map(
61
- raw.packageMap ? Object.entries(raw.packageMap) : []
62
- ),
63
- defaultPackageName: raw.defaultPackageName
113
+ packageMap,
114
+ defaultPackageName
115
+ });
116
+ return {
117
+ snapshot,
118
+ components: snapshot.components,
119
+ blocks: snapshot.blocks,
120
+ tokens: snapshot.tokens,
121
+ graph: snapshot.graph,
122
+ performanceSummary: snapshot.performanceSummary,
123
+ packageMap: snapshot.packageMap,
124
+ defaultPackageName: snapshot.defaultPackageName,
125
+ capabilities: new Set(snapshot.capabilities)
64
126
  };
65
127
  }
66
128
  };
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/adapters/custom-json.ts","../src/search-config.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport { existsSync } from 'node:fs';\nimport type { DesignSystemData } from '../types.js';\nimport type { DataAdapter } from './types.js';\n\nexport class CustomJsonAdapter implements DataAdapter {\n readonly name = 'custom-json';\n\n constructor(private filePath: string) {}\n\n discover(): string[] {\n return existsSync(this.filePath) ? [this.filePath] : [];\n }\n\n async load(_projectRoot = ''): Promise<DesignSystemData> {\n if (!existsSync(this.filePath)) {\n throw new Error(`Custom data file not found: ${this.filePath}`);\n }\n\n const content = await readFile(this.filePath, 'utf-8');\n const raw = JSON.parse(content) as Record<string, unknown>;\n\n // Validate required fields\n if (!raw.components || typeof raw.components !== 'object') {\n throw new Error(\n `Invalid design system data: \"components\" field is required and must be an object. ` +\n `File: ${this.filePath}`\n );\n }\n\n return {\n components: raw.components as DesignSystemData['components'],\n blocks: raw.blocks as DesignSystemData['blocks'],\n tokens: raw.tokens as DesignSystemData['tokens'],\n graph: raw.graph as DesignSystemData[\"graph\"],\n performanceSummary: raw.performanceSummary,\n packageMap: new Map(\n raw.packageMap\n ? Object.entries(raw.packageMap as Record<string, string>)\n : []\n ),\n defaultPackageName: raw.defaultPackageName as string | undefined,\n };\n }\n}\n","import { SYNONYM_MAP, USE_CASE_TOKEN_CATEGORIES } from './orama-index.js';\nimport { MINIMUM_SCORE_THRESHOLD, BLOCK_BOOST_PER_OCCURRENCE } from './scoring.js';\n\nexport interface SearchConfig {\n synonyms?: Record<string, string[]>;\n useCaseTokenCategories?: Record<string, string[]>;\n minimumScoreThreshold?: number;\n blockBoostPerOccurrence?: number;\n vectorSearchUrl?: string;\n vectorSearchTimeoutMs?: number;\n}\n\nexport const DEFAULT_SEARCH_CONFIG: Required<SearchConfig> = {\n synonyms: SYNONYM_MAP,\n useCaseTokenCategories: USE_CASE_TOKEN_CATEGORIES,\n minimumScoreThreshold: MINIMUM_SCORE_THRESHOLD,\n blockBoostPerOccurrence: BLOCK_BOOST_PER_OCCURRENCE,\n vectorSearchUrl: 'https://combative-jay-834.convex.site/search',\n vectorSearchTimeoutMs: 3000,\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,gBAAgB;AACzB,SAAS,kBAAkB;AAIpB,IAAM,oBAAN,MAA+C;AAAA,EAGpD,YAAoB,UAAkB;AAAlB;AAAA,EAAmB;AAAA,EAF9B,OAAO;AAAA,EAIhB,WAAqB;AACnB,WAAO,WAAW,KAAK,QAAQ,IAAI,CAAC,KAAK,QAAQ,IAAI,CAAC;AAAA,EACxD;AAAA,EAEA,MAAM,KAAK,eAAe,IAA+B;AACvD,QAAI,CAAC,WAAW,KAAK,QAAQ,GAAG;AAC9B,YAAM,IAAI,MAAM,+BAA+B,KAAK,QAAQ,EAAE;AAAA,IAChE;AAEA,UAAM,UAAU,MAAM,SAAS,KAAK,UAAU,OAAO;AACrD,UAAM,MAAM,KAAK,MAAM,OAAO;AAG9B,QAAI,CAAC,IAAI,cAAc,OAAO,IAAI,eAAe,UAAU;AACzD,YAAM,IAAI;AAAA,QACR,2FACS,KAAK,QAAQ;AAAA,MACxB;AAAA,IACF;AAEA,WAAO;AAAA,MACL,YAAY,IAAI;AAAA,MAChB,QAAQ,IAAI;AAAA,MACZ,QAAQ,IAAI;AAAA,MACZ,OAAO,IAAI;AAAA,MACX,oBAAoB,IAAI;AAAA,MACxB,YAAY,IAAI;AAAA,QACd,IAAI,aACA,OAAO,QAAQ,IAAI,UAAoC,IACvD,CAAC;AAAA,MACP;AAAA,MACA,oBAAoB,IAAI;AAAA,IAC1B;AAAA,EACF;AACF;;;AChCO,IAAM,wBAAgD;AAAA,EAC3D,UAAU;AAAA,EACV,wBAAwB;AAAA,EACxB,uBAAuB;AAAA,EACvB,yBAAyB;AAAA,EACzB,iBAAiB;AAAA,EACjB,uBAAuB;AACzB;","names":[]}
1
+ {"version":3,"sources":["../src/adapters/custom-json.ts","../src/search-config.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport { existsSync } from 'node:fs';\nimport { mcpSnapshotSchema, type McpSnapshot } from '@fragments-sdk/core';\nimport type {\n CompiledBlock,\n CompiledFragment,\n CompiledTokenData,\n} from '@fragments-sdk/context/types';\nimport type { SerializedComponentGraph } from '@fragments-sdk/context/graph';\nimport type { DesignSystemData } from '../types.js';\nimport type { DataAdapter } from './types.js';\nimport {\n blockFromCompiledBlock,\n buildCapabilities,\n componentFromCompiledFragment,\n tokensFromCompiledTokenData,\n validateSnapshot,\n} from './snapshot-converters.js';\n\nexport class CustomJsonAdapter implements DataAdapter {\n readonly name = 'custom-json';\n\n constructor(private filePath: string) {}\n\n discover(): string[] {\n return existsSync(this.filePath) ? [this.filePath] : [];\n }\n\n async load(_projectRoot = ''): Promise<DesignSystemData> {\n if (!existsSync(this.filePath)) {\n throw new Error(`Custom data file not found: ${this.filePath}`);\n }\n\n const content = await readFile(this.filePath, 'utf-8');\n const raw = JSON.parse(content) as Record<string, unknown>;\n\n if (\n raw.schemaVersion === 1 &&\n typeof raw.sourceType === 'string' &&\n raw.components &&\n typeof raw.components === 'object'\n ) {\n const snapshot = mcpSnapshotSchema.parse(raw) as McpSnapshot;\n return {\n snapshot,\n components: snapshot.components,\n blocks: snapshot.blocks,\n tokens: snapshot.tokens,\n graph: snapshot.graph as SerializedComponentGraph | undefined,\n performanceSummary: snapshot.performanceSummary,\n packageMap: snapshot.packageMap,\n defaultPackageName: snapshot.defaultPackageName,\n capabilities: new Set(snapshot.capabilities),\n };\n }\n\n if (!raw.components || typeof raw.components !== 'object') {\n throw new Error(\n `Invalid design system data: \"components\" field is required and must be an object. ` +\n `File: ${this.filePath}`,\n );\n }\n\n const packageMap =\n (raw.packageMap as Record<string, string> | undefined) ?? {};\n const defaultPackageName = raw.defaultPackageName as string | undefined;\n const components = Object.fromEntries(\n Object.entries(raw.components as Record<string, CompiledFragment>).map(\n ([key, fragment]) => [\n key,\n componentFromCompiledFragment({\n id: key,\n fragment,\n sourceType: 'custom-json',\n packageName: packageMap[fragment.meta.name] ?? defaultPackageName,\n importPath: packageMap[fragment.meta.name] ?? defaultPackageName,\n }),\n ],\n ),\n );\n const blocks = raw.blocks\n ? Object.fromEntries(\n Object.entries(raw.blocks as Record<string, CompiledBlock>).map(\n ([key, block]) => [key, blockFromCompiledBlock(key, block)],\n ),\n )\n : undefined;\n const tokens = raw.tokens\n ? tokensFromCompiledTokenData(raw.tokens as CompiledTokenData)\n : undefined;\n const snapshot = validateSnapshot({\n schemaVersion: 1,\n sourceType: 'custom-json',\n sourceLabel: this.filePath,\n capabilities: buildCapabilities({\n components,\n blocks,\n tokens,\n graph: raw.graph,\n performanceSummary: raw.performanceSummary,\n }),\n metadata: {\n packageName: defaultPackageName,\n importPath: defaultPackageName,\n },\n components,\n blocks,\n tokens,\n graph: raw.graph as SerializedComponentGraph | undefined,\n performanceSummary:\n raw.performanceSummary as McpSnapshot['performanceSummary'],\n packageMap,\n defaultPackageName,\n });\n\n return {\n snapshot,\n components: snapshot.components,\n blocks: snapshot.blocks,\n tokens: snapshot.tokens,\n graph: snapshot.graph as SerializedComponentGraph | undefined,\n performanceSummary: snapshot.performanceSummary,\n packageMap: snapshot.packageMap,\n defaultPackageName: snapshot.defaultPackageName,\n capabilities: new Set(snapshot.capabilities),\n };\n }\n}\n","import { SYNONYM_MAP, USE_CASE_TOKEN_CATEGORIES } from './orama-index.js';\nimport { MINIMUM_SCORE_THRESHOLD, BLOCK_BOOST_PER_OCCURRENCE } from './scoring.js';\n\nexport interface SearchConfig {\n synonyms?: Record<string, string[]>;\n useCaseTokenCategories?: Record<string, string[]>;\n minimumScoreThreshold?: number;\n blockBoostPerOccurrence?: number;\n vectorSearchUrl?: string;\n vectorSearchTimeoutMs?: number;\n}\n\nexport const DEFAULT_SEARCH_CONFIG: Required<SearchConfig> = {\n synonyms: SYNONYM_MAP,\n useCaseTokenCategories: USE_CASE_TOKEN_CATEGORIES,\n minimumScoreThreshold: MINIMUM_SCORE_THRESHOLD,\n blockBoostPerOccurrence: BLOCK_BOOST_PER_OCCURRENCE,\n vectorSearchUrl: 'https://combative-jay-834.convex.site/search',\n vectorSearchTimeoutMs: 3000,\n};\n"],"mappings":"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","names":["snapshot"]}
@@ -0,0 +1,8 @@
1
+ import {
2
+ generateRulesFiles
3
+ } from "./chunk-VV2PJ75X.js";
4
+ import "./chunk-YSRGQDEB.js";
5
+ export {
6
+ generateRulesFiles
7
+ };
8
+ //# sourceMappingURL=rules-CKBRD3UL.js.map
package/dist/server.js CHANGED
@@ -2,9 +2,9 @@ import {
2
2
  createMcpServer,
3
3
  createSandboxServer,
4
4
  startMcpServer
5
- } from "./chunk-WBOVO43F.js";
5
+ } from "./chunk-HGGAXLRO.js";
6
6
  import "./chunk-4SVS3AA3.js";
7
- import "./chunk-FGIBLPSU.js";
7
+ import "./chunk-YSRGQDEB.js";
8
8
  export {
9
9
  createMcpServer,
10
10
  createSandboxServer,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fragments-sdk/mcp",
3
- "version": "0.6.2",
3
+ "version": "0.7.1",
4
4
  "license": "FSL-1.1-MIT",
5
5
  "description": "Standalone MCP server for Fragments design system — zero-config component discovery with semantic search",
6
6
  "mcpName": "io.github.ConanMcN/fragments-mcp",
@@ -62,8 +62,9 @@
62
62
  "@modelcontextprotocol/sdk": "^1.0.0",
63
63
  "@orama/orama": "^3.1.18",
64
64
  "typescript": "^5.7.2",
65
- "@fragments-sdk/context": "0.6.0",
66
- "@fragments-sdk/govern": "0.3.1"
65
+ "@fragments-sdk/context": "0.6.1",
66
+ "@fragments-sdk/core": "2.1.0",
67
+ "@fragments-sdk/govern": "0.3.2"
67
68
  },
68
69
  "devDependencies": {
69
70
  "@types/node": "^22.0.0",
@@ -71,7 +72,7 @@
71
72
  "tsup": "^8.3.5",
72
73
  "tsx": "^4.19.0",
73
74
  "vitest": "^2.1.8",
74
- "@fragments-sdk/extract": "0.1.0"
75
+ "@fragments-sdk/extract": "0.1.1"
75
76
  },
76
77
  "scripts": {
77
78
  "build": "tsup",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/rules.ts"],"sourcesContent":["import { join } from 'node:path';\nimport { writeFileSync, mkdirSync, existsSync } from 'node:fs';\nimport type { DesignSystemData } from './types.js';\n\nexport type RulesFormat = 'cursor' | 'claude' | 'copilot';\n\nexport interface RulesGeneratorOptions {\n data: DesignSystemData;\n brandName: string;\n outputDir: string;\n formats: RulesFormat[];\n /** Overwrite existing files (default: false — skip and warn) */\n force?: boolean;\n}\n\n/**\n * Generate IDE rules files from design system data.\n * Returns list of files written. Skips existing files unless force is true.\n */\nexport function generateRulesFiles(options: RulesGeneratorOptions): string[] {\n const { data, brandName, outputDir, formats, force = false } = options;\n const content = buildRulesContent(data, brandName);\n const files: string[] = [];\n\n for (const format of formats) {\n let filePath: string;\n let fileContent: string;\n\n switch (format) {\n case 'cursor':\n filePath = join(outputDir, '.cursorrules');\n fileContent = content;\n break;\n case 'claude':\n filePath = join(outputDir, 'CLAUDE.md');\n fileContent = `# CLAUDE.md\\n\\nThis file provides guidance to Claude Code when working with code in this repository.\\n\\n${content}`;\n break;\n case 'copilot': {\n const dir = join(outputDir, '.github');\n if (!existsSync(dir)) mkdirSync(dir, { recursive: true });\n filePath = join(dir, 'copilot-instructions.md');\n fileContent = content;\n break;\n }\n }\n\n if (!force && existsSync(filePath)) {\n console.error(` Skipped ${filePath} (already exists, use --force to overwrite)`);\n continue;\n }\n\n writeFileSync(filePath, fileContent, 'utf-8');\n files.push(filePath);\n }\n\n return files;\n}\n\nfunction buildRulesContent(data: DesignSystemData, brandName: string): string {\n const sections: string[] = [];\n\n // Header\n sections.push(`# ${brandName} Design System Rules\\n`);\n sections.push(`Always use ${brandName} components and design tokens when building UI. Do not use raw HTML elements, Tailwind classes, or hardcoded CSS values when a design system component or token exists.\\n`);\n\n // Component inventory\n const components = Object.values(data.components);\n if (components.length > 0) {\n sections.push('## Components\\n');\n const byCategory = new Map<string, string[]>();\n for (const c of components) {\n const cat = c.meta.category || 'uncategorized';\n if (!byCategory.has(cat)) byCategory.set(cat, []);\n byCategory.get(cat)!.push(c.meta.name);\n }\n for (const [cat, names] of byCategory) {\n sections.push(`### ${cat}\\n`);\n sections.push(names.map(n => `- ${n}`).join('\\n'));\n sections.push('');\n }\n }\n\n // Import pattern\n if (data.defaultPackageName) {\n sections.push('## Imports\\n');\n sections.push(`Import components from \\`${data.defaultPackageName}\\`:\\n`);\n sections.push('```typescript');\n const exampleNames = components.slice(0, 3).map(c => c.meta.name);\n sections.push(`import { ${exampleNames.join(', ')} } from '${data.defaultPackageName}';`);\n sections.push('```\\n');\n }\n\n // Tokens\n if (data.tokens && data.tokens.total > 0) {\n sections.push('## Design Tokens\\n');\n sections.push(`Prefix: \\`${data.tokens.prefix}\\`. Use \\`var(--token-name)\\` in CSS/styles.\\n`);\n sections.push('Available categories:');\n for (const [cat, tokens] of Object.entries(data.tokens.categories)) {\n sections.push(`- **${cat}** (${tokens.length} tokens)`);\n }\n sections.push('');\n }\n\n // Usage guidelines (aggregated from all components)\n const allDos: string[] = [];\n const allDonts: string[] = [];\n for (const c of components) {\n if (c.usage?.when) allDos.push(...c.usage.when.slice(0, 1).map(w => `${c.meta.name}: ${w}`));\n if (c.usage?.whenNot) allDonts.push(...c.usage.whenNot.slice(0, 1).map(w => `${c.meta.name}: ${w}`));\n }\n if (allDos.length > 0 || allDonts.length > 0) {\n sections.push('## Usage Guidelines\\n');\n if (allDos.length > 0) {\n sections.push('**Do:**');\n sections.push(allDos.slice(0, 10).map(d => `- ${d}`).join('\\n'));\n sections.push('');\n }\n if (allDonts.length > 0) {\n sections.push('**Don\\'t:**');\n sections.push(allDonts.slice(0, 10).map(d => `- ${d}`).join('\\n'));\n sections.push('');\n }\n }\n\n return sections.join('\\n');\n}\n"],"mappings":"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","names":[]}
@@ -1,29 +0,0 @@
1
- // src/config.ts
2
- import { readFileSync, existsSync } from "fs";
3
- import { join } from "path";
4
- function loadConfigFile(projectRoot) {
5
- const configPath = join(projectRoot, "ds-mcp.config.json");
6
- if (existsSync(configPath)) {
7
- try {
8
- const content = readFileSync(configPath, "utf-8");
9
- return JSON.parse(content);
10
- } catch (e) {
11
- throw new Error(`Failed to parse ${configPath}: ${e instanceof Error ? e.message : String(e)}`);
12
- }
13
- }
14
- const pkgPath = join(projectRoot, "package.json");
15
- if (existsSync(pkgPath)) {
16
- try {
17
- const content = readFileSync(pkgPath, "utf-8");
18
- const pkg = JSON.parse(content);
19
- if (pkg.dsMcp) return pkg.dsMcp;
20
- } catch {
21
- }
22
- }
23
- return null;
24
- }
25
-
26
- export {
27
- loadConfigFile
28
- };
29
- //# sourceMappingURL=chunk-FGIBLPSU.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/config.ts"],"sourcesContent":["import { readFileSync, existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { SearchConfig } from './search-config.js';\nimport type { ServiceEndpoints } from './service.js';\nimport type { Brand } from './constants.js';\n\nexport interface DsMcpConfigFile {\n /** Override branding (name, prefix, etc.) */\n brand?: Partial<Brand>;\n /** Search configuration overrides */\n search?: SearchConfig;\n /** Service endpoint path overrides */\n endpoints?: Partial<ServiceEndpoints>;\n /** Tool configuration */\n tools?: {\n /** Tool keys to exclude from registration */\n exclude?: string[];\n };\n /** Vector search configuration */\n vectorSearch?: {\n url?: string;\n apiKey?: string;\n };\n /** Playground URL for generate_ui */\n playgroundUrl?: string;\n}\n\n/**\n * Load config from ds-mcp.config.json or package.json \"dsMcp\" field.\n * Returns null if no config file is found (pure defaults).\n */\nexport function loadConfigFile(projectRoot: string): DsMcpConfigFile | null {\n // 1. Check for ds-mcp.config.json\n const configPath = join(projectRoot, 'ds-mcp.config.json');\n if (existsSync(configPath)) {\n try {\n const content = readFileSync(configPath, 'utf-8');\n return JSON.parse(content) as DsMcpConfigFile;\n } catch (e) {\n throw new Error(`Failed to parse ${configPath}: ${e instanceof Error ? e.message : String(e)}`);\n }\n }\n\n // 2. Check package.json \"dsMcp\" field\n const pkgPath = join(projectRoot, 'package.json');\n if (existsSync(pkgPath)) {\n try {\n const content = readFileSync(pkgPath, 'utf-8');\n const pkg = JSON.parse(content) as { dsMcp?: DsMcpConfigFile };\n if (pkg.dsMcp) return pkg.dsMcp;\n } catch {\n // Ignore parse errors in package.json\n }\n }\n\n return null;\n}\n"],"mappings":";AAAA,SAAS,cAAc,kBAAkB;AACzC,SAAS,YAAY;AA8Bd,SAAS,eAAe,aAA6C;AAE1E,QAAM,aAAa,KAAK,aAAa,oBAAoB;AACzD,MAAI,WAAW,UAAU,GAAG;AAC1B,QAAI;AACF,YAAM,UAAU,aAAa,YAAY,OAAO;AAChD,aAAO,KAAK,MAAM,OAAO;AAAA,IAC3B,SAAS,GAAG;AACV,YAAM,IAAI,MAAM,mBAAmB,UAAU,KAAK,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAAC,EAAE;AAAA,IAChG;AAAA,EACF;AAGA,QAAM,UAAU,KAAK,aAAa,cAAc;AAChD,MAAI,WAAW,OAAO,GAAG;AACvB,QAAI;AACF,YAAM,UAAU,aAAa,SAAS,OAAO;AAC7C,YAAM,MAAM,KAAK,MAAM,OAAO;AAC9B,UAAI,IAAI,MAAO,QAAO,IAAI;AAAA,IAC5B,QAAQ;AAAA,IAER;AAAA,EACF;AAEA,SAAO;AACT;","names":[]}