@czi-sds/mcp 0.15.0 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/stdio.js CHANGED
@@ -1,242 +1,186 @@
1
1
  #!/usr/bin/env node
2
- import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
3
- import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
4
- import { z } from 'zod';
5
- import fs, { readFileSync, existsSync } from 'fs';
6
- import path, { dirname as dirname$1, join } from 'path';
7
- import { fileURLToPath } from 'url';
8
-
9
- var server = new McpServer({
10
- name: "sds-mcp",
11
- version: "0.1.0",
12
- capabilities: {
13
- prompts: {},
14
- resources: {
15
- subscribe: true,
16
- listChanged: true
17
- },
18
- tools: {}
19
- }
2
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
4
+ import { z } from "zod";
5
+ import fs, { existsSync, readFileSync } from "fs";
6
+ import path, { dirname, join } from "path";
7
+ import { fileURLToPath } from "url";
8
+ //#region src/server.ts
9
+ const server = new McpServer({
10
+ name: "sds-mcp",
11
+ version: "0.1.0",
12
+ capabilities: {
13
+ prompts: {},
14
+ resources: {
15
+ subscribe: true,
16
+ listChanged: true
17
+ },
18
+ tools: {}
19
+ }
20
20
  });
21
- var filename = fileURLToPath(import.meta.url);
22
- var dirname = path.dirname(filename);
21
+ //#endregion
22
+ //#region src/lib/fetch.ts
23
+ const filename$1 = fileURLToPath(import.meta.url);
24
+ const dirname$2 = path.dirname(filename$1);
25
+ /**
26
+ * Gets all component names from both packages
27
+ */
23
28
  async function getAllComponentNames() {
24
- try {
25
- const possiblePaths = [
26
- path.join(dirname, "../../data/component-list.json"),
27
- // From src/lib in dev
28
- path.join(dirname, "../data/component-list.json"),
29
- // From dist in prod
30
- path.join(process.cwd(), "data/component-list.json")
31
- // From current working directory
32
- ];
33
- let dataPath = "";
34
- for (const p of possiblePaths) {
35
- if (fs.existsSync(p)) {
36
- dataPath = p;
37
- break;
38
- }
39
- }
40
- if (!dataPath) {
41
- throw new Error(
42
- "Component list not found in any expected location. Please run 'yarn generate:components-list' first."
43
- );
44
- }
45
- const fileContent = fs.readFileSync(dataPath, "utf-8");
46
- const componentList = JSON.parse(fileContent);
47
- return componentList;
48
- } catch (error) {
49
- throw new Error(
50
- `Failed to load component list: ${error instanceof Error ? error.message : `Unknown error ${error}`}`
51
- );
52
- }
29
+ try {
30
+ const possiblePaths = [
31
+ path.join(dirname$2, "../../data/component-list.json"),
32
+ path.join(dirname$2, "../data/component-list.json"),
33
+ path.join(process.cwd(), "data/component-list.json")
34
+ ];
35
+ let dataPath = "";
36
+ for (const p of possiblePaths) if (fs.existsSync(p)) {
37
+ dataPath = p;
38
+ break;
39
+ }
40
+ if (!dataPath) throw new Error("Component list not found in any expected location. Please run 'yarn generate:components-list' first.");
41
+ const fileContent = fs.readFileSync(dataPath, "utf-8");
42
+ return JSON.parse(fileContent);
43
+ } catch (error) {
44
+ throw new Error(`Failed to load component list: ${error instanceof Error ? error.message : `Unknown error ${error}`}`);
45
+ }
53
46
  }
54
47
  async function fetchComponentProps(component) {
55
- try {
56
- const propsPaths = [
57
- path.join(dirname, `../../data/component-props/${component}.json`),
58
- // From src/lib in dev
59
- path.join(dirname, `../data/component-props/${component}.json`),
60
- // From dist in prod
61
- path.join(process.cwd(), `data/component-props/${component}.json`)
62
- // From current working directory
63
- ];
64
- let propsPath = "";
65
- for (const p of propsPaths) {
66
- if (fs.existsSync(p)) {
67
- propsPath = p;
68
- break;
69
- }
70
- }
71
- if (!propsPath) {
72
- return {
73
- [component]: {
74
- message: "Props information not available for this component. Run 'yarn generate:component-props' to generate props data.",
75
- props: {}
76
- }
77
- };
78
- }
79
- const fileContent = fs.readFileSync(propsPath, "utf-8");
80
- return JSON.parse(fileContent);
81
- } catch (error) {
82
- throw new Error(
83
- `Failed to load props for ${component}: ${error instanceof Error ? error.message : "Unknown error"}`
84
- );
85
- }
48
+ try {
49
+ const propsPaths = [
50
+ path.join(dirname$2, `../../data/component-props/${component}.json`),
51
+ path.join(dirname$2, `../data/component-props/${component}.json`),
52
+ path.join(process.cwd(), `data/component-props/${component}.json`)
53
+ ];
54
+ let propsPath = "";
55
+ for (const p of propsPaths) if (fs.existsSync(p)) {
56
+ propsPath = p;
57
+ break;
58
+ }
59
+ if (!propsPath) return { [component]: {
60
+ message: "Props information not available for this component. Run 'yarn generate:component-props' to generate props data.",
61
+ props: {}
62
+ } };
63
+ const fileContent = fs.readFileSync(propsPath, "utf-8");
64
+ return JSON.parse(fileContent);
65
+ } catch (error) {
66
+ throw new Error(`Failed to load props for ${component}: ${error instanceof Error ? error.message : "Unknown error"}`);
67
+ }
86
68
  }
69
+ /**
70
+ * Gets all component names from both packages
71
+ */
87
72
  async function fetchTailwindTokens() {
88
- try {
89
- const possiblePaths = [
90
- path.join(dirname, "../../data/tailwind.json"),
91
- // From src/lib in dev
92
- path.join(dirname, "../data/tailwind.json"),
93
- // From dist in prod
94
- path.join(process.cwd(), "data/tailwind.json")
95
- // From current working directory
96
- ];
97
- let dataPath = "";
98
- for (const p of possiblePaths) {
99
- if (fs.existsSync(p)) {
100
- dataPath = p;
101
- break;
102
- }
103
- }
104
- if (!dataPath) {
105
- throw new Error(
106
- "Component list not found in any expected location. Please run 'yarn generate:tailwind-tokens' first."
107
- );
108
- }
109
- const fileContent = fs.readFileSync(dataPath, "utf-8");
110
- const tailwindTokens = JSON.parse(fileContent);
111
- return tailwindTokens;
112
- } catch (error) {
113
- throw new Error(
114
- `Failed to load tailwind tokens: ${error instanceof Error ? error.message : `Unknown error ${error}`}`
115
- );
116
- }
73
+ try {
74
+ const possiblePaths = [
75
+ path.join(dirname$2, "../../data/tailwind.json"),
76
+ path.join(dirname$2, "../data/tailwind.json"),
77
+ path.join(process.cwd(), "data/tailwind.json")
78
+ ];
79
+ let dataPath = "";
80
+ for (const p of possiblePaths) if (fs.existsSync(p)) {
81
+ dataPath = p;
82
+ break;
83
+ }
84
+ if (!dataPath) throw new Error("Component list not found in any expected location. Please run 'yarn generate:tailwind-tokens' first.");
85
+ const fileContent = fs.readFileSync(dataPath, "utf-8");
86
+ return JSON.parse(fileContent);
87
+ } catch (error) {
88
+ throw new Error(`Failed to load tailwind tokens: ${error instanceof Error ? error.message : `Unknown error ${error}`}`);
89
+ }
117
90
  }
118
-
119
- // src/tools/get-component-props.ts
120
- var getComponentPropsTool = {
121
- name: "get_component_props",
122
- description: "Get detailed properties of a specific SDS component. This tool retrieves the properties, attributes, design related props for a component, like sdsStyle, sdsType, sdsSize, etc. and configuration options available for a given SDS component.",
123
- async ctx() {
124
- try {
125
- const componentList = await getAllComponentNames();
126
- return {
127
- componentList: [
128
- ...componentList.components,
129
- ...componentList["data-viz"]
130
- ]
131
- };
132
- } catch (error) {
133
- throw new Error(
134
- `Failed to initialize component props tool: ${error instanceof Error ? error.message : "Unknown error"}`
135
- );
136
- }
137
- },
138
- exec(server2, { ctx, name, description }) {
139
- server2.tool(
140
- name,
141
- description,
142
- {
143
- component: z.enum(ctx.componentList).describe("The name of the SDS component to get properties for")
144
- },
145
- async ({ component }) => {
146
- try {
147
- const json = await fetchComponentProps(component);
148
- return {
149
- content: [
150
- {
151
- type: "text",
152
- text: JSON.stringify(json)
153
- }
154
- ]
155
- };
156
- } catch (error) {
157
- return {
158
- content: [
159
- {
160
- type: "text",
161
- text: `Failed to get component props for ${component}: ${error instanceof Error ? error.message : "Unknown error"}`
162
- }
163
- ]
164
- };
165
- }
166
- }
167
- );
168
- }
91
+ //#endregion
92
+ //#region src/tools/get-component-props.ts
93
+ const getComponentPropsTool = {
94
+ name: "get_component_props",
95
+ description: "Get detailed properties of a specific SDS component. This tool retrieves the properties, attributes, design related props for a component, like sdsStyle, sdsType, sdsSize, etc. and configuration options available for a given SDS component.",
96
+ async ctx() {
97
+ try {
98
+ const componentList = await getAllComponentNames();
99
+ return { componentList: [...componentList.components, ...componentList["data-viz"]] };
100
+ } catch (error) {
101
+ throw new Error(`Failed to initialize component props tool: ${error instanceof Error ? error.message : "Unknown error"}`);
102
+ }
103
+ },
104
+ exec(server, { ctx, name, description }) {
105
+ server.tool(name, description, { component: z.enum(ctx.componentList).describe("The name of the SDS component to get properties for") }, async ({ component }) => {
106
+ try {
107
+ const json = await fetchComponentProps(component);
108
+ return { content: [{
109
+ type: "text",
110
+ text: JSON.stringify(json)
111
+ }] };
112
+ } catch (error) {
113
+ return { content: [{
114
+ type: "text",
115
+ text: `Failed to get component props for ${component}: ${error instanceof Error ? error.message : "Unknown error"}`
116
+ }] };
117
+ }
118
+ });
119
+ }
169
120
  };
170
-
171
- // src/tools/list-components.ts
172
- var listComponentsTool = {
173
- name: "list_components",
174
- description: "List all available components in SDS. This tool retrieves the names of all SDS components from both the @czi-sds/components package and the @czi-sds/data-viz package.",
175
- async ctx() {
176
- try {
177
- const componentList = await getAllComponentNames();
178
- return { componentList };
179
- } catch (error) {
180
- throw new Error(
181
- `Failed to initialize list components tool: ${error instanceof Error ? error.message : "Unknown error"}`
182
- );
183
- }
184
- },
185
- exec(server2, { ctx, name, description }) {
186
- server2.tool(name, description, {}, async () => {
187
- return {
188
- content: [
189
- {
190
- type: "text",
191
- text: JSON.stringify(ctx.componentList, null, 2)
192
- }
193
- ]
194
- };
195
- });
196
- }
121
+ //#endregion
122
+ //#region src/tools/list-components.ts
123
+ const listComponentsTool = {
124
+ name: "list_components",
125
+ description: "List all available components in SDS. This tool retrieves the names of all SDS components from both the @czi-sds/components package and the @czi-sds/data-viz package.",
126
+ async ctx() {
127
+ try {
128
+ return { componentList: await getAllComponentNames() };
129
+ } catch (error) {
130
+ throw new Error(`Failed to initialize list components tool: ${error instanceof Error ? error.message : "Unknown error"}`);
131
+ }
132
+ },
133
+ exec(server, { ctx, name, description }) {
134
+ server.tool(name, description, {}, async () => {
135
+ return { content: [{
136
+ type: "text",
137
+ text: JSON.stringify(ctx.componentList, null, 2)
138
+ }] };
139
+ });
140
+ }
197
141
  };
198
-
199
- // src/lib/tailwind-guidance.ts
200
- var TAILWIND_TOKEN_GUIDANCE = {
201
- colors: {
202
- category: "Colors",
203
- description: "Theme-aware color tokens support both light and dark modes. Both modes follow the same token name structure: use light-token-name for light mode colors and dark:dark-token-name for dark mode colors.",
204
- prefixes: [
205
- "bg-",
206
- "border-",
207
- "divide-",
208
- "outline-",
209
- "ring-",
210
- "ring-offset-",
211
- "text-",
212
- "placeholder-",
213
- "caret-",
214
- "decoration-",
215
- "accent-",
216
- "shadow-",
217
- "fill-",
218
- "stroke-",
219
- "from-",
220
- "via-",
221
- "to-"
222
- ],
223
- examples: [
224
- {
225
- description: "Basic text and background colors",
226
- code: `<div className="bg-light-sds-color-semantic-base-background-primary dark:bg-dark-sds-color-semantic-base-background-primary text-light-sds-color-semantic-base-text-primary dark:text-dark-sds-color-semantic-base-text-primary">
142
+ //#endregion
143
+ //#region src/lib/tailwind-guidance.ts
144
+ const TAILWIND_TOKEN_GUIDANCE = {
145
+ colors: {
146
+ category: "Colors",
147
+ description: "Theme-aware color tokens support both light and dark modes. Both modes follow the same token name structure: use light-token-name for light mode colors and dark:dark-token-name for dark mode colors.",
148
+ prefixes: [
149
+ "bg-",
150
+ "border-",
151
+ "divide-",
152
+ "outline-",
153
+ "ring-",
154
+ "ring-offset-",
155
+ "text-",
156
+ "placeholder-",
157
+ "caret-",
158
+ "decoration-",
159
+ "accent-",
160
+ "shadow-",
161
+ "fill-",
162
+ "stroke-",
163
+ "from-",
164
+ "via-",
165
+ "to-"
166
+ ],
167
+ examples: [
168
+ {
169
+ description: "Basic text and background colors",
170
+ code: `<div className="bg-light-sds-color-semantic-base-background-primary dark:bg-dark-sds-color-semantic-base-background-primary text-light-sds-color-semantic-base-text-primary dark:text-dark-sds-color-semantic-base-text-primary">
227
171
  Content with semantic colors
228
172
  </div>`
229
- },
230
- {
231
- description: "Dark mode with hover states",
232
- code: `<button className="bg-light-sds-color-semantic-accent-fill-primary dark:bg-dark-sds-color-semantic-accent-fill-primary
173
+ },
174
+ {
175
+ description: "Dark mode with hover states",
176
+ code: `<button className="bg-light-sds-color-semantic-accent-fill-primary dark:bg-dark-sds-color-semantic-accent-fill-primary
233
177
  hover:bg-light-sds-color-semantic-accent-fill-hover dark:hover:bg-dark-sds-color-semantic-accent-fill-hover">
234
178
  Click me
235
179
  </button>`
236
- },
237
- {
238
- description: "Border and focus states",
239
- code: `<input className="
180
+ },
181
+ {
182
+ description: "Border and focus states",
183
+ code: `<input className="
240
184
  border-light-sds-color-semantic-base-border-primary
241
185
  hover:border-light-sds-color-semantic-base-border-primary-hover
242
186
  focus:border-light-sds-color-semantic-base-border-primary-pressed
@@ -244,21 +188,22 @@ var TAILWIND_TOKEN_GUIDANCE = {
244
188
  dark:hover:border-dark-sds-color-semantic-base-border-primary-hover
245
189
  dark:focus:border-dark-sds-color-semantic-base-border-primary-pressed
246
190
  "/>`
247
- }
248
- ],
249
- tips: [
250
- "Always use semantic colors (e.g., 'bg-light-sds-color-semantic-base-background-primary dark:bg-dark-sds-color-semantic-base-background-primary') over primitive colors when possible",
251
- "Include both light and dark variants for proper theme support"
252
- ]
253
- },
254
- typography: {
255
- category: "Typography",
256
- description: "Complete text styling presets including font, size, weight, and spacing",
257
- prefixes: ["font-", "text-", "leading-", "tracking-"],
258
- examples: [
259
- {
260
- description: "Typography presets (recommended). SDS typography tokens come in narrow and wide variants: use token-narrow on screens smaller than md, and token-wide on md and up.",
261
- code: `<!-- Use typography tokens for complete text styling -->
191
+ }
192
+ ],
193
+ tips: ["Always use semantic colors (e.g., 'bg-light-sds-color-semantic-base-background-primary dark:bg-dark-sds-color-semantic-base-background-primary') over primitive colors when possible", "Include both light and dark variants for proper theme support"]
194
+ },
195
+ typography: {
196
+ category: "Typography",
197
+ description: "Complete text styling presets including font, size, weight, and spacing",
198
+ prefixes: [
199
+ "font-",
200
+ "text-",
201
+ "leading-",
202
+ "tracking-"
203
+ ],
204
+ examples: [{
205
+ description: "Typography presets (recommended). SDS typography tokens come in narrow and wide variants: use token-narrow on screens smaller than md, and token-wide on md and up.",
206
+ code: `<!-- Use typography tokens for complete text styling -->
262
207
  <h1 className="prose-sds-title-l-700-wide">Title</h1>
263
208
  <h1 className="prose-sds-header-xl-600-wide">Heading</h1>
264
209
  <p className="prose-sds-body-m-500-wide">Body text</p>
@@ -266,10 +211,9 @@ var TAILWIND_TOKEN_GUIDANCE = {
266
211
  <span className="prose-sds-tabular-xxs-600-wide">Tabular Numbers</span>
267
212
  <span className="prose-sds-code-s-500-wide">Code</span>
268
213
  <span className="prose-sds-link-l-500-wide">Link style</span>`
269
- },
270
- {
271
- description: "Individual typography properties",
272
- code: `<!-- Or use individual properties when needed -->
214
+ }, {
215
+ description: "Individual typography properties",
216
+ code: `<!-- Or use individual properties when needed -->
273
217
  <p className="
274
218
  font-sds-body
275
219
  text-sds-body-m-400-wide
@@ -278,48 +222,47 @@ var TAILWIND_TOKEN_GUIDANCE = {
278
222
  ">
279
223
  Custom styled text
280
224
  </p>`
281
- }
282
- ],
283
- tips: [
284
- "Use 'narrow' variants for mobile/compact layouts",
285
- "Use 'wide' variants for desktop/spacious layouts",
286
- "Font weights: 400 (regular), 500 (medium), 600 (semibold), 700 (bold)"
287
- ]
288
- },
289
- spacing: {
290
- category: "Spacing",
291
- description: "Consistent spacing scale for padding, margin, and gaps",
292
- prefixes: [
293
- "p-",
294
- "px-",
295
- "py-",
296
- "pt-",
297
- "pr-",
298
- "pb-",
299
- "pl-",
300
- "m-",
301
- "mx-",
302
- "my-",
303
- "mt-",
304
- "mr-",
305
- "mb-",
306
- "ml-",
307
- "gap-",
308
- "gap-x-",
309
- "gap-y-",
310
- "space-x-",
311
- "space-y-"
312
- ],
313
- examples: [
314
- {
315
- description: "Padding and margin",
316
- code: `<div className="p-sds-m mx-sds-l my-sds-s">
225
+ }],
226
+ tips: [
227
+ "Use 'narrow' variants for mobile/compact layouts",
228
+ "Use 'wide' variants for desktop/spacious layouts",
229
+ "Font weights: 400 (regular), 500 (medium), 600 (semibold), 700 (bold)"
230
+ ]
231
+ },
232
+ spacing: {
233
+ category: "Spacing",
234
+ description: "Consistent spacing scale for padding, margin, and gaps",
235
+ prefixes: [
236
+ "p-",
237
+ "px-",
238
+ "py-",
239
+ "pt-",
240
+ "pr-",
241
+ "pb-",
242
+ "pl-",
243
+ "m-",
244
+ "mx-",
245
+ "my-",
246
+ "mt-",
247
+ "mr-",
248
+ "mb-",
249
+ "ml-",
250
+ "gap-",
251
+ "gap-x-",
252
+ "gap-y-",
253
+ "space-x-",
254
+ "space-y-"
255
+ ],
256
+ examples: [
257
+ {
258
+ description: "Padding and margin",
259
+ code: `<div className="p-sds-m mx-sds-l my-sds-s">
317
260
  Content with medium padding and different margins
318
261
  </div>`
319
- },
320
- {
321
- description: "Flexbox and grid gaps",
322
- code: `<div className="flex gap-sds-m">
262
+ },
263
+ {
264
+ description: "Flexbox and grid gaps",
265
+ code: `<div className="flex gap-sds-m">
323
266
  <div>Item 1</div>
324
267
  <div>Item 2</div>
325
268
  </div>
@@ -327,72 +270,71 @@ var TAILWIND_TOKEN_GUIDANCE = {
327
270
  <div className="grid grid-cols-3 gap-sds-l">
328
271
  <div>Grid item</div>
329
272
  </div>`
330
- },
331
- {
332
- description: "Negative margins for overlapping",
333
- code: `<div className="-mt-sds-s">
273
+ },
274
+ {
275
+ description: "Negative margins for overlapping",
276
+ code: `<div className="-mt-sds-s">
334
277
  Overlapping element
335
278
  </div>`
336
- }
337
- ],
338
- tips: [
339
- "Scale: sds-s (small), sds-default (default), sds-m (medium), sds-l (large), sds-xl (extra large)",
340
- "Use consistent spacing throughout your component",
341
- "Combine with responsive prefixes: sm:p-sds-m lg:p-sds-l"
342
- ]
343
- },
344
- borderRadius: {
345
- category: "Border Radius",
346
- description: "Corner radius values for rounded elements",
347
- prefixes: [
348
- "rounded-",
349
- "rounded-t-",
350
- "rounded-r-",
351
- "rounded-b-",
352
- "rounded-l-"
353
- ],
354
- examples: [
355
- {
356
- description: "Basic rounded corners",
357
- code: `<div className="rounded-sds-default">
279
+ }
280
+ ],
281
+ tips: [
282
+ "Scale: sds-s (small), sds-default (default), sds-m (medium), sds-l (large), sds-xl (extra large)",
283
+ "Use consistent spacing throughout your component",
284
+ "Combine with responsive prefixes: sm:p-sds-m lg:p-sds-l"
285
+ ]
286
+ },
287
+ borderRadius: {
288
+ category: "Border Radius",
289
+ description: "Corner radius values for rounded elements",
290
+ prefixes: [
291
+ "rounded-",
292
+ "rounded-t-",
293
+ "rounded-r-",
294
+ "rounded-b-",
295
+ "rounded-l-"
296
+ ],
297
+ examples: [{
298
+ description: "Basic rounded corners",
299
+ code: `<div className="rounded-sds-default">
358
300
  Standard rounded corners
359
301
  </div>
360
302
 
361
303
  <button className="rounded-sds-m">
362
304
  More rounded button
363
305
  </button>`
364
- },
365
- {
366
- description: "Directional radius",
367
- code: `<div className="rounded-t-sds-l rounded-b-none">
306
+ }, {
307
+ description: "Directional radius",
308
+ code: `<div className="rounded-t-sds-l rounded-b-none">
368
309
  Only top corners rounded
369
310
  </div>`
370
- }
371
- ],
372
- tips: [
373
- "Use sds-default for most UI elements",
374
- "Larger values (sds-l, sds-xl) for prominent elements",
375
- "Combine with borders: border rounded-sds-m"
376
- ]
377
- },
378
- boxShadow: {
379
- category: "Box Shadow",
380
- description: "Elevation shadows for depth and hierarchy",
381
- prefixes: ["shadow-", "hover:shadow-", "focus:shadow-"],
382
- examples: [
383
- {
384
- description: "Basic shadows",
385
- code: `<div className="shadow-sds-s">
311
+ }],
312
+ tips: [
313
+ "Use sds-default for most UI elements",
314
+ "Larger values (sds-l, sds-xl) for prominent elements",
315
+ "Combine with borders: border rounded-sds-m"
316
+ ]
317
+ },
318
+ boxShadow: {
319
+ category: "Box Shadow",
320
+ description: "Elevation shadows for depth and hierarchy",
321
+ prefixes: [
322
+ "shadow-",
323
+ "hover:shadow-",
324
+ "focus:shadow-"
325
+ ],
326
+ examples: [{
327
+ description: "Basic shadows",
328
+ code: `<div className="shadow-sds-s">
386
329
  Subtle shadow
387
330
  </div>
388
331
 
389
332
  <div className="shadow-sds-m">
390
333
  Medium elevation
391
334
  </div>`
392
- },
393
- {
394
- description: "Interactive shadows",
395
- code: `<button className="
335
+ }, {
336
+ description: "Interactive shadows",
337
+ code: `<button className="
396
338
  shadow-sds-s
397
339
  hover:shadow-sds-m
398
340
  active:shadow-sds-xs
@@ -400,18 +342,16 @@ var TAILWIND_TOKEN_GUIDANCE = {
400
342
  ">
401
343
  Interactive element
402
344
  </button>`
403
- }
404
- ],
405
- tips: [
406
- "Use smaller shadows (sds-xs, sds-s) for subtle depth",
407
- "Use larger shadows (sds-l, sds-xl) for modals and popovers",
408
- "Combine with hover states for interactive feedback"
409
- ]
410
- }
345
+ }],
346
+ tips: [
347
+ "Use smaller shadows (sds-xs, sds-s) for subtle depth",
348
+ "Use larger shadows (sds-l, sds-xl) for modals and popovers",
349
+ "Combine with hover states for interactive feedback"
350
+ ]
351
+ }
411
352
  };
412
353
  function getTokenGuidance(category) {
413
- if (!category || category === "all") {
414
- return `SDS Design System Tokens for Tailwind CSS
354
+ if (!category || category === "all") return `SDS Design System Tokens for Tailwind CSS
415
355
 
416
356
  The Science Design System provides a comprehensive set of design tokens that map directly to Tailwind utilities.
417
357
 
@@ -438,450 +378,309 @@ typography: This category can be used for formatting typography in the tailwind.
438
378
  height, width, borderRadius, boxShadow, breakpoints: These categories can be used for formatting height, width, border radius, box shadow, and breakpoints in the tailwind.config.js file
439
379
  spacing: This category can be used for formatting spacing in the tailwind.config.js file
440
380
  colors: This category can be used for formatting colors in the tailwind.config.js file`;
441
- }
442
- const guidance = TAILWIND_TOKEN_GUIDANCE[category];
443
- if (!guidance) {
444
- return `Category "${category}" not found. Available categories: ${Object.keys(
445
- TAILWIND_TOKEN_GUIDANCE
446
- ).join(", ")}`;
447
- }
448
- let output = `## ${guidance.category} Tokens
449
-
450
- `;
451
- output += `${guidance.description}
452
-
453
- `;
454
- output += `**Tailwind Prefixes:** ${guidance.prefixes.join(", ")}
455
-
456
- `;
457
- output += `### Examples:
458
-
459
- `;
460
- guidance.examples.forEach((example, index) => {
461
- output += `${index + 1}. **${example.description}**
462
- \`\`\`jsx
463
- ${example.code}
464
- \`\`\`
465
-
466
- `;
467
- });
468
- if (guidance.tips && guidance.tips.length > 0) {
469
- output += `### Tips:
470
- `;
471
- guidance.tips.forEach((tip) => {
472
- output += `- ${tip}
473
- `;
474
- });
475
- }
476
- return output;
381
+ const guidance = TAILWIND_TOKEN_GUIDANCE[category];
382
+ if (!guidance) return `Category "${category}" not found. Available categories: ${Object.keys(TAILWIND_TOKEN_GUIDANCE).join(", ")}`;
383
+ let output = `## ${guidance.category} Tokens\n\n`;
384
+ output += `${guidance.description}\n\n`;
385
+ output += `**Tailwind Prefixes:** ${guidance.prefixes.join(", ")}\n\n`;
386
+ output += `### Examples:\n\n`;
387
+ guidance.examples.forEach((example, index) => {
388
+ output += `${index + 1}. **${example.description}**\n\`\`\`jsx\n${example.code}\n\`\`\`\n\n`;
389
+ });
390
+ if (guidance.tips && guidance.tips.length > 0) {
391
+ output += `### Tips:\n`;
392
+ guidance.tips.forEach((tip) => {
393
+ output += `- ${tip}\n`;
394
+ });
395
+ }
396
+ return output;
477
397
  }
478
-
479
- // src/tools/get-tailwind-tokens.ts
480
- var getTailwindTokensTool = {
481
- name: "get_tailwind_tokens",
482
- description: "Get all available Tailwind tokens from the SDS design system. Available design tokens include fontFamily, fontSize, fontVariantNumeric, letterSpacing, lineHeight, textDecoration, textTransform, typography, height, width, borderRadius, boxShadow, breakpoints, colors, spacing, and more.",
483
- async ctx() {
484
- try {
485
- const tailwindTokens = await fetchTailwindTokens();
486
- return { tailwindTokens };
487
- } catch (error) {
488
- throw new Error(
489
- `Failed to initialize tailwind tokens tool: ${error instanceof Error ? error.message : "Unknown error"}`
490
- );
491
- }
492
- },
493
- exec(server2, { ctx, name, description }) {
494
- server2.tool(
495
- name,
496
- description,
497
- {
498
- category: z.enum([
499
- "all",
500
- "fontFamily",
501
- "fontSize",
502
- "fontVariantNumeric",
503
- "letterSpacing",
504
- "lineHeight",
505
- "textDecoration",
506
- "textTransform",
507
- "typography",
508
- "height",
509
- "width",
510
- "borderRadius",
511
- "boxShadow",
512
- "breakpoints",
513
- "colors",
514
- "spacing"
515
- ]).optional().describe(
516
- "Optional category of tokens to retrieve. If not specified, returns all tokens."
517
- )
518
- },
519
- async ({ category }) => {
520
- try {
521
- const tokens = ctx.tailwindTokens;
522
- let result;
523
- if (!category || category === "all") {
524
- result = tokens;
525
- } else {
526
- result = tokens[category] || {};
527
- }
528
- const responseContent = [];
529
- const guidance = getTokenGuidance(category);
530
- responseContent.push({
531
- type: "text",
532
- text: guidance
533
- });
534
- responseContent.push({
535
- type: "text",
536
- text: JSON.stringify(result, null, 2)
537
- });
538
- return {
539
- content: responseContent
540
- };
541
- } catch (error) {
542
- return {
543
- content: [
544
- {
545
- type: "text",
546
- text: `Failed to get Tailwind tokens: ${error instanceof Error ? error.message : "Unknown error"}`
547
- }
548
- ]
549
- };
550
- }
551
- }
552
- );
553
- }
398
+ //#endregion
399
+ //#region src/tools/get-tailwind-tokens.ts
400
+ const getTailwindTokensTool = {
401
+ name: "get_tailwind_tokens",
402
+ description: "Get all available Tailwind tokens from the SDS design system. Available design tokens include fontFamily, fontSize, fontVariantNumeric, letterSpacing, lineHeight, textDecoration, textTransform, typography, height, width, borderRadius, boxShadow, breakpoints, colors, spacing, and more.",
403
+ async ctx() {
404
+ try {
405
+ return { tailwindTokens: await fetchTailwindTokens() };
406
+ } catch (error) {
407
+ throw new Error(`Failed to initialize tailwind tokens tool: ${error instanceof Error ? error.message : "Unknown error"}`);
408
+ }
409
+ },
410
+ exec(server, { ctx, name, description }) {
411
+ server.tool(name, description, { category: z.enum([
412
+ "all",
413
+ "fontFamily",
414
+ "fontSize",
415
+ "fontVariantNumeric",
416
+ "letterSpacing",
417
+ "lineHeight",
418
+ "textDecoration",
419
+ "textTransform",
420
+ "typography",
421
+ "height",
422
+ "width",
423
+ "borderRadius",
424
+ "boxShadow",
425
+ "breakpoints",
426
+ "colors",
427
+ "spacing"
428
+ ]).optional().describe("Optional category of tokens to retrieve. If not specified, returns all tokens.") }, async ({ category }) => {
429
+ try {
430
+ const tokens = ctx.tailwindTokens;
431
+ let result;
432
+ if (!category || category === "all") result = tokens;
433
+ else result = tokens[category] || {};
434
+ const responseContent = [];
435
+ const guidance = getTokenGuidance(category);
436
+ responseContent.push({
437
+ type: "text",
438
+ text: guidance
439
+ });
440
+ responseContent.push({
441
+ type: "text",
442
+ text: JSON.stringify(result, null, 2)
443
+ });
444
+ return { content: responseContent };
445
+ } catch (error) {
446
+ return { content: [{
447
+ type: "text",
448
+ text: `Failed to get Tailwind tokens: ${error instanceof Error ? error.message : "Unknown error"}`
449
+ }] };
450
+ }
451
+ });
452
+ }
554
453
  };
555
- var filename2 = fileURLToPath(import.meta.url);
556
- var dirname2 = path.dirname(filename2);
454
+ //#endregion
455
+ //#region src/tools/get-component-docs.ts
456
+ const filename = fileURLToPath(import.meta.url);
457
+ const dirname$1 = path.dirname(filename);
458
+ /**
459
+ * Maps a component name to the corresponding Zeroheight file using manual mapping
460
+ */
557
461
  function mapComponentToFile(componentName, exportedFiles) {
558
- const componentToFileMap = {
559
- // Button components
560
- Button: "Buttons",
561
- ButtonDropdown: "Buttons",
562
- ButtonIcon: "Buttons",
563
- ButtonToggle: "Buttons",
564
- // Table components
565
- TableHeader: "Table",
566
- TableRow: "Table",
567
- // Input components
568
- InputCheckbox: "Control-Inputs",
569
- InputRadio: "Control-Inputs",
570
- InputToggle: "Control-Inputs",
571
- InputText: "Field-Inputs",
572
- InputDropdown: "Dropdown-Input",
573
- InputSearch: "Search-Input",
574
- InputSlider: "Control-Inputs",
575
- // Dropdown components
576
- Dropdown: "Dropdown-Menu",
577
- DropdownMenu: "Dropdown-Menu",
578
- // Content components
579
- ContentCard: "Content-Card",
580
- LoadingIndicator: "Loading-Indicator",
581
- // Navigation components
582
- NavigationFooter: "Navigation",
583
- NavigationHeader: "Navigation",
584
- NavigationJumpTo: "Navigation",
585
- // Control components
586
- SegmentedControl: "Segmented-Control",
587
- // List and menu components
588
- List: "Lists",
589
- Menu: "Dropdown-Menu",
590
- MenuItem: "Dropdown-Menu",
591
- MenuSelect: "Dropdown-Menu",
592
- // Tag components
593
- Tag: "Tags",
594
- TagFilter: "Tags",
595
- // Tooltip components
596
- Tooltip: "Tooltips",
597
- TooltipCondensed: "Tooltips",
598
- TooltipTable: "Tooltips",
599
- // Table Cell components
600
- CellBasic: "Table",
601
- CellComponent: "Table",
602
- CellHeader: "Table",
603
- // Filter components
604
- ComplexFilter: "Filters",
605
- // Other components
606
- Icon: "Icons",
607
- Chip: "Tags",
608
- // Chips are often similar to tags
609
- Pagination: "Navigation"
610
- // Pagination is often part of navigation
611
- };
612
- const mappedFile = componentToFileMap[componentName];
613
- if (mappedFile && exportedFiles.includes(mappedFile)) {
614
- return `${mappedFile}.md`;
615
- }
616
- if (exportedFiles.includes(componentName)) {
617
- return `${componentName}.md`;
618
- }
619
- return null;
462
+ const mappedFile = {
463
+ Button: "Buttons",
464
+ ButtonDropdown: "Buttons",
465
+ ButtonIcon: "Buttons",
466
+ ButtonToggle: "Buttons",
467
+ TableHeader: "Table",
468
+ TableRow: "Table",
469
+ InputCheckbox: "Control-Inputs",
470
+ InputRadio: "Control-Inputs",
471
+ InputToggle: "Control-Inputs",
472
+ InputText: "Field-Inputs",
473
+ InputDropdown: "Dropdown-Input",
474
+ InputSearch: "Search-Input",
475
+ InputSlider: "Control-Inputs",
476
+ Dropdown: "Dropdown-Menu",
477
+ DropdownMenu: "Dropdown-Menu",
478
+ ContentCard: "Content-Card",
479
+ LoadingIndicator: "Loading-Indicator",
480
+ NavigationFooter: "Navigation",
481
+ NavigationHeader: "Navigation",
482
+ NavigationJumpTo: "Navigation",
483
+ SegmentedControl: "Segmented-Control",
484
+ List: "Lists",
485
+ Menu: "Dropdown-Menu",
486
+ MenuItem: "Dropdown-Menu",
487
+ MenuSelect: "Dropdown-Menu",
488
+ Tag: "Tags",
489
+ TagFilter: "Tags",
490
+ Tooltip: "Tooltips",
491
+ TooltipCondensed: "Tooltips",
492
+ TooltipTable: "Tooltips",
493
+ CellBasic: "Table",
494
+ CellComponent: "Table",
495
+ CellHeader: "Table",
496
+ ComplexFilter: "Filters",
497
+ Icon: "Icons",
498
+ Chip: "Tags",
499
+ Pagination: "Navigation"
500
+ }[componentName];
501
+ if (mappedFile && exportedFiles.includes(mappedFile)) return `${mappedFile}.md`;
502
+ if (exportedFiles.includes(componentName)) return `${componentName}.md`;
503
+ return null;
620
504
  }
505
+ /**
506
+ * Get list of exported documentation files
507
+ */
621
508
  function getExportedFiles() {
622
- try {
623
- const possiblePaths = [
624
- path.join(dirname2, "../../data/zeroheight-exports"),
625
- // From src/lib in dev
626
- path.join(dirname2, "../data/zeroheight-exports"),
627
- // From dist in prod
628
- path.join(process.cwd(), "data/zeroheight-exports")
629
- // From current working directory
630
- ];
631
- let exportDir = "";
632
- for (const p of possiblePaths) {
633
- if (fs.existsSync(p)) {
634
- exportDir = p;
635
- break;
636
- }
637
- }
638
- if (!exportDir) {
639
- console.warn(
640
- "Export directory not found in any expected location. Please run Zeroheight export first."
641
- );
642
- return [];
643
- }
644
- const files = fs.readdirSync(exportDir).filter((file) => file.endsWith(".md") && file !== "README.md").map((file) => file.replace(".md", ""));
645
- return files;
646
- } catch (error) {
647
- console.warn("Could not read exported files:", error);
648
- return [];
649
- }
509
+ try {
510
+ const possiblePaths = [
511
+ path.join(dirname$1, "../../data/zeroheight-exports"),
512
+ path.join(dirname$1, "../data/zeroheight-exports"),
513
+ path.join(process.cwd(), "data/zeroheight-exports")
514
+ ];
515
+ let exportDir = "";
516
+ for (const p of possiblePaths) if (fs.existsSync(p)) {
517
+ exportDir = p;
518
+ break;
519
+ }
520
+ if (!exportDir) {
521
+ console.warn("Export directory not found in any expected location. Please run Zeroheight export first.");
522
+ return [];
523
+ }
524
+ return fs.readdirSync(exportDir).filter((file) => file.endsWith(".md") && file !== "README.md").map((file) => file.replace(".md", ""));
525
+ } catch (error) {
526
+ console.warn("Could not read exported files:", error);
527
+ return [];
528
+ }
650
529
  }
530
+ /**
531
+ * Get list of components that have documentation available
532
+ */
651
533
  function getComponentsWithDocs(allComponents, exportedFiles) {
652
- return allComponents.filter((component) => {
653
- const mappedFile = mapComponentToFile(component, exportedFiles);
654
- return mappedFile !== null;
655
- });
534
+ return allComponents.filter((component) => {
535
+ return mapComponentToFile(component, exportedFiles) !== null;
536
+ });
656
537
  }
657
- var getComponentDocsTool = {
658
- name: "get_component_docs",
659
- description: "Get design system documentation for a specific component. Retrieves the corresponding Zeroheight documentation file for the given component name. Supports all SDS components and maps them to their appropriate documentation files.",
660
- async ctx() {
661
- try {
662
- const componentList = await getAllComponentNames();
663
- const allComponents = [
664
- ...componentList.components,
665
- ...componentList["data-viz"]
666
- ];
667
- const exportedFiles = getExportedFiles();
668
- const componentsWithDocs = getComponentsWithDocs(
669
- allComponents,
670
- exportedFiles
671
- );
672
- return {
673
- componentsWithDocs,
674
- exportedFiles
675
- };
676
- } catch (error) {
677
- throw new Error(
678
- `Failed to initialize get component docs tool: ${error instanceof Error ? error.message : "Unknown error"}`
679
- );
680
- }
681
- },
682
- exec(server2, { ctx, name, description }) {
683
- server2.tool(
684
- name,
685
- description,
686
- {
687
- component: z.enum(ctx.componentsWithDocs).describe("The name of the SDS component to get documentation for")
688
- },
689
- async ({ component }) => {
690
- try {
691
- const mappedFile = mapComponentToFile(component, ctx.exportedFiles);
692
- if (!mappedFile) {
693
- return {
694
- content: [
695
- {
696
- type: "text",
697
- text: `No documentation found for component '${component}'. This component may not have design system documentation available.`
698
- }
699
- ]
700
- };
701
- }
702
- const possiblePaths = [
703
- path.join(dirname2, "../../data/zeroheight-exports", mappedFile),
704
- // From src/lib in dev
705
- path.join(dirname2, "../data/zeroheight-exports", mappedFile),
706
- // From dist in prod
707
- path.join(process.cwd(), "data/zeroheight-exports", mappedFile)
708
- // From current working directory
709
- ];
710
- let filePath = "";
711
- for (const p of possiblePaths) {
712
- if (fs.existsSync(p)) {
713
- filePath = p;
714
- break;
715
- }
716
- }
717
- if (!filePath) {
718
- throw new Error(`Documentation file ${mappedFile} not found`);
719
- }
720
- const documentation = fs.readFileSync(filePath, "utf8");
721
- return {
722
- content: [
723
- {
724
- type: "text",
725
- text: `# Documentation for ${component}
726
-
727
- Source: ${mappedFile}
728
-
729
- ${documentation}`
730
- }
731
- ]
732
- };
733
- } catch (error) {
734
- return {
735
- content: [
736
- {
737
- type: "text",
738
- text: `Error reading documentation file for '${component}': ${error instanceof Error ? error.message : "Unknown error"}`
739
- }
740
- ]
741
- };
742
- }
743
- }
744
- );
745
- }
746
- };
747
-
748
- // src/tools/index.ts
749
- var tools = [
750
- getComponentPropsTool,
751
- getComponentDocsTool,
752
- listComponentsTool,
753
- getTailwindTokensTool
538
+ //#endregion
539
+ //#region src/tools/index.ts
540
+ const tools = [
541
+ getComponentPropsTool,
542
+ {
543
+ name: "get_component_docs",
544
+ description: "Get design system documentation for a specific component. Retrieves the corresponding Zeroheight documentation file for the given component name. Supports all SDS components and maps them to their appropriate documentation files.",
545
+ async ctx() {
546
+ try {
547
+ const componentList = await getAllComponentNames();
548
+ const allComponents = [...componentList.components, ...componentList["data-viz"]];
549
+ const exportedFiles = getExportedFiles();
550
+ return {
551
+ componentsWithDocs: getComponentsWithDocs(allComponents, exportedFiles),
552
+ exportedFiles
553
+ };
554
+ } catch (error) {
555
+ throw new Error(`Failed to initialize get component docs tool: ${error instanceof Error ? error.message : "Unknown error"}`);
556
+ }
557
+ },
558
+ exec(server, { ctx, name, description }) {
559
+ server.tool(name, description, { component: z.enum(ctx.componentsWithDocs).describe("The name of the SDS component to get documentation for") }, async ({ component }) => {
560
+ try {
561
+ const mappedFile = mapComponentToFile(component, ctx.exportedFiles);
562
+ if (!mappedFile) return { content: [{
563
+ type: "text",
564
+ text: `No documentation found for component '${component}'. This component may not have design system documentation available.`
565
+ }] };
566
+ const possiblePaths = [
567
+ path.join(dirname$1, "../../data/zeroheight-exports", mappedFile),
568
+ path.join(dirname$1, "../data/zeroheight-exports", mappedFile),
569
+ path.join(process.cwd(), "data/zeroheight-exports", mappedFile)
570
+ ];
571
+ let filePath = "";
572
+ for (const p of possiblePaths) if (fs.existsSync(p)) {
573
+ filePath = p;
574
+ break;
575
+ }
576
+ if (!filePath) throw new Error(`Documentation file ${mappedFile} not found`);
577
+ return { content: [{
578
+ type: "text",
579
+ text: `# Documentation for ${component}\n\nSource: ${mappedFile}\n\n${fs.readFileSync(filePath, "utf8")}`
580
+ }] };
581
+ } catch (error) {
582
+ return { content: [{
583
+ type: "text",
584
+ text: `Error reading documentation file for '${component}': ${error instanceof Error ? error.message : "Unknown error"}`
585
+ }] };
586
+ }
587
+ });
588
+ }
589
+ },
590
+ listComponentsTool,
591
+ getTailwindTokensTool
754
592
  ];
755
- var registeredToolCache = /* @__PURE__ */ new Map();
756
- var initializeTools = async (server2, config) => {
757
- const enabledTools = tools.filter((tool) => !tool.disabled?.(config));
758
- await Promise.all(
759
- enabledTools.map(async (tool) => {
760
- const toolCtx = await tool.ctx?.();
761
- if (registeredToolCache.has(tool.name)) {
762
- return;
763
- }
764
- registeredToolCache.set(tool.name, tool);
765
- tool.exec(server2, {
766
- config,
767
- ctx: toolCtx,
768
- description: tool.description,
769
- name: tool.name
770
- });
771
- })
772
- );
593
+ const registeredToolCache = /* @__PURE__ */ new Map();
594
+ const initializeTools = async (server, config) => {
595
+ const enabledTools = tools.filter((tool) => !tool.disabled?.(config));
596
+ await Promise.all(enabledTools.map(async (tool) => {
597
+ const toolCtx = await tool.ctx?.();
598
+ if (registeredToolCache.has(tool.name)) return;
599
+ registeredToolCache.set(tool.name, tool);
600
+ tool.exec(server, {
601
+ config,
602
+ ctx: toolCtx,
603
+ description: tool.description,
604
+ name: tool.name
605
+ });
606
+ }));
773
607
  };
774
- var FILENAME = fileURLToPath(import.meta.url);
775
- var DIRNAME = dirname$1(FILENAME);
776
- var MIME_TYPE_MARKDOWN = "text/markdown";
777
- var UNKNOWN_ERROR = "Unknown error";
608
+ //#endregion
609
+ //#region src/resources/index.ts
610
+ const DIRNAME = dirname(fileURLToPath(import.meta.url));
611
+ const MIME_TYPE_MARKDOWN = "text/markdown";
612
+ const UNKNOWN_ERROR = "Unknown error";
613
+ /**
614
+ * Finds the resource file by trying multiple paths
615
+ * to support both dev and production environments
616
+ */
778
617
  function findResourceFile(fileName) {
779
- const possiblePaths = [
780
- join(DIRNAME, "../../data/resources", fileName),
781
- // From src/resources in dev
782
- join(DIRNAME, "../data/resources", fileName),
783
- // From dist/resources in prod
784
- join(process.cwd(), "data/resources", fileName)
785
- // From current working directory
786
- ];
787
- for (const p of possiblePaths) {
788
- if (existsSync(p)) {
789
- return p;
790
- }
791
- }
792
- throw new Error(
793
- `Resource file '${fileName}' not found in any expected location`
794
- );
618
+ const possiblePaths = [
619
+ join(DIRNAME, "../../data/resources", fileName),
620
+ join(DIRNAME, "../data/resources", fileName),
621
+ join(process.cwd(), "data/resources", fileName)
622
+ ];
623
+ for (const p of possiblePaths) if (existsSync(p)) return p;
624
+ throw new Error(`Resource file '${fileName}' not found in any expected location`);
795
625
  }
796
- function initializeResources(server2) {
797
- server2.resource(
798
- "Figma to Code Translation Rules",
799
- "sds://rules/figma",
800
- {
801
- mimeType: MIME_TYPE_MARKDOWN,
802
- description: "Rules for translating Figma designs to SDS code"
803
- },
804
- async () => {
805
- try {
806
- const filePath = findResourceFile("figma-rules.md");
807
- const content = readFileSync(filePath, "utf-8");
808
- return {
809
- contents: [
810
- {
811
- uri: "sds://rules/figma",
812
- mimeType: MIME_TYPE_MARKDOWN,
813
- text: content
814
- }
815
- ]
816
- };
817
- } catch (err) {
818
- const message = err instanceof Error ? err.message : UNKNOWN_ERROR;
819
- throw new Error("Failed to read Figma rules: " + message);
820
- }
821
- }
822
- );
823
- server2.resource(
824
- "SDS Component Usage Rules",
825
- "sds://rules/components",
826
- {
827
- mimeType: MIME_TYPE_MARKDOWN,
828
- description: "Guidelines for using SDS components correctly"
829
- },
830
- async () => {
831
- try {
832
- const filePath = findResourceFile("sds-component-rules.md");
833
- const content = readFileSync(filePath, "utf-8");
834
- return {
835
- contents: [
836
- {
837
- uri: "sds://rules/components",
838
- mimeType: MIME_TYPE_MARKDOWN,
839
- text: content
840
- }
841
- ]
842
- };
843
- } catch (err) {
844
- const message = err instanceof Error ? err.message : UNKNOWN_ERROR;
845
- throw new Error("Failed to read component rules: " + message);
846
- }
847
- }
848
- );
849
- server2.resource(
850
- "Zeroheight Documentation Rules",
851
- "sds://rules/zeroheight",
852
- {
853
- mimeType: MIME_TYPE_MARKDOWN,
854
- description: "Rules for following Zeroheight documentation"
855
- },
856
- async () => {
857
- try {
858
- const filePath = findResourceFile("zeroheight-rules.md");
859
- const content = readFileSync(filePath, "utf-8");
860
- return {
861
- contents: [
862
- {
863
- uri: "sds://rules/zeroheight",
864
- mimeType: MIME_TYPE_MARKDOWN,
865
- text: content
866
- }
867
- ]
868
- };
869
- } catch (err) {
870
- const message = err instanceof Error ? err.message : UNKNOWN_ERROR;
871
- throw new Error("Failed to read Zeroheight rules: " + message);
872
- }
873
- }
874
- );
626
+ function initializeResources(server) {
627
+ server.resource("Figma to Code Translation Rules", "sds://rules/figma", {
628
+ mimeType: MIME_TYPE_MARKDOWN,
629
+ description: "Rules for translating Figma designs to SDS code"
630
+ }, async () => {
631
+ try {
632
+ return { contents: [{
633
+ uri: "sds://rules/figma",
634
+ mimeType: MIME_TYPE_MARKDOWN,
635
+ text: readFileSync(findResourceFile("figma-rules.md"), "utf-8")
636
+ }] };
637
+ } catch (err) {
638
+ const message = err instanceof Error ? err.message : UNKNOWN_ERROR;
639
+ throw new Error("Failed to read Figma rules: " + message);
640
+ }
641
+ });
642
+ server.resource("SDS Component Usage Rules", "sds://rules/components", {
643
+ mimeType: MIME_TYPE_MARKDOWN,
644
+ description: "Guidelines for using SDS components correctly"
645
+ }, async () => {
646
+ try {
647
+ return { contents: [{
648
+ uri: "sds://rules/components",
649
+ mimeType: MIME_TYPE_MARKDOWN,
650
+ text: readFileSync(findResourceFile("sds-component-rules.md"), "utf-8")
651
+ }] };
652
+ } catch (err) {
653
+ const message = err instanceof Error ? err.message : UNKNOWN_ERROR;
654
+ throw new Error("Failed to read component rules: " + message);
655
+ }
656
+ });
657
+ server.resource("Zeroheight Documentation Rules", "sds://rules/zeroheight", {
658
+ mimeType: MIME_TYPE_MARKDOWN,
659
+ description: "Rules for following Zeroheight documentation"
660
+ }, async () => {
661
+ try {
662
+ return { contents: [{
663
+ uri: "sds://rules/zeroheight",
664
+ mimeType: MIME_TYPE_MARKDOWN,
665
+ text: readFileSync(findResourceFile("zeroheight-rules.md"), "utf-8")
666
+ }] };
667
+ } catch (err) {
668
+ const message = err instanceof Error ? err.message : UNKNOWN_ERROR;
669
+ throw new Error("Failed to read Zeroheight rules: " + message);
670
+ }
671
+ });
875
672
  }
876
-
877
- // src/stdio.ts
673
+ //#endregion
674
+ //#region src/stdio.ts
878
675
  async function main() {
879
- await initializeTools(server, {});
880
- initializeResources(server);
881
- const transport = new StdioServerTransport();
882
- await server.connect(transport);
676
+ await initializeTools(server, {});
677
+ initializeResources(server);
678
+ const transport = new StdioServerTransport();
679
+ await server.connect(transport);
883
680
  }
884
681
  main().catch((error) => {
885
- console.error("Fatal error in main():", error);
886
- process.exit(1);
682
+ console.error("Fatal error in main():", error);
683
+ process.exit(1);
887
684
  });
685
+ //#endregion
686
+ export {};