@cobwds/mcp-server 1.19.3
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/README.md +235 -0
- package/data/cem/custom-elements.json +15923 -0
- package/data/guides/.gitkeep +0 -0
- package/data/guides/fonts.md +56 -0
- package/data/guides/form-validation.md +169 -0
- package/data/guides/frameworks/angular.md +71 -0
- package/data/guides/frameworks/dotnet.md +42 -0
- package/data/guides/frameworks/drupal.md +39 -0
- package/data/guides/frameworks/react.md +115 -0
- package/data/guides/frameworks/vanilla.md +45 -0
- package/data/guides/installation.md +73 -0
- package/data/guides/page-structure.md +161 -0
- package/data/guides/styles.md +48 -0
- package/data/guides/themes.md +61 -0
- package/data/tokens/tokens.css +479 -0
- package/data/tokens/tokens.json +1553 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/lib/cem-parser.d.ts +102 -0
- package/dist/lib/cem-parser.d.ts.map +1 -0
- package/dist/lib/cem-parser.js +92 -0
- package/dist/lib/search.d.ts +20 -0
- package/dist/lib/search.d.ts.map +1 -0
- package/dist/lib/search.js +87 -0
- package/dist/lib/token-parser.d.ts +128 -0
- package/dist/lib/token-parser.d.ts.map +1 -0
- package/dist/lib/token-parser.js +431 -0
- package/dist/prompts/cobwds-mode.d.ts +8 -0
- package/dist/prompts/cobwds-mode.d.ts.map +1 -0
- package/dist/prompts/cobwds-mode.js +60 -0
- package/dist/resources/components.d.ts +12 -0
- package/dist/resources/components.d.ts.map +1 -0
- package/dist/resources/components.js +62 -0
- package/dist/resources/guides.d.ts +11 -0
- package/dist/resources/guides.d.ts.map +1 -0
- package/dist/resources/guides.js +76 -0
- package/dist/resources/index.d.ts +8 -0
- package/dist/resources/index.d.ts.map +1 -0
- package/dist/resources/index.js +13 -0
- package/dist/resources/tokens.d.ts +17 -0
- package/dist/resources/tokens.d.ts.map +1 -0
- package/dist/resources/tokens.js +312 -0
- package/dist/server.d.ts +11 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +30 -0
- package/dist/tools/component-tools.d.ts +12 -0
- package/dist/tools/component-tools.d.ts.map +1 -0
- package/dist/tools/component-tools.js +95 -0
- package/dist/tools/guide-tools.d.ts +9 -0
- package/dist/tools/guide-tools.d.ts.map +1 -0
- package/dist/tools/guide-tools.js +80 -0
- package/dist/tools/index.d.ts +8 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +17 -0
- package/dist/tools/token-tools.d.ts +13 -0
- package/dist/tools/token-tools.d.ts.map +1 -0
- package/dist/tools/token-tools.js +207 -0
- package/dist/tools/utility-tools.d.ts +8 -0
- package/dist/tools/utility-tools.d.ts.map +1 -0
- package/dist/tools/utility-tools.js +293 -0
- package/dist/tools/validation-tools.d.ts +11 -0
- package/dist/tools/validation-tools.d.ts.map +1 -0
- package/dist/tools/validation-tools.js +60 -0
- package/package.json +54 -0
|
@@ -0,0 +1,431 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Design Token Parser
|
|
3
|
+
*
|
|
4
|
+
* Reads and parses COBWDS design tokens with a CSS-centric approach.
|
|
5
|
+
* Returns data aligned with tokens.css output (not JSON internals).
|
|
6
|
+
*
|
|
7
|
+
* Key transformations:
|
|
8
|
+
* - Token paths are converted to CSS variable names
|
|
9
|
+
* - Alias references become var() expressions
|
|
10
|
+
* - Layer prefixes (primitive, applied) are stripped
|
|
11
|
+
*/
|
|
12
|
+
import { readFileSync, existsSync } from "node:fs";
|
|
13
|
+
import { resolve, dirname } from "node:path";
|
|
14
|
+
import { fileURLToPath } from "node:url";
|
|
15
|
+
// ESM path resolution
|
|
16
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
17
|
+
const __dirname = dirname(__filename);
|
|
18
|
+
// ============================================================================
|
|
19
|
+
// Token Data Cache
|
|
20
|
+
// ============================================================================
|
|
21
|
+
let cachedCSSTokens = null;
|
|
22
|
+
let cachedTokenGraph = null;
|
|
23
|
+
let cachedRawTokens = null;
|
|
24
|
+
// ============================================================================
|
|
25
|
+
// Path Resolution
|
|
26
|
+
// ============================================================================
|
|
27
|
+
/**
|
|
28
|
+
* Get the path to tokens.json file
|
|
29
|
+
* Uses ESM-compatible path resolution with fallbacks for different contexts
|
|
30
|
+
*/
|
|
31
|
+
export function getTokensPath() {
|
|
32
|
+
const possiblePaths = [
|
|
33
|
+
// Bundled data — works in standalone installs (most reliable)
|
|
34
|
+
resolve(__dirname, "../../data/tokens/tokens.json"),
|
|
35
|
+
// From lib/ directory (normal execution)
|
|
36
|
+
resolve(__dirname, "../../../../tokens/src/tokens.json"),
|
|
37
|
+
// From mcp-server package root
|
|
38
|
+
resolve(__dirname, "../../../tokens/src/tokens.json"),
|
|
39
|
+
// From monorepo root
|
|
40
|
+
resolve(__dirname, "../../../../../packages/tokens/src/tokens.json"),
|
|
41
|
+
// Direct path from monorepo root
|
|
42
|
+
resolve(process.cwd(), "packages/tokens/src/tokens.json"),
|
|
43
|
+
// From mcp-server package
|
|
44
|
+
resolve(process.cwd(), "../tokens/src/tokens.json"),
|
|
45
|
+
];
|
|
46
|
+
for (const path of possiblePaths) {
|
|
47
|
+
if (existsSync(path)) {
|
|
48
|
+
return path;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Get the path to tokens.css file
|
|
55
|
+
*/
|
|
56
|
+
export function getTokensCSSPath() {
|
|
57
|
+
const possiblePaths = [
|
|
58
|
+
// Bundled data — works in standalone installs (most reliable)
|
|
59
|
+
resolve(__dirname, "../../data/tokens/tokens.css"),
|
|
60
|
+
resolve(__dirname, "../../../../tokens/dist/tokens.css"),
|
|
61
|
+
resolve(__dirname, "../../../tokens/dist/tokens.css"),
|
|
62
|
+
resolve(__dirname, "../../../../../packages/tokens/dist/tokens.css"),
|
|
63
|
+
resolve(process.cwd(), "packages/tokens/dist/tokens.css"),
|
|
64
|
+
resolve(process.cwd(), "../tokens/dist/tokens.css"),
|
|
65
|
+
];
|
|
66
|
+
for (const path of possiblePaths) {
|
|
67
|
+
if (existsSync(path)) {
|
|
68
|
+
return path;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
// ============================================================================
|
|
74
|
+
// Constants
|
|
75
|
+
// ============================================================================
|
|
76
|
+
const LAYER_PREFIXES = ["primitive", "applied", "appearance", "theme"];
|
|
77
|
+
// ============================================================================
|
|
78
|
+
// CSS Variable Transformation
|
|
79
|
+
// ============================================================================
|
|
80
|
+
/**
|
|
81
|
+
* Transform a JSON token path to CSS variable name
|
|
82
|
+
*
|
|
83
|
+
* Examples:
|
|
84
|
+
* - "primitive.color.neutral.900" → "--cob-color-neutral-900"
|
|
85
|
+
* - "applied.color.text.default" → "--cob-color-text"
|
|
86
|
+
* - "color.theme.default" → "--cob-color-theme"
|
|
87
|
+
* - "font.size.md" → "--cob-font-size-md"
|
|
88
|
+
*/
|
|
89
|
+
export function toCSSVariable(jsonPath) {
|
|
90
|
+
let name = "--cob-" +
|
|
91
|
+
jsonPath
|
|
92
|
+
// Strip layer prefixes
|
|
93
|
+
.replace(new RegExp(`^(${LAYER_PREFIXES.join("|")})\\.`), "")
|
|
94
|
+
// Dots to hyphens
|
|
95
|
+
.replace(/\./g, "-");
|
|
96
|
+
// Strip trailing -default suffix
|
|
97
|
+
name = name.replace(/-default$/, "");
|
|
98
|
+
return name;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Convert an alias reference to CSS var() syntax
|
|
102
|
+
*
|
|
103
|
+
* Examples:
|
|
104
|
+
* - "{primitive.color.neutral.900}" → "var(--cob-color-neutral-900)"
|
|
105
|
+
* - "{font.size.md}" → "var(--cob-font-size-md)"
|
|
106
|
+
*/
|
|
107
|
+
export function aliasToVarRef(aliasValue) {
|
|
108
|
+
// Extract the path from {path.to.token}
|
|
109
|
+
const match = aliasValue.match(/^\{(.+)\}$/);
|
|
110
|
+
if (!match) {
|
|
111
|
+
return { cssValue: aliasValue, referencesVariable: "" };
|
|
112
|
+
}
|
|
113
|
+
const referencesVariable = toCSSVariable(match[1]);
|
|
114
|
+
const cssValue = `var(${referencesVariable})`;
|
|
115
|
+
return { cssValue, referencesVariable };
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Determine the category from a JSON path
|
|
119
|
+
*/
|
|
120
|
+
function getCategoryFromPath(jsonPath) {
|
|
121
|
+
const parts = jsonPath.split(".");
|
|
122
|
+
// Skip layer prefix if present
|
|
123
|
+
const startIndex = LAYER_PREFIXES.includes(parts[0]) ? 1 : 0;
|
|
124
|
+
return parts[startIndex] || "unknown";
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Determine the layer from a JSON path
|
|
128
|
+
*
|
|
129
|
+
* Layers:
|
|
130
|
+
* - primitive: Raw values (colors, sizes, fonts, spacing, etc.)
|
|
131
|
+
* - applied: Semantic tokens that reference primitives (includes color.theme.* defaults)
|
|
132
|
+
* - theme: Agency theme overrides
|
|
133
|
+
* - appearance: Light/dark mode variations
|
|
134
|
+
*/
|
|
135
|
+
function getLayerFromPath(jsonPath) {
|
|
136
|
+
const parts = jsonPath.split(".");
|
|
137
|
+
// Check for explicit layer prefixes
|
|
138
|
+
if (LAYER_PREFIXES.includes(parts[0])) {
|
|
139
|
+
return parts[0];
|
|
140
|
+
}
|
|
141
|
+
// color.theme.* tokens are applied semantic tokens (agency themes override these)
|
|
142
|
+
if (parts[0] === "color" && parts[1] === "theme") {
|
|
143
|
+
return "applied";
|
|
144
|
+
}
|
|
145
|
+
// Non-prefixed categories (space, size, font, radius, etc.) contain raw values
|
|
146
|
+
// so they are classified as "primitive"
|
|
147
|
+
return "primitive";
|
|
148
|
+
}
|
|
149
|
+
// ============================================================================
|
|
150
|
+
// Token Parsing
|
|
151
|
+
// ============================================================================
|
|
152
|
+
/**
|
|
153
|
+
* Load raw token data from tokens.json
|
|
154
|
+
*/
|
|
155
|
+
function loadRawTokens() {
|
|
156
|
+
if (cachedRawTokens) {
|
|
157
|
+
return cachedRawTokens;
|
|
158
|
+
}
|
|
159
|
+
const tokensPath = getTokensPath();
|
|
160
|
+
if (!tokensPath) {
|
|
161
|
+
console.error("Warning: No tokens file found");
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
164
|
+
try {
|
|
165
|
+
const content = readFileSync(tokensPath, "utf-8");
|
|
166
|
+
cachedRawTokens = JSON.parse(content);
|
|
167
|
+
return cachedRawTokens;
|
|
168
|
+
}
|
|
169
|
+
catch (error) {
|
|
170
|
+
console.error("Warning: Could not parse tokens file:", error);
|
|
171
|
+
return null;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Parse tokens recursively into CSS-centric format
|
|
176
|
+
*/
|
|
177
|
+
function parseCSSTokens(obj, prefix = "", resolvedValues = new Map()) {
|
|
178
|
+
const tokens = [];
|
|
179
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
180
|
+
if (key.startsWith("$"))
|
|
181
|
+
continue; // Skip meta properties
|
|
182
|
+
const jsonPath = prefix ? `${prefix}.${key}` : key;
|
|
183
|
+
if (typeof value === "object" &&
|
|
184
|
+
value !== null &&
|
|
185
|
+
"$value" in value) {
|
|
186
|
+
// This is a token
|
|
187
|
+
const tokenObj = value;
|
|
188
|
+
const rawValue = tokenObj.$value;
|
|
189
|
+
const description = tokenObj.$description;
|
|
190
|
+
const cssVariable = toCSSVariable(jsonPath);
|
|
191
|
+
const category = getCategoryFromPath(jsonPath);
|
|
192
|
+
const layer = getLayerFromPath(jsonPath);
|
|
193
|
+
let cssValue;
|
|
194
|
+
let referencesVariable;
|
|
195
|
+
let resolvedValue;
|
|
196
|
+
// Handle different value types
|
|
197
|
+
if (typeof rawValue === "string" && rawValue.startsWith("{")) {
|
|
198
|
+
// Alias reference
|
|
199
|
+
const aliasResult = aliasToVarRef(rawValue);
|
|
200
|
+
cssValue = aliasResult.cssValue;
|
|
201
|
+
referencesVariable = aliasResult.referencesVariable;
|
|
202
|
+
// Try to resolve the value
|
|
203
|
+
resolvedValue = resolvedValues.get(referencesVariable);
|
|
204
|
+
}
|
|
205
|
+
else if (Array.isArray(rawValue)) {
|
|
206
|
+
// Complex value (like shadows) - format as string
|
|
207
|
+
cssValue = JSON.stringify(rawValue);
|
|
208
|
+
resolvedValue = cssValue;
|
|
209
|
+
}
|
|
210
|
+
else if (typeof rawValue === "object" && rawValue !== null) {
|
|
211
|
+
// Object value (like single shadow)
|
|
212
|
+
cssValue = JSON.stringify(rawValue);
|
|
213
|
+
resolvedValue = cssValue;
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
// Direct value
|
|
217
|
+
cssValue = String(rawValue);
|
|
218
|
+
resolvedValue = cssValue;
|
|
219
|
+
}
|
|
220
|
+
// Store resolved value for other tokens to reference
|
|
221
|
+
if (resolvedValue) {
|
|
222
|
+
resolvedValues.set(cssVariable, resolvedValue);
|
|
223
|
+
}
|
|
224
|
+
tokens.push({
|
|
225
|
+
cssVariable,
|
|
226
|
+
cssValue,
|
|
227
|
+
referencesVariable,
|
|
228
|
+
resolvedValue,
|
|
229
|
+
description,
|
|
230
|
+
category,
|
|
231
|
+
layer,
|
|
232
|
+
jsonPath,
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
else if (typeof value === "object" && value !== null) {
|
|
236
|
+
// Recurse into nested group
|
|
237
|
+
tokens.push(...parseCSSTokens(value, jsonPath, resolvedValues));
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
return tokens;
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Resolve all alias values to their final resolved values
|
|
244
|
+
*/
|
|
245
|
+
function resolveAllValues(tokens) {
|
|
246
|
+
const byVariable = new Map();
|
|
247
|
+
for (const token of tokens) {
|
|
248
|
+
byVariable.set(token.cssVariable, token);
|
|
249
|
+
}
|
|
250
|
+
// Iterate to resolve nested aliases (max 10 levels to prevent infinite loops)
|
|
251
|
+
for (let i = 0; i < 10; i++) {
|
|
252
|
+
let changed = false;
|
|
253
|
+
for (const token of tokens) {
|
|
254
|
+
if (token.referencesVariable && !token.resolvedValue) {
|
|
255
|
+
const referenced = byVariable.get(token.referencesVariable);
|
|
256
|
+
if (referenced?.resolvedValue) {
|
|
257
|
+
token.resolvedValue = referenced.resolvedValue;
|
|
258
|
+
changed = true;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
if (!changed)
|
|
263
|
+
break;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
// ============================================================================
|
|
267
|
+
// Token Graph
|
|
268
|
+
// ============================================================================
|
|
269
|
+
/**
|
|
270
|
+
* Build a dependency graph of tokens
|
|
271
|
+
* Shows which tokens reference which, and which tokens are used by which
|
|
272
|
+
*/
|
|
273
|
+
export function buildTokenGraph() {
|
|
274
|
+
if (cachedTokenGraph) {
|
|
275
|
+
return cachedTokenGraph;
|
|
276
|
+
}
|
|
277
|
+
const tokens = getCSSTokens();
|
|
278
|
+
const graph = new Map();
|
|
279
|
+
// Initialize all nodes
|
|
280
|
+
for (const token of tokens) {
|
|
281
|
+
graph.set(token.cssVariable, {
|
|
282
|
+
cssVariable: token.cssVariable,
|
|
283
|
+
referencesVariable: token.referencesVariable,
|
|
284
|
+
usedBy: [],
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
// Build usedBy relationships
|
|
288
|
+
for (const token of tokens) {
|
|
289
|
+
if (token.referencesVariable) {
|
|
290
|
+
const referenced = graph.get(token.referencesVariable);
|
|
291
|
+
if (referenced) {
|
|
292
|
+
referenced.usedBy.push(token.cssVariable);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
cachedTokenGraph = graph;
|
|
297
|
+
return graph;
|
|
298
|
+
}
|
|
299
|
+
// ============================================================================
|
|
300
|
+
// Public API - CSS-Centric
|
|
301
|
+
// ============================================================================
|
|
302
|
+
/**
|
|
303
|
+
* Get all tokens in CSS-centric format
|
|
304
|
+
*/
|
|
305
|
+
export function getCSSTokens() {
|
|
306
|
+
if (cachedCSSTokens) {
|
|
307
|
+
return cachedCSSTokens;
|
|
308
|
+
}
|
|
309
|
+
const rawTokens = loadRawTokens();
|
|
310
|
+
if (!rawTokens) {
|
|
311
|
+
cachedCSSTokens = [];
|
|
312
|
+
return cachedCSSTokens;
|
|
313
|
+
}
|
|
314
|
+
cachedCSSTokens = parseCSSTokens(rawTokens);
|
|
315
|
+
resolveAllValues(cachedCSSTokens);
|
|
316
|
+
return cachedCSSTokens;
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Get CSS tokens filtered by category
|
|
320
|
+
*/
|
|
321
|
+
export function getCSSTokensByCategory(category) {
|
|
322
|
+
const tokens = getCSSTokens();
|
|
323
|
+
return tokens.filter((t) => t.category.toLowerCase() === category.toLowerCase());
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Get a single token by CSS variable name
|
|
327
|
+
*/
|
|
328
|
+
export function getCSSTokenByVariable(variableName) {
|
|
329
|
+
const tokens = getCSSTokens();
|
|
330
|
+
// Normalize: accept with or without -- prefix
|
|
331
|
+
const normalized = variableName.startsWith("--")
|
|
332
|
+
? variableName
|
|
333
|
+
: `--cob-${variableName}`;
|
|
334
|
+
return tokens.find((t) => t.cssVariable === normalized);
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* Get all unique categories
|
|
338
|
+
*/
|
|
339
|
+
export function getCSSTokenCategories() {
|
|
340
|
+
const tokens = getCSSTokens();
|
|
341
|
+
const counts = new Map();
|
|
342
|
+
for (const token of tokens) {
|
|
343
|
+
counts.set(token.category, (counts.get(token.category) || 0) + 1);
|
|
344
|
+
}
|
|
345
|
+
return Array.from(counts.entries())
|
|
346
|
+
.map(([category, count]) => ({ category, count }))
|
|
347
|
+
.sort((a, b) => a.category.localeCompare(b.category));
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Get raw tokens.css content
|
|
351
|
+
*/
|
|
352
|
+
export function getTokensCSS() {
|
|
353
|
+
const cssPath = getTokensCSSPath();
|
|
354
|
+
if (!cssPath) {
|
|
355
|
+
return null;
|
|
356
|
+
}
|
|
357
|
+
try {
|
|
358
|
+
return readFileSync(cssPath, "utf-8");
|
|
359
|
+
}
|
|
360
|
+
catch {
|
|
361
|
+
return null;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* Get recommended tokens for everyday use.
|
|
366
|
+
*
|
|
367
|
+
* Excludes color primitive tokens (the ~150 palette ramps like neutral-*, red-*,
|
|
368
|
+
* blue-*) which are low-level raw values. For font tokens, applied aliases
|
|
369
|
+
* (body-*, h*, ui-*) are sorted before primitives so the most useful tokens
|
|
370
|
+
* appear first.
|
|
371
|
+
*/
|
|
372
|
+
export function getRecommendedTokens() {
|
|
373
|
+
const tokens = getCSSTokens();
|
|
374
|
+
const filtered = tokens.filter((t) => !(t.category === "color" && t.layer === "primitive"));
|
|
375
|
+
// For font tokens, sort applied before primitive so named aliases surface first
|
|
376
|
+
filtered.sort((a, b) => {
|
|
377
|
+
if (a.category === "font" && b.category === "font") {
|
|
378
|
+
if (a.layer === "applied" && b.layer !== "applied")
|
|
379
|
+
return -1;
|
|
380
|
+
if (a.layer !== "applied" && b.layer === "applied")
|
|
381
|
+
return 1;
|
|
382
|
+
}
|
|
383
|
+
return 0;
|
|
384
|
+
});
|
|
385
|
+
return filtered;
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* Get only primitive (raw value) tokens across all categories.
|
|
389
|
+
*/
|
|
390
|
+
export function getPrimitiveTokens() {
|
|
391
|
+
const tokens = getCSSTokens();
|
|
392
|
+
return tokens.filter((t) => t.layer === "primitive");
|
|
393
|
+
}
|
|
394
|
+
/**
|
|
395
|
+
* Get alternative tokens in the same category that share the same name prefix.
|
|
396
|
+
*
|
|
397
|
+
* First looks for child variants (tokens starting with this token's name + "-"):
|
|
398
|
+
* --cob-color-text → finds --cob-color-text-weak, --cob-color-text-reverse, etc.
|
|
399
|
+
*
|
|
400
|
+
* If no children exist, looks for siblings (tokens sharing the same parent prefix):
|
|
401
|
+
* --cob-color-text-weak → parent: --cob-color-text → finds text, text-weaker, etc.
|
|
402
|
+
*
|
|
403
|
+
* Returns an array of cssVariable strings (empty if none found).
|
|
404
|
+
*/
|
|
405
|
+
export function getAlternativeTokens(token) {
|
|
406
|
+
const varName = token.cssVariable;
|
|
407
|
+
const tokens = getCSSTokens();
|
|
408
|
+
// Look for child variants: tokens starting with this token's name + "-"
|
|
409
|
+
const children = tokens.filter((t) => t.category === token.category && t.cssVariable.startsWith(varName + "-"));
|
|
410
|
+
if (children.length > 0) {
|
|
411
|
+
return children.map((t) => t.cssVariable);
|
|
412
|
+
}
|
|
413
|
+
// No children — look for siblings sharing the same parent prefix
|
|
414
|
+
const lastDash = varName.lastIndexOf("-");
|
|
415
|
+
if (lastDash <= 5)
|
|
416
|
+
return []; // "--cob-" is 6 chars minimum
|
|
417
|
+
const parent = varName.slice(0, lastDash);
|
|
418
|
+
return tokens
|
|
419
|
+
.filter((t) => t.category === token.category &&
|
|
420
|
+
t.cssVariable !== varName &&
|
|
421
|
+
(t.cssVariable === parent || t.cssVariable.startsWith(parent + "-")))
|
|
422
|
+
.map((t) => t.cssVariable);
|
|
423
|
+
}
|
|
424
|
+
/**
|
|
425
|
+
* Clear all cached tokens (useful for testing)
|
|
426
|
+
*/
|
|
427
|
+
export function clearTokenCache() {
|
|
428
|
+
cachedCSSTokens = null;
|
|
429
|
+
cachedTokenGraph = null;
|
|
430
|
+
cachedRawTokens = null;
|
|
431
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* COBWDS Mode Prompt
|
|
3
|
+
*
|
|
4
|
+
* Activates COBWDS-aware coding assistance.
|
|
5
|
+
*/
|
|
6
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
7
|
+
export declare function registerPrompts(server: McpServer): void;
|
|
8
|
+
//# sourceMappingURL=cobwds-mode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cobwds-mode.d.ts","sourceRoot":"","sources":["../../src/prompts/cobwds-mode.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA2DvD"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* COBWDS Mode Prompt
|
|
3
|
+
*
|
|
4
|
+
* Activates COBWDS-aware coding assistance.
|
|
5
|
+
*/
|
|
6
|
+
export function registerPrompts(server) {
|
|
7
|
+
server.prompt("cobwds_mode", "Activates COBWDS-aware coding assistance with knowledge of components, tokens, and best practices", {}, async () => {
|
|
8
|
+
return {
|
|
9
|
+
messages: [
|
|
10
|
+
{
|
|
11
|
+
role: "user",
|
|
12
|
+
content: {
|
|
13
|
+
type: "text",
|
|
14
|
+
text: `You are now in COBWDS (City of Boston Web Design System) mode. You have access to comprehensive knowledge about COBWDS web components and design tokens.
|
|
15
|
+
|
|
16
|
+
## Your Capabilities
|
|
17
|
+
|
|
18
|
+
1. **Component Knowledge**: You can list, search, and provide detailed documentation for all COBWDS web components using the available tools.
|
|
19
|
+
|
|
20
|
+
2. **Design Tokens**: You can access and explain COBWDS design tokens for colors, spacing, typography, and more.
|
|
21
|
+
|
|
22
|
+
3. **Code Generation**: When generating code that uses UI components, prefer COBWDS components over generic HTML or other libraries.
|
|
23
|
+
|
|
24
|
+
4. **Validation**: You can validate component usage to ensure correct attribute and property usage.
|
|
25
|
+
|
|
26
|
+
5. **Framework Integration**: You can provide setup guides for various frameworks (React, Angular, .NET, Drupal, Vanilla JS).
|
|
27
|
+
|
|
28
|
+
## Best Practices
|
|
29
|
+
|
|
30
|
+
- Always use semantic COBWDS components (e.g., \`<cob-button>\` instead of \`<button>\`)
|
|
31
|
+
- Use COBWDS design tokens via CSS custom properties for consistent styling
|
|
32
|
+
- Follow accessibility guidelines built into COBWDS components
|
|
33
|
+
- Reference the official documentation at https://cityofboston.github.io/nywds-poc/
|
|
34
|
+
|
|
35
|
+
## Available Tools
|
|
36
|
+
|
|
37
|
+
### Components
|
|
38
|
+
- \`find_components\`: Search for components or list all (omit query to list all)
|
|
39
|
+
- \`get_component\`: Get detailed docs for a specific component
|
|
40
|
+
- \`validate_component_api\`: Validate component attribute/property usage
|
|
41
|
+
|
|
42
|
+
### Design Tokens
|
|
43
|
+
- \`get_tokens\`: Get tokens, categories, or themes (use output parameter)
|
|
44
|
+
- \`find_tokens\`: Search for tokens by name, value, or description
|
|
45
|
+
- \`get_token_info\`: Get details about a specific token with optional context validation
|
|
46
|
+
- \`get_token_graph\`: Explore token dependencies
|
|
47
|
+
|
|
48
|
+
### Styles & Utilities
|
|
49
|
+
- \`get_utility_classes\`: Grid, flexbox, spacing, and other utility classes
|
|
50
|
+
|
|
51
|
+
### Guides
|
|
52
|
+
- \`get_guide\`: Get guides for installation, forms, styles, fonts, page structure, or framework setup
|
|
53
|
+
|
|
54
|
+
When helping with UI development for the City of Boston projects, prioritize COBWDS components and patterns.`,
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
],
|
|
58
|
+
};
|
|
59
|
+
});
|
|
60
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Component Resources
|
|
3
|
+
*
|
|
4
|
+
* MCP resources for COBWDS component documentation.
|
|
5
|
+
*
|
|
6
|
+
* P0 Resources:
|
|
7
|
+
* - cobwds://components - Component overview list
|
|
8
|
+
* - cobwds://component/{tag} - Individual component docs
|
|
9
|
+
*/
|
|
10
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
11
|
+
export declare function registerComponentResources(server: McpServer): void;
|
|
12
|
+
//# sourceMappingURL=components.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../../src/resources/components.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGzE,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAiElE"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Component Resources
|
|
3
|
+
*
|
|
4
|
+
* MCP resources for COBWDS component documentation.
|
|
5
|
+
*
|
|
6
|
+
* P0 Resources:
|
|
7
|
+
* - cobwds://components - Component overview list
|
|
8
|
+
* - cobwds://component/{tag} - Individual component docs
|
|
9
|
+
*/
|
|
10
|
+
import { getAllComponents, getComponent } from "../lib/cem-parser.js";
|
|
11
|
+
export function registerComponentResources(server) {
|
|
12
|
+
// cobwds://components - Component overview list
|
|
13
|
+
server.resource("components", "cobwds://components", {
|
|
14
|
+
description: "List of all COBWDS web components with summaries",
|
|
15
|
+
mimeType: "application/json",
|
|
16
|
+
}, async () => {
|
|
17
|
+
const components = getAllComponents();
|
|
18
|
+
const list = components.map((c) => ({
|
|
19
|
+
tagName: c.tagName,
|
|
20
|
+
name: c.name,
|
|
21
|
+
summary: c.summary || c.description?.split("\n")[0] || "No description",
|
|
22
|
+
}));
|
|
23
|
+
return {
|
|
24
|
+
contents: [
|
|
25
|
+
{
|
|
26
|
+
uri: "cobwds://components",
|
|
27
|
+
mimeType: "application/json",
|
|
28
|
+
text: JSON.stringify(list, null, 2),
|
|
29
|
+
},
|
|
30
|
+
],
|
|
31
|
+
};
|
|
32
|
+
});
|
|
33
|
+
// cobwds://component/{tag} - Individual component docs
|
|
34
|
+
server.resource("component", "cobwds://component/{tag}", {
|
|
35
|
+
description: "Full documentation for a specific COBWDS component",
|
|
36
|
+
mimeType: "application/json",
|
|
37
|
+
}, async (uri) => {
|
|
38
|
+
// Extract tag from URI: cobwds://component/cob-button -> cob-button
|
|
39
|
+
const tag = uri.pathname.split("/").pop() || "";
|
|
40
|
+
const component = getComponent(tag);
|
|
41
|
+
if (!component) {
|
|
42
|
+
return {
|
|
43
|
+
contents: [
|
|
44
|
+
{
|
|
45
|
+
uri: uri.href,
|
|
46
|
+
mimeType: "text/plain",
|
|
47
|
+
text: `Component "${tag}" not found`,
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
return {
|
|
53
|
+
contents: [
|
|
54
|
+
{
|
|
55
|
+
uri: uri.href,
|
|
56
|
+
mimeType: "application/json",
|
|
57
|
+
text: JSON.stringify(component, null, 2),
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
};
|
|
61
|
+
});
|
|
62
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Guide Resources
|
|
3
|
+
*
|
|
4
|
+
* MCP resources for COBWDS installation and usage guides.
|
|
5
|
+
*
|
|
6
|
+
* P0 Resources:
|
|
7
|
+
* - cobwds://installation - Installation guide
|
|
8
|
+
*/
|
|
9
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
10
|
+
export declare function registerGuideResources(server: McpServer): void;
|
|
11
|
+
//# sourceMappingURL=guides.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guides.d.ts","sourceRoot":"","sources":["../../src/resources/guides.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAyE9D"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Guide Resources
|
|
3
|
+
*
|
|
4
|
+
* MCP resources for COBWDS installation and usage guides.
|
|
5
|
+
*
|
|
6
|
+
* P0 Resources:
|
|
7
|
+
* - cobwds://installation - Installation guide
|
|
8
|
+
*/
|
|
9
|
+
export function registerGuideResources(server) {
|
|
10
|
+
// cobwds://installation - Installation guide
|
|
11
|
+
server.resource("installation", "cobwds://installation", {
|
|
12
|
+
description: "COBWDS installation and setup guide",
|
|
13
|
+
mimeType: "text/markdown",
|
|
14
|
+
}, async () => {
|
|
15
|
+
const guide = `# COBWDS Installation Guide
|
|
16
|
+
|
|
17
|
+
## 1. Install packages
|
|
18
|
+
|
|
19
|
+
\`\`\`bash
|
|
20
|
+
npm install @cobwds/components @cobwds/styles
|
|
21
|
+
\`\`\`
|
|
22
|
+
|
|
23
|
+
## 2. Load styles
|
|
24
|
+
|
|
25
|
+
COBWDS components require CSS variables to render correctly. Choose the right stylesheet:
|
|
26
|
+
|
|
27
|
+
**New project** — includes a CSS reset, typography, and utility/layout classes:
|
|
28
|
+
\`\`\`css
|
|
29
|
+
@import '@cobwds/styles/full';
|
|
30
|
+
\`\`\`
|
|
31
|
+
|
|
32
|
+
**Existing project** — loads only the CSS variables that style the components:
|
|
33
|
+
\`\`\`css
|
|
34
|
+
@import '@cobwds/styles';
|
|
35
|
+
\`\`\`
|
|
36
|
+
|
|
37
|
+
## 3. Import and use components
|
|
38
|
+
|
|
39
|
+
\`\`\`javascript
|
|
40
|
+
import '@cobwds/cob-button';
|
|
41
|
+
import '@cobwds/cob-alert';
|
|
42
|
+
\`\`\`
|
|
43
|
+
|
|
44
|
+
Or import all components:
|
|
45
|
+
|
|
46
|
+
\`\`\`javascript
|
|
47
|
+
import '@cobwds/components';
|
|
48
|
+
\`\`\`
|
|
49
|
+
|
|
50
|
+
Then use them in HTML:
|
|
51
|
+
|
|
52
|
+
\`\`\`html
|
|
53
|
+
<cob-button label="Submit" variant="filled"></cob-button>
|
|
54
|
+
<cob-alert type="info">This is an informational message.</cob-alert>
|
|
55
|
+
\`\`\`
|
|
56
|
+
|
|
57
|
+
## Framework Integration
|
|
58
|
+
|
|
59
|
+
For framework-specific setup, use the \`get_guide\` tool with \`topic: "framework"\` and a \`framework\` parameter (angular, react, dotnet, drupal, or vanilla).
|
|
60
|
+
|
|
61
|
+
## Resources
|
|
62
|
+
|
|
63
|
+
- Documentation: https://cityofboston.github.io/nywds-poc/
|
|
64
|
+
- GitHub: https://github.com/CityOfBoston/nywds-poc
|
|
65
|
+
`;
|
|
66
|
+
return {
|
|
67
|
+
contents: [
|
|
68
|
+
{
|
|
69
|
+
uri: "cobwds://installation",
|
|
70
|
+
mimeType: "text/markdown",
|
|
71
|
+
text: guide,
|
|
72
|
+
},
|
|
73
|
+
],
|
|
74
|
+
};
|
|
75
|
+
});
|
|
76
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Resources Registration
|
|
3
|
+
*
|
|
4
|
+
* Registers all COBWDS resources with the MCP server.
|
|
5
|
+
*/
|
|
6
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
7
|
+
export declare function registerResources(server: McpServer): void;
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/resources/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKzE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAIzD"}
|