@czi-sds/mcp 0.15.0 → 0.17.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.
Files changed (164) hide show
  1. package/README.md +2 -1
  2. package/data/component-docs/Accordion.md +291 -0
  3. package/data/component-docs/Autocomplete.md +525 -0
  4. package/data/component-docs/Banner.md +231 -0
  5. package/data/component-docs/Button.md +224 -0
  6. package/data/component-docs/ButtonDropdown.md +256 -0
  7. package/data/component-docs/ButtonGroup.md +320 -0
  8. package/data/component-docs/ButtonToggle.md +397 -0
  9. package/data/component-docs/Callout.md +268 -0
  10. package/data/component-docs/CellBasic.md +122 -0
  11. package/data/component-docs/CellComponent.md +63 -0
  12. package/data/component-docs/CellHeader.md +128 -0
  13. package/data/component-docs/ComplexFilter.md +294 -0
  14. package/data/component-docs/ContentCard.md +406 -0
  15. package/data/component-docs/Dialog.md +651 -0
  16. package/data/component-docs/Dropdown.md +155 -0
  17. package/data/component-docs/DropdownMenu.md +949 -0
  18. package/data/component-docs/HeatmapChart.md +782 -0
  19. package/data/component-docs/Hero.md +363 -0
  20. package/data/component-docs/Icon.md +283 -0
  21. package/data/component-docs/InputCheckbox.md +205 -0
  22. package/data/component-docs/InputDropdown.md +482 -0
  23. package/data/component-docs/InputRadio.md +173 -0
  24. package/data/component-docs/InputSearch.md +81 -0
  25. package/data/component-docs/InputSlider.md +189 -0
  26. package/data/component-docs/InputText.md +110 -0
  27. package/data/component-docs/InputToggle.md +141 -0
  28. package/data/component-docs/IntentMessage.md +293 -0
  29. package/data/component-docs/Legend.md +442 -0
  30. package/data/component-docs/Link.md +23 -0
  31. package/data/component-docs/List.md +300 -0
  32. package/data/component-docs/LoadingIndicator.md +198 -0
  33. package/data/component-docs/Menu.md +298 -0
  34. package/data/component-docs/MenuItem.md +100 -0
  35. package/data/component-docs/NavigationFooter.md +165 -0
  36. package/data/component-docs/NavigationHeader.md +500 -0
  37. package/data/component-docs/NavigationJumpTo.md +414 -0
  38. package/data/component-docs/Notification.md +288 -0
  39. package/data/component-docs/Pagination.md +67 -0
  40. package/data/component-docs/Panel.md +636 -0
  41. package/data/component-docs/Popover.md +448 -0
  42. package/data/component-docs/PreComposedTable.md +2947 -0
  43. package/data/component-docs/SegmentedControl.md +396 -0
  44. package/data/component-docs/StackedBarChart.md +475 -0
  45. package/data/component-docs/Table.md +2000 -0
  46. package/data/component-docs/TableHeader.md +53 -0
  47. package/data/component-docs/TableRow.md +74 -0
  48. package/data/component-docs/Tabs.md +455 -0
  49. package/data/component-docs/Tag.md +647 -0
  50. package/data/component-docs/TagFilter.md +131 -0
  51. package/data/component-docs/Tooltip.md +561 -0
  52. package/data/component-docs/TooltipCondensed.md +203 -0
  53. package/data/component-docs/TooltipTable.md +145 -0
  54. package/data/component-docs/index.json +262 -0
  55. package/data/component-list.json +2 -5
  56. package/data/component-props/Accordion.json +31 -11
  57. package/data/component-props/Alert.json +3 -3
  58. package/data/component-props/Autocomplete.json +150 -15
  59. package/data/component-props/Banner.json +31 -17
  60. package/data/component-props/Button.json +45 -20
  61. package/data/component-props/ButtonDropdown.json +36 -17
  62. package/data/component-props/ButtonDropdownLegacy.json +11 -11
  63. package/data/component-props/ButtonGroup.json +32 -11
  64. package/data/component-props/ButtonIcon.json +10 -10
  65. package/data/component-props/ButtonLegacy.json +19 -19
  66. package/data/component-props/ButtonToggle.json +32 -19
  67. package/data/component-props/ButtonToggleLegacy.json +11 -11
  68. package/data/component-props/Callout.json +58 -17
  69. package/data/component-props/CellBasic.json +94 -41
  70. package/data/component-props/CellComponent.json +23 -7
  71. package/data/component-props/CellHeader.json +62 -19
  72. package/data/component-props/ComplexFilter.json +52 -21
  73. package/data/component-props/ContentCard.json +70 -47
  74. package/data/component-props/Dialog.json +47 -14
  75. package/data/component-props/Dropdown.json +67 -31
  76. package/data/component-props/DropdownMenu.json +128 -23
  77. package/data/component-props/HeatmapChart.json +88 -12
  78. package/data/component-props/Hero.json +80 -39
  79. package/data/component-props/Icon.json +20 -9
  80. package/data/component-props/InputCheckbox.json +36 -14
  81. package/data/component-props/InputDropdown.json +75 -27
  82. package/data/component-props/InputRadio.json +31 -13
  83. package/data/component-props/InputSearch.json +41 -18
  84. package/data/component-props/InputSlider.json +46 -19
  85. package/data/component-props/InputText.json +26 -19
  86. package/data/component-props/InputToggle.json +26 -9
  87. package/data/component-props/IntentMessage.json +38 -9
  88. package/data/component-props/Link.json +13 -7
  89. package/data/component-props/LoadingIndicator.json +11 -3
  90. package/data/component-props/MenuItem.json +38 -19
  91. package/data/component-props/MenuSelect.json +8 -8
  92. package/data/component-props/NavigationFooter.json +49 -19
  93. package/data/component-props/NavigationHeader.json +150 -37
  94. package/data/component-props/NavigationJumpTo.json +33 -7
  95. package/data/component-props/Notification.json +39 -21
  96. package/data/component-props/Pagination.json +39 -11
  97. package/data/component-props/Panel.json +62 -9
  98. package/data/component-props/Popover.json +80 -7
  99. package/data/component-props/PreComposedTable.json +99 -27
  100. package/data/component-props/SegmentedControl.json +42 -3
  101. package/data/component-props/StackedBarChart.json +116 -42
  102. package/data/component-props/TableRow.json +38 -19
  103. package/data/component-props/Tabs.json +66 -9
  104. package/data/component-props/Tag.json +34 -17
  105. package/data/component-props/TagFilter.json +10 -3
  106. package/data/component-props/Tooltip.json +49 -18
  107. package/data/component-props/TooltipCondensed.json +18 -9
  108. package/data/component-props/TooltipTable.json +17 -7
  109. package/data/resources/{zeroheight-rules.md → documentation-rules.md} +43 -30
  110. package/data/resources/figma-rules.md +2 -2
  111. package/dist/stdio.js +483 -780
  112. package/package.json +12 -8
  113. package/data/component-props/ButtonDropdownV2.json +0 -34
  114. package/data/component-props/ButtonNew.json +0 -47
  115. package/data/component-props/ButtonToggleV2.json +0 -44
  116. package/data/component-props/ButtonV2.json +0 -43
  117. package/data/zeroheight-cache.json +0 -10259
  118. package/data/zeroheight-exports/Accordion.md +0 -774
  119. package/data/zeroheight-exports/Banner.md +0 -691
  120. package/data/zeroheight-exports/Borders.md +0 -117
  121. package/data/zeroheight-exports/Buttons.md +0 -1854
  122. package/data/zeroheight-exports/Callout.md +0 -931
  123. package/data/zeroheight-exports/Colors.md +0 -1755
  124. package/data/zeroheight-exports/Content-Card.md +0 -309
  125. package/data/zeroheight-exports/Contributing-to-SDS.md +0 -98
  126. package/data/zeroheight-exports/Control-Inputs.md +0 -2818
  127. package/data/zeroheight-exports/Corners.md +0 -104
  128. package/data/zeroheight-exports/Cover-page.md +0 -3
  129. package/data/zeroheight-exports/Dialog.md +0 -1367
  130. package/data/zeroheight-exports/Downloads.md +0 -236
  131. package/data/zeroheight-exports/Drop-Shadows.md +0 -79
  132. package/data/zeroheight-exports/Dropdown-Input.md +0 -1776
  133. package/data/zeroheight-exports/Dropdown-Menus.md +0 -913
  134. package/data/zeroheight-exports/Element-Status-Tracker.md +0 -267
  135. package/data/zeroheight-exports/Field-Inputs.md +0 -1405
  136. package/data/zeroheight-exports/Filters.md +0 -1111
  137. package/data/zeroheight-exports/Getting-Started.md +0 -1157
  138. package/data/zeroheight-exports/Hero.md +0 -414
  139. package/data/zeroheight-exports/Icons.md +0 -2067
  140. package/data/zeroheight-exports/Intent.md +0 -86
  141. package/data/zeroheight-exports/Introduction-to-Bases.md +0 -35
  142. package/data/zeroheight-exports/Introduction-to-Cells.md +0 -35
  143. package/data/zeroheight-exports/Introduction-to-DNA.md +0 -35
  144. package/data/zeroheight-exports/Introduction-to-Genes.md +0 -35
  145. package/data/zeroheight-exports/Introduction.md +0 -115
  146. package/data/zeroheight-exports/Link.md +0 -432
  147. package/data/zeroheight-exports/Lists.md +0 -986
  148. package/data/zeroheight-exports/Loading-Indicator.md +0 -41
  149. package/data/zeroheight-exports/Navigation.md +0 -1190
  150. package/data/zeroheight-exports/Notification.md +0 -1038
  151. package/data/zeroheight-exports/Panel.md +0 -1030
  152. package/data/zeroheight-exports/README.md +0 -122
  153. package/data/zeroheight-exports/Responsive-Design.md +0 -330
  154. package/data/zeroheight-exports/Search-Input.md +0 -91
  155. package/data/zeroheight-exports/Search.md +0 -822
  156. package/data/zeroheight-exports/Segmented-Control.md +0 -609
  157. package/data/zeroheight-exports/Spacing.md +0 -297
  158. package/data/zeroheight-exports/Table.md +0 -5345
  159. package/data/zeroheight-exports/Tabs.md +0 -1324
  160. package/data/zeroheight-exports/Tags.md +0 -1545
  161. package/data/zeroheight-exports/Text-Link.md +0 -268
  162. package/data/zeroheight-exports/Theming.md +0 -362
  163. package/data/zeroheight-exports/Tooltips.md +0 -2015
  164. package/data/zeroheight-exports/Typography.md +0 -800
package/dist/stdio.js CHANGED
@@ -1,242 +1,189 @@
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 = fileURLToPath(import.meta.url);
24
+ const dirname$1 = path.dirname(filename);
25
+ /**
26
+ * Locates a file under `data/`. The server runs both from source via tsx and
27
+ * from the bundle in `dist/`, which sit at different depths, and may also be
28
+ * started from the package root.
29
+ */
30
+ function resolveDataPath(relativePath) {
31
+ return [
32
+ path.join(dirname$1, "../../data", relativePath),
33
+ path.join(dirname$1, "../data", relativePath),
34
+ path.join(process.cwd(), "data", relativePath)
35
+ ].find((candidate) => fs.existsSync(candidate)) ?? null;
36
+ }
37
+ function readDataFile(relativePath, missingHint) {
38
+ const dataPath = resolveDataPath(relativePath);
39
+ if (!dataPath) throw new Error(`${relativePath} not found in any expected location. ${missingHint}`);
40
+ return fs.readFileSync(dataPath, "utf-8");
41
+ }
42
+ /**
43
+ * Gets all component names from both packages
44
+ */
23
45
  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
- }
46
+ try {
47
+ return JSON.parse(readDataFile("component-list.json", "Please run 'yarn generate:components-list' first."));
48
+ } catch (error) {
49
+ throw new Error(`Failed to load component list: ${error instanceof Error ? error.message : `Unknown error ${error}`}`);
50
+ }
53
51
  }
54
52
  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
- }
53
+ try {
54
+ const propsPath = resolveDataPath(`component-props/${component}.json`);
55
+ if (!propsPath) return { [component]: {
56
+ message: "Props information not available for this component. Run 'yarn generate:component-props' to generate props data.",
57
+ props: {}
58
+ } };
59
+ return JSON.parse(fs.readFileSync(propsPath, "utf-8"));
60
+ } catch (error) {
61
+ throw new Error(`Failed to load props for ${component}: ${error instanceof Error ? error.message : "Unknown error"}`);
62
+ }
86
63
  }
64
+ /**
65
+ * Gets the index of components that have generated documentation
66
+ */
67
+ async function getComponentDocsIndex() {
68
+ try {
69
+ return JSON.parse(readDataFile("component-docs/index.json", "Please run 'yarn generate:component-docs' first."));
70
+ } catch (error) {
71
+ throw new Error(`Failed to load component docs index: ${error instanceof Error ? error.message : `Unknown error ${error}`}`);
72
+ }
73
+ }
74
+ /**
75
+ * Fetches the generated documentation markdown for a specific component
76
+ */
77
+ async function fetchComponentDocs(file) {
78
+ try {
79
+ return readDataFile(`component-docs/${file}`, "Please run 'yarn generate:component-docs' first.");
80
+ } catch (error) {
81
+ throw new Error(`Failed to load documentation from ${file}: ${error instanceof Error ? error.message : "Unknown error"}`);
82
+ }
83
+ }
84
+ /**
85
+ * Gets all component names from both packages
86
+ */
87
87
  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
- }
88
+ try {
89
+ return JSON.parse(readDataFile("tailwind.json", "Please run 'yarn generate:tailwind-tokens' first."));
90
+ } catch (error) {
91
+ throw new Error(`Failed to load tailwind tokens: ${error instanceof Error ? error.message : `Unknown error ${error}`}`);
92
+ }
117
93
  }
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
- }
94
+ //#endregion
95
+ //#region src/tools/get-component-props.ts
96
+ const getComponentPropsTool = {
97
+ name: "get_component_props",
98
+ 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.",
99
+ async ctx() {
100
+ try {
101
+ const componentList = await getAllComponentNames();
102
+ return { componentList: [...componentList.components, ...componentList["data-viz"]] };
103
+ } catch (error) {
104
+ throw new Error(`Failed to initialize component props tool: ${error instanceof Error ? error.message : "Unknown error"}`);
105
+ }
106
+ },
107
+ exec(server, { ctx, name, description }) {
108
+ server.tool(name, description, { component: z.enum(ctx.componentList).describe("The name of the SDS component to get properties for") }, async ({ component }) => {
109
+ try {
110
+ const json = await fetchComponentProps(component);
111
+ return { content: [{
112
+ type: "text",
113
+ text: JSON.stringify(json)
114
+ }] };
115
+ } catch (error) {
116
+ return { content: [{
117
+ type: "text",
118
+ text: `Failed to get component props for ${component}: ${error instanceof Error ? error.message : "Unknown error"}`
119
+ }] };
120
+ }
121
+ });
122
+ }
169
123
  };
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
- }
124
+ //#endregion
125
+ //#region src/tools/list-components.ts
126
+ const listComponentsTool = {
127
+ name: "list_components",
128
+ 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.",
129
+ async ctx() {
130
+ try {
131
+ return { componentList: await getAllComponentNames() };
132
+ } catch (error) {
133
+ throw new Error(`Failed to initialize list components tool: ${error instanceof Error ? error.message : "Unknown error"}`);
134
+ }
135
+ },
136
+ exec(server, { ctx, name, description }) {
137
+ server.tool(name, description, {}, async () => {
138
+ return { content: [{
139
+ type: "text",
140
+ text: JSON.stringify(ctx.componentList, null, 2)
141
+ }] };
142
+ });
143
+ }
197
144
  };
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">
145
+ //#endregion
146
+ //#region src/lib/tailwind-guidance.ts
147
+ const TAILWIND_TOKEN_GUIDANCE = {
148
+ colors: {
149
+ category: "Colors",
150
+ 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.",
151
+ prefixes: [
152
+ "bg-",
153
+ "border-",
154
+ "divide-",
155
+ "outline-",
156
+ "ring-",
157
+ "ring-offset-",
158
+ "text-",
159
+ "placeholder-",
160
+ "caret-",
161
+ "decoration-",
162
+ "accent-",
163
+ "shadow-",
164
+ "fill-",
165
+ "stroke-",
166
+ "from-",
167
+ "via-",
168
+ "to-"
169
+ ],
170
+ examples: [
171
+ {
172
+ description: "Basic text and background colors",
173
+ 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
174
  Content with semantic colors
228
175
  </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
176
+ },
177
+ {
178
+ description: "Dark mode with hover states",
179
+ code: `<button className="bg-light-sds-color-semantic-accent-fill-primary dark:bg-dark-sds-color-semantic-accent-fill-primary
233
180
  hover:bg-light-sds-color-semantic-accent-fill-hover dark:hover:bg-dark-sds-color-semantic-accent-fill-hover">
234
181
  Click me
235
182
  </button>`
236
- },
237
- {
238
- description: "Border and focus states",
239
- code: `<input className="
183
+ },
184
+ {
185
+ description: "Border and focus states",
186
+ code: `<input className="
240
187
  border-light-sds-color-semantic-base-border-primary
241
188
  hover:border-light-sds-color-semantic-base-border-primary-hover
242
189
  focus:border-light-sds-color-semantic-base-border-primary-pressed
@@ -244,21 +191,22 @@ var TAILWIND_TOKEN_GUIDANCE = {
244
191
  dark:hover:border-dark-sds-color-semantic-base-border-primary-hover
245
192
  dark:focus:border-dark-sds-color-semantic-base-border-primary-pressed
246
193
  "/>`
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 -->
194
+ }
195
+ ],
196
+ 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"]
197
+ },
198
+ typography: {
199
+ category: "Typography",
200
+ description: "Complete text styling presets including font, size, weight, and spacing",
201
+ prefixes: [
202
+ "font-",
203
+ "text-",
204
+ "leading-",
205
+ "tracking-"
206
+ ],
207
+ examples: [{
208
+ 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.",
209
+ code: `<!-- Use typography tokens for complete text styling -->
262
210
  <h1 className="prose-sds-title-l-700-wide">Title</h1>
263
211
  <h1 className="prose-sds-header-xl-600-wide">Heading</h1>
264
212
  <p className="prose-sds-body-m-500-wide">Body text</p>
@@ -266,10 +214,9 @@ var TAILWIND_TOKEN_GUIDANCE = {
266
214
  <span className="prose-sds-tabular-xxs-600-wide">Tabular Numbers</span>
267
215
  <span className="prose-sds-code-s-500-wide">Code</span>
268
216
  <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 -->
217
+ }, {
218
+ description: "Individual typography properties",
219
+ code: `<!-- Or use individual properties when needed -->
273
220
  <p className="
274
221
  font-sds-body
275
222
  text-sds-body-m-400-wide
@@ -278,48 +225,47 @@ var TAILWIND_TOKEN_GUIDANCE = {
278
225
  ">
279
226
  Custom styled text
280
227
  </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">
228
+ }],
229
+ tips: [
230
+ "Use 'narrow' variants for mobile/compact layouts",
231
+ "Use 'wide' variants for desktop/spacious layouts",
232
+ "Font weights: 400 (regular), 500 (medium), 600 (semibold), 700 (bold)"
233
+ ]
234
+ },
235
+ spacing: {
236
+ category: "Spacing",
237
+ description: "Consistent spacing scale for padding, margin, and gaps",
238
+ prefixes: [
239
+ "p-",
240
+ "px-",
241
+ "py-",
242
+ "pt-",
243
+ "pr-",
244
+ "pb-",
245
+ "pl-",
246
+ "m-",
247
+ "mx-",
248
+ "my-",
249
+ "mt-",
250
+ "mr-",
251
+ "mb-",
252
+ "ml-",
253
+ "gap-",
254
+ "gap-x-",
255
+ "gap-y-",
256
+ "space-x-",
257
+ "space-y-"
258
+ ],
259
+ examples: [
260
+ {
261
+ description: "Padding and margin",
262
+ code: `<div className="p-sds-m mx-sds-l my-sds-s">
317
263
  Content with medium padding and different margins
318
264
  </div>`
319
- },
320
- {
321
- description: "Flexbox and grid gaps",
322
- code: `<div className="flex gap-sds-m">
265
+ },
266
+ {
267
+ description: "Flexbox and grid gaps",
268
+ code: `<div className="flex gap-sds-m">
323
269
  <div>Item 1</div>
324
270
  <div>Item 2</div>
325
271
  </div>
@@ -327,72 +273,71 @@ var TAILWIND_TOKEN_GUIDANCE = {
327
273
  <div className="grid grid-cols-3 gap-sds-l">
328
274
  <div>Grid item</div>
329
275
  </div>`
330
- },
331
- {
332
- description: "Negative margins for overlapping",
333
- code: `<div className="-mt-sds-s">
276
+ },
277
+ {
278
+ description: "Negative margins for overlapping",
279
+ code: `<div className="-mt-sds-s">
334
280
  Overlapping element
335
281
  </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">
282
+ }
283
+ ],
284
+ tips: [
285
+ "Scale: sds-s (small), sds-default (default), sds-m (medium), sds-l (large), sds-xl (extra large)",
286
+ "Use consistent spacing throughout your component",
287
+ "Combine with responsive prefixes: sm:p-sds-m lg:p-sds-l"
288
+ ]
289
+ },
290
+ borderRadius: {
291
+ category: "Border Radius",
292
+ description: "Corner radius values for rounded elements",
293
+ prefixes: [
294
+ "rounded-",
295
+ "rounded-t-",
296
+ "rounded-r-",
297
+ "rounded-b-",
298
+ "rounded-l-"
299
+ ],
300
+ examples: [{
301
+ description: "Basic rounded corners",
302
+ code: `<div className="rounded-sds-default">
358
303
  Standard rounded corners
359
304
  </div>
360
305
 
361
306
  <button className="rounded-sds-m">
362
307
  More rounded button
363
308
  </button>`
364
- },
365
- {
366
- description: "Directional radius",
367
- code: `<div className="rounded-t-sds-l rounded-b-none">
309
+ }, {
310
+ description: "Directional radius",
311
+ code: `<div className="rounded-t-sds-l rounded-b-none">
368
312
  Only top corners rounded
369
313
  </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">
314
+ }],
315
+ tips: [
316
+ "Use sds-default for most UI elements",
317
+ "Larger values (sds-l, sds-xl) for prominent elements",
318
+ "Combine with borders: border rounded-sds-m"
319
+ ]
320
+ },
321
+ boxShadow: {
322
+ category: "Box Shadow",
323
+ description: "Elevation shadows for depth and hierarchy",
324
+ prefixes: [
325
+ "shadow-",
326
+ "hover:shadow-",
327
+ "focus:shadow-"
328
+ ],
329
+ examples: [{
330
+ description: "Basic shadows",
331
+ code: `<div className="shadow-sds-s">
386
332
  Subtle shadow
387
333
  </div>
388
334
 
389
335
  <div className="shadow-sds-m">
390
336
  Medium elevation
391
337
  </div>`
392
- },
393
- {
394
- description: "Interactive shadows",
395
- code: `<button className="
338
+ }, {
339
+ description: "Interactive shadows",
340
+ code: `<button className="
396
341
  shadow-sds-s
397
342
  hover:shadow-sds-m
398
343
  active:shadow-sds-xs
@@ -400,18 +345,16 @@ var TAILWIND_TOKEN_GUIDANCE = {
400
345
  ">
401
346
  Interactive element
402
347
  </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
- }
348
+ }],
349
+ tips: [
350
+ "Use smaller shadows (sds-xs, sds-s) for subtle depth",
351
+ "Use larger shadows (sds-l, sds-xl) for modals and popovers",
352
+ "Combine with hover states for interactive feedback"
353
+ ]
354
+ }
411
355
  };
412
356
  function getTokenGuidance(category) {
413
- if (!category || category === "all") {
414
- return `SDS Design System Tokens for Tailwind CSS
357
+ if (!category || category === "all") return `SDS Design System Tokens for Tailwind CSS
415
358
 
416
359
  The Science Design System provides a comprehensive set of design tokens that map directly to Tailwind utilities.
417
360
 
@@ -438,450 +381,210 @@ typography: This category can be used for formatting typography in the tailwind.
438
381
  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
382
  spacing: This category can be used for formatting spacing in the tailwind.config.js file
440
383
  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;
477
- }
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
- }
554
- };
555
- var filename2 = fileURLToPath(import.meta.url);
556
- var dirname2 = path.dirname(filename2);
557
- 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;
620
- }
621
- 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
- }
650
- }
651
- function getComponentsWithDocs(allComponents, exportedFiles) {
652
- return allComponents.filter((component) => {
653
- const mappedFile = mapComponentToFile(component, exportedFiles);
654
- return mappedFile !== null;
655
- });
384
+ const guidance = TAILWIND_TOKEN_GUIDANCE[category];
385
+ if (!guidance) return `Category "${category}" not found. Available categories: ${Object.keys(TAILWIND_TOKEN_GUIDANCE).join(", ")}`;
386
+ let output = `## ${guidance.category} Tokens\n\n`;
387
+ output += `${guidance.description}\n\n`;
388
+ output += `**Tailwind Prefixes:** ${guidance.prefixes.join(", ")}\n\n`;
389
+ output += `### Examples:\n\n`;
390
+ guidance.examples.forEach((example, index) => {
391
+ output += `${index + 1}. **${example.description}**\n\`\`\`jsx\n${example.code}\n\`\`\`\n\n`;
392
+ });
393
+ if (guidance.tips && guidance.tips.length > 0) {
394
+ output += `### Tips:\n`;
395
+ guidance.tips.forEach((tip) => {
396
+ output += `- ${tip}\n`;
397
+ });
398
+ }
399
+ return output;
656
400
  }
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
401
+ //#endregion
402
+ //#region src/tools/index.ts
403
+ const tools = [
404
+ getComponentPropsTool,
405
+ {
406
+ name: "get_component_docs",
407
+ description: "Get design system documentation for a specific SDS component. Returns the component's full documentation, including how it differs from the underlying MUI component, its props, and runnable code examples for each supported variation.",
408
+ async ctx() {
409
+ try {
410
+ const index = await getComponentDocsIndex();
411
+ return {
412
+ index,
413
+ documented: Object.keys(index)
414
+ };
415
+ } catch (error) {
416
+ throw new Error(`Failed to initialize get component docs tool: ${error instanceof Error ? error.message : "Unknown error"}`);
417
+ }
418
+ },
419
+ exec(server, { ctx, name, description }) {
420
+ server.tool(name, description, { component: z.enum(ctx.documented).describe("The name of the SDS component to get documentation for") }, async ({ component }) => {
421
+ try {
422
+ const entry = ctx.index[component];
423
+ if (!entry) return { content: [{
424
+ type: "text",
425
+ text: `No documentation found for component '${component}'. This component may not have design system documentation available.`
426
+ }] };
427
+ const documentation = await fetchComponentDocs(entry.file);
428
+ return { content: [{
429
+ type: "text",
430
+ text: `Package: ${entry.package}\nSource: ${entry.source}\n\n${documentation}`
431
+ }] };
432
+ } catch (error) {
433
+ return { content: [{
434
+ type: "text",
435
+ text: `Error reading documentation for '${component}': ${error instanceof Error ? error.message : "Unknown error"}`
436
+ }] };
437
+ }
438
+ });
439
+ }
440
+ },
441
+ listComponentsTool,
442
+ {
443
+ name: "get_tailwind_tokens",
444
+ 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.",
445
+ async ctx() {
446
+ try {
447
+ return { tailwindTokens: await fetchTailwindTokens() };
448
+ } catch (error) {
449
+ throw new Error(`Failed to initialize tailwind tokens tool: ${error instanceof Error ? error.message : "Unknown error"}`);
450
+ }
451
+ },
452
+ exec(server, { ctx, name, description }) {
453
+ server.tool(name, description, { category: z.enum([
454
+ "all",
455
+ "fontFamily",
456
+ "fontSize",
457
+ "fontVariantNumeric",
458
+ "letterSpacing",
459
+ "lineHeight",
460
+ "textDecoration",
461
+ "textTransform",
462
+ "typography",
463
+ "height",
464
+ "width",
465
+ "borderRadius",
466
+ "boxShadow",
467
+ "breakpoints",
468
+ "colors",
469
+ "spacing"
470
+ ]).optional().describe("Optional category of tokens to retrieve. If not specified, returns all tokens.") }, async ({ category }) => {
471
+ try {
472
+ const tokens = ctx.tailwindTokens;
473
+ let result;
474
+ if (!category || category === "all") result = tokens;
475
+ else result = tokens[category] || {};
476
+ const responseContent = [];
477
+ const guidance = getTokenGuidance(category);
478
+ responseContent.push({
479
+ type: "text",
480
+ text: guidance
481
+ });
482
+ responseContent.push({
483
+ type: "text",
484
+ text: JSON.stringify(result, null, 2)
485
+ });
486
+ return { content: responseContent };
487
+ } catch (error) {
488
+ return { content: [{
489
+ type: "text",
490
+ text: `Failed to get Tailwind tokens: ${error instanceof Error ? error.message : "Unknown error"}`
491
+ }] };
492
+ }
493
+ });
494
+ }
495
+ }
754
496
  ];
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
- );
497
+ const registeredToolCache = /* @__PURE__ */ new Map();
498
+ const initializeTools = async (server, config) => {
499
+ const enabledTools = tools.filter((tool) => !tool.disabled?.(config));
500
+ await Promise.all(enabledTools.map(async (tool) => {
501
+ const toolCtx = await tool.ctx?.();
502
+ if (registeredToolCache.has(tool.name)) return;
503
+ registeredToolCache.set(tool.name, tool);
504
+ tool.exec(server, {
505
+ config,
506
+ ctx: toolCtx,
507
+ description: tool.description,
508
+ name: tool.name
509
+ });
510
+ }));
773
511
  };
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";
512
+ //#endregion
513
+ //#region src/resources/index.ts
514
+ const DIRNAME = dirname(fileURLToPath(import.meta.url));
515
+ const MIME_TYPE_MARKDOWN = "text/markdown";
516
+ const UNKNOWN_ERROR = "Unknown error";
517
+ /**
518
+ * Finds the resource file by trying multiple paths
519
+ * to support both dev and production environments
520
+ */
778
521
  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
- );
522
+ const possiblePaths = [
523
+ join(DIRNAME, "../../data/resources", fileName),
524
+ join(DIRNAME, "../data/resources", fileName),
525
+ join(process.cwd(), "data/resources", fileName)
526
+ ];
527
+ for (const p of possiblePaths) if (existsSync(p)) return p;
528
+ throw new Error(`Resource file '${fileName}' not found in any expected location`);
795
529
  }
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
- );
530
+ function initializeResources(server) {
531
+ server.resource("Figma to Code Translation Rules", "sds://rules/figma", {
532
+ mimeType: MIME_TYPE_MARKDOWN,
533
+ description: "Rules for translating Figma designs to SDS code"
534
+ }, async () => {
535
+ try {
536
+ return { contents: [{
537
+ uri: "sds://rules/figma",
538
+ mimeType: MIME_TYPE_MARKDOWN,
539
+ text: readFileSync(findResourceFile("figma-rules.md"), "utf-8")
540
+ }] };
541
+ } catch (err) {
542
+ const message = err instanceof Error ? err.message : UNKNOWN_ERROR;
543
+ throw new Error("Failed to read Figma rules: " + message);
544
+ }
545
+ });
546
+ server.resource("SDS Component Usage Rules", "sds://rules/components", {
547
+ mimeType: MIME_TYPE_MARKDOWN,
548
+ description: "Guidelines for using SDS components correctly"
549
+ }, async () => {
550
+ try {
551
+ return { contents: [{
552
+ uri: "sds://rules/components",
553
+ mimeType: MIME_TYPE_MARKDOWN,
554
+ text: readFileSync(findResourceFile("sds-component-rules.md"), "utf-8")
555
+ }] };
556
+ } catch (err) {
557
+ const message = err instanceof Error ? err.message : UNKNOWN_ERROR;
558
+ throw new Error("Failed to read component rules: " + message);
559
+ }
560
+ });
561
+ server.resource("SDS Documentation Rules", "sds://rules/documentation", {
562
+ mimeType: MIME_TYPE_MARKDOWN,
563
+ description: "Rules for following the SDS component documentation"
564
+ }, async () => {
565
+ try {
566
+ return { contents: [{
567
+ uri: "sds://rules/documentation",
568
+ mimeType: MIME_TYPE_MARKDOWN,
569
+ text: readFileSync(findResourceFile("documentation-rules.md"), "utf-8")
570
+ }] };
571
+ } catch (err) {
572
+ const message = err instanceof Error ? err.message : UNKNOWN_ERROR;
573
+ throw new Error("Failed to read documentation rules: " + message);
574
+ }
575
+ });
875
576
  }
876
-
877
- // src/stdio.ts
577
+ //#endregion
578
+ //#region src/stdio.ts
878
579
  async function main() {
879
- await initializeTools(server, {});
880
- initializeResources(server);
881
- const transport = new StdioServerTransport();
882
- await server.connect(transport);
580
+ await initializeTools(server, {});
581
+ initializeResources(server);
582
+ const transport = new StdioServerTransport();
583
+ await server.connect(transport);
883
584
  }
884
585
  main().catch((error) => {
885
- console.error("Fatal error in main():", error);
886
- process.exit(1);
586
+ console.error("Fatal error in main():", error);
587
+ process.exit(1);
887
588
  });
589
+ //#endregion
590
+ export {};