@tmorrow/cre8-wc 1.1.4 → 1.1.6

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.
@@ -0,0 +1,350 @@
1
+ /**
2
+ * Generate MCP Manifest from Web Component Analyzer output.
3
+ *
4
+ * Reads WCA JSON output and transforms it into the MCP manifest format
5
+ * used by the cre8-mcp server for component intelligence.
6
+ */
7
+ import { readFileSync, writeFileSync } from 'fs';
8
+ import { join, dirname } from 'path';
9
+ import { fileURLToPath } from 'url';
10
+ const __filename = fileURLToPath(import.meta.url);
11
+ const __dirname = dirname(__filename);
12
+ const ROOT = join(__dirname, '..');
13
+ // ─── Category Mapping ────────────────────────────────────────────────
14
+ const CATEGORY_MAP = {
15
+ 'button': 'Actions',
16
+ 'danger-button': 'Actions',
17
+ 'button-group': 'Actions',
18
+ 'split-button': 'Actions',
19
+ 'field': 'Forms',
20
+ 'field-note': 'Forms',
21
+ 'select': 'Forms',
22
+ 'multi-select': 'Forms',
23
+ 'checkbox-field': 'Forms',
24
+ 'checkbox-field-group': 'Forms',
25
+ 'checkbox-field-item': 'Forms',
26
+ 'radio-field': 'Forms',
27
+ 'radio-field-group': 'Forms',
28
+ 'radio-field-item': 'Forms',
29
+ 'date-picker': 'Forms',
30
+ 'select-tile': 'Forms',
31
+ 'select-tile-group': 'Forms',
32
+ 'select-tile-list': 'Forms',
33
+ 'toggle-field': 'Forms',
34
+ 'text-area': 'Forms',
35
+ 'form-fieldset': 'Forms',
36
+ 'card': 'Layout',
37
+ 'grid': 'Layout',
38
+ 'grid-item': 'Layout',
39
+ 'layout': 'Layout',
40
+ 'layout-container': 'Layout',
41
+ 'layout-section': 'Layout',
42
+ 'linelength-container': 'Layout',
43
+ 'section': 'Layout',
44
+ 'hero': 'Layout',
45
+ 'band': 'Layout',
46
+ 'divider': 'Layout',
47
+ 'main': 'Layout',
48
+ 'heading': 'Typography',
49
+ 'text-passage': 'Typography',
50
+ 'text-link': 'Typography',
51
+ 'link': 'Navigation',
52
+ 'link-list': 'Navigation',
53
+ 'link-list-item': 'Navigation',
54
+ 'breadcrumbs': 'Navigation',
55
+ 'breadcrumbs-item': 'Navigation',
56
+ 'pagination': 'Navigation',
57
+ 'header': 'Navigation',
58
+ 'footer': 'Navigation',
59
+ 'footer-nav': 'Navigation',
60
+ 'tabs': 'Navigation',
61
+ 'tab': 'Navigation',
62
+ 'tab-panel': 'Navigation',
63
+ 'global-nav': 'Navigation',
64
+ 'global-nav-item': 'Navigation',
65
+ 'primary-nav': 'Navigation',
66
+ 'primary-nav-item': 'Navigation',
67
+ 'tertiary-nav': 'Navigation',
68
+ 'tertiary-nav-item': 'Navigation',
69
+ 'utility-nav': 'Navigation',
70
+ 'utility-nav-item': 'Navigation',
71
+ 'nav-container': 'Navigation',
72
+ 'skip-nav': 'Navigation',
73
+ 'accordion': 'Disclosure',
74
+ 'accordion-item': 'Disclosure',
75
+ 'accordion-panel': 'Disclosure',
76
+ 'dropdown': 'Disclosure',
77
+ 'dropdown-item': 'Disclosure',
78
+ 'modal': 'Disclosure',
79
+ 'popover': 'Disclosure',
80
+ 'tooltip': 'Disclosure',
81
+ 'submenu': 'Disclosure',
82
+ 'submenu-item': 'Disclosure',
83
+ 'alert': 'Feedback',
84
+ 'inline-alert': 'Feedback',
85
+ 'badge': 'Feedback',
86
+ 'loading-spinner': 'Feedback',
87
+ 'skeleton-loader': 'Feedback',
88
+ 'progress-meter': 'Feedback',
89
+ 'percent-bar': 'Feedback',
90
+ 'progress-steps-item': 'Feedback',
91
+ 'table': 'Data',
92
+ 'table-header': 'Data',
93
+ 'table-header-cell': 'Data',
94
+ 'table-body': 'Data',
95
+ 'table-row': 'Data',
96
+ 'table-cell': 'Data',
97
+ 'table-object': 'Data',
98
+ 'list': 'Data',
99
+ 'list-item': 'Data',
100
+ 'tag': 'Data',
101
+ 'tag-list': 'Data',
102
+ 'remove-tag': 'Data',
103
+ 'chart': 'Data',
104
+ 'icon': 'Media',
105
+ 'logo': 'Media',
106
+ 'feature': 'Marketing',
107
+ 'page-header': 'Marketing',
108
+ };
109
+ // ─── Transform Helpers ──────────────────────────────────────────────
110
+ /**
111
+ * Parse a WCA type string into a base type and optional values array.
112
+ * e.g. '"primary" | "secondary" | "tertiary"' → { type: 'string', values: ['primary', 'secondary', 'tertiary'] }
113
+ */
114
+ function parseType(typeStr) {
115
+ if (!typeStr)
116
+ return { type: 'string' };
117
+ // Check for union of string literals: "a" | "b" | "c"
118
+ const unionMatch = typeStr.match(/^"[^"]*"(\s*\|\s*"[^"]*")+$/);
119
+ if (unionMatch) {
120
+ const values = [...typeStr.matchAll(/"([^"]*)"/g)].map(m => m[1]);
121
+ return { type: 'string', values };
122
+ }
123
+ // Check for union with undefined: "a" | "b" | undefined
124
+ const unionWithUndefined = typeStr.replace(/\s*\|\s*undefined/g, '').trim();
125
+ if (unionWithUndefined !== typeStr) {
126
+ return parseType(unionWithUndefined);
127
+ }
128
+ // Map common types
129
+ const lower = typeStr.toLowerCase().trim();
130
+ if (lower === 'boolean' || lower === 'true | false' || lower === 'false | true')
131
+ return { type: 'boolean' };
132
+ if (lower === 'number')
133
+ return { type: 'number' };
134
+ if (lower === 'string')
135
+ return { type: 'string' };
136
+ return { type: typeStr };
137
+ }
138
+ /**
139
+ * Parse a default value string into the appropriate JS type.
140
+ */
141
+ function parseDefault(defaultStr, type) {
142
+ if (defaultStr === undefined || defaultStr === 'undefined' || defaultStr === '""' || defaultStr === "''") {
143
+ return undefined;
144
+ }
145
+ // Boolean
146
+ if (defaultStr === 'false')
147
+ return false;
148
+ if (defaultStr === 'true')
149
+ return true;
150
+ // Number
151
+ if (type === 'number' && !isNaN(Number(defaultStr))) {
152
+ return Number(defaultStr);
153
+ }
154
+ // Strip quotes
155
+ const unquoted = defaultStr.replace(/^["']|["']$/g, '');
156
+ return unquoted || undefined;
157
+ }
158
+ /**
159
+ * Get the component short name (without cre8- prefix) for category lookup.
160
+ */
161
+ function getShortName(tagName) {
162
+ return tagName.replace(/^cre8-/, '');
163
+ }
164
+ /**
165
+ * Determine category from component name.
166
+ */
167
+ function getCategory(tagName) {
168
+ const short = getShortName(tagName);
169
+ return CATEGORY_MAP[short] || 'Other';
170
+ }
171
+ /**
172
+ * Generate basic examples for a component based on its attributes.
173
+ */
174
+ function generateExamples(tag) {
175
+ const examples = [];
176
+ const name = tag.name;
177
+ // Find variant attribute
178
+ const variantAttr = tag.attributes?.find(a => a.name === 'variant');
179
+ const textAttr = tag.attributes?.find(a => a.name === 'text');
180
+ if (variantAttr) {
181
+ const { values } = parseType(variantAttr.type);
182
+ if (values && values.length > 0) {
183
+ const primaryVariant = values[0];
184
+ let attrs = `variant="${primaryVariant}"`;
185
+ if (textAttr)
186
+ attrs += ` text="${capitalize(getShortName(name))}"`;
187
+ examples.push({
188
+ description: `${capitalize(primaryVariant)} ${getShortName(name)}`,
189
+ html: `<${name} ${attrs}></${name}>`,
190
+ });
191
+ }
192
+ }
193
+ else if (textAttr) {
194
+ examples.push({
195
+ description: `Basic ${getShortName(name)}`,
196
+ html: `<${name} text="${capitalize(getShortName(name))}"></${name}>`,
197
+ });
198
+ }
199
+ return examples;
200
+ }
201
+ function capitalize(s) {
202
+ return s.split('-').map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(' ');
203
+ }
204
+ // ─── Main Transform ─────────────────────────────────────────────────
205
+ function transformTag(tag) {
206
+ // Separate WCA attributes into true HTML attributes vs JS-only properties.
207
+ // In Lit, @property() without an explicit `attribute:` option auto-creates
208
+ // a lowercased attribute. But camelCase names (e.g. iconRotateDegree →
209
+ // "iconrotatedegree") are awkward and rarely used as HTML attributes in
210
+ // practice. We treat those as properties instead.
211
+ const attributes = {};
212
+ const properties = {};
213
+ // Build a set of property names that WCA links to attributes
214
+ for (const attr of tag.attributes || []) {
215
+ const { type, values } = parseType(attr.type);
216
+ const defaultValue = parseDefault(attr.default, type);
217
+ const isCamelCase = /[A-Z]/.test(attr.name);
218
+ const entry = { type };
219
+ if (values)
220
+ entry.values = values;
221
+ if (defaultValue !== undefined)
222
+ entry.default = defaultValue;
223
+ if (attr.description)
224
+ entry.description = attr.description;
225
+ if (isCamelCase) {
226
+ // CamelCase → treat as a JS property (set via .prop or Lit binding)
227
+ properties[attr.name] = entry;
228
+ }
229
+ else {
230
+ // Simple lowercase name → genuine HTML attribute
231
+ attributes[attr.name] = entry;
232
+ }
233
+ }
234
+ // Add properties that WCA lists with no attribute linkage (true prop-only),
235
+ // but skip inherited Lit/DOM internals that aren't useful for consumers
236
+ const SKIP_PROPERTIES = new Set([
237
+ 'styles', 'formAssociated', 'field', 'form', 'validationMessage',
238
+ 'validity', 'willValidate', 'shadowRoot', 'renderRoot',
239
+ 'isUpdatePending', 'hasUpdated', 'updateComplete',
240
+ ]);
241
+ for (const prop of tag.properties || []) {
242
+ if (prop.attribute)
243
+ continue; // Already handled above
244
+ if (SKIP_PROPERTIES.has(prop.name))
245
+ continue;
246
+ const { type } = parseType(prop.type);
247
+ const entry = { type };
248
+ if (prop.description)
249
+ entry.description = prop.description;
250
+ properties[prop.name] = entry;
251
+ }
252
+ // Transform slots
253
+ const slots = {};
254
+ for (const slot of tag.slots || []) {
255
+ const slotName = slot.name || 'default';
256
+ slots[slotName] = {};
257
+ if (slot.description)
258
+ slots[slotName].description = slot.description;
259
+ }
260
+ // Transform events
261
+ const events = {};
262
+ for (const event of tag.events || []) {
263
+ events[event.name] = { detail: {} };
264
+ if (event.description)
265
+ events[event.name].description = event.description;
266
+ }
267
+ // Transform CSS properties
268
+ const cssProperties = {};
269
+ for (const cssProp of tag.cssProperties || []) {
270
+ cssProperties[cssProp.name] = {};
271
+ if (cssProp.description)
272
+ cssProperties[cssProp.name].description = cssProp.description;
273
+ }
274
+ return {
275
+ name: tag.name,
276
+ category: getCategory(tag.name),
277
+ description: tag.description || `${capitalize(getShortName(tag.name))} component.`,
278
+ attributes,
279
+ properties,
280
+ slots,
281
+ events,
282
+ cssProperties,
283
+ examples: generateExamples(tag),
284
+ };
285
+ }
286
+ function main() {
287
+ // Read WCA output
288
+ const wcaPath = process.argv[2] || '/tmp/wca-raw.json';
289
+ console.log(`Reading WCA output from: ${wcaPath}`);
290
+ let wcaData;
291
+ try {
292
+ wcaData = JSON.parse(readFileSync(wcaPath, 'utf-8'));
293
+ }
294
+ catch (err) {
295
+ console.error(`Failed to read WCA output: ${err}`);
296
+ process.exit(1);
297
+ }
298
+ console.log(`Found ${wcaData.tags.length} tags in WCA output`);
299
+ // Read static data
300
+ const staticData = JSON.parse(readFileSync(join(__dirname, 'mcp-static-data.json'), 'utf-8'));
301
+ // Read package.json for version and dependencies
302
+ const pkgJson = JSON.parse(readFileSync(join(ROOT, 'package.json'), 'utf-8'));
303
+ // Transform components
304
+ const components = wcaData.tags
305
+ .filter(tag => tag.name.startsWith('cre8-'))
306
+ .map(transformTag)
307
+ .sort((a, b) => {
308
+ // Sort by category, then name
309
+ const catCompare = a.category.localeCompare(b.category);
310
+ if (catCompare !== 0)
311
+ return catCompare;
312
+ return a.name.localeCompare(b.name);
313
+ });
314
+ console.log(`Transformed ${components.length} components`);
315
+ // Log category distribution
316
+ const categories = {};
317
+ for (const comp of components) {
318
+ categories[comp.category] = (categories[comp.category] || 0) + 1;
319
+ }
320
+ console.log('Categories:', JSON.stringify(categories, null, 2));
321
+ // Build dependencies from package.json
322
+ const dependencies = {};
323
+ const depKeys = ['lit', '@lit/context', '@lit/react', '@a11y/focus-trap', 'chart.js', 'classnames', 'nanoid', 'zod', '@tmorrow/cre8-design-tokens'];
324
+ for (const key of depKeys) {
325
+ if (pkgJson.dependencies?.[key]) {
326
+ dependencies[key] = pkgJson.dependencies[key];
327
+ }
328
+ }
329
+ // Build manifest
330
+ const manifest = {
331
+ version: pkgJson.version,
332
+ library: pkgJson.name,
333
+ tagPrefix: 'cre8',
334
+ description: pkgJson.description,
335
+ framework: `Lit ${pkgJson.dependencies?.lit || '3.x'}`,
336
+ components,
337
+ baseClasses: staticData.baseClasses,
338
+ patterns: staticData.patterns,
339
+ designTokens: staticData.designTokens,
340
+ accessibility: staticData.accessibility,
341
+ dependencies,
342
+ };
343
+ // Write output
344
+ const outputPath = join(ROOT, 'mcp-manifest.json');
345
+ writeFileSync(outputPath, JSON.stringify(manifest, null, 2) + '\n');
346
+ console.log(`Wrote manifest to: ${outputPath}`);
347
+ console.log(`Total components: ${components.length}`);
348
+ }
349
+ main();
350
+ //# sourceMappingURL=generate-mcp-manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-mcp-manifest.js","sourceRoot":"","sources":["../../scripts/generate-mcp-manifest.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Generate MCP Manifest from Web Component Analyzer output.\n *\n * Reads WCA JSON output and transforms it into the MCP manifest format\n * used by the cre8-mcp server for component intelligence.\n */\n\nimport { readFileSync, writeFileSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\nconst ROOT = join(__dirname, '..');\n\n// ─── Category Mapping ────────────────────────────────────────────────\nconst CATEGORY_MAP: Record<string, string> = {\n 'button': 'Actions',\n 'danger-button': 'Actions',\n 'button-group': 'Actions',\n 'split-button': 'Actions',\n 'field': 'Forms',\n 'field-note': 'Forms',\n 'select': 'Forms',\n 'multi-select': 'Forms',\n 'checkbox-field': 'Forms',\n 'checkbox-field-group': 'Forms',\n 'checkbox-field-item': 'Forms',\n 'radio-field': 'Forms',\n 'radio-field-group': 'Forms',\n 'radio-field-item': 'Forms',\n 'date-picker': 'Forms',\n 'select-tile': 'Forms',\n 'select-tile-group': 'Forms',\n 'select-tile-list': 'Forms',\n 'toggle-field': 'Forms',\n 'text-area': 'Forms',\n 'form-fieldset': 'Forms',\n 'card': 'Layout',\n 'grid': 'Layout',\n 'grid-item': 'Layout',\n 'layout': 'Layout',\n 'layout-container': 'Layout',\n 'layout-section': 'Layout',\n 'linelength-container': 'Layout',\n 'section': 'Layout',\n 'hero': 'Layout',\n 'band': 'Layout',\n 'divider': 'Layout',\n 'main': 'Layout',\n 'heading': 'Typography',\n 'text-passage': 'Typography',\n 'text-link': 'Typography',\n 'link': 'Navigation',\n 'link-list': 'Navigation',\n 'link-list-item': 'Navigation',\n 'breadcrumbs': 'Navigation',\n 'breadcrumbs-item': 'Navigation',\n 'pagination': 'Navigation',\n 'header': 'Navigation',\n 'footer': 'Navigation',\n 'footer-nav': 'Navigation',\n 'tabs': 'Navigation',\n 'tab': 'Navigation',\n 'tab-panel': 'Navigation',\n 'global-nav': 'Navigation',\n 'global-nav-item': 'Navigation',\n 'primary-nav': 'Navigation',\n 'primary-nav-item': 'Navigation',\n 'tertiary-nav': 'Navigation',\n 'tertiary-nav-item': 'Navigation',\n 'utility-nav': 'Navigation',\n 'utility-nav-item': 'Navigation',\n 'nav-container': 'Navigation',\n 'skip-nav': 'Navigation',\n 'accordion': 'Disclosure',\n 'accordion-item': 'Disclosure',\n 'accordion-panel': 'Disclosure',\n 'dropdown': 'Disclosure',\n 'dropdown-item': 'Disclosure',\n 'modal': 'Disclosure',\n 'popover': 'Disclosure',\n 'tooltip': 'Disclosure',\n 'submenu': 'Disclosure',\n 'submenu-item': 'Disclosure',\n 'alert': 'Feedback',\n 'inline-alert': 'Feedback',\n 'badge': 'Feedback',\n 'loading-spinner': 'Feedback',\n 'skeleton-loader': 'Feedback',\n 'progress-meter': 'Feedback',\n 'percent-bar': 'Feedback',\n 'progress-steps-item': 'Feedback',\n 'table': 'Data',\n 'table-header': 'Data',\n 'table-header-cell': 'Data',\n 'table-body': 'Data',\n 'table-row': 'Data',\n 'table-cell': 'Data',\n 'table-object': 'Data',\n 'list': 'Data',\n 'list-item': 'Data',\n 'tag': 'Data',\n 'tag-list': 'Data',\n 'remove-tag': 'Data',\n 'chart': 'Data',\n 'icon': 'Media',\n 'logo': 'Media',\n 'feature': 'Marketing',\n 'page-header': 'Marketing',\n};\n\n// ─── WCA Types ───────────────────────────────────────────────────────\ninterface WcaTag {\n name: string;\n path: string;\n description?: string;\n attributes?: WcaAttribute[];\n properties?: WcaProperty[];\n slots?: WcaSlot[];\n events?: WcaEvent[];\n cssParts?: WcaCssPart[];\n cssProperties?: WcaCssProperty[];\n}\n\ninterface WcaAttribute {\n name: string;\n type?: string;\n default?: string;\n description?: string;\n}\n\ninterface WcaProperty {\n name: string;\n type?: string;\n default?: string;\n attribute?: string;\n description?: string;\n}\n\ninterface WcaSlot {\n name: string;\n description?: string;\n}\n\ninterface WcaEvent {\n name: string;\n description?: string;\n}\n\ninterface WcaCssPart {\n name: string;\n description?: string;\n}\n\ninterface WcaCssProperty {\n name: string;\n description?: string;\n}\n\ninterface WcaOutput {\n tags: WcaTag[];\n}\n\n// ─── MCP Manifest Types ─────────────────────────────────────────────\ninterface McpAttribute {\n type: string;\n values?: string[];\n default?: string | boolean | number;\n description?: string;\n}\n\ninterface McpSlot {\n description?: string;\n}\n\ninterface McpEvent {\n detail?: Record<string, unknown>;\n description?: string;\n}\n\ninterface McpCssProperty {\n description?: string;\n}\n\ninterface McpComponent {\n name: string;\n category: string;\n description: string;\n attributes: Record<string, McpAttribute>;\n properties: Record<string, { type: string; description?: string }>;\n slots: Record<string, McpSlot>;\n events: Record<string, McpEvent>;\n cssProperties: Record<string, McpCssProperty>;\n examples: Array<{ description: string; html: string }>;\n}\n\n// ─── Transform Helpers ──────────────────────────────────────────────\n\n\n/**\n * Parse a WCA type string into a base type and optional values array.\n * e.g. '\"primary\" | \"secondary\" | \"tertiary\"' → { type: 'string', values: ['primary', 'secondary', 'tertiary'] }\n */\nfunction parseType(typeStr?: string): { type: string; values?: string[] } {\n if (!typeStr) return { type: 'string' };\n\n // Check for union of string literals: \"a\" | \"b\" | \"c\"\n const unionMatch = typeStr.match(/^\"[^\"]*\"(\\s*\\|\\s*\"[^\"]*\")+$/);\n if (unionMatch) {\n const values = [...typeStr.matchAll(/\"([^\"]*)\"/g)].map(m => m[1]);\n return { type: 'string', values };\n }\n\n // Check for union with undefined: \"a\" | \"b\" | undefined\n const unionWithUndefined = typeStr.replace(/\\s*\\|\\s*undefined/g, '').trim();\n if (unionWithUndefined !== typeStr) {\n return parseType(unionWithUndefined);\n }\n\n // Map common types\n const lower = typeStr.toLowerCase().trim();\n if (lower === 'boolean' || lower === 'true | false' || lower === 'false | true') return { type: 'boolean' };\n if (lower === 'number') return { type: 'number' };\n if (lower === 'string') return { type: 'string' };\n\n return { type: typeStr };\n}\n\n/**\n * Parse a default value string into the appropriate JS type.\n */\nfunction parseDefault(defaultStr?: string, type?: string): string | boolean | number | undefined {\n if (defaultStr === undefined || defaultStr === 'undefined' || defaultStr === '\"\"' || defaultStr === \"''\") {\n return undefined;\n }\n\n // Boolean\n if (defaultStr === 'false') return false;\n if (defaultStr === 'true') return true;\n\n // Number\n if (type === 'number' && !isNaN(Number(defaultStr))) {\n return Number(defaultStr);\n }\n\n // Strip quotes\n const unquoted = defaultStr.replace(/^[\"']|[\"']$/g, '');\n return unquoted || undefined;\n}\n\n/**\n * Get the component short name (without cre8- prefix) for category lookup.\n */\nfunction getShortName(tagName: string): string {\n return tagName.replace(/^cre8-/, '');\n}\n\n/**\n * Determine category from component name.\n */\nfunction getCategory(tagName: string): string {\n const short = getShortName(tagName);\n return CATEGORY_MAP[short] || 'Other';\n}\n\n/**\n * Generate basic examples for a component based on its attributes.\n */\nfunction generateExamples(tag: WcaTag): Array<{ description: string; html: string }> {\n const examples: Array<{ description: string; html: string }> = [];\n const name = tag.name;\n\n // Find variant attribute\n const variantAttr = tag.attributes?.find(a => a.name === 'variant');\n const textAttr = tag.attributes?.find(a => a.name === 'text');\n\n if (variantAttr) {\n const { values } = parseType(variantAttr.type);\n if (values && values.length > 0) {\n const primaryVariant = values[0];\n let attrs = `variant=\"${primaryVariant}\"`;\n if (textAttr) attrs += ` text=\"${capitalize(getShortName(name))}\"`;\n examples.push({\n description: `${capitalize(primaryVariant)} ${getShortName(name)}`,\n html: `<${name} ${attrs}></${name}>`,\n });\n }\n } else if (textAttr) {\n examples.push({\n description: `Basic ${getShortName(name)}`,\n html: `<${name} text=\"${capitalize(getShortName(name))}\"></${name}>`,\n });\n }\n\n return examples;\n}\n\nfunction capitalize(s: string): string {\n return s.split('-').map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(' ');\n}\n\n// ─── Main Transform ─────────────────────────────────────────────────\n\nfunction transformTag(tag: WcaTag): McpComponent {\n // Separate WCA attributes into true HTML attributes vs JS-only properties.\n // In Lit, @property() without an explicit `attribute:` option auto-creates\n // a lowercased attribute. But camelCase names (e.g. iconRotateDegree →\n // \"iconrotatedegree\") are awkward and rarely used as HTML attributes in\n // practice. We treat those as properties instead.\n const attributes: Record<string, McpAttribute> = {};\n const properties: Record<string, { type: string; values?: string[]; default?: string | boolean | number; description?: string }> = {};\n\n // Build a set of property names that WCA links to attributes\n\n\n for (const attr of tag.attributes || []) {\n const { type, values } = parseType(attr.type);\n const defaultValue = parseDefault(attr.default, type);\n const isCamelCase = /[A-Z]/.test(attr.name);\n\n const entry: McpAttribute = { type };\n if (values) entry.values = values;\n if (defaultValue !== undefined) entry.default = defaultValue;\n if (attr.description) entry.description = attr.description;\n\n if (isCamelCase) {\n // CamelCase → treat as a JS property (set via .prop or Lit binding)\n properties[attr.name] = entry;\n } else {\n // Simple lowercase name → genuine HTML attribute\n attributes[attr.name] = entry;\n }\n }\n\n // Add properties that WCA lists with no attribute linkage (true prop-only),\n // but skip inherited Lit/DOM internals that aren't useful for consumers\n const SKIP_PROPERTIES = new Set([\n 'styles', 'formAssociated', 'field', 'form', 'validationMessage',\n 'validity', 'willValidate', 'shadowRoot', 'renderRoot',\n 'isUpdatePending', 'hasUpdated', 'updateComplete',\n ]);\n for (const prop of tag.properties || []) {\n if (prop.attribute) continue; // Already handled above\n if (SKIP_PROPERTIES.has(prop.name)) continue;\n const { type } = parseType(prop.type);\n const entry: { type: string; description?: string } = { type };\n if (prop.description) entry.description = prop.description;\n properties[prop.name] = entry;\n }\n\n // Transform slots\n const slots: Record<string, McpSlot> = {};\n for (const slot of tag.slots || []) {\n const slotName = slot.name || 'default';\n slots[slotName] = {};\n if (slot.description) slots[slotName].description = slot.description;\n }\n\n // Transform events\n const events: Record<string, McpEvent> = {};\n for (const event of tag.events || []) {\n events[event.name] = { detail: {} };\n if (event.description) events[event.name].description = event.description;\n }\n\n // Transform CSS properties\n const cssProperties: Record<string, McpCssProperty> = {};\n for (const cssProp of tag.cssProperties || []) {\n cssProperties[cssProp.name] = {};\n if (cssProp.description) cssProperties[cssProp.name].description = cssProp.description;\n }\n\n return {\n name: tag.name,\n category: getCategory(tag.name),\n description: tag.description || `${capitalize(getShortName(tag.name))} component.`,\n attributes,\n properties,\n slots,\n events,\n cssProperties,\n examples: generateExamples(tag),\n };\n}\n\nfunction main() {\n // Read WCA output\n const wcaPath = process.argv[2] || '/tmp/wca-raw.json';\n console.log(`Reading WCA output from: ${wcaPath}`);\n\n let wcaData: WcaOutput;\n try {\n wcaData = JSON.parse(readFileSync(wcaPath, 'utf-8'));\n } catch (err) {\n console.error(`Failed to read WCA output: ${err}`);\n process.exit(1);\n }\n\n console.log(`Found ${wcaData.tags.length} tags in WCA output`);\n\n // Read static data\n const staticData = JSON.parse(\n readFileSync(join(__dirname, 'mcp-static-data.json'), 'utf-8')\n );\n\n // Read package.json for version and dependencies\n const pkgJson = JSON.parse(\n readFileSync(join(ROOT, 'package.json'), 'utf-8')\n );\n\n // Transform components\n const components = wcaData.tags\n .filter(tag => tag.name.startsWith('cre8-'))\n .map(transformTag)\n .sort((a, b) => {\n // Sort by category, then name\n const catCompare = a.category.localeCompare(b.category);\n if (catCompare !== 0) return catCompare;\n return a.name.localeCompare(b.name);\n });\n\n console.log(`Transformed ${components.length} components`);\n\n // Log category distribution\n const categories: Record<string, number> = {};\n for (const comp of components) {\n categories[comp.category] = (categories[comp.category] || 0) + 1;\n }\n console.log('Categories:', JSON.stringify(categories, null, 2));\n\n // Build dependencies from package.json\n const dependencies: Record<string, string> = {};\n const depKeys = ['lit', '@lit/context', '@lit/react', '@a11y/focus-trap', 'chart.js', 'classnames', 'nanoid', 'zod', '@tmorrow/cre8-design-tokens'];\n for (const key of depKeys) {\n if (pkgJson.dependencies?.[key]) {\n dependencies[key] = pkgJson.dependencies[key];\n }\n }\n\n // Build manifest\n const manifest = {\n version: pkgJson.version,\n library: pkgJson.name,\n tagPrefix: 'cre8',\n description: pkgJson.description,\n framework: `Lit ${pkgJson.dependencies?.lit || '3.x'}`,\n components,\n baseClasses: staticData.baseClasses,\n patterns: staticData.patterns,\n designTokens: staticData.designTokens,\n accessibility: staticData.accessibility,\n dependencies,\n };\n\n // Write output\n const outputPath = join(ROOT, 'mcp-manifest.json');\n writeFileSync(outputPath, JSON.stringify(manifest, null, 2) + '\\n');\n console.log(`Wrote manifest to: ${outputPath}`);\n console.log(`Total components: ${components.length}`);\n}\n\nmain();\n"]}