@volue/wave-mcp 0.1.3-next.1 → 0.1.3-next.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,6 +4,8 @@
4
4
 
5
5
  ## Available Tools
6
6
 
7
+ The following tools are available in the Wave MCP server and can be executed by LLMs using agent mode:
8
+
7
9
  | Tool Name | Description |
8
10
  | ------------------------ | -------------------------------------------------------------------------------- |
9
11
  | `init` | Initialize the Wave Design System in your project |
@@ -21,7 +23,7 @@
21
23
 
22
24
  Add configuration code that tells your MCP-compatible client how to connect to the Wave MCP server.
23
25
 
24
- ### VS Code
26
+ ### VS Code (Copilot)
25
27
 
26
28
  [![Install in VS Code](https://img.shields.io/badge/VS_Code-Install_Wave_MCP-0098FF?style=plastic)](https://insiders.vscode.dev/redirect/mcp/install?name=Wave%20Design%20System&config=%7B%22type%22%3A%22stdio%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40volue%2Fwave-mcp%40latest%22%5D%7D)
27
29
 
@@ -65,6 +67,27 @@ Or manually add to your Claude Code MCP servers configuration:
65
67
  }
66
68
  ```
67
69
 
70
+ > **Windows Users**: On native Windows (not WSL), you must use the `cmd /c` wrapper for npx commands to work correctly:
71
+ >
72
+ > CLI:
73
+ >
74
+ > ```bash
75
+ > claude mcp add wave --scope project -- cmd /c npx -y @volue/wave-mcp@latest
76
+ > ```
77
+ >
78
+ > Manual configuration:
79
+ >
80
+ > ```json
81
+ > {
82
+ > "mcpServers": {
83
+ > "wave": {
84
+ > "command": "cmd",
85
+ > "args": ["/c", "npx", "-y", "@volue/wave-mcp@latest"]
86
+ > }
87
+ > }
88
+ > }
89
+ > ```
90
+
68
91
  ### Cursor
69
92
 
70
93
  [![Install in Cursor](https://img.shields.io/badge/Cursor-Install_Wave_MCP-000000?style=plastic)](https://cursor.com/en/install-mcp?name=wave&config=eyJ0eXBlIjoic3RkaW8iLCJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkB2b2x1ZS93YXZlLW1jcEBsYXRlc3QiXX0=)
@@ -0,0 +1,292 @@
1
+ var P=Object.defineProperty;var s=(e,t)=>P(e,"name",{value:t,configurable:!0});import{a as p,f as u,u as y,g as d}from"./server-CktjsKoU.js";import A from"@volue/design-colors/generic";import*as D from"@volue/design-icons";import*as N from"@volue/design-media-queries";import j from"remark-parse";import O from"unified";import{z as v}from"zod";import{core as F,data as H,background as V,foreground as G,border as X,rgb as q}from"@volue/design-colors/flat";function m(){return m=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var o in n)({}).hasOwnProperty.call(n,o)&&(e[o]=n[o])}return e},m.apply(null,arguments)}s(m,"_extends");const J="0 1px 2.5px hsla(var(--shadow-color, 191, 74%, 6%), calc(var(--shadow-intensity, 1) * 0.08)), 0 3px 9px hsla(var(--shadow-color, 191, 74%, 6%), calc(var(--shadow-intensity, 1) * 0.048))",Q="0 0.4px 2.2px hsla(var(--shadow-color, 191, 74%, 6%), calc(var(--shadow-intensity, 1) * 0.022)), 0 1.4px 5px hsla(var(--shadow-color, 191, 74%, 6%), calc(var(--shadow-intensity, 1) * 0.04)), 0 5px 14px hsla(var(--shadow-color, 191, 74%, 6%), calc(var(--shadow-intensity, 1) * 0.06))",Y="0 0.3px 2px hsla(var(--shadow-color, 191, 74%, 6%), calc(var(--shadow-intensity, 1) * 0.015)), 0 1.5px 8px hsla(var(--shadow-color, 191, 74%, 6%), calc(var(--shadow-intensity, 1) * 0.024)), 0 4px 16px hsla(var(--shadow-color, 191, 74%, 6%), calc(var(--shadow-intensity, 1) * 0.04)), 0 8px 24px hsla(var(--shadow-color, 191, 74%, 6%), calc(var(--shadow-intensity, 1) * 0.07))",K="0 0.7px 2px hsla(var(--shadow-color, 191, 74%, 6%), calc(var(--shadow-intensity, 1) * 0.015)), 0 1.6px 8px hsla(var(--shadow-color, 191, 74%, 6%), calc(var(--shadow-intensity, 1) * 0.024)), 0 3.3px 16px hsla(var(--shadow-color, 191, 74%, 6%), calc(var(--shadow-intensity, 1) * 0.034)), 0 5px 26px hsla(var(--shadow-color, 191, 74%, 6%), calc(var(--shadow-intensity, 1) * 0.06)), 0 12px 42px hsla(var(--shadow-color, 191, 74%, 6%), calc(var(--shadow-intensity, 1) * 0.08))";var Z=Object.freeze({__proto__:null,elevationL:K,elevationM:Y,elevationS:Q,elevationXs:J}),h={base:{2:"0.125rem",4:"0.25rem",6:"0.375rem",8:"0.5rem",12:"0.75rem",14:"0.875rem",16:"1rem",20:"1.25rem",24:"1.5rem",28:"1.75rem",32:"2rem",36:"2.25rem",40:"2.5rem",44:"2.75rem",48:"3rem",64:"4rem",72:"4.5rem",80:"5rem",96:"6rem",112:"7rem",128:"8rem"},borderRadius:{xs:"0.25rem",s:"0.375rem",m:"0.5rem",l:"0.75rem",xl:"1rem",full:"100vh"},spacing:{xs:"0.25rem",s:"0.5rem",m:"1rem",l:"1.5rem",xl:"2rem",xxl:"3rem",xxxl:"4.5rem"}},g={font:{family:{base:"'Source Sans Pro', system-ui, -apple-system, 'Segoe UI'",display:"'FK Display', 'Source Sans Pro', system-ui, -apple-system, 'Segoe UI', sans-serif",mono:"ui-monospace, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace"},weight:{normal:"400",semibold:"600"}},size:{font:{base:"16px",eta:"12px",zeta:"14px",epsilon:"16px",delta:"19px",gamma:"21px",beta:"28px",alpha:"38px",giga:"51px"},letterSpacing:{tighter:"-0.05em",tight:"-0.025em",normal:"normal",wide:"0.025em",wider:"0.05em",widest:"0.1em"},lineHeight:{none:"1",body:"1.5",base:"1.5rem",small:"1.25rem",xSmall:"1.125rem",zeta:"1.714286",epsilon:"1.5",delta:"1.263158",gamma:"1.52381",beta:"1.714286",alpha:"1.263158",giga:"1.411765"}}};function ee(e){return e.charAt(0).toUpperCase()+e.slice(1)}s(ee,"capitalizeFirstLetter");var T=Object.keys(h.spacing).reduce(function(e,t){var n;return m({},e,(n={},n["spacing"+ee(t)]=h.spacing[t],n))},{}),C={colors:m({},F,H,V,G,X,q),space:T,zIndices:{auto:"auto",0:"0",1:"100",2:"200",3:"300",4:"400",5:"500",9:"900"},fonts:g.font.family,fontWeights:g.font.weight,fontSizes:g.size.font,lineHeights:g.size.lineHeight,letterSpacings:g.size.letterSpacing,sizes:m({},h.base,{measureNarrow:"30ch",measureMedium:"60ch",measureWide:"90ch",containerNarrow:"32rem",containerMedium:"48rem",containerWide:"74rem"}),radii:m({},h.borderRadius,T),shadows:m({},Z,{lift:"0 10px 20px -5px rgba(0, 0, 0, 0.15)"})};const te=O().use(j),B={Components:"component","UX patterns":"pattern"};function ne(e,t){const n=te.parse(e);let o=null;return n.children.reduce((r,a)=>{if(p(a,"heading")&&a.depth===2)return o=oe(a),r;if(!o||!p(a,"list"))return r;const i=o,c=a.children.map(l=>re(l,i,t)).filter(l=>l!==null);return r.concat(c)},[])}s(ne,"parseLlmsIndex");function oe(e){const[t]=e.children;if(!t||!p(t,"text"))return null;const n=t.value.trim();if(!(n in B))return null;const o=B[n];return{title:n,type:o}}s(oe,"extractSectionContext");function re(e,t,n){const[o]=e.children;if(!o||!p(o,"paragraph")||o.children.length!==2)return null;const[r,a]=o.children;if(!p(r,"link")||!p(a,"text")||r.children.length!==1)return null;const i=r.children[0];if(!p(i,"text"))return null;const c=i.value.trim(),l=r.url.replace(/^\//,""),z=new URL(l,`${n}/`).toString(),W=ae(l),U=se(t.title,l,t.type),M=ce(a.value);return{name:c,slug:W,category:U,section:t.title,type:t.type,url:z,description:M??void 0}}s(re,"listItemToResource");function ae(e){return e.replace(/\.md$/,"").split("/").pop()??""}s(ae,"deriveSlug");function se(e,t,n){const o=t.replace(/\.md$/,"").split("/");if(n==="component"||n==="pattern"){const r=o.length>=3?o[o.length-2]:null;return r?`${e} / ${ie(r)}`:e}return e}s(se,"deriveCategory");function ie(e){return e.split("-").filter(Boolean).map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join(" ")}s(ie,"formatSegment");function ce(e){if(!e)return null;const t=e.replace(/^\s*:\s*/,"").trim();return t.toLowerCase()==="no description available"?null:t}s(ce,"normalizeDescription");const x=process.env.USE_STABLE_DOCS==="true"||process.env.USE_STABLE_DOCS==="1"?"https://wave.volue.com":"https://wave-design-system.vercel.app",le=`${x}/llms.txt`,de=1e3*60*15,pe=process.env.WAVE_RESOURCES_CACHE_TIME?Number.parseInt(process.env.WAVE_RESOURCES_CACHE_TIME,10):de;function b(e){const t=new URL(e,x);return t.pathname.endsWith(".md")||(t.pathname+=".md"),t.toString()}s(b,"createUrl");let S=null,R=0;async function me(){if(S!==null&&Date.now()<R)return S;const e=await ue();return S=e,R=Date.now()+pe,e}s(me,"listCachedResources");let f=null;async function ue(){return f||(f=ge().finally(()=>{f=null})),f}s(ue,"idempotentLoadResourcesFromLlms");async function ge(){const e=await u(le,void 0,"fetch llms.txt");return ne(e,x)}s(ge,"loadResourcesFromLlms");async function he(e){return u(e.url,void 0,`fetch ${e.name} documentation`)}s(he,"fetchComponent");function fe(e){return u(e.url,void 0,`fetch ${e.name} pattern`)}s(fe,"fetchPattern");async function ye(){return u(b("get-started/developing"),void 0,"fetch developing guide")}s(ye,"fetchDevelopingGuide");async function ve(){return u(b("tokens/colors"),void 0,"fetch color usage guidelines")}s(ve,"fetchColorUsageGuidelines");function w(){return Object.entries(D).map(([e,t])=>({name:e,svg:t}))}s(w,"listIcons");function xe(){const e=w();return y(e.map(t=>t.name))}s(xe,"getIconNames");function be(e,t){const n=t.trim().toLowerCase();return e.find(o=>o.name.toLowerCase()===n)}s(be,"findIconByName");async function E(e){return(await me()).filter(n=>n.type===e)}s(E,"listResourcesByType");function I(e,t){const n=t.trim().toLowerCase();return e.find(o=>o.name.toLowerCase()===n)}s(I,"findResourceByName");function k(){return E("component")}s(k,"listComponents");async function Se(){const e=await k();return y(e.map(t=>t.name))}s(Se,"getComponentNames");function $(){return E("pattern")}s($,"listPatterns");async function we(){const e=await $();return y(e.map(t=>t.name))}s(we,"getPatternNames");function L(e){return e.reduce((t,n)=>(t[n.category]||(t[n.category]=[]),t[n.category].push(n),t),{})}s(L,"groupResourcesByCategory");const ke={name:"get_color_usage",description:"Retrieve the Wave Design System color tokens and guidelines for applying color in user interfaces.",exec(e,{name:t,description:n}){e.tool(t,n,async()=>{try{const o=await ve();return{content:[{type:"text",text:JSON.stringify(A)},{type:"text",text:`Here are the Wave Design System color usage guidelines:
2
+
3
+ ${o}
4
+
5
+ ---
6
+ Source: ${b("tokens/colors")}`}]}}catch(o){return{isError:!0,content:[{type:"text",text:`Failed to retrieve color usage guidelines: ${d(o)}`}]}}})}},$e={name:"get_component",description:"Retrieve comprehensive documentation for a specific Wave Design System component by name. This tool retrieves the import instructions, basic usage and advanced configuration examples, code snippets for common scenarios, available props/properties table and some general guidelines for a given Wave Design System component.",async ctx(){try{return{componentNames:await Se()}}catch(e){throw new Error(`Failed to initialize component tool: ${d(e)}`)}},exec(e,{ctx:t,name:n,description:o}){e.tool(n,o,{name:v.enum(t.componentNames).describe("The name of the component to retrieve documentation for. This can be derived from calling the `get_components` tool.")},async({name:r})=>{try{const a=await k(),i=I(a,r);if(!i)throw new Error("Component not found");const c=await he(i);return c?{content:[{type:"text",text:`Here is the documentation for the \`${i.name}\` component from the Wave Design System:
7
+
8
+ ${c}
9
+
10
+ ---
11
+ Source: ${i.url}`}]}:{content:[{type:"text",text:`No documentation content found for the \`${i.name}\` component.`}]}}catch(a){return{isError:!0,content:[{type:"text",text:`Failed to retrieve documentation for \`${r}\`: ${d(a)}`}]}}})}},Te={name:"get_icon",description:"Retrieve a specific icon information by name from Wave Design System.",exec(e,{name:t,description:n}){e.tool(t,n,{name:v.enum(xe()).describe("The icon name to retrieve. This can be derived from calling the `list_icon` tool.")},async({name:o})=>{try{const r=w(),a=be(r,o);if(!a)throw new Error("Icon not found.");const i=`<SvgIcon iconName="${a.name}" />`,c=`<div class="svgIcon svgIcon--stroked">
12
+ <svg focusable="false" aria-hidden="true">
13
+ <use xlink:href="#svg--${a.name}"></use>
14
+ </svg>
15
+ </div>`;return{content:[{type:"text",text:`# ${a.name} icon
16
+
17
+ ## React component:
18
+
19
+ \`\`\`tsx
20
+ ${i}
21
+ \`\`\`
22
+
23
+ ## HTML markup:
24
+
25
+ \`\`\`html
26
+ ${c}
27
+ \`\`\`
28
+
29
+ ## Raw SVG code:
30
+
31
+ \`\`\`svg
32
+ ${a.svg}
33
+ \`\`\``}]}}catch(r){return{isError:!0,content:[{type:"text",text:`Failed to retrieve icon \`${o}\`: ${d(r)}`}]}}})}},Ce={name:"get_pattern",description:"Retrieve documentation for a specific Wave Design System UX pattern by name. This tool provides guidance, examples and components that implement the selected pattern.",async ctx(){try{return{patternNames:await we()}}catch(e){throw new Error(`Failed to initialize pattern tool: ${d(e)}`)}},exec(e,{ctx:t,name:n,description:o}){e.tool(n,o,{name:v.enum(t.patternNames).describe("The name of the UX pattern to retrieve documentation for. This can be derived from calling the `list_patterns` tool.")},async({name:r})=>{try{const a=await $(),i=I(a,r);if(!i)throw new Error("Pattern not found");const c=await fe(i);return{content:[{type:"text",text:`Here are the guidelines for the \`${i.name}\` UX pattern from the Wave Design System:
34
+
35
+ ${c}
36
+
37
+ ---
38
+ Source: ${i.url}`}]}}catch(a){return{isError:!0,content:[{type:"text",text:`Failed to retrieve documentation for \`${r}\`: ${d(a)}`}]}}})}},Be={name:"get_styling_guidelines",description:"Retrieve guidelines for styling Wave Design System components and creating custom styled components.",exec(e,{name:t,description:n}){e.tool(t,n,async()=>({content:[{type:"text",text:`Wave Design System components can be styled using standard React approaches (className, style prop), but Wave provides specialized styling APIs for customizing component styles and creating custom styled components. These APIs are powered by Stitches.js, a CSS-in-JS library with near-zero runtime. They are the recommended approach because they integrate seamlessly with Wave's design tokens and provide type-safe styles.
39
+
40
+ ## Styling APIs
41
+
42
+ ### CSS Prop
43
+
44
+ The \`css\` property is available on all Wave components for styling. It generates CSS class names from the style object, supporting all standard CSS properties and selectors, plus design tokens and responsive breakpoints.
45
+
46
+ Example:
47
+
48
+ \`\`\`tsx
49
+ import { Box } from '@volue/wave-react';
50
+
51
+ <Box
52
+ css={{
53
+ display: 'flex',
54
+ color: '$foregroundInverse',
55
+ backgroundColor: '$backgroundAccentStrong',
56
+ padding: '$spacingM'
57
+ }}
58
+ />
59
+ \`\`\`
60
+
61
+ The \`css\` prop works best for one-off style customizations of specific component instances.
62
+
63
+ ### Styled Function
64
+
65
+ Use \`styled()\` to create reusable styled components with semantic names. It supports all \`css\` prop features, variants for conditional styling, and provides better performance than the \`css\` prop.
66
+
67
+ \`\`\`tsx
68
+ import { styled } from '@volue/wave-react';
69
+
70
+ // Create a simple styled component
71
+ const Container = styled('div', {
72
+ padding: '$spacingM',
73
+ backgroundColor: '$backgroundNeutralSubtle',
74
+ borderRadius: '$borderRadiusM'
75
+ });
76
+
77
+ // Create a styled component with variants
78
+ const SectionTitle = styled('h2', {
79
+ fontWeight: '$semibold',
80
+ color: '$foregroundAccent',
81
+
82
+ variants: {
83
+ size: {
84
+ medium: {
85
+ fontSize: '$gamma',
86
+ },
87
+ large: {
88
+ fontSize: '$beta',
89
+ }
90
+ }
91
+ },
92
+
93
+ // optional defaultVariants
94
+ defaultVariants: {
95
+ size: 'medium'
96
+ }
97
+ });
98
+
99
+ // Use with a specific variant
100
+ <SectionTitle size="large">Analytics Overview</SectionTitle>
101
+
102
+ // Extend an existing Wave component
103
+ import { AppFrame } from '@volue/wave-react';
104
+
105
+ const StyledAppFrame = styled(AppFrame.Root, {
106
+ backgroundColor: '$backgroundNeutralMinimal'
107
+ });
108
+ \`\`\`
109
+
110
+ ## Design Tokens
111
+
112
+ Wave provides a comprehensive set of design tokens for colors, spacing, typography, border radii, shadows, and more. All tokens are available in both \`css\` prop and \`styled()\` function using the \`$tokenName\` syntax (as shown in the examples above).
113
+
114
+ **Use the \`get_tokens\` tool to discover all available design tokens** including their values and usage examples.
115
+
116
+ ## Media Query Tokens
117
+
118
+ Wave provides media query tokens for responsive design. Use these tokens to create breakpoint-based styles:
119
+
120
+ ${Object.entries(N).map(([r,a])=>`- \`@${r}\`: ${a}`).join(`
121
+ `)}
122
+
123
+ ### Responsive Styling Examples
124
+
125
+ **Using media queries with the css prop:**
126
+
127
+ \`\`\`tsx
128
+ import { Box } from '@volue/wave-react';
129
+
130
+ <Box
131
+ css={{
132
+ padding: '$spacingS',
133
+
134
+ '@mqMediumAndUp': {
135
+ padding: '$spacingM'
136
+ },
137
+ '@mqLargeAndUp': {
138
+ padding: '$spacingL'
139
+ }
140
+ }}
141
+ >
142
+ Responsive padding
143
+ </Box>
144
+ \`\`\`
145
+
146
+ **Using media queries with styled function:**
147
+
148
+ \`\`\`tsx
149
+ import { styled } from '@volue/wave-react';
150
+
151
+ const ResponsiveContainer = styled('div', {
152
+ display: 'flex',
153
+ flexDirection: 'column',
154
+ gap: '$spacingS',
155
+
156
+ '@mqMediumAndUp': {
157
+ flexDirection: 'row',
158
+ gap: '$spacingM'
159
+ }
160
+ });
161
+ \`\`\`
162
+
163
+ **Responsive variants:**
164
+
165
+ \`\`\`tsx
166
+ import { styled } from '@volue/wave-react';
167
+
168
+ const Button = styled('button', {
169
+ variants: {
170
+ size: {
171
+ small: { padding: '$spacingS' },
172
+ large: { padding: '$spacingL' }
173
+ }
174
+ }
175
+ });
176
+
177
+ // Apply different variants at different breakpoints
178
+ <Button
179
+ size={{
180
+ '@initial': 'small',
181
+ '@mqLargeAndUp': 'large'
182
+ }}
183
+ >
184
+ Responsive Button
185
+ </Button>
186
+ \`\`\`
187
+
188
+ ## Best Practices
189
+
190
+ 1. **Use design tokens**: Always prefer design tokens (prefixed with \`$\`) over hardcoded values for consistency. Use the \`get_tokens\` tool to discover available tokens.
191
+ 2. **Choose the right API**: Use \`css\` prop for one-off styles, \`styled()\` for reusable components
192
+ 3. **Semantic breakpoints**: Use Wave's semantic media query tokens rather than arbitrary pixel values
193
+ `}]}))}},Re={colors:["background","backgroundColor","backgroundImage","border","borderBlock","borderBlockEnd","borderBlockStart","borderBottom","borderBottomColor","borderColor","borderInline","borderInlineEnd","borderInlineStart","borderLeft","borderLeftColor","borderRight","borderRightColor","borderTop","borderTopColor","caretColor","color","columnRuleColor","fill","outlineColor","stroke","textDecorationColor"],fonts:["fontFamily"],fontSizes:["fontSize"],fontWeights:["fontWeight"],lineHeights:["lineHeight"],letterSpacings:["letterSpacing"],radii:["borderRadius","borderTopLeftRadius","borderTopRightRadius","borderBottomRightRadius","borderBottomLeftRadius"],sizes:["blockSize","minBlockSize","maxBlockSize","inlineSize","minInlineSize","maxInlineSize","width","minWidth","maxWidth","height","minHeight","maxHeight","flexBasis","gridTemplateColumns","gridTemplateRows"],space:["gap","gridGap","columnGap","gridColumnGap","rowGap","gridRowGap","inset","insetBlock","insetBlockEnd","insetBlockStart","insetInline","insetInlineEnd","insetInlineStart","margin","marginTop","marginRight","marginBottom","marginLeft","marginBlock","marginBlockEnd","marginBlockStart","marginInline","marginInlineEnd","marginInlineStart","padding","paddingTop","paddingRight","paddingBottom","paddingLeft","paddingBlock","paddingBlockEnd","paddingBlockStart","paddingInline","paddingInlineEnd","paddingInlineStart","top","right","bottom","left","scrollMargin","scrollMarginTop","scrollMarginRight","scrollMarginBottom","scrollMarginLeft","scrollMarginX","scrollMarginY","scrollMarginBlock","scrollMarginBlockEnd","scrollMarginBlockStart","scrollMarginInline","scrollMarginInlineEnd","scrollMarginInlineStart","scrollPadding","scrollPaddingTop","scrollPaddingRight","scrollPaddingBottom","scrollPaddingLeft","scrollPaddingX","scrollPaddingY","scrollPaddingBlock","scrollPaddingBlockEnd","scrollPaddingBlockStart","scrollPaddingInline","scrollPaddingInlineEnd","scrollPaddingInlineStart"],zIndices:["zIndex"],shadows:["boxShadow","textShadow"],transitions:["transition"],borderWidths:["borderWidth","borderTopWidth","borderRightWidth","borderBottomWidth","borderLeftWidth"],borderStyles:["borderStyle","borderTopStyle","borderRightStyle","borderBottomStyle","borderLeftStyle"]},Ee={name:"get_tokens",description:"Retrieve the Wave Design System design tokens (colors, fonts, spacing, font styles, etc.) exposed by the `@volue/wave-react` package. Includes token type mappings to CSS properties and usage examples.",exec(e,{name:t,description:n}){e.tool(t,n,async()=>{const o=Object.entries(Re).map(([r,a])=>`| ${r} | ${a.join(", ")} |`).join(`
194
+ `);return{content:[{type:"text",text:`Below is a list of design tokens available from Wave Design System.
195
+ There are ${Object.keys(C).length} token types available:
196
+
197
+ ${JSON.stringify(C)}`},{type:"text",text:`## Token Type to CSS Property Mapping
198
+
199
+ Token types are automatically mapped to CSS Properties:
200
+
201
+ | Token | Properties |
202
+ |-------|------------|
203
+ ${o}
204
+
205
+ ## Using tokens
206
+
207
+ Tokens can be used to style components.
208
+
209
+ \`\`\`tsx
210
+ import { styled } from '@volue/wave-react';
211
+
212
+ const Button = styled('button', {
213
+ backgroundColor: '$backgroundAccentStrong'
214
+ });
215
+
216
+ () => <Button>Button</Button>;
217
+ \`\`\`
218
+
219
+ Tokens also work inside the \`css\` prop.
220
+
221
+ \`\`\`tsx
222
+ const Button = styled('button', {});
223
+
224
+ () => (
225
+ <Button
226
+ css={{
227
+ backgroundColor: '$backgroundAccentStrong'
228
+ }}
229
+ >
230
+ Button
231
+ </Button>
232
+ );
233
+ \`\`\`
234
+
235
+ You can pick a token from any of available token types by prefixing them with the type name, in case they aren't automatically mapped.
236
+
237
+ \`\`\`tsx
238
+ const Button = styled('button', {
239
+ // use a token from the sizes scale
240
+ marginTop: '$sizes$6'
241
+ });
242
+ \`\`\`
243
+
244
+ For more comprehensive styling guidelines including responsive design, variants, and best practices, use the \`get_styling_guidelines\` tool.
245
+
246
+ ## Programmatic theme access
247
+
248
+ \`\`\`tsx
249
+ import { theme } from '@volue/wave-react';
250
+
251
+ // .value returns raw values ("#0c4957", "0.5rem") for JavaScript operations
252
+ const rawColor = theme.colors.foregroundAccent.value;
253
+ const rawSpacing = theme.space.spacingS.value;
254
+ const rawSize = theme.sizes['20'].value;
255
+
256
+ // .computedValue (or default) returns serialized CSS variables ("var(--colors-foregroundAccent)")
257
+ const cssVar = theme.colors.foregroundAccent.computedValue;
258
+ \`\`\`
259
+ `}]}})}},Ie={name:"init",description:"Get guide on how to setup or create a project that includes Wave Design System.",exec(e,{name:t,description:n}){e.tool(t,n,async()=>{try{return{content:[{type:"text",text:`The getting started documentation for developing with Wave Design System is included below.
260
+
261
+ It's **important** that if the project is using a tool like Vite or Next.js, one of the pre-configured starter templates should be used instead of manual configuration:
262
+
263
+ - https://github.com/Volue/wave-vite-example (Vite template)
264
+ - https://github.com/Volue/wave-nextjs-app-router-example (Next.js App Router template)
265
+
266
+ ---
267
+
268
+ ${await ye()}
269
+ `}]}}catch(o){return{isError:!0,content:[{type:"text",text:`Failed to retrieve getting started documentation: ${d(o)}`}]}}})}},Le={name:"list_components",description:"List all components available from the Wave Design System. This tool retrieves the names of all available Wave Design System components grouped by category.",exec(e,{name:t,description:n}){e.tool(t,n,async()=>{try{const o=await k(),r=L(o);return{content:[{type:"text",text:`The following components are available in the Wave Design System:
270
+
271
+ ${Object.entries(r).map(([i,c])=>`## ${i}
272
+ ${c.map(l=>`- ${l.name}`).join(`
273
+ `)}`).join(`
274
+
275
+ `)}
276
+
277
+ Use the \`get_component\` tool to get more information about a specific component.
278
+
279
+ Use these components from the @volue/wave-react package.`}]}}catch(o){return{isError:!0,content:[{type:"text",text:`Failed to retrieve the component index: ${d(o)}`}]}}})}},_e={name:"list_icons",description:"List all icons available from the Wave Design System. Icons are sourced directly from the `@volue/design-icons` package.",exec(e,{name:t,description:n}){e.tool(t,n,async()=>{try{return{content:[{type:"text",text:`The following icons are available in the Wave Design System:
280
+
281
+ ${w().map(a=>`- ${a.name}`).join(`
282
+ `)}
283
+
284
+ Use the \`get_icon\` tool to retrieve the SVG markup and usage guidelines for a specific icon.`}]}}catch(o){return{isError:!0,content:[{type:"text",text:`Failed to retrieve the icon data: ${d(o)}`}]}}})}},ze={name:"list_patterns",description:"List all UX patterns available from the Wave Design System. This tool retrieves the names of all available Wave Design System patterns grouped by category.",exec(e,{name:t,description:n}){e.tool(t,n,async()=>{try{const o=await $(),r=L(o);return{content:[{type:"text",text:`The following UX patterns are available in the Wave Design System:
285
+
286
+ ${Object.entries(r).map(([i,c])=>`## ${i}
287
+ ${c.map(l=>`- ${l.name}`).join(`
288
+ `)}`).join(`
289
+
290
+ `)}
291
+
292
+ Use the \`get_pattern\` tool to access detailed guidance for a specific pattern.`}]}}catch(o){return{isError:!0,content:[{type:"text",text:`Failed to retrieve the pattern index: ${d(o)}`}]}}})}},We=[Ie,Le,$e,ze,Ce,ke,_e,Te,Ee,Be],_=new Set;async function Ue(e){await Promise.all(We.map(async t=>{if(_.has(t.name))return;const n=await t.ctx?.();_.add(t.name),t.exec(e,{name:t.name,description:t.description,ctx:n})}))}s(Ue,"initializeTools");export{Ue as i};
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- var e=Object.defineProperty;var t=(o,r)=>e(o,"name",{value:r,configurable:!0});import{i}from"./server-4exaheDz.js";import{s as g}from"./server-4exaheDz.js";import"node:fs";import"node:url";import"@modelcontextprotocol/sdk/server/mcp.js";if(i(import.meta.url)){const r=process.argv.slice(2)[0]||"stdio";async function s(){try{switch(r){case"stdio":await import("./transports/stdio.js");break;case"http":process.argv.push("--auto-run"),await import("./transports/http.js");break;default:console.error(`Unknown transport: ${r}`),console.error("Available transports: stdio, http"),process.exit(1)}}catch(a){console.error("Error running transport:",a),process.exit(1)}}t(s,"run"),s()}export{g as server};
2
+ var e=Object.defineProperty;var t=(o,r)=>e(o,"name",{value:r,configurable:!0});import{i}from"./server-CktjsKoU.js";import{s as g}from"./server-CktjsKoU.js";import"node:fs";import"node:url";import"@modelcontextprotocol/sdk/server/mcp.js";if(i(import.meta.url)){const r=process.argv.slice(2)[0]||"stdio";async function s(){try{switch(r){case"stdio":await import("./transports/stdio.js");break;case"http":process.argv.push("--auto-run"),await import("./transports/http.js");break;default:console.error(`Unknown transport: ${r}`),console.error("Available transports: stdio, http"),process.exit(1)}}catch(a){console.error("Error running transport:",a),process.exit(1)}}t(s,"run"),s()}export{g as server};
@@ -1 +1 @@
1
- var i=Object.defineProperty;var t=(e,r)=>i(e,"name",{value:r,configurable:!0});import{realpathSync as c}from"node:fs";import{pathToFileURL as f}from"node:url";import{McpServer as p}from"@modelcontextprotocol/sdk/server/mcp.js";async function u(e,r,n){const s=await fetch(e,r);if(!s.ok){const a=n??`fetch ${e}`;throw new Error(`Failed to ${a}: ${s.status} ${s.statusText}`)}return s.text()}t(u,"fetchMarkdown");function m(e,r){return e.type===r}t(m,"isNodeType");function v(e){return Array.from(new Set(e))}t(v,"uniq");function h(e){return e instanceof Error?e.message:"Unknown error"}t(h,"getErrorMessage");function g(e){if(!process.argv[1])return!1;const r=c(process.argv[1]),n=f(r);return e===n.href}t(g,"isEntryFile");var l="0.1.3-next.1",o={version:l};const w=new p({name:"Wave Design System",version:o.version,capabilities:{prompts:{},resources:{},tools:{}}});export{m as a,u as f,h as g,g as i,o as p,w as s,v as u};
1
+ var i=Object.defineProperty;var t=(e,r)=>i(e,"name",{value:r,configurable:!0});import{realpathSync as c}from"node:fs";import{pathToFileURL as f}from"node:url";import{McpServer as p}from"@modelcontextprotocol/sdk/server/mcp.js";async function u(e,r,n){const s=await fetch(e,r);if(!s.ok){const a=n??`fetch ${e}`;throw new Error(`Failed to ${a}: ${s.status} ${s.statusText}`)}return s.text()}t(u,"fetchMarkdown");function m(e,r){return e.type===r}t(m,"isNodeType");function v(e){return Array.from(new Set(e))}t(v,"uniq");function h(e){return e instanceof Error?e.message:"Unknown error"}t(h,"getErrorMessage");function g(e){if(!process.argv[1])return!1;const r=c(process.argv[1]),n=f(r);return e===n.href}t(g,"isEntryFile");var l="0.1.3-next.3",o={version:l};const w=new p({name:"Wave Design System",version:o.version,capabilities:{prompts:{},resources:{},tools:{}}});export{m as a,u as f,h as g,g as i,o as p,w as s,v as u};
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- var h=Object.defineProperty;var i=(e,s)=>h(e,"name",{value:s,configurable:!0});import{StreamableHTTPServerTransport as f}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{isInitializeRequest as g}from"@modelcontextprotocol/sdk/types.js";import I from"cors";import l from"express";import{randomUUID as S}from"node:crypto";import{s as m,p as T,i as w}from"../server-4exaheDz.js";import{i as y}from"../index-CS97aye0.js";import"node:fs";import"node:url";import"@modelcontextprotocol/sdk/server/mcp.js";import"@volue/design-colors/generic";import"@volue/design-icons";import"@volue/design-media-queries";import"@volue/wave-react/tokens";import"remark-parse";import"unified";import"zod";const t=l(),P=process.env.CORS_ORIGIN?.split(",")??"*";t.use(I({origin:P,exposedHeaders:["Mcp-Session-Id"],allowedHeaders:["Content-Type","mcp-session-id"]})),t.use(l.json());const r=new Map;t.post("/mcp",async(e,s)=>{const n=e.headers["mcp-session-id"];let o;if(n&&r.has(n))o=r.get(n);else if(!n&&g(e.body))o=new f({sessionIdGenerator:i(()=>S(),"sessionIdGenerator"),onsessioninitialized:i(v=>{r.set(v,o)},"onsessioninitialized")}),o.onclose=()=>{o.sessionId&&r.has(o.sessionId)&&r.delete(o.sessionId)},await y(m),await m.connect(o);else return s.status(400).json({error:{message:"Bad Request: No valid session ID provided"}});await o.handleRequest(e,s,e.body)});const d=i(async(e,s)=>{const n=e.headers["mcp-session-id"];if(!n||!r.has(n))return s.status(404).send("Invalid or missing session ID");await r.get(n).handleRequest(e,s)},"handleSessionRequest");t.get("/mcp",d),t.delete("/mcp",d),t.get("/",(e,s)=>{s.json({name:"Wave MCP Server",version:T.version,description:"MCP server for Wave Design System",endpoints:{"/":"Server information (this response)","/mcp":"Streamable HTTP endpoint for MCP connection","/health":"Health check endpoint"}})}),t.get("/health",(e,s)=>{s.json({status:"healthy",timestamp:new Date().toISOString(),uptime:process.uptime()})});const a=process.env.HOST??"localhost",p=process.env.PORT?Number(process.env.PORT):3e3;let c=null;(process.argv.includes("--auto-run")||w(import.meta.url))&&(c=t.listen(p,a,e=>{e&&(console.error("\u274C Failed to start server:",e),process.exit(1)),console.log(`\u{1F680} Wave MCP Server running on http://${a}:${p}`),console.log(`\u{1F517} Connect via http://${a}:${p}/mcp`)}));const u=i(async()=>{const e=Array.from(r.values()).map(s=>s.close());c&&e.push(new Promise(s=>c.close(()=>s()))),await Promise.allSettled(e),console.log("\u{1F44B} Server shut down gracefully"),process.exit(0)},"cleanup");process.on("SIGTERM",u),process.on("SIGINT",u);export{t as default};
2
+ var h=Object.defineProperty;var i=(e,s)=>h(e,"name",{value:s,configurable:!0});import{StreamableHTTPServerTransport as f}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{isInitializeRequest as g}from"@modelcontextprotocol/sdk/types.js";import I from"cors";import l from"express";import{randomUUID as S}from"node:crypto";import{s as m,p as T,i as w}from"../server-CktjsKoU.js";import{i as y}from"../index-BVmL4O38.js";import"node:fs";import"node:url";import"@modelcontextprotocol/sdk/server/mcp.js";import"@volue/design-colors/generic";import"@volue/design-icons";import"@volue/design-media-queries";import"remark-parse";import"unified";import"zod";import"@volue/design-colors/flat";const t=l(),P=process.env.CORS_ORIGIN?.split(",")??"*";t.use(I({origin:P,exposedHeaders:["Mcp-Session-Id"],allowedHeaders:["Content-Type","mcp-session-id"]})),t.use(l.json());const r=new Map;t.post("/mcp",async(e,s)=>{const n=e.headers["mcp-session-id"];let o;if(n&&r.has(n))o=r.get(n);else if(!n&&g(e.body))o=new f({sessionIdGenerator:i(()=>S(),"sessionIdGenerator"),onsessioninitialized:i(v=>{r.set(v,o)},"onsessioninitialized")}),o.onclose=()=>{o.sessionId&&r.has(o.sessionId)&&r.delete(o.sessionId)},await y(m),await m.connect(o);else return s.status(400).json({error:{message:"Bad Request: No valid session ID provided"}});await o.handleRequest(e,s,e.body)});const d=i(async(e,s)=>{const n=e.headers["mcp-session-id"];if(!n||!r.has(n))return s.status(404).send("Invalid or missing session ID");await r.get(n).handleRequest(e,s)},"handleSessionRequest");t.get("/mcp",d),t.delete("/mcp",d),t.get("/",(e,s)=>{s.json({name:"Wave MCP Server",version:T.version,description:"MCP server for Wave Design System",endpoints:{"/":"Server information (this response)","/mcp":"Streamable HTTP endpoint for MCP connection","/health":"Health check endpoint"}})}),t.get("/health",(e,s)=>{s.json({status:"healthy",timestamp:new Date().toISOString(),uptime:process.uptime()})});const a=process.env.HOST??"localhost",p=process.env.PORT?Number(process.env.PORT):3e3;let c=null;(process.argv.includes("--auto-run")||w(import.meta.url))&&(c=t.listen(p,a,e=>{e&&(console.error("\u274C Failed to start server:",e),process.exit(1)),console.log(`\u{1F680} Wave MCP Server running on http://${a}:${p}`),console.log(`\u{1F517} Connect via http://${a}:${p}/mcp`)}));const u=i(async()=>{const e=Array.from(r.values()).map(s=>s.close());c&&e.push(new Promise(s=>c.close(()=>s()))),await Promise.allSettled(e),console.log("\u{1F44B} Server shut down gracefully"),process.exit(0)},"cleanup");process.on("SIGTERM",u),process.on("SIGINT",u);export{t as default};
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- var s=Object.defineProperty;var t=(o,r)=>s(o,"name",{value:r,configurable:!0});import{StdioServerTransport as e}from"@modelcontextprotocol/sdk/server/stdio.js";import{s as i}from"../server-4exaheDz.js";import{i as p}from"../index-CS97aye0.js";import"node:fs";import"node:url";import"@modelcontextprotocol/sdk/server/mcp.js";import"@volue/design-colors/generic";import"@volue/design-icons";import"@volue/design-media-queries";import"@volue/wave-react/tokens";import"remark-parse";import"unified";import"zod";async function a(){await p(i);const o=new e;await i.connect(o);const r=t(async()=>{await o.close(),process.exit(0)},"cleanup");process.on("SIGTERM",r),process.on("SIGINT",r)}t(a,"main"),a().catch(o=>{console.error("\u274C Failed to start server:",o),process.exit(1)});
2
+ var s=Object.defineProperty;var t=(o,r)=>s(o,"name",{value:r,configurable:!0});import{StdioServerTransport as e}from"@modelcontextprotocol/sdk/server/stdio.js";import{s as i}from"../server-CktjsKoU.js";import{i as p}from"../index-BVmL4O38.js";import"node:fs";import"node:url";import"@modelcontextprotocol/sdk/server/mcp.js";import"@volue/design-colors/generic";import"@volue/design-icons";import"@volue/design-media-queries";import"remark-parse";import"unified";import"zod";import"@volue/design-colors/flat";async function a(){await p(i);const o=new e;await i.connect(o);const r=t(async()=>{await o.close(),process.exit(0)},"cleanup");process.on("SIGTERM",r),process.on("SIGINT",r)}t(a,"main"),a().catch(o=>{console.error("\u274C Failed to start server:",o),process.exit(1)});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@volue/wave-mcp",
3
- "version": "0.1.3-next.1",
3
+ "version": "0.1.3-next.3",
4
4
  "description": "An MCP server that connects AI tools to the Wave Design System",
5
5
  "license": "UNLICENSED",
6
6
  "repository": {
@@ -51,14 +51,14 @@
51
51
  "inspect:http": "yarn dlx -q @modelcontextprotocol/inspector --transport http --server-url http://localhost:3000/mcp"
52
52
  },
53
53
  "dependencies": {
54
- "@modelcontextprotocol/sdk": "1.20.2",
54
+ "@modelcontextprotocol/sdk": "1.21.0",
55
55
  "@types/cors": "2.8.19",
56
56
  "@types/express": "5.0.5",
57
57
  "@types/express-serve-static-core": "5.1.0",
58
- "@volue/design-colors": "^3.0.11-next.0",
59
- "@volue/design-icons": "^1.9.5-next.0",
60
- "@volue/design-media-queries": "^1.3.14-next.0",
61
- "@volue/wave-react": "^1.3.2-next.0",
58
+ "@types/mdast": "3.0.15",
59
+ "@volue/design-colors": "^3.0.11-next.1",
60
+ "@volue/design-icons": "^1.9.5-next.1",
61
+ "@volue/design-media-queries": "^1.3.14-next.1",
62
62
  "cors": "2.8.5",
63
63
  "express": "5.1.0",
64
64
  "remark-parse": "8.0.3",
@@ -67,9 +67,9 @@
67
67
  "zod": "3.25.76"
68
68
  },
69
69
  "devDependencies": {
70
- "@types/mdast": "3.0.15",
71
- "@types/node": "22.18.13",
72
- "@volue/eslint-config": "1.3.11",
70
+ "@types/node": "22.19.0",
71
+ "@volue/eslint-config": "1.3.12",
72
+ "@volue/wave-react": "1.3.2-next.2",
73
73
  "eslint": "9.39.0",
74
74
  "npm-run-all2": "8.0.4",
75
75
  "pkgroll": "2.20.1",
@@ -1,292 +0,0 @@
1
- var _=Object.defineProperty;var s=(e,t)=>_(e,"name",{value:t,configurable:!0});import{a as p,f as m,u as g,g as d}from"./server-4exaheDz.js";import U from"@volue/design-colors/generic";import*as A from"@volue/design-icons";import*as P from"@volue/design-media-queries";import k from"@volue/wave-react/tokens";import z from"remark-parse";import D from"unified";import{z as f}from"zod";const M=D().use(z),w={Components:"component","UX patterns":"pattern"};function N(e,t){const o=M.parse(e);let n=null;return o.children.reduce((r,i)=>{if(p(i,"heading")&&i.depth===2)return n=j(i),r;if(!n||!p(i,"list"))return r;const a=n,c=i.children.map(l=>F(l,a,t)).filter(l=>l!==null);return r.concat(c)},[])}s(N,"parseLlmsIndex");function j(e){const[t]=e.children;if(!t||!p(t,"text"))return null;const o=t.value.trim();if(!(o in w))return null;const n=w[o];return{title:o,type:n}}s(j,"extractSectionContext");function F(e,t,o){const[n]=e.children;if(!n||!p(n,"paragraph")||n.children.length!==2)return null;const[r,i]=n.children;if(!p(r,"link")||!p(i,"text")||r.children.length!==1)return null;const a=r.children[0];if(!p(a,"text"))return null;const c=a.value.trim(),l=r.url.replace(/^\//,""),R=new URL(l,`${o}/`).toString(),I=O(l),L=V(t.title,l,t.type),W=H(i.value);return{name:c,slug:I,category:L,section:t.title,type:t.type,url:R,description:W??void 0}}s(F,"listItemToResource");function O(e){return e.replace(/\.md$/,"").split("/").pop()??""}s(O,"deriveSlug");function V(e,t,o){const n=t.replace(/\.md$/,"").split("/");if(o==="component"||o==="pattern"){const r=n.length>=3?n[n.length-2]:null;return r?`${e} / ${G(r)}`:e}return e}s(V,"deriveCategory");function G(e){return e.split("-").filter(Boolean).map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join(" ")}s(G,"formatSegment");function H(e){if(!e)return null;const t=e.replace(/^\s*:\s*/,"").trim();return t.toLowerCase()==="no description available"?null:t}s(H,"normalizeDescription");const h=process.env.USE_STABLE_DOCS==="true"||process.env.USE_STABLE_DOCS==="1"?"https://wave.volue.com":"https://wave-design-system.vercel.app",q=`${h}/llms.txt`,X=1e3*60*15,J=process.env.WAVE_RESOURCES_CACHE_TIME?Number.parseInt(process.env.WAVE_RESOURCES_CACHE_TIME,10):X;function y(e){const t=new URL(e,h);return t.pathname.endsWith(".md")||(t.pathname+=".md"),t.toString()}s(y,"createUrl");let v=null,$=0;async function Q(){if(v!==null&&Date.now()<$)return v;const e=await Y();return v=e,$=Date.now()+J,e}s(Q,"listCachedResources");let u=null;async function Y(){return u||(u=K().finally(()=>{u=null})),u}s(Y,"idempotentLoadResourcesFromLlms");async function K(){const e=await m(q,void 0,"fetch llms.txt");return N(e,h)}s(K,"loadResourcesFromLlms");async function Z(e){return m(e.url,void 0,`fetch ${e.name} documentation`)}s(Z,"fetchComponent");function ee(e){return m(e.url,void 0,`fetch ${e.name} pattern`)}s(ee,"fetchPattern");async function te(){return m(y("get-started/developing"),void 0,"fetch developing guide")}s(te,"fetchDevelopingGuide");async function ne(){return m(y("tokens/colors"),void 0,"fetch color usage guidelines")}s(ne,"fetchColorUsageGuidelines");function b(){return Object.entries(A).map(([e,t])=>({name:e,svg:t}))}s(b,"listIcons");function oe(){const e=b();return g(e.map(t=>t.name))}s(oe,"getIconNames");function re(e,t){const o=t.trim().toLowerCase();return e.find(n=>n.name.toLowerCase()===o)}s(re,"findIconByName");async function T(e){return(await Q()).filter(o=>o.type===e)}s(T,"listResourcesByType");function C(e,t){const o=t.trim().toLowerCase();return e.find(n=>n.name.toLowerCase()===o)}s(C,"findResourceByName");function S(){return T("component")}s(S,"listComponents");async function ie(){const e=await S();return g(e.map(t=>t.name))}s(ie,"getComponentNames");function x(){return T("pattern")}s(x,"listPatterns");async function se(){const e=await x();return g(e.map(t=>t.name))}s(se,"getPatternNames");function B(e){return e.reduce((t,o)=>(t[o.category]||(t[o.category]=[]),t[o.category].push(o),t),{})}s(B,"groupResourcesByCategory");const ae={name:"get_color_usage",description:"Retrieve the Wave Design System color tokens and guidelines for applying color in user interfaces.",exec(e,{name:t,description:o}){e.tool(t,o,async()=>{try{const n=await ne();return{content:[{type:"text",text:JSON.stringify(U)},{type:"text",text:`Here are the Wave Design System color usage guidelines:
2
-
3
- ${n}
4
-
5
- ---
6
- Source: ${y("tokens/colors")}`}]}}catch(n){return{isError:!0,content:[{type:"text",text:`Failed to retrieve color usage guidelines: ${d(n)}`}]}}})}},ce={name:"get_component",description:"Retrieve comprehensive documentation for a specific Wave Design System component by name. This tool retrieves the import instructions, basic usage and advanced configuration examples, code snippets for common scenarios, available props/properties table and some general guidelines for a given Wave Design System component.",async ctx(){try{return{componentNames:await ie()}}catch(e){throw new Error(`Failed to initialize component tool: ${d(e)}`)}},exec(e,{ctx:t,name:o,description:n}){e.tool(o,n,{name:f.enum(t.componentNames).describe("The name of the component to retrieve documentation for. This can be derived from calling the `get_components` tool.")},async({name:r})=>{try{const i=await S(),a=C(i,r);if(!a)throw new Error("Component not found");const c=await Z(a);return c?{content:[{type:"text",text:`Here is the documentation for the \`${a.name}\` component from the Wave Design System:
7
-
8
- ${c}
9
-
10
- ---
11
- Source: ${a.url}`}]}:{content:[{type:"text",text:`No documentation content found for the \`${a.name}\` component.`}]}}catch(i){return{isError:!0,content:[{type:"text",text:`Failed to retrieve documentation for \`${r}\`: ${d(i)}`}]}}})}},le={name:"get_icon",description:"Retrieve a specific icon information by name from Wave Design System.",exec(e,{name:t,description:o}){e.tool(t,o,{name:f.enum(oe()).describe("The icon name to retrieve. This can be derived from calling the `list_icon` tool.")},async({name:n})=>{try{const r=b(),i=re(r,n);if(!i)throw new Error("Icon not found.");const a=`<SvgIcon iconName="${i.name}" />`,c=`<div class="svgIcon svgIcon--stroked">
12
- <svg focusable="false" aria-hidden="true">
13
- <use xlink:href="#svg--${i.name}"></use>
14
- </svg>
15
- </div>`;return{content:[{type:"text",text:`# ${i.name} icon
16
-
17
- ## React component:
18
-
19
- \`\`\`tsx
20
- ${a}
21
- \`\`\`
22
-
23
- ## HTML markup:
24
-
25
- \`\`\`html
26
- ${c}
27
- \`\`\`
28
-
29
- ## Raw SVG code:
30
-
31
- \`\`\`svg
32
- ${i.svg}
33
- \`\`\``}]}}catch(r){return{isError:!0,content:[{type:"text",text:`Failed to retrieve icon \`${n}\`: ${d(r)}`}]}}})}},de={name:"get_pattern",description:"Retrieve documentation for a specific Wave Design System UX pattern by name. This tool provides guidance, examples and components that implement the selected pattern.",async ctx(){try{return{patternNames:await se()}}catch(e){throw new Error(`Failed to initialize pattern tool: ${d(e)}`)}},exec(e,{ctx:t,name:o,description:n}){e.tool(o,n,{name:f.enum(t.patternNames).describe("The name of the UX pattern to retrieve documentation for. This can be derived from calling the `list_patterns` tool.")},async({name:r})=>{try{const i=await x(),a=C(i,r);if(!a)throw new Error("Pattern not found");const c=await ee(a);return{content:[{type:"text",text:`Here are the guidelines for the \`${a.name}\` UX pattern from the Wave Design System:
34
-
35
- ${c}
36
-
37
- ---
38
- Source: ${a.url}`}]}}catch(i){return{isError:!0,content:[{type:"text",text:`Failed to retrieve documentation for \`${r}\`: ${d(i)}`}]}}})}},pe={name:"get_styling_guidelines",description:"Retrieve guidelines for styling Wave Design System components and creating custom styled components.",exec(e,{name:t,description:o}){e.tool(t,o,async()=>({content:[{type:"text",text:`Wave Design System components can be styled using standard React approaches (className, style prop), but Wave provides specialized styling APIs for customizing component styles and creating custom styled components. These APIs are powered by Stitches.js, a CSS-in-JS library with near-zero runtime. They are the recommended approach because they integrate seamlessly with Wave's design tokens and provide type-safe styles.
39
-
40
- ## Styling APIs
41
-
42
- ### CSS Prop
43
-
44
- The \`css\` property is available on all Wave components for styling. It generates CSS class names from the style object, supporting all standard CSS properties and selectors, plus design tokens and responsive breakpoints.
45
-
46
- Example:
47
-
48
- \`\`\`tsx
49
- import { Box } from '@volue/wave-react';
50
-
51
- <Box
52
- css={{
53
- display: 'flex',
54
- color: '$foregroundInverse',
55
- backgroundColor: '$backgroundAccentStrong',
56
- padding: '$spacingM'
57
- }}
58
- />
59
- \`\`\`
60
-
61
- The \`css\` prop works best for one-off style customizations of specific component instances.
62
-
63
- ### Styled Function
64
-
65
- Use \`styled()\` to create reusable styled components with semantic names. It supports all \`css\` prop features, variants for conditional styling, and provides better performance than the \`css\` prop.
66
-
67
- \`\`\`tsx
68
- import { styled } from '@volue/wave-react';
69
-
70
- // Create a simple styled component
71
- const Container = styled('div', {
72
- padding: '$spacingM',
73
- backgroundColor: '$backgroundNeutralSubtle',
74
- borderRadius: '$borderRadiusM'
75
- });
76
-
77
- // Create a styled component with variants
78
- const SectionTitle = styled('h2', {
79
- fontWeight: '$semibold',
80
- color: '$foregroundAccent',
81
-
82
- variants: {
83
- size: {
84
- medium: {
85
- fontSize: '$gamma',
86
- },
87
- large: {
88
- fontSize: '$beta',
89
- }
90
- }
91
- },
92
-
93
- // optional defaultVariants
94
- defaultVariants: {
95
- size: 'medium'
96
- }
97
- });
98
-
99
- // Use with a specific variant
100
- <SectionTitle size="large">Analytics Overview</SectionTitle>
101
-
102
- // Extend an existing Wave component
103
- import { AppFrame } from '@volue/wave-react';
104
-
105
- const StyledAppFrame = styled(AppFrame.Root, {
106
- backgroundColor: '$backgroundNeutralMinimal'
107
- });
108
- \`\`\`
109
-
110
- ## Design Tokens
111
-
112
- Wave provides a comprehensive set of design tokens for colors, spacing, typography, border radii, shadows, and more. All tokens are available in both \`css\` prop and \`styled()\` function using the \`$tokenName\` syntax (as shown in the examples above).
113
-
114
- **Use the \`get_tokens\` tool to discover all available design tokens** including their values and usage examples.
115
-
116
- ## Media Query Tokens
117
-
118
- Wave provides media query tokens for responsive design. Use these tokens to create breakpoint-based styles:
119
-
120
- ${Object.entries(P).map(([r,i])=>`- \`@${r}\`: ${i}`).join(`
121
- `)}
122
-
123
- ### Responsive Styling Examples
124
-
125
- **Using media queries with the css prop:**
126
-
127
- \`\`\`tsx
128
- import { Box } from '@volue/wave-react';
129
-
130
- <Box
131
- css={{
132
- padding: '$spacingS',
133
-
134
- '@mqMediumAndUp': {
135
- padding: '$spacingM'
136
- },
137
- '@mqLargeAndUp': {
138
- padding: '$spacingL'
139
- }
140
- }}
141
- >
142
- Responsive padding
143
- </Box>
144
- \`\`\`
145
-
146
- **Using media queries with styled function:**
147
-
148
- \`\`\`tsx
149
- import { styled } from '@volue/wave-react';
150
-
151
- const ResponsiveContainer = styled('div', {
152
- display: 'flex',
153
- flexDirection: 'column',
154
- gap: '$spacingS',
155
-
156
- '@mqMediumAndUp': {
157
- flexDirection: 'row',
158
- gap: '$spacingM'
159
- }
160
- });
161
- \`\`\`
162
-
163
- **Responsive variants:**
164
-
165
- \`\`\`tsx
166
- import { styled } from '@volue/wave-react';
167
-
168
- const Button = styled('button', {
169
- variants: {
170
- size: {
171
- small: { padding: '$spacingS' },
172
- large: { padding: '$spacingL' }
173
- }
174
- }
175
- });
176
-
177
- // Apply different variants at different breakpoints
178
- <Button
179
- size={{
180
- '@initial': 'small',
181
- '@mqLargeAndUp': 'large'
182
- }}
183
- >
184
- Responsive Button
185
- </Button>
186
- \`\`\`
187
-
188
- ## Best Practices
189
-
190
- 1. **Use design tokens**: Always prefer design tokens (prefixed with \`$\`) over hardcoded values for consistency. Use the \`get_tokens\` tool to discover available tokens.
191
- 2. **Choose the right API**: Use \`css\` prop for one-off styles, \`styled()\` for reusable components
192
- 3. **Semantic breakpoints**: Use Wave's semantic media query tokens rather than arbitrary pixel values
193
- `}]}))}},me={colors:["background","backgroundColor","backgroundImage","border","borderBlock","borderBlockEnd","borderBlockStart","borderBottom","borderBottomColor","borderColor","borderInline","borderInlineEnd","borderInlineStart","borderLeft","borderLeftColor","borderRight","borderRightColor","borderTop","borderTopColor","caretColor","color","columnRuleColor","fill","outlineColor","stroke","textDecorationColor"],fonts:["fontFamily"],fontSizes:["fontSize"],fontWeights:["fontWeight"],lineHeights:["lineHeight"],letterSpacings:["letterSpacing"],radii:["borderRadius","borderTopLeftRadius","borderTopRightRadius","borderBottomRightRadius","borderBottomLeftRadius"],sizes:["blockSize","minBlockSize","maxBlockSize","inlineSize","minInlineSize","maxInlineSize","width","minWidth","maxWidth","height","minHeight","maxHeight","flexBasis","gridTemplateColumns","gridTemplateRows"],space:["gap","gridGap","columnGap","gridColumnGap","rowGap","gridRowGap","inset","insetBlock","insetBlockEnd","insetBlockStart","insetInline","insetInlineEnd","insetInlineStart","margin","marginTop","marginRight","marginBottom","marginLeft","marginBlock","marginBlockEnd","marginBlockStart","marginInline","marginInlineEnd","marginInlineStart","padding","paddingTop","paddingRight","paddingBottom","paddingLeft","paddingBlock","paddingBlockEnd","paddingBlockStart","paddingInline","paddingInlineEnd","paddingInlineStart","top","right","bottom","left","scrollMargin","scrollMarginTop","scrollMarginRight","scrollMarginBottom","scrollMarginLeft","scrollMarginX","scrollMarginY","scrollMarginBlock","scrollMarginBlockEnd","scrollMarginBlockStart","scrollMarginInline","scrollMarginInlineEnd","scrollMarginInlineStart","scrollPadding","scrollPaddingTop","scrollPaddingRight","scrollPaddingBottom","scrollPaddingLeft","scrollPaddingX","scrollPaddingY","scrollPaddingBlock","scrollPaddingBlockEnd","scrollPaddingBlockStart","scrollPaddingInline","scrollPaddingInlineEnd","scrollPaddingInlineStart"],zIndices:["zIndex"],shadows:["boxShadow","textShadow"],transitions:["transition"],borderWidths:["borderWidth","borderTopWidth","borderRightWidth","borderBottomWidth","borderLeftWidth"],borderStyles:["borderStyle","borderTopStyle","borderRightStyle","borderBottomStyle","borderLeftStyle"]},ue={name:"get_tokens",description:"Retrieve the Wave Design System design tokens (colors, fonts, spacing, font styles, etc.) exposed by the `@volue/wave-react` package. Includes token type mappings to CSS properties and usage examples.",exec(e,{name:t,description:o}){e.tool(t,o,async()=>{const n=Object.entries(me).map(([r,i])=>`| ${r} | ${i.join(", ")} |`).join(`
194
- `);return{content:[{type:"text",text:`Below is a list of design tokens available from Wave Design System.
195
- There are ${Object.keys(k).length} token types available:
196
-
197
- ${JSON.stringify(k)}`},{type:"text",text:`## Token Type to CSS Property Mapping
198
-
199
- Token types are automatically mapped to CSS Properties:
200
-
201
- | Token | Properties |
202
- |-------|------------|
203
- ${n}
204
-
205
- ## Using tokens
206
-
207
- Tokens can be used to style components.
208
-
209
- \`\`\`tsx
210
- import { styled } from '@volue/wave-react';
211
-
212
- const Button = styled('button', {
213
- backgroundColor: '$backgroundAccentStrong'
214
- });
215
-
216
- () => <Button>Button</Button>;
217
- \`\`\`
218
-
219
- Tokens also work inside the \`css\` prop.
220
-
221
- \`\`\`tsx
222
- const Button = styled('button', {});
223
-
224
- () => (
225
- <Button
226
- css={{
227
- backgroundColor: '$backgroundAccentStrong'
228
- }}
229
- >
230
- Button
231
- </Button>
232
- );
233
- \`\`\`
234
-
235
- You can pick a token from any of available token types by prefixing them with the type name, in case they aren't automatically mapped.
236
-
237
- \`\`\`tsx
238
- const Button = styled('button', {
239
- // use a token from the sizes scale
240
- marginTop: '$sizes$6'
241
- });
242
- \`\`\`
243
-
244
- For more comprehensive styling guidelines including responsive design, variants, and best practices, use the \`get_styling_guidelines\` tool.
245
-
246
- ## Programmatic theme access
247
-
248
- \`\`\`tsx
249
- import { theme } from '@volue/wave-react';
250
-
251
- // .value returns raw values ("#0c4957", "0.5rem") for JavaScript operations
252
- const rawColor = theme.colors.foregroundAccent.value;
253
- const rawSpacing = theme.space.spacingS.value;
254
- const rawSize = theme.sizes['20'].value;
255
-
256
- // .computedValue (or default) returns serialized CSS variables ("var(--colors-foregroundAccent)")
257
- const cssVar = theme.colors.foregroundAccent.computedValue;
258
- \`\`\`
259
- `}]}})}},ge={name:"init",description:"Get guide on how to setup or create a project that includes Wave Design System.",exec(e,{name:t,description:o}){e.tool(t,o,async()=>{try{return{content:[{type:"text",text:`The getting started documentation for developing with Wave Design System is included below.
260
-
261
- It's **important** that if the project is using a tool like Vite or Next.js, one of the pre-configured starter templates should be used instead of manual configuration:
262
-
263
- - https://github.com/Volue/wave-vite-example (Vite template)
264
- - https://github.com/Volue/wave-nextjs-app-router-example (Next.js App Router template)
265
-
266
- ---
267
-
268
- ${await te()}
269
- `}]}}catch(n){return{isError:!0,content:[{type:"text",text:`Failed to retrieve getting started documentation: ${d(n)}`}]}}})}},fe={name:"list_components",description:"List all components available from the Wave Design System. This tool retrieves the names of all available Wave Design System components grouped by category.",exec(e,{name:t,description:o}){e.tool(t,o,async()=>{try{const n=await S(),r=B(n);return{content:[{type:"text",text:`The following components are available in the Wave Design System:
270
-
271
- ${Object.entries(r).map(([a,c])=>`## ${a}
272
- ${c.map(l=>`- ${l.name}`).join(`
273
- `)}`).join(`
274
-
275
- `)}
276
-
277
- Use the \`get_component\` tool to get more information about a specific component.
278
-
279
- Use these components from the @volue/wave-react package.`}]}}catch(n){return{isError:!0,content:[{type:"text",text:`Failed to retrieve the component index: ${d(n)}`}]}}})}},he={name:"list_icons",description:"List all icons available from the Wave Design System. Icons are sourced directly from the `@volue/design-icons` package.",exec(e,{name:t,description:o}){e.tool(t,o,async()=>{try{return{content:[{type:"text",text:`The following icons are available in the Wave Design System:
280
-
281
- ${b().map(i=>`- ${i.name}`).join(`
282
- `)}
283
-
284
- Use the \`get_icon\` tool to retrieve the SVG markup and usage guidelines for a specific icon.`}]}}catch(n){return{isError:!0,content:[{type:"text",text:`Failed to retrieve the icon data: ${d(n)}`}]}}})}},ye={name:"list_patterns",description:"List all UX patterns available from the Wave Design System. This tool retrieves the names of all available Wave Design System patterns grouped by category.",exec(e,{name:t,description:o}){e.tool(t,o,async()=>{try{const n=await x(),r=B(n);return{content:[{type:"text",text:`The following UX patterns are available in the Wave Design System:
285
-
286
- ${Object.entries(r).map(([a,c])=>`## ${a}
287
- ${c.map(l=>`- ${l.name}`).join(`
288
- `)}`).join(`
289
-
290
- `)}
291
-
292
- Use the \`get_pattern\` tool to access detailed guidance for a specific pattern.`}]}}catch(n){return{isError:!0,content:[{type:"text",text:`Failed to retrieve the pattern index: ${d(n)}`}]}}})}},ve=[ge,fe,ce,ye,de,ae,he,le,ue,pe],E=new Set;async function be(e){await Promise.all(ve.map(async t=>{if(E.has(t.name))return;const o=await t.ctx?.();E.add(t.name),t.exec(e,{name:t.name,description:t.description,ctx:o})}))}s(be,"initializeTools");export{be as i};