@sit-onyx/modelcontextprotocol 0.1.1-dev-20260630065749 → 0.2.0-dev-20260701075643

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/config.d.ts CHANGED
@@ -5,6 +5,8 @@ export declare const REGISTRY_URL: string;
5
5
  */
6
6
  export declare const SIT_ONYX_MIN_VERSION = "1.12.0";
7
7
  export declare const SIT_ONYX_COMPONENT_META_FILE = "package/dist/component-meta.json";
8
+ export declare const SIT_ONYX_DESIGN_TOKENS_FILE = "package/src/styles/variables/themes/onyx.css";
9
+ export declare const SIT_ONYX_DESIGN_TOKENS_SPACINGS_FILE = "package/src/styles/variables/spacing.css";
8
10
  /**
9
11
  * Minimum `@sit-onyx/icons` version that provides the `metadata.json` file
10
12
  */
package/dist/index.js CHANGED
@@ -1,7 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from "node:module";
3
3
  import { error, log } from "node:console";
4
+ import { mkdir, stat, writeFile } from "node:fs/promises";
4
5
  import { parseArgs } from "node:util";
6
+ import { resolve } from "node:path";
5
7
  import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
6
8
  import { createServer as createServer$1 } from "node:http";
7
9
  import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
@@ -77,20 +79,101 @@ var package_default = {
77
79
  },
78
80
  dependencies: { "@modelcontextprotocol/sdk": "^1.29.0" },
79
81
  devDependencies: {
82
+ "@adobe/css-tools": "^4.5.0",
80
83
  "@sit-onyx/shared": "workspace:^",
84
+ "@types/mdast": "^4.0.4",
81
85
  "@types/node": "catalog:",
82
86
  "@types/tar-stream": "^3.1.4",
87
+ "@types/unist": "^3.0.3",
83
88
  "query-registry": "^4.3.0",
89
+ "remark": "^15.0.1",
90
+ "remark-frontmatter": "^5.0.0",
91
+ "remark-parse": "^11.0.0",
92
+ "remark-stringify": "^11.0.0",
84
93
  "tar-stream": "^3.2.0",
85
94
  "typescript": "catalog:",
95
+ "unified": "^11.0.5",
86
96
  "unplugin-dts": "catalog:",
87
97
  "vite": "catalog:",
88
98
  "vue-component-meta": "catalog:",
99
+ "yaml": "^2.9.0",
89
100
  "zod": "^4.4.3"
90
101
  },
91
102
  engines: { "node": ">=20" }
92
103
  };
93
104
  //#endregion
105
+ //#region src/resources/skills/onyx-components/SKILL.md
106
+ var SKILL_exports$2 = /* @__PURE__ */ __exportAll({
107
+ default: () => SKILL_default$2,
108
+ frontmatter: () => frontmatter$2,
109
+ raw: () => raw$2
110
+ });
111
+ var SKILL_default$2 = "# Onyx Components\n\nImplement and configure Onyx Vue 3 UI components using authoritative API definitions.\n\n## Rule: Mandatory Dynamic API Lookups (MCP)\n\nOnyx component APIs are dynamic and change across versions. **NEVER guess or assume props, events, or slots.**\n\n## Onyx MCP Server Installation & Setup\n\nTo allow coding-agents to dynamically query component API specifications and icons, install and configure the official Onyx Model Context Protocol (MCP) server.\n\n### 1. Global Installation\n\nInstall the package globally using your package manager:\n\n```bash\n# Using npm\nnpm install -g @sit-onyx/modelcontextprotocol\n\n# Using pnpm\npnpm install -g @sit-onyx/modelcontextprotocol\n```\n\nVerify the installation is successful:\n\n```bash\nonyx-mcp -h\n```\n\n### 2. General MCP Client Configuration\n\nConfigure the server in your preferred MCP-compliant client (such as Cursor, Claude Desktop, VS Code plugins, or general command-line utilities) using these standard parameters:\n\n* **Command:** `onyx-mcp`\n* **Arguments:** `[\"-r\"]` (Optional: Use the recursive flag depending on environment)\n* **Description:** `\"Information about components of the onyx UI component library\"`\n\n### Step 1: Version Autodiscovery\n\nBefore querying the MCP server, you **MUST** discover the exact Onyx version used in the project:\n\n1. Open and parse the root `package.json`.\n2. Find the version defined under `dependencies` or `devDependencies` for `sit-onyx`.\n3. Use this parsed version number (e.g. `\"1.2.3\"`) as the required `version` parameter for all subsequent MCP tool calls.\n\n### Step 2: Query the MCP Server\n\nUse the connected `onyx-mcp` tools using your discovered version:\n\n* `mcp_onyx-mcp_list-components`: Discover the exact names of available components in this version.\n* `mcp_onyx-mcp_get-component-api`: Retrieve authoritative props, events, and slots for a specific component before writing code.\n* `mcp_onyx-mcp_list-icons`: Retrieve available icon names when implementing components with icon properties.\n\n***\n\n## Component Implementation Rules\n\n### Action Components (Buttons & Links)\n\n* **Props-based Links:** Components like `OnyxButton`, `OnyxIconButton`, `OnyxSystemButton`, `OnyxMenuItem`, and `OnyxNavItem` support a `link` prop. Do not wrap these components in raw `<a>` tags; pass the URL to the `link` prop.\n* **Headless Links:** Use the `useLink` composable (`const { navigate, isActive } = useLink()`) or `OnyxRouterLink` for custom unstyled navigation components.\n\n### Form Elements\n\n* **Labels & Messages:** Always configure standard `Message` and `LabelPositions` properties consistently.\n* **Loading State:** Implement built-in `Skeleton` loading states when loading form data.\n* **Accessibility:** Use proper labels and fieldsets for complex multi-input forms (`date-picker`, `radio-group`, `checkbox-group`).\n\n### Cards & Layout Structure\n\n* Nest and structure basic components (`Accordion`, `Cards`, `Badge`, `Tag`) inside the Onyx grid layout (see `onyx-foundation`) to prevent layout breaking.\n\n***\n\n## Validation & Quality Check\n\nAfter writing or updating components, you **MUST** run the following verification steps:\n\n1. **Type Check:** Run TypeScript verification (e.g., `npx vue-tsc --noEmit` or `npm run type-check`) to confirm no invalid props or event bindings exist.\n2. **Linter Check:** Run standard project linters (e.g., `npm run lint` or `eslint .`) to confirm code style and rules are respected.\n3. **Manual Verification:** Confirm all slots and custom events mapped conform to the authoritative API fetched from the MCP.\n";
112
+ var raw$2 = "---\nname: onyx-components\ndescription: Best practices and dynamic API lookup instructions for Onyx UI components. Use when implementing UI features, forms, or building Vue templates.\nlicense: Apache-2.0\n---\n\n# Onyx Components\n\nImplement and configure Onyx Vue 3 UI components using authoritative API definitions.\n\n## Rule: Mandatory Dynamic API Lookups (MCP)\n\nOnyx component APIs are dynamic and change across versions. **NEVER guess or assume props, events, or slots.**\n\n## Onyx MCP Server Installation & Setup\n\nTo allow coding-agents to dynamically query component API specifications and icons, install and configure the official Onyx Model Context Protocol (MCP) server.\n\n### 1. Global Installation\n\nInstall the package globally using your package manager:\n\n```bash\n# Using npm\nnpm install -g @sit-onyx/modelcontextprotocol\n\n# Using pnpm\npnpm install -g @sit-onyx/modelcontextprotocol\n```\n\nVerify the installation is successful:\n\n```bash\nonyx-mcp -h\n```\n\n### 2. General MCP Client Configuration\n\nConfigure the server in your preferred MCP-compliant client (such as Cursor, Claude Desktop, VS Code plugins, or general command-line utilities) using these standard parameters:\n\n- **Command:** `onyx-mcp`\n- **Arguments:** `[\"-r\"]` (Optional: Use the recursive flag depending on environment)\n- **Description:** `\"Information about components of the onyx UI component library\"`\n\n### Step 1: Version Autodiscovery\n\nBefore querying the MCP server, you **MUST** discover the exact Onyx version used in the project:\n\n1. Open and parse the root `package.json`.\n2. Find the version defined under `dependencies` or `devDependencies` for `sit-onyx`.\n3. Use this parsed version number (e.g. `\"1.2.3\"`) as the required `version` parameter for all subsequent MCP tool calls.\n\n### Step 2: Query the MCP Server\n\nUse the connected `onyx-mcp` tools using your discovered version:\n\n- `mcp_onyx-mcp_list-components`: Discover the exact names of available components in this version.\n- `mcp_onyx-mcp_get-component-api`: Retrieve authoritative props, events, and slots for a specific component before writing code.\n- `mcp_onyx-mcp_list-icons`: Retrieve available icon names when implementing components with icon properties.\n\n---\n\n## Component Implementation Rules\n\n### Action Components (Buttons & Links)\n\n- **Props-based Links:** Components like `OnyxButton`, `OnyxIconButton`, `OnyxSystemButton`, `OnyxMenuItem`, and `OnyxNavItem` support a `link` prop. Do not wrap these components in raw `<a>` tags; pass the URL to the `link` prop.\n- **Headless Links:** Use the `useLink` composable (`const { navigate, isActive } = useLink()`) or `OnyxRouterLink` for custom unstyled navigation components.\n\n### Form Elements\n\n- **Labels & Messages:** Always configure standard `Message` and `LabelPositions` properties consistently.\n- **Loading State:** Implement built-in `Skeleton` loading states when loading form data.\n- **Accessibility:** Use proper labels and fieldsets for complex multi-input forms (`date-picker`, `radio-group`, `checkbox-group`).\n\n### Cards & Layout Structure\n\n- Nest and structure basic components (`Accordion`, `Cards`, `Badge`, `Tag`) inside the Onyx grid layout (see `onyx-foundation`) to prevent layout breaking.\n\n---\n\n## Validation & Quality Check\n\nAfter writing or updating components, you **MUST** run the following verification steps:\n\n1. **Type Check:** Run TypeScript verification (e.g., `npx vue-tsc --noEmit` or `npm run type-check`) to confirm no invalid props or event bindings exist.\n2. **Linter Check:** Run standard project linters (e.g., `npm run lint` or `eslint .`) to confirm code style and rules are respected.\n3. **Manual Verification:** Confirm all slots and custom events mapped conform to the authoritative API fetched from the MCP.\n";
113
+ var frontmatter$2 = {
114
+ "name": "onyx-components",
115
+ "description": "Best practices and dynamic API lookup instructions for Onyx UI components. Use when implementing UI features, forms, or building Vue templates.",
116
+ "license": "Apache-2.0"
117
+ };
118
+ //#endregion
119
+ //#region src/resources/skills/onyx-foundation/SKILL.md
120
+ var SKILL_exports$1 = /* @__PURE__ */ __exportAll({
121
+ default: () => SKILL_default$1,
122
+ frontmatter: () => frontmatter$1,
123
+ raw: () => raw$1
124
+ });
125
+ var SKILL_default$1 = "# Onyx Foundation & Theming\n\nApply Onyx styling foundations, CSS variables, responsive grid, and layout rules.\n\n## Theming & Colors\n\nOnyx supports light and dark themes out-of-the-box. Theme switching is handled automatically.\n\n### Rule: CSS Variables Only\n\n**NEVER hardcode hex, rgb, or hsl color values.** Always use semantic Onyx CSS variables (prefixed with `--onyx-`).\n\n* **Base backgrounds:** `var(--onyx-color-base-background-tinted)`, `var(--onyx-color-base-background-blank)`\n* **Primary brand:** `var(--onyx-color-base-primary-500)`, `var(--onyx-color-base-primary-100)`\n* **Text & icons:** `var(--onyx-color-text-icons-primary-soft)`, `var(--onyx-color-text-icons-primary-medium)`, `var(--onyx-color-text-icons-primary-intense)`\n* **Component states:** `var(--onyx-color-component-cta-default)`, `var(--onyx-color-component-border-primary)`, `var(--onyx-color-component-focus-primary)`\n\n*Note: Access ONLY Semantic variables. Do NOT use global or component variables directly in applications.*\n\n## Density\n\nDensity levels control the vertical white space and heights (base heights: Compact = 32px, Default = 40px, Cozy = 48px).\nApply density via properties on supported components or by adding these CSS classes to any element:\n\n* `.onyx-density-compact`\n* `.onyx-density-default`\n* `.onyx-density-cozy`\n\n## Breakpoints\n\nThe design system defines six standard breakpoints:\n\n* `2xs`: `320px` to `576px` (Max 4 columns)\n* `xs`: `577px` to `768px` (Max 8 columns)\n* `sm`: `769px` to `992px` (Max 8 columns)\n* `md`: `993px` to `1440px` (Max 12 columns)\n* `lg`: `1441px` to `1920px` (Max 12 or 16 columns)\n* `xl`: `1921px` and beyond (Max 12, 16, or 20 columns)\n\n### Responsive SCSS Mixins\n\nImport `\"sit-onyx/breakpoints.scss\"` to apply media or container queries:\n\n```scss\n@use \"sit-onyx/breakpoints.scss\";\n\n// Media queries (compares against whole screen width)\n.my-screen-class {\n @include breakpoints.screen(max, sm) {\n /* styles for sm and smaller */\n }\n @include breakpoints.screen(min, md) {\n /* styles for md and larger */\n }\n}\n\n// Container queries (compares against nearest container width)\n// MUST set container-type on the parent element\n.my-container-class {\n container-type: inline-size;\n\n @include breakpoints.container(max, md) {\n /* styles for md container and smaller */\n }\n @include breakpoints.container(min, lg) {\n /* styles for lg container and larger */\n }\n}\n```\n\n## Grid System\n\nOnyx uses container-query-based grids. The nearest parent component with `container-type: inline-size;` (automatically set by `OnyxPageLayout`, `OnyxAppLayout`, `OnyxSidebar`) determines the active grid width.\n\n### Grid Classes\n\n* **Container:** `.onyx-grid` (Defines a grid container)\n* **Spanning Columns:** `.onyx-grid-span-<number>` (Define exact span from 1 to 12)\n* **Full Width:** `.onyx-grid-span-full` (Span all available columns)\n* **Breakpoint-Specific Span:** `.onyx-grid-<breakpoint>-span-<number>` (Define column span for a specific breakpoint **and larger**)\n\n### Grid Margin\n\nApply `.onyx-grid-layout` manually to wrap page contents and add outer page margins if not using `OnyxPageLayout`.\n\n```vue\n<template>\n <div class=\"onyx-grid\">\n <!-- Spans 4 cols on smaller screens, 6 on md and larger -->\n <OnyxCard class=\"onyx-grid-span-4 onyx-grid-md-span-6\">Content</OnyxCard>\n\n <!-- Spans full width always -->\n <OnyxCard class=\"onyx-grid-span-full\">Footer / Hero</OnyxCard>\n </div>\n</template>\n```\n\n### Grid Customization\n\nSet these CSS classes on the root element of your application (e.g. `OnyxAppLayout`):\n\n* **Limit Max Width:** `onyx-grid-max-md` (max 1440px) or `onyx-grid-max-lg` (max 1920px)\n* **Alignment:** `onyx-grid-center` (Centers the layout when screen size exceeds max width)\n* **Max Columns (lg and beyond):** `onyx-grid-lg-16` (16 columns) or `onyx-grid-xl-20` (20 columns)\n\n## Page Layout (`OnyxPageLayout`)\n\nImplement the `OnyxPageLayout` component as the root element on every individual page/view to ensure standardized paddings, page-level scroll behavior, and unified outer page margins.\n\n```vue\n<template>\n <OnyxPageLayout>\n <OnyxHeadline is=\"h1\">Page Title</OnyxHeadline>\n </OnyxPageLayout>\n</template>\n```\n\nFor recurring page elements (like sidebars, footers, or sub-navigation), wrap the `OnyxPageLayout` in a reusable component or a Nuxt layout.\n\n## Layout Principles & Page Anatomy\n\nAll custom layout constructions must align with the core Onyx layout guidelines:\n\n### Core Principles\n\n* **Responsive:** Layouts must fluidly adapt to maintain usability and visual hierarchy across all device sizes.\n* **Content-Driven:** Prioritize structural layout decisions based on the content's hierarchy and user needs, not vice versa.\n\n### The Four Page Anatomy Regions\n\n1. **Main Navigation (`OnyxNavBar`):** Persistent top/left area independent of scroll containers, providing access to top-level views.\n2. **Sidebar (`OnyxSidebar`):** Persistent left/right sidebar used for secondary navigation or master-detail detail panels.\n3. **Page Content (`OnyxPageLayout`):** The flexible central area governed by the grid system and acting as the primary scroll container.\n4. **Bottom Bar (`OnyxBottomBar`):** Scroll-independent sticky bar at the bottom for status confirmations or primary page-level triggers.\n\n### Component Alignment Rule\n\n* **STRICT Left-Alignment:** All internal component layout structures must be left-aligned to preserve scannability.\n* **Exception:** Tables and data grids may utilize center/right alignment within specific columns depending on data type formats (e.g. numeric currencies).\n\n### Visual Rhythm & Grouping\n\n* **Spatial Grouping:** Group functionally related components together using generous empty space (white space), typography, or dividers to minimize cognitive load. Ensure balanced proportions across all section distributions.\n\n***\n\n## Validation & Quality Check\n\nAfter writing custom layouts or styling overrides, you **MUST** run the following verification steps:\n\n1. **CSS Variables Audit:** Scan your stylesheets for any hardcoded hex, rgb, or hsl values, or direct global/component variable usages. Replace them with proper `--onyx-` semantic variables.\n2. **Layout Alignment Check:** Verify all custom component interiors are left-aligned (with the exception of specific table/data grid columns).\n3. **Responsive Verification:** Verify your CSS container-query selectors are properly paired with a parent `container-type: inline-size;`. Ensure no breakpoint styles break responsive fluidity.\n";
126
+ var raw$1 = "---\nname: onyx-foundation\ndescription: Styling foundations, CSS variables, layout grid, breakpoints, and responsive mixins for Onyx. Use when writing custom CSS, designing layouts, or ensuring theme compliance.\nlicense: Apache-2.0\n---\n\n# Onyx Foundation & Theming\n\nApply Onyx styling foundations, CSS variables, responsive grid, and layout rules.\n\n## Theming & Colors\n\nOnyx supports light and dark themes out-of-the-box. Theme switching is handled automatically.\n\n### Rule: CSS Variables Only\n\n**NEVER hardcode hex, rgb, or hsl color values.** Always use semantic Onyx CSS variables (prefixed with `--onyx-`).\n\n- **Base backgrounds:** `var(--onyx-color-base-background-tinted)`, `var(--onyx-color-base-background-blank)`\n- **Primary brand:** `var(--onyx-color-base-primary-500)`, `var(--onyx-color-base-primary-100)`\n- **Text & icons:** `var(--onyx-color-text-icons-primary-soft)`, `var(--onyx-color-text-icons-primary-medium)`, `var(--onyx-color-text-icons-primary-intense)`\n- **Component states:** `var(--onyx-color-component-cta-default)`, `var(--onyx-color-component-border-primary)`, `var(--onyx-color-component-focus-primary)`\n\n_Note: Access ONLY Semantic variables. Do NOT use global or component variables directly in applications._\n\n## Density\n\nDensity levels control the vertical white space and heights (base heights: Compact = 32px, Default = 40px, Cozy = 48px).\nApply density via properties on supported components or by adding these CSS classes to any element:\n\n- `.onyx-density-compact`\n- `.onyx-density-default`\n- `.onyx-density-cozy`\n\n## Breakpoints\n\nThe design system defines six standard breakpoints:\n\n- `2xs`: `320px` to `576px` (Max 4 columns)\n- `xs`: `577px` to `768px` (Max 8 columns)\n- `sm`: `769px` to `992px` (Max 8 columns)\n- `md`: `993px` to `1440px` (Max 12 columns)\n- `lg`: `1441px` to `1920px` (Max 12 or 16 columns)\n- `xl`: `1921px` and beyond (Max 12, 16, or 20 columns)\n\n### Responsive SCSS Mixins\n\nImport `\"sit-onyx/breakpoints.scss\"` to apply media or container queries:\n\n```scss\n@use \"sit-onyx/breakpoints.scss\";\n\n// Media queries (compares against whole screen width)\n.my-screen-class {\n @include breakpoints.screen(max, sm) {\n /* styles for sm and smaller */\n }\n @include breakpoints.screen(min, md) {\n /* styles for md and larger */\n }\n}\n\n// Container queries (compares against nearest container width)\n// MUST set container-type on the parent element\n.my-container-class {\n container-type: inline-size;\n\n @include breakpoints.container(max, md) {\n /* styles for md container and smaller */\n }\n @include breakpoints.container(min, lg) {\n /* styles for lg container and larger */\n }\n}\n```\n\n## Grid System\n\nOnyx uses container-query-based grids. The nearest parent component with `container-type: inline-size;` (automatically set by `OnyxPageLayout`, `OnyxAppLayout`, `OnyxSidebar`) determines the active grid width.\n\n### Grid Classes\n\n- **Container:** `.onyx-grid` (Defines a grid container)\n- **Spanning Columns:** `.onyx-grid-span-<number>` (Define exact span from 1 to 12)\n- **Full Width:** `.onyx-grid-span-full` (Span all available columns)\n- **Breakpoint-Specific Span:** `.onyx-grid-<breakpoint>-span-<number>` (Define column span for a specific breakpoint **and larger**)\n\n### Grid Margin\n\nApply `.onyx-grid-layout` manually to wrap page contents and add outer page margins if not using `OnyxPageLayout`.\n\n```vue\n<template>\n <div class=\"onyx-grid\">\n <!-- Spans 4 cols on smaller screens, 6 on md and larger -->\n <OnyxCard class=\"onyx-grid-span-4 onyx-grid-md-span-6\">Content</OnyxCard>\n\n <!-- Spans full width always -->\n <OnyxCard class=\"onyx-grid-span-full\">Footer / Hero</OnyxCard>\n </div>\n</template>\n```\n\n### Grid Customization\n\nSet these CSS classes on the root element of your application (e.g. `OnyxAppLayout`):\n\n- **Limit Max Width:** `onyx-grid-max-md` (max 1440px) or `onyx-grid-max-lg` (max 1920px)\n- **Alignment:** `onyx-grid-center` (Centers the layout when screen size exceeds max width)\n- **Max Columns (lg and beyond):** `onyx-grid-lg-16` (16 columns) or `onyx-grid-xl-20` (20 columns)\n\n## Page Layout (`OnyxPageLayout`)\n\nImplement the `OnyxPageLayout` component as the root element on every individual page/view to ensure standardized paddings, page-level scroll behavior, and unified outer page margins.\n\n```vue\n<template>\n <OnyxPageLayout>\n <OnyxHeadline is=\"h1\">Page Title</OnyxHeadline>\n </OnyxPageLayout>\n</template>\n```\n\nFor recurring page elements (like sidebars, footers, or sub-navigation), wrap the `OnyxPageLayout` in a reusable component or a Nuxt layout.\n\n## Layout Principles & Page Anatomy\n\nAll custom layout constructions must align with the core Onyx layout guidelines:\n\n### Core Principles\n\n- **Responsive:** Layouts must fluidly adapt to maintain usability and visual hierarchy across all device sizes.\n- **Content-Driven:** Prioritize structural layout decisions based on the content's hierarchy and user needs, not vice versa.\n\n### The Four Page Anatomy Regions\n\n1. **Main Navigation (`OnyxNavBar`):** Persistent top/left area independent of scroll containers, providing access to top-level views.\n2. **Sidebar (`OnyxSidebar`):** Persistent left/right sidebar used for secondary navigation or master-detail detail panels.\n3. **Page Content (`OnyxPageLayout`):** The flexible central area governed by the grid system and acting as the primary scroll container.\n4. **Bottom Bar (`OnyxBottomBar`):** Scroll-independent sticky bar at the bottom for status confirmations or primary page-level triggers.\n\n### Component Alignment Rule\n\n- **STRICT Left-Alignment:** All internal component layout structures must be left-aligned to preserve scannability.\n- **Exception:** Tables and data grids may utilize center/right alignment within specific columns depending on data type formats (e.g. numeric currencies).\n\n### Visual Rhythm & Grouping\n\n- **Spatial Grouping:** Group functionally related components together using generous empty space (white space), typography, or dividers to minimize cognitive load. Ensure balanced proportions across all section distributions.\n\n---\n\n## Validation & Quality Check\n\nAfter writing custom layouts or styling overrides, you **MUST** run the following verification steps:\n\n1. **CSS Variables Audit:** Scan your stylesheets for any hardcoded hex, rgb, or hsl values, or direct global/component variable usages. Replace them with proper `--onyx-` semantic variables.\n2. **Layout Alignment Check:** Verify all custom component interiors are left-aligned (with the exception of specific table/data grid columns).\n3. **Responsive Verification:** Verify your CSS container-query selectors are properly paired with a parent `container-type: inline-size;`. Ensure no breakpoint styles break responsive fluidity.\n";
127
+ var frontmatter$1 = {
128
+ "name": "onyx-foundation",
129
+ "description": "Styling foundations, CSS variables, layout grid, breakpoints, and responsive mixins for Onyx. Use when writing custom CSS, designing layouts, or ensuring theme compliance.",
130
+ "license": "Apache-2.0"
131
+ };
132
+ //#endregion
133
+ //#region src/resources/skills/onyx-setup/SKILL.md
134
+ var SKILL_exports = /* @__PURE__ */ __exportAll({
135
+ default: () => SKILL_default,
136
+ frontmatter: () => frontmatter,
137
+ raw: () => raw
138
+ });
139
+ var SKILL_default = "# Onyx Setup & Integration\n\nConfigure and initialize the Onyx Vue 3 design system, mandatory styles, fonts, internationalization, and root layout scaffolding.\n\n## Setup & Initialization\n\n### Vue 3 Setup\n\n1. Install `sit-onyx`.\n2. Import style files and initialize the Onyx plugin.\n\n```typescript\nimport { createApp } from \"vue\";\nimport { createOnyx } from \"sit-onyx\";\nimport App from \"./App.vue\";\n\n// Mandatory component styles\nimport \"sit-onyx/style.css\";\n\n// Highly recommended global application styles (sets body background, font, etc.)\nimport \"sit-onyx/global.css\";\n\nconst onyx = createOnyx({\n // router: routerInstance // Option: Pass router instance here\n});\n\nconst app = createApp(App);\napp.use(onyx);\n```\n\n### Nuxt Setup\n\n1. Install `@sit-onyx/nuxt`.\n2. Register the module in `nuxt.config.ts`. Do not manually call `createOnyx()`.\n\n```typescript\nexport default defineNuxtConfig({\n modules: [\"@sit-onyx/nuxt\"],\n onyx: {\n // optional module options here\n },\n});\n```\n\n## Internationalization (i18n) Setup\n\nEnglish (`en-US`) is default and registered out-of-the-box. Additional languages must be registered manually.\n\n### Vue 3 Integration with `vue-i18n`\n\nTo sync translations, import the JSON file from Onyx and register it in the `createOnyx` initialization options:\n\n```typescript\nimport { createApp } from \"vue\";\nimport { createI18n } from \"vue-i18n\";\nimport { createOnyx } from \"sit-onyx\";\nimport App from \"./App.vue\";\n\n// Import required Onyx translation file\nimport onyxDE from \"sit-onyx/locales/de-DE.json\";\n\nconst i18n = createI18n({\n legacy: false,\n locale: \"de-DE\",\n // your messages setup\n});\n\nconst onyx = createOnyx({\n i18n: {\n // Syncs initial language\n locale: i18n.global.locale,\n // Message locale name MUST exactly match the code in vue-i18n\n messages: {\n \"de-DE\": onyxDE,\n },\n },\n});\n\nconst app = createApp(App);\napp.use(i18n).use(onyx);\n```\n\n*Note: Onyx translations update automatically whenever you change the active language inside `vue-i18n`.*\n\n### Nuxt Integration with `@nuxtjs/i18n`\n\nThe `@sit-onyx/nuxt` module automatically registers the corresponding Onyx languages for you.\n\n**Strict BCP 47 Rule:**\nIf you use 2-digit locale codes (e.g. `es` instead of `es-ES`), you **MUST** configure the `language` property inside `nuxt.config.ts` so Onyx can map the translation correctly:\n\n```typescript\nexport default defineNuxtConfig({\n modules: [\"@sit-onyx/nuxt\", \"@nuxtjs/i18n\"],\n i18n: {\n locales: [\n { code: \"de-DE\" }, // Standard 4-digit code works automatically\n { code: \"es\", language: \"es-ES\" }, // 2-digit code requires language mapping\n ],\n },\n});\n```\n\n## Recommended Font Setup\n\nInstall font packages `@fontsource-variable/source-sans-3` and `@fontsource-variable/source-code-pro`. Import them into your main entrypoint:\n\n### Vue (`main.ts`)\n\n```typescript\nimport \"@fontsource-variable/source-code-pro\";\nimport \"@fontsource-variable/source-sans-3\";\n```\n\n### Nuxt (`nuxt.config.ts`)\n\n```typescript\nexport default defineNuxtConfig({\n css: [\"@fontsource-variable/source-code-pro\", \"@fontsource-variable/source-sans-3\"],\n});\n```\n\n## App Layout Scaffolding (Boilerplate)\n\nUse Onyx layout components to manage structural complexity, scroll behaviors, and responsive constraints.\n\n### Root Shell (`OnyxAppLayout`)\n\nPlace `OnyxAppLayout` at the root of the application (e.g. `App.vue` or `app/app.vue`). Use class modifiers to cap maximum width on large screens.\n\n```vue\n<template>\n <!-- Cap width at 1920px (lg breakpoint) and center align the layout -->\n <OnyxAppLayout class=\"onyx-grid-max-lg onyx-grid-center\">\n <template #navBar>\n <OnyxNavBar app-name=\"Example App\">\n <OnyxNavItem label=\"Home\" link=\"/\" />\n </OnyxNavBar>\n </template>\n\n <!-- Render pages inside the root layout shell -->\n <RouterView />\n </OnyxAppLayout>\n</template>\n```\n\n## Vue Router Integration\n\nPass the Vue router instance to `createOnyx({ router })` to enable native routing integration:\n\n* Internal links (e.g., `/my-page`) passed to navigation components (`OnyxLink`, `OnyxNavBar`, `OnyxNavItem`, `OnyxMenuItem`) navigate via Vue Router automatically.\n* Active states on `OnyxNavItem` and `OnyxMenuItem` update automatically depending on the active route.\n* Mobile flyouts close automatically upon navigation.\n* **Fallback:** Uses native browser navigation for external links, links with `target=\"_blank\"`, or when no router is registered.\n";
140
+ var raw = "---\nname: onyx-setup\ndescription: One-time configuration, initialization, CSS/font imports, i18n, and layout scaffolding for the Onyx design system. Use when setting up a new project or integrating Vue Router.\nlicense: Apache-2.0\n---\n\n# Onyx Setup & Integration\n\nConfigure and initialize the Onyx Vue 3 design system, mandatory styles, fonts, internationalization, and root layout scaffolding.\n\n## Setup & Initialization\n\n### Vue 3 Setup\n\n1. Install `sit-onyx`.\n2. Import style files and initialize the Onyx plugin.\n\n```typescript\nimport { createApp } from \"vue\";\nimport { createOnyx } from \"sit-onyx\";\nimport App from \"./App.vue\";\n\n// Mandatory component styles\nimport \"sit-onyx/style.css\";\n\n// Highly recommended global application styles (sets body background, font, etc.)\nimport \"sit-onyx/global.css\";\n\nconst onyx = createOnyx({\n // router: routerInstance // Option: Pass router instance here\n});\n\nconst app = createApp(App);\napp.use(onyx);\n```\n\n### Nuxt Setup\n\n1. Install `@sit-onyx/nuxt`.\n2. Register the module in `nuxt.config.ts`. Do not manually call `createOnyx()`.\n\n```typescript\nexport default defineNuxtConfig({\n modules: [\"@sit-onyx/nuxt\"],\n onyx: {\n // optional module options here\n },\n});\n```\n\n## Internationalization (i18n) Setup\n\nEnglish (`en-US`) is default and registered out-of-the-box. Additional languages must be registered manually.\n\n### Vue 3 Integration with `vue-i18n`\n\nTo sync translations, import the JSON file from Onyx and register it in the `createOnyx` initialization options:\n\n```typescript\nimport { createApp } from \"vue\";\nimport { createI18n } from \"vue-i18n\";\nimport { createOnyx } from \"sit-onyx\";\nimport App from \"./App.vue\";\n\n// Import required Onyx translation file\nimport onyxDE from \"sit-onyx/locales/de-DE.json\";\n\nconst i18n = createI18n({\n legacy: false,\n locale: \"de-DE\",\n // your messages setup\n});\n\nconst onyx = createOnyx({\n i18n: {\n // Syncs initial language\n locale: i18n.global.locale,\n // Message locale name MUST exactly match the code in vue-i18n\n messages: {\n \"de-DE\": onyxDE,\n },\n },\n});\n\nconst app = createApp(App);\napp.use(i18n).use(onyx);\n```\n\n_Note: Onyx translations update automatically whenever you change the active language inside `vue-i18n`._\n\n### Nuxt Integration with `@nuxtjs/i18n`\n\nThe `@sit-onyx/nuxt` module automatically registers the corresponding Onyx languages for you.\n\n**Strict BCP 47 Rule:**\nIf you use 2-digit locale codes (e.g. `es` instead of `es-ES`), you **MUST** configure the `language` property inside `nuxt.config.ts` so Onyx can map the translation correctly:\n\n```typescript\nexport default defineNuxtConfig({\n modules: [\"@sit-onyx/nuxt\", \"@nuxtjs/i18n\"],\n i18n: {\n locales: [\n { code: \"de-DE\" }, // Standard 4-digit code works automatically\n { code: \"es\", language: \"es-ES\" }, // 2-digit code requires language mapping\n ],\n },\n});\n```\n\n## Recommended Font Setup\n\nInstall font packages `@fontsource-variable/source-sans-3` and `@fontsource-variable/source-code-pro`. Import them into your main entrypoint:\n\n### Vue (`main.ts`)\n\n```typescript\nimport \"@fontsource-variable/source-code-pro\";\nimport \"@fontsource-variable/source-sans-3\";\n```\n\n### Nuxt (`nuxt.config.ts`)\n\n```typescript\nexport default defineNuxtConfig({\n css: [\"@fontsource-variable/source-code-pro\", \"@fontsource-variable/source-sans-3\"],\n});\n```\n\n## App Layout Scaffolding (Boilerplate)\n\nUse Onyx layout components to manage structural complexity, scroll behaviors, and responsive constraints.\n\n### Root Shell (`OnyxAppLayout`)\n\nPlace `OnyxAppLayout` at the root of the application (e.g. `App.vue` or `app/app.vue`). Use class modifiers to cap maximum width on large screens.\n\n```vue\n<template>\n <!-- Cap width at 1920px (lg breakpoint) and center align the layout -->\n <OnyxAppLayout class=\"onyx-grid-max-lg onyx-grid-center\">\n <template #navBar>\n <OnyxNavBar app-name=\"Example App\">\n <OnyxNavItem label=\"Home\" link=\"/\" />\n </OnyxNavBar>\n </template>\n\n <!-- Render pages inside the root layout shell -->\n <RouterView />\n </OnyxAppLayout>\n</template>\n```\n\n## Vue Router Integration\n\nPass the Vue router instance to `createOnyx({ router })` to enable native routing integration:\n\n- Internal links (e.g., `/my-page`) passed to navigation components (`OnyxLink`, `OnyxNavBar`, `OnyxNavItem`, `OnyxMenuItem`) navigate via Vue Router automatically.\n- Active states on `OnyxNavItem` and `OnyxMenuItem` update automatically depending on the active route.\n- Mobile flyouts close automatically upon navigation.\n- **Fallback:** Uses native browser navigation for external links, links with `target=\"_blank\"`, or when no router is registered.\n";
141
+ var frontmatter = {
142
+ "name": "onyx-setup",
143
+ "description": "One-time configuration, initialization, CSS/font imports, i18n, and layout scaffolding for the Onyx design system. Use when setting up a new project or integrating Vue Router.",
144
+ "license": "Apache-2.0"
145
+ };
146
+ //#endregion
147
+ //#region src/resources/skills.ts
148
+ var skills = /* #__PURE__ */ Object.assign({
149
+ "./skills/onyx-components/SKILL.md": SKILL_exports$2,
150
+ "./skills/onyx-foundation/SKILL.md": SKILL_exports$1,
151
+ "./skills/onyx-setup/SKILL.md": SKILL_exports
152
+ });
153
+ var allSkills = Object.values(skills).map(({ default: text, frontmatter: { description, name } }) => [
154
+ name,
155
+ `sit-onyx://skill/${name}`,
156
+ {
157
+ title: name,
158
+ description,
159
+ mimeType: "text/markdown"
160
+ },
161
+ (uri) => ({ contents: [{
162
+ uri: uri.href,
163
+ text,
164
+ mimeType: "text/markdown"
165
+ }] })
166
+ ]);
167
+ var writeSkillFiles = async (skillsDirectory) => {
168
+ const promises = Object.values(skills).map(async (skill) => {
169
+ const directory = resolve(skillsDirectory, skill.frontmatter.name);
170
+ await mkdir(directory, { recursive: true });
171
+ await writeFile(resolve(directory, "SKILL.md"), skill.raw);
172
+ log(`Skill ${skill.frontmatter.name} written to ${directory}`);
173
+ });
174
+ return Promise.all(promises);
175
+ };
176
+ //#endregion
94
177
  //#region src/server/http.ts
95
178
  /**
96
179
  * MCP server running as a http server.
@@ -122,6 +205,8 @@ var REGISTRY_URL = process.env.REGISTRY_URL ?? "https://registry.npmjs.org";
122
205
  */
123
206
  var SIT_ONYX_MIN_VERSION = "1.12.0";
124
207
  var SIT_ONYX_COMPONENT_META_FILE = "package/dist/component-meta.json";
208
+ var SIT_ONYX_DESIGN_TOKENS_FILE = "package/src/styles/variables/themes/onyx.css";
209
+ var SIT_ONYX_DESIGN_TOKENS_SPACINGS_FILE = "package/src/styles/variables/spacing.css";
125
210
  var SIT_ONYX_ICONS_METADATA_FILE = "package/dist/metadata.json";
126
211
  //#endregion
127
212
  //#region src/util/cached.ts
@@ -7420,11 +7505,9 @@ var import_tar_stream = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin((
7420
7505
  exports.pack = require_pack();
7421
7506
  })))(), 1);
7422
7507
  var SuccessfulAbort = class {
7423
- constructor(data) {
7424
- this.data = data;
7425
- }
7508
+ constructor() {}
7426
7509
  };
7427
- async function getSingleFileFromPackage(packageIdent, matcher, userAgent) {
7510
+ async function getFilesFromPackage(packageIdent, filenames, userAgent) {
7428
7511
  const { dist } = await getPackageManifest(packageIdent.name, packageIdent.versionOrTag, packageIdent.registry);
7429
7512
  const { body } = await fetch(dist.tarball, { headers: { "User-Agent": userAgent } });
7430
7513
  if (!body) throw new Error(`No body in response for tarball request to "${dist.tarball}"!`);
@@ -7433,14 +7516,16 @@ async function getSingleFileFromPackage(packageIdent, matcher, userAgent) {
7433
7516
  * We also use the abort reason to emit the result.
7434
7517
  */
7435
7518
  const abortController = new AbortController();
7519
+ const results = [];
7436
7520
  const archiveDownload = Readable.fromWeb(body);
7437
7521
  const decompress = createGunzip();
7438
- const fileSearcher = createTarFileSearcher(matcher, abortController);
7522
+ const fileSearcher = createTarFileSearcher(filenames, results, abortController);
7439
7523
  try {
7440
7524
  await pipeline(archiveDownload, decompress, fileSearcher, { signal: abortController.signal });
7525
+ if (results.length) return results;
7441
7526
  throw new Error("No matching file found!");
7442
7527
  } catch (error) {
7443
- if (error instanceof Error && error.name === "AbortError" && error.cause instanceof SuccessfulAbort) return error.cause.data;
7528
+ if (error instanceof Error && error.name === "AbortError" && error.cause instanceof SuccessfulAbort) return results;
7444
7529
  throw error;
7445
7530
  }
7446
7531
  }
@@ -7448,13 +7533,18 @@ async function getSingleFileFromPackage(packageIdent, matcher, userAgent) {
7448
7533
  * Returns a writable stream, which searches a file in a tar archive.
7449
7534
  * If found, will call the AbortController with the file content as reason.
7450
7535
  */
7451
- function createTarFileSearcher(matcher, abortController) {
7536
+ function createTarFileSearcher(filenames, results, abortController) {
7452
7537
  const searchFile = import_tar_stream.extract();
7453
7538
  searchFile.on("entry", async (headers, stream, next) => {
7454
- if (matcher(headers)) {
7539
+ if (filenames.includes(headers.name)) {
7455
7540
  const data = await buffer(stream);
7456
- abortController.abort(new SuccessfulAbort(data));
7457
- } else {
7541
+ results.push({
7542
+ headers,
7543
+ data
7544
+ });
7545
+ }
7546
+ if (results.length === filenames.length) abortController.abort(new SuccessfulAbort());
7547
+ else {
7458
7548
  stream.resume();
7459
7549
  next();
7460
7550
  }
@@ -7464,11 +7554,11 @@ function createTarFileSearcher(matcher, abortController) {
7464
7554
  //#endregion
7465
7555
  //#region src/util/component-meta-json.ts
7466
7556
  var retrieveComponentMetaJsonFile = cached$1(async (versionOrTag) => {
7467
- const data = await getSingleFileFromPackage({
7557
+ const [file] = await getFilesFromPackage({
7468
7558
  name: "sit-onyx",
7469
7559
  versionOrTag
7470
- }, (header) => header.name === SIT_ONYX_COMPONENT_META_FILE, USER_AGENT);
7471
- return JSON.parse(data.toString("utf-8"));
7560
+ }, [SIT_ONYX_COMPONENT_META_FILE], USER_AGENT);
7561
+ return JSON.parse(file.data.toString("utf-8") ?? "");
7472
7562
  });
7473
7563
  //#endregion
7474
7564
  //#region src/resources/get-component-api.ts
@@ -7479,7 +7569,7 @@ var compareDefined = (a, b) => a && b && a.trim().toLowerCase() === b.trim().toL
7479
7569
  var tagsToList = (tags) => tags.filter(({ name }) => !!name).map(({ text, name }) => `- ${name}: ${text}`).join("\n");
7480
7570
  var getComponentApi = [
7481
7571
  "get-component-api",
7482
- new ResourceTemplate("components://sit-onyx/{version}/{component}", { list: void 0 }),
7572
+ new ResourceTemplate("sit-onyx://components/{version}/{component}", { list: void 0 }),
7483
7573
  {
7484
7574
  title: "Get Component API",
7485
7575
  description: "Gets the component API for a specific component and version of onyx",
@@ -7555,7 +7645,7 @@ var versionCompare = (a, b) => {
7555
7645
  //#region src/resources/list-components.ts
7556
7646
  var listComponents = [
7557
7647
  "list-components",
7558
- new ResourceTemplate("components://sit-onyx/{version}", { list: async () => {
7648
+ new ResourceTemplate("sit-onyx://components/{version}", { list: async () => {
7559
7649
  const { versions } = await getAbbreviatedPackument("sit-onyx", REGISTRY_URL);
7560
7650
  return { resources: Object.keys(versions).filter((version) => versionCompare(SIT_ONYX_MIN_VERSION, version) >= 0).map((version) => ({
7561
7651
  uri: `components://sit-onyx/${version}`,
@@ -7578,51 +7668,685 @@ var listComponents = [
7578
7668
  }
7579
7669
  ];
7580
7670
  //#endregion
7581
- //#region src/util/icons-metadata-json.ts
7582
- var retrieveIconsMetadataJsonFile = cached$1(async (versionOrTag) => {
7583
- const data = await getSingleFileFromPackage({
7584
- name: "@sit-onyx/icons",
7671
+ //#region ../../node_modules/.pnpm/@adobe+css-tools@4.5.0/node_modules/@adobe/css-tools/dist/esm/adobe-css-tools.mjs
7672
+ var t = class extends Error {
7673
+ reason;
7674
+ filename;
7675
+ line;
7676
+ column;
7677
+ source;
7678
+ constructor(t, i, e, s, n) {
7679
+ super(`${t}:${e}:${s}: ${i}`), this.reason = i, this.filename = t, this.line = e, this.column = s, this.source = n;
7680
+ }
7681
+ };
7682
+ var i = class {
7683
+ start;
7684
+ end;
7685
+ source;
7686
+ constructor(t, i, e) {
7687
+ this.start = t, this.end = i, this.source = e;
7688
+ }
7689
+ };
7690
+ var e;
7691
+ (function(t) {
7692
+ t.stylesheet = "stylesheet", t.rule = "rule", t.declaration = "declaration", t.comment = "comment", t.atRule = "at-rule", t.container = "container", t.charset = "charset", t.counterStyle = "counter-style", t.document = "document", t.customMedia = "custom-media", t.fontFace = "font-face", t.fontFeatureValues = "font-feature-values", t.host = "host", t.import = "import", t.keyframes = "keyframes", t.keyframe = "keyframe", t.layer = "layer", t.media = "media", t.namespace = "namespace", t.page = "page", t.pageMarginBox = "page-margin-box", t.positionTry = "position-try", t.property = "property", t.scope = "scope", t.startingStyle = "starting-style", t.supports = "supports", t.viewTransition = "view-transition";
7693
+ })(e || (e = {}));
7694
+ var s = (t, i, e) => {
7695
+ let s = e, n = 1e4;
7696
+ do {
7697
+ const e = i.map((i) => t.indexOf(i, s));
7698
+ e.push(t.indexOf("\\", s));
7699
+ const r = e.filter((t) => -1 !== t);
7700
+ if (0 === r.length) return -1;
7701
+ const o = Math.min(...r);
7702
+ if ("\\" !== t[o]) return o;
7703
+ s = o + 2, n--;
7704
+ } while (n > 0);
7705
+ throw new Error("Too many escaping");
7706
+ }, n = (t, i, e) => {
7707
+ let r = e, o = 1e4;
7708
+ do {
7709
+ const e = i.map((i) => t.indexOf(i, r));
7710
+ e.push(t.indexOf("(", r)), e.push(t.indexOf("\"", r)), e.push(t.indexOf("'", r)), e.push(t.indexOf("\\", r));
7711
+ const c = e.filter((t) => -1 !== t);
7712
+ if (0 === c.length) return -1;
7713
+ const h = Math.min(...c);
7714
+ switch (t[h]) {
7715
+ case "\\":
7716
+ r = h + 2;
7717
+ break;
7718
+ case "(":
7719
+ {
7720
+ const i = n(t, [")"], h + 1);
7721
+ if (-1 === i) return -1;
7722
+ r = i + 1;
7723
+ }
7724
+ break;
7725
+ case "\"":
7726
+ {
7727
+ const i = s(t, ["\""], h + 1);
7728
+ if (-1 === i) return -1;
7729
+ r = i + 1;
7730
+ }
7731
+ break;
7732
+ case "'":
7733
+ {
7734
+ const i = s(t, ["'"], h + 1);
7735
+ if (-1 === i) return -1;
7736
+ r = i + 1;
7737
+ }
7738
+ break;
7739
+ default: return h;
7740
+ }
7741
+ o--;
7742
+ } while (o > 0);
7743
+ throw new Error("Too many escaping");
7744
+ }, r = /\/\*[^]*?(?:\*\/|$)/g;
7745
+ function o(t) {
7746
+ return t ? t.trim() : "";
7747
+ }
7748
+ function c(t, i) {
7749
+ const e = t && "string" == typeof t.type, s = e ? t : i;
7750
+ for (const i in t) {
7751
+ const e = t[i];
7752
+ Array.isArray(e) ? e.forEach((t) => {
7753
+ c(t, s);
7754
+ }) : e && "object" == typeof e && c(e, s);
7755
+ }
7756
+ return e && Object.defineProperty(t, "parent", {
7757
+ configurable: !0,
7758
+ writable: !0,
7759
+ enumerable: !1,
7760
+ value: i || null
7761
+ }), t;
7762
+ }
7763
+ var a = (s, h) => {
7764
+ h = h || {};
7765
+ let a = 1, m = 1;
7766
+ function u() {
7767
+ const t = {
7768
+ line: a,
7769
+ column: m
7770
+ };
7771
+ return (e) => (e.position = new i(t, {
7772
+ line: a,
7773
+ column: m
7774
+ }, h?.source || ""), g(), e);
7775
+ }
7776
+ const p = [];
7777
+ function l(i) {
7778
+ const e = new t(h?.source || "", i, a, m, s);
7779
+ if (!h?.silent) throw e;
7780
+ p.push(e);
7781
+ }
7782
+ function f() {
7783
+ const t = /^{\s*/.exec(s);
7784
+ return !!t && (y(t), !0);
7785
+ }
7786
+ function d() {
7787
+ const t = /^}/.exec(s);
7788
+ return !!t && (y(t), !0);
7789
+ }
7790
+ function y(t) {
7791
+ const i = t[0];
7792
+ return function(t) {
7793
+ const i = t.match(/\n/g);
7794
+ i && (a += i.length);
7795
+ const e = t.lastIndexOf("\n");
7796
+ m = ~e ? t.length - e : m + t.length;
7797
+ }(i), s = s.slice(i.length), t;
7798
+ }
7799
+ function g() {
7800
+ const t = /^\s*/.exec(s);
7801
+ t && y(t);
7802
+ }
7803
+ function $(t) {
7804
+ t = t || [];
7805
+ let i = x();
7806
+ for (; i;) t.push(i), i = x();
7807
+ return t;
7808
+ }
7809
+ function x() {
7810
+ const t = u();
7811
+ if ("/" !== s.charAt(0) || "*" !== s.charAt(1)) return;
7812
+ const i = /^\/\*[^]*?\*\//.exec(s);
7813
+ return i ? (y(i), t({
7814
+ type: e.comment,
7815
+ comment: i[0].slice(2, -2)
7816
+ })) : l("End of comment missing");
7817
+ }
7818
+ function V() {
7819
+ const t = n(s, ["{"]);
7820
+ if (-1 === t || 0 === t) return;
7821
+ const i = s.substring(0, t);
7822
+ y([i]);
7823
+ return ((t, i) => {
7824
+ const e = [];
7825
+ let s = 0;
7826
+ for (; s < t.length;) {
7827
+ const r = n(t, i, s);
7828
+ if (-1 === r) return e.push(t.substring(s)), e;
7829
+ e.push(t.substring(s, r)), s = r + 1;
7830
+ }
7831
+ return e;
7832
+ })(o(i).replace(r, ""), [","]).map((t) => o(t));
7833
+ }
7834
+ function v() {
7835
+ const t = u(), i = /^(\*?[-#/*\\\w]+(\[[0-9a-z_-]+\])?)\s*/.exec(s);
7836
+ if (!i) return;
7837
+ y(i);
7838
+ const c = o(i[0]), h = /^:\s*/.exec(s);
7839
+ if (!h) return l("property missing ':'");
7840
+ y(h);
7841
+ let a = "";
7842
+ const m = n(s, [";", "}"]);
7843
+ if (-1 !== m) {
7844
+ a = s.substring(0, m);
7845
+ y([a]), a = o(a).replace(r, "");
7846
+ }
7847
+ const p = t({
7848
+ type: e.declaration,
7849
+ property: c.replace(r, ""),
7850
+ value: a
7851
+ }), f = /^[;\s]*/.exec(s);
7852
+ return f && y(f), p;
7853
+ }
7854
+ function w() {
7855
+ const t = [];
7856
+ if (!f()) return l("missing '{'");
7857
+ $(t);
7858
+ let i = v();
7859
+ for (; i;) t.push(i), $(t), i = v();
7860
+ for (; h?.silent && s.length && "}" !== s.charAt(0);) {
7861
+ const e = s.indexOf(";"), n = s.indexOf("}");
7862
+ if (-1 === e || !(-1 === n || e < n)) break;
7863
+ for (y([s.substring(0, e + 1)]), g(), $(t), i = v(); i;) t.push(i), $(t), i = v();
7864
+ }
7865
+ return d() ? t : l("missing '}'");
7866
+ }
7867
+ function b() {
7868
+ const t = n(s, ["{"]);
7869
+ if (-1 === t) return !1;
7870
+ const i = n(s, [";"]), e = n(s, ["}"]);
7871
+ return !(-1 !== i && i < t) && !(-1 !== e && e < t);
7872
+ }
7873
+ function k() {
7874
+ const t = [];
7875
+ if (!f()) return l("missing '{'");
7876
+ for ($(t); s.length && "}" !== s.charAt(0);) {
7877
+ if ("@" === s.charAt(0)) {
7878
+ const i = E();
7879
+ if (i) {
7880
+ t.push(i), $(t);
7881
+ continue;
7882
+ }
7883
+ }
7884
+ if (b()) {
7885
+ const i = R();
7886
+ if (i) {
7887
+ t.push(i), $(t);
7888
+ continue;
7889
+ }
7890
+ }
7891
+ const i = v();
7892
+ if (!i) {
7893
+ if (h?.silent) {
7894
+ const i = s.indexOf(";"), e = s.indexOf("}");
7895
+ if (-1 !== i && (-1 === e || i < e)) {
7896
+ y([s.substring(0, i + 1)]), g(), $(t);
7897
+ continue;
7898
+ }
7899
+ }
7900
+ break;
7901
+ }
7902
+ t.push(i), $(t);
7903
+ }
7904
+ return d() ? t : l("missing '}'");
7905
+ }
7906
+ function A() {
7907
+ const t = [];
7908
+ for (g(), $(t); s.length && "}" !== s.charAt(0);) {
7909
+ if ("@" === s.charAt(0)) {
7910
+ const i = E();
7911
+ if (i) {
7912
+ t.push(i), $(t);
7913
+ continue;
7914
+ }
7915
+ }
7916
+ if (b()) {
7917
+ const i = R();
7918
+ if (i) {
7919
+ t.push(i), $(t);
7920
+ continue;
7921
+ }
7922
+ }
7923
+ const i = v();
7924
+ if (!i) {
7925
+ if (h?.silent) {
7926
+ const i = s.indexOf(";"), e = s.indexOf("}");
7927
+ if (-1 !== i && (-1 === e || i < e)) {
7928
+ y([s.substring(0, i + 1)]), g(), $(t);
7929
+ continue;
7930
+ }
7931
+ }
7932
+ break;
7933
+ }
7934
+ t.push(i), $(t);
7935
+ }
7936
+ return t;
7937
+ }
7938
+ function O() {
7939
+ const t = [], i = u();
7940
+ let n = /^((\d+\.\d+|\.\d+|\d+)%?|[a-z]+)\s*/.exec(s);
7941
+ for (; n;) {
7942
+ const i = y(n);
7943
+ t.push(i[1]);
7944
+ const e = /^,\s*/.exec(s);
7945
+ e && y(e), n = /^((\d+\.\d+|\.\d+|\d+)%?|[a-z]+)\s*/.exec(s);
7946
+ }
7947
+ if (t.length) return i({
7948
+ type: e.keyframe,
7949
+ values: t,
7950
+ declarations: w() || []
7951
+ });
7952
+ }
7953
+ const F = new RegExp(`^@(${[
7954
+ "top-left-corner",
7955
+ "top-left",
7956
+ "top-center",
7957
+ "top-right",
7958
+ "top-right-corner",
7959
+ "bottom-left-corner",
7960
+ "bottom-left",
7961
+ "bottom-center",
7962
+ "bottom-right",
7963
+ "bottom-right-corner",
7964
+ "left-top",
7965
+ "left-middle",
7966
+ "left-bottom",
7967
+ "right-top",
7968
+ "right-middle",
7969
+ "right-bottom"
7970
+ ].join("|")})(?![\\w-])\\s*`);
7971
+ const j = S("import"), M = S("charset"), T = S("namespace");
7972
+ function S(t) {
7973
+ const i = new RegExp("^@" + t + "\\s*((?::?[^;'\"]|\"(?:\\\\\"|[^\"])*?\"|'(?:\\\\'|[^'])*?')+)(?:;|$)");
7974
+ return () => {
7975
+ const e = u(), n = i.exec(s);
7976
+ if (!n) return;
7977
+ const r = y(n), o = { type: t };
7978
+ return o[t] = r[1].trim(), e(o);
7979
+ };
7980
+ }
7981
+ function E() {
7982
+ if ("@" === s[0]) return function() {
7983
+ const t = u(), i = /^@([-\w]+)?keyframes\s*/.exec(s);
7984
+ if (!i) return;
7985
+ const n = y(i)[1], r = /^([-\w]+)\s*/.exec(s);
7986
+ if (!r) return l("@keyframes missing name");
7987
+ const o = y(r)[1];
7988
+ if (!f()) return l("@keyframes missing '{'");
7989
+ let c = $(), h = O();
7990
+ for (; h;) c.push(h), c = c.concat($()), h = O();
7991
+ return d() ? t({
7992
+ type: e.keyframes,
7993
+ name: o,
7994
+ vendor: n,
7995
+ keyframes: c
7996
+ }) : l("@keyframes missing '}'");
7997
+ }() || function() {
7998
+ const t = u(), i = /^@media *([^{]+)/.exec(s);
7999
+ if (!i) return;
8000
+ const n = o(y(i)[1]);
8001
+ if (!f()) return l("@media missing '{'");
8002
+ const r = A();
8003
+ return d() ? t({
8004
+ type: e.media,
8005
+ media: n,
8006
+ rules: r
8007
+ }) : l("@media missing '}'");
8008
+ }() || function() {
8009
+ const t = u(), i = /^@custom-media\s+(--\S+)\s+([^{;\s][^{;]*);/.exec(s);
8010
+ if (!i) return;
8011
+ const n = y(i);
8012
+ return t({
8013
+ type: e.customMedia,
8014
+ name: o(n[1]),
8015
+ media: o(n[2])
8016
+ });
8017
+ }() || function() {
8018
+ const t = u(), i = /^@supports *([^{]+)/.exec(s);
8019
+ if (!i) return;
8020
+ const n = o(y(i)[1]);
8021
+ if (!f()) return l("@supports missing '{'");
8022
+ const r = A();
8023
+ return d() ? t({
8024
+ type: e.supports,
8025
+ supports: n,
8026
+ rules: r
8027
+ }) : l("@supports missing '}'");
8028
+ }() || j() || M() || T() || function() {
8029
+ const t = u(), i = /^@([-\w]+)?document *([^{]+)/.exec(s);
8030
+ if (!i) return;
8031
+ const n = y(i), r = o(n[1]), c = o(n[2]);
8032
+ if (!f()) return l("@document missing '{'");
8033
+ const h = A();
8034
+ return d() ? t({
8035
+ type: e.document,
8036
+ document: c,
8037
+ vendor: r,
8038
+ rules: h
8039
+ }) : l("@document missing '}'");
8040
+ }() || function() {
8041
+ const t = u(), i = /^@page */.exec(s);
8042
+ if (!i) return;
8043
+ y(i);
8044
+ const n = V() || [];
8045
+ if (!f()) return l("@page missing '{'");
8046
+ const r = [];
8047
+ for ($(r); s.length && "}" !== s.charAt(0);) {
8048
+ if ("@" === s.charAt(0)) {
8049
+ const t = E();
8050
+ if (t) {
8051
+ r.push(t), $(r);
8052
+ continue;
8053
+ }
8054
+ }
8055
+ const t = v();
8056
+ if (!t) break;
8057
+ r.push(t), $(r);
8058
+ }
8059
+ return d() ? t({
8060
+ type: e.page,
8061
+ selectors: n,
8062
+ declarations: r
8063
+ }) : l("@page missing '}'");
8064
+ }() || function() {
8065
+ const t = u(), i = /^@host\s*/.exec(s);
8066
+ if (!i) return;
8067
+ if (y(i), !f()) return l("@host missing '{'");
8068
+ const n = A();
8069
+ return d() ? t({
8070
+ type: e.host,
8071
+ rules: n
8072
+ }) : l("@host missing '}'");
8073
+ }() || function() {
8074
+ const t = u(), i = /^@font-face\s*/.exec(s);
8075
+ if (!i) return;
8076
+ if (y(i), !f()) return l("@font-face missing '{'");
8077
+ let n = $(), r = v();
8078
+ for (; r;) n.push(r), n = n.concat($()), r = v();
8079
+ return d() ? t({
8080
+ type: e.fontFace,
8081
+ declarations: n
8082
+ }) : l("@font-face missing '}'");
8083
+ }() || function() {
8084
+ const t = u(), i = /^@font-feature-values\s+([^{]+)/.exec(s);
8085
+ if (!i) return;
8086
+ const n = o(y(i)[1]);
8087
+ if (!f()) return l("@font-feature-values missing '{'");
8088
+ const r = A();
8089
+ return d() ? t({
8090
+ type: e.fontFeatureValues,
8091
+ fontFamily: n,
8092
+ rules: r
8093
+ }) : l("@font-feature-values missing '}'");
8094
+ }() || function() {
8095
+ const t = u(), i = /^@container *([^{]+)/.exec(s);
8096
+ if (!i) return;
8097
+ const n = o(y(i)[1]);
8098
+ if (!f()) return l("@container missing '{'");
8099
+ const r = A();
8100
+ return d() ? t({
8101
+ type: e.container,
8102
+ container: n,
8103
+ rules: r
8104
+ }) : l("@container missing '}'");
8105
+ }() || function() {
8106
+ const t = u(), i = /^@starting-style\s*/.exec(s);
8107
+ if (!i) return;
8108
+ if (y(i), !f()) return l("@starting-style missing '{'");
8109
+ const n = A();
8110
+ return d() ? t({
8111
+ type: e.startingStyle,
8112
+ rules: n
8113
+ }) : l("@starting-style missing '}'");
8114
+ }() || function() {
8115
+ const t = u(), i = /^@layer *([^{;@]+)/.exec(s);
8116
+ if (!i) return;
8117
+ const n = o(y(i)[1]);
8118
+ if (!f()) {
8119
+ const i = /^[;\s]*/.exec(s);
8120
+ return i && y(i), t({
8121
+ type: e.layer,
8122
+ layer: n
8123
+ });
8124
+ }
8125
+ const r = A();
8126
+ return d() ? t({
8127
+ type: e.layer,
8128
+ layer: n,
8129
+ rules: r
8130
+ }) : l("@layer missing '}'");
8131
+ }() || function() {
8132
+ const t = u(), i = /^@property\s+(--[-\w]+)\s*/.exec(s);
8133
+ if (!i) return;
8134
+ const n = y(i)[1];
8135
+ if (!f()) return l("@property missing '{'");
8136
+ let r = $(), o = v();
8137
+ for (; o;) r.push(o), r = r.concat($()), o = v();
8138
+ return d() ? t({
8139
+ type: e.property,
8140
+ name: n,
8141
+ declarations: r
8142
+ }) : l("@property missing '}'");
8143
+ }() || function() {
8144
+ const t = u(), i = /^@counter-style\s+([-\w]+)\s*/.exec(s);
8145
+ if (!i) return;
8146
+ const n = y(i)[1];
8147
+ if (!f()) return l("@counter-style missing '{'");
8148
+ let r = $(), o = v();
8149
+ for (; o;) r.push(o), r = r.concat($()), o = v();
8150
+ return d() ? t({
8151
+ type: e.counterStyle,
8152
+ name: n,
8153
+ declarations: r
8154
+ }) : l("@counter-style missing '}'");
8155
+ }() || function() {
8156
+ const t = u(), i = /^@scope\s*([^{]*)/.exec(s);
8157
+ if (!i) return;
8158
+ const n = o(y(i)[1]);
8159
+ if (!f()) return l("@scope missing '{'");
8160
+ const r = A();
8161
+ return d() ? t({
8162
+ type: e.scope,
8163
+ scope: n,
8164
+ rules: r
8165
+ }) : l("@scope missing '}'");
8166
+ }() || function() {
8167
+ const t = u(), i = /^@view-transition\s*/.exec(s);
8168
+ if (!i) return;
8169
+ if (y(i), !f()) return l("@view-transition missing '{'");
8170
+ let n = $(), r = v();
8171
+ for (; r;) n.push(r), n = n.concat($()), r = v();
8172
+ return d() ? t({
8173
+ type: e.viewTransition,
8174
+ declarations: n
8175
+ }) : l("@view-transition missing '}'");
8176
+ }() || function() {
8177
+ const t = u(), i = /^@position-try\s+(--[-\w]+)\s*/.exec(s);
8178
+ if (!i) return;
8179
+ const n = y(i)[1];
8180
+ if (!f()) return l("@position-try missing '{'");
8181
+ let r = $(), o = v();
8182
+ for (; o;) r.push(o), r = r.concat($()), o = v();
8183
+ return d() ? t({
8184
+ type: e.positionTry,
8185
+ name: n,
8186
+ declarations: r
8187
+ }) : l("@position-try missing '}'");
8188
+ }() || function() {
8189
+ const t = u(), i = F.exec(s);
8190
+ if (!i) return;
8191
+ const n = y(i)[1];
8192
+ if (!f()) return l(`@${n} missing '{'`);
8193
+ let r = $(), o = v();
8194
+ for (; o;) r.push(o), r = r.concat($()), o = v();
8195
+ return d() ? t({
8196
+ type: e.pageMarginBox,
8197
+ name: n,
8198
+ declarations: r
8199
+ }) : l(`@${n} missing '}'`);
8200
+ }() || function() {
8201
+ const t = u(), i = /^@([-\w]+)\s*/.exec(s);
8202
+ if (!i) return;
8203
+ const r = y(i)[1];
8204
+ let c = "";
8205
+ const h = n(s, ["{", ";"]);
8206
+ -1 !== h && h > 0 && (c = o(s.substring(0, h)), y([s.substring(0, h)]));
8207
+ if (f()) {
8208
+ const i = A();
8209
+ return d() ? t({
8210
+ type: e.atRule,
8211
+ name: r,
8212
+ prelude: c,
8213
+ rules: i
8214
+ }) : l(`@${r} missing '}'`);
8215
+ }
8216
+ const a = /^[;\s]*/.exec(s);
8217
+ return a && y(a), t({
8218
+ type: e.atRule,
8219
+ name: r,
8220
+ prelude: c
8221
+ });
8222
+ }();
8223
+ }
8224
+ function R() {
8225
+ const t = u(), i = V();
8226
+ return i ? ($(), t({
8227
+ type: e.rule,
8228
+ selectors: i,
8229
+ declarations: k() || []
8230
+ })) : l("selector missing");
8231
+ }
8232
+ return c(function() {
8233
+ const t = function() {
8234
+ let t;
8235
+ const i = [];
8236
+ g(), $(i);
8237
+ for (; s.length;) {
8238
+ if ("}" === s.charAt(0)) {
8239
+ if (h?.silent) {
8240
+ l("extra '}'");
8241
+ y(["}"]), g(), $(i);
8242
+ continue;
8243
+ }
8244
+ break;
8245
+ }
8246
+ if (t = E() || R(), !t) {
8247
+ if (h?.silent) {
8248
+ y([s.charAt(0)]), g(), $(i);
8249
+ continue;
8250
+ }
8251
+ break;
8252
+ }
8253
+ i.push(t), $(i);
8254
+ }
8255
+ return i;
8256
+ }();
8257
+ return {
8258
+ type: e.stylesheet,
8259
+ stylesheet: {
8260
+ source: h?.source,
8261
+ rules: t,
8262
+ parsingErrors: p
8263
+ }
8264
+ };
8265
+ }());
8266
+ };
8267
+ //#endregion
8268
+ //#region src/util/onyx-css-design-tokens.ts
8269
+ var retrieveOnyxDesignTokens = cached$1(async (versionOrTag) => {
8270
+ return (await getFilesFromPackage({
8271
+ name: "sit-onyx",
7585
8272
  versionOrTag
7586
- }, (header) => header.name === SIT_ONYX_ICONS_METADATA_FILE, USER_AGENT);
7587
- return JSON.parse(data.toString("utf-8"));
8273
+ }, [SIT_ONYX_DESIGN_TOKENS_FILE, SIT_ONYX_DESIGN_TOKENS_SPACINGS_FILE], USER_AGENT)).flatMap(({ data }) => {
8274
+ return a(data.toString()).stylesheet.rules.filter((e$1) => e$1.type === e.rule).flatMap((r) => r.declarations).map((d) => d.type === e.declaration ? d.property : void 0).filter((p) => p !== void 0).filter((p) => p.startsWith("--"));
8275
+ });
7588
8276
  });
7589
8277
  //#endregion
7590
- //#region src/resources/list-icons.ts
7591
- var listIcons = [
7592
- "list-icons",
7593
- new ResourceTemplate("icons://sit-onyx/{version}", { list: void 0 }),
8278
+ //#region src/resources/list-css-design-tokens.ts
8279
+ var listCssDesignTokens = [
8280
+ "list-css-design-tokens",
8281
+ new ResourceTemplate("sit-onyx://css-design-tokens/{version}", { list: void 0 }),
7594
8282
  {
7595
- title: "List @sit-onyx/icons icons",
7596
- description: "List all icons available in a specific version of @sit-onyx/icons",
8283
+ title: "List @sit-onyx/icons design-tokens by their CSS custom property name",
8284
+ description: "List all allowed design tokens with their CSS custom property name in a specific version of sit-onyx",
7597
8285
  mimeType: "text/markdown"
7598
8286
  },
7599
8287
  cached$1(async (uri, { version: _version }) => {
7600
8288
  const version = Array.isArray(_version) ? _version[0] : _version;
7601
- const iconsMetadata = await retrieveIconsMetadataJsonFile(version);
7602
- const categoryMap = /* @__PURE__ */ new Map();
7603
- Object.entries(iconsMetadata).forEach(([name, data]) => {
7604
- if (!categoryMap.has(data.category)) categoryMap.set(data.category, []);
7605
- categoryMap.get(data.category).push({
7606
- name,
7607
- ...data
8289
+ const tokens = await retrieveOnyxDesignTokens(version);
8290
+ const text = `${`# Design Tokens for \`sit-onyx@${version}\`\n\n`}${tokens.map((n) => `- \`${n}\``).join("\n")}`;
8291
+ return { contents: [{
8292
+ uri: uri.href,
8293
+ text,
8294
+ mimeType: "text/markdown"
8295
+ }] };
8296
+ })
8297
+ ];
8298
+ //#endregion
8299
+ //#region src/util/icons-metadata-json.ts
8300
+ var retrieveIconsMetadataJsonFile = cached$1(async (versionOrTag) => {
8301
+ const [file] = await getFilesFromPackage({
8302
+ name: "@sit-onyx/icons",
8303
+ versionOrTag
8304
+ }, [SIT_ONYX_ICONS_METADATA_FILE], USER_AGENT);
8305
+ return JSON.parse(file.data.toString("utf-8") ?? "");
8306
+ });
8307
+ //#endregion
8308
+ //#region src/resources/index.ts
8309
+ var resources = [
8310
+ getComponentApi,
8311
+ listComponents,
8312
+ [
8313
+ "list-icons",
8314
+ new ResourceTemplate("sit-onyx://icons/{version}", { list: void 0 }),
8315
+ {
8316
+ title: "List @sit-onyx/icons icons",
8317
+ description: "List all icons available in a specific version of @sit-onyx/icons",
8318
+ mimeType: "text/markdown"
8319
+ },
8320
+ cached$1(async (uri, { version: _version }) => {
8321
+ const version = Array.isArray(_version) ? _version[0] : _version;
8322
+ const iconsMetadata = await retrieveIconsMetadataJsonFile(version);
8323
+ const categoryMap = /* @__PURE__ */ new Map();
8324
+ Object.entries(iconsMetadata).forEach(([name, data]) => {
8325
+ if (!categoryMap.has(data.category)) categoryMap.set(data.category, []);
8326
+ categoryMap.get(data.category).push({
8327
+ name,
8328
+ ...data
8329
+ });
7608
8330
  });
7609
- });
7610
- const text = `# Icons for \`@sit-onyx/icons@${version}\`
8331
+ const text = `# Icons for \`@sit-onyx/icons@${version}\`
7611
8332
 
7612
8333
  This is a list of all icons offered by the \`@sit-onyx/icons@${version}\` package.
7613
8334
  The icons are grouped by category.
7614
8335
 
7615
8336
  ${categoryMap.entries().toArray().toSorted(([a], [b]) => a.localeCompare(b)).map(([category, icons]) => {
7616
- return `## ${category}
8337
+ return `## ${category}
7617
8338
 
7618
8339
  ${icons.map(({ aliases, name }) => `- \`${name}\` (aliases: ${aliases.join(", ")})`).join("\n")}`;
7619
- }).join("\n\n")}`;
7620
- return { contents: [{
7621
- uri: uri.href,
7622
- text,
7623
- mimeType: "text/markdown"
7624
- }] };
7625
- })
8340
+ }).join("\n\n")}`;
8341
+ return { contents: [{
8342
+ uri: uri.href,
8343
+ text,
8344
+ mimeType: "text/markdown"
8345
+ }] };
8346
+ })
8347
+ ],
8348
+ listCssDesignTokens,
8349
+ ...allSkills
7626
8350
  ];
7627
8351
  //#endregion
7628
8352
  //#region ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/mini/schemas.js
@@ -7666,7 +8390,7 @@ function string(params) {
7666
8390
  //#region src/util/mcp-server.ts
7667
8391
  var resourceToTool = (resource) => {
7668
8392
  const [name, template, { title, description }, cb] = resource;
7669
- const hasInputSchema = !!template.uriTemplate.variableNames.length;
8393
+ const hasInputSchema = typeof template === "object" && template.uriTemplate.variableNames.length;
7670
8394
  return [
7671
8395
  name,
7672
8396
  {
@@ -7681,7 +8405,7 @@ var resourceToTool = (resource) => {
7681
8405
  },
7682
8406
  (async (...args) => {
7683
8407
  const [vars, extra] = hasInputSchema ? args : [{}, args.at(0)];
7684
- const { contents } = await cb(new URL(template.uriTemplate.expand(vars)), vars, extra);
8408
+ const { contents } = await cb(new URL(hasInputSchema ? template.uriTemplate.expand(vars) : template), vars, extra);
7685
8409
  return { content: contents.map((resource) => ({
7686
8410
  type: "resource",
7687
8411
  resource
@@ -7692,11 +8416,6 @@ var resourceToTool = (resource) => {
7692
8416
  //#endregion
7693
8417
  //#region src/server/server.ts
7694
8418
  var { name, version, description } = package_default;
7695
- var resources = [
7696
- listComponents,
7697
- getComponentApi,
7698
- listIcons
7699
- ];
7700
8419
  var createServer = ({ resourcesAsTools }) => {
7701
8420
  /**
7702
8421
  * Internal McpServer, which provides the MCP resources.
@@ -7729,7 +8448,7 @@ var SUPPORTED_TRANSPORTS = {
7729
8448
  http: run
7730
8449
  };
7731
8450
  if (import.meta.main) {
7732
- const { values: { transport, version, help, resourcesAsTools } } = parseArgs({
8451
+ const { values: { transport, version, help, resourcesAsTools, writeSkills } } = parseArgs({
7733
8452
  args: process.argv.slice(2),
7734
8453
  options: {
7735
8454
  transport: {
@@ -7742,6 +8461,10 @@ if (import.meta.main) {
7742
8461
  short: "r",
7743
8462
  default: false
7744
8463
  },
8464
+ writeSkills: {
8465
+ type: "string",
8466
+ short: "w"
8467
+ },
7745
8468
  help: {
7746
8469
  type: "boolean",
7747
8470
  short: "h",
@@ -7764,16 +8487,21 @@ Usage:
7764
8487
  onyx-mcp [options]
7765
8488
 
7766
8489
  Options:
7767
- -t, --transport <stdio|http> Which kind of MCP server should be started (default: stdio).
7768
- The "http" transport considers PORT and HOST environment variables, when starting the server.
7769
- -r, --resourcesAsTools Some LLM Coding Assistants (e.g. Gemini) are not able to to use MCP resources (yet).
7770
- This setting makes resources also available as tools to support these Coding Assistants.
7771
- -h, --help Show this help text and quit.
7772
- -v, --version Show version number and quit.`);
8490
+ -t, --transport <"stdio"|"http"> Which kind of MCP server should be started (default: stdio).
8491
+ The "http" transport considers PORT and HOST environment variables, when starting the server.
8492
+ -r, --resourcesAsTools Some LLM Coding Assistants (e.g. Gemini) are not able to to use MCP resources (yet).
8493
+ This setting makes resources also available as tools to support these Coding Assistants.
8494
+ -w, --write-skills <directory> Write skill resources to SKILL.md files in the specified directory.
8495
+ -h, --help Show this help text and quit.
8496
+ -v, --version Show version number and quit.`);
7773
8497
  process.exit(0);
7774
8498
  } else if (version) {
7775
8499
  log(package_default.version);
7776
8500
  process.exit(0);
8501
+ } else if (writeSkills) {
8502
+ if (!(await stat(writeSkills)).isDirectory()) throw new Error(`${writeSkills} is not a directory`);
8503
+ await writeSkillFiles(writeSkills);
8504
+ process.exit(0);
7777
8505
  } else {
7778
8506
  if (!Object.keys(SUPPORTED_TRANSPORTS).includes(transport)) throw new Error(`Unsupported transport: ${transport}`);
7779
8507
  const getServer = () => createServer({ resourcesAsTools });
@@ -1,2 +1,2 @@
1
1
  import { RegisterableResource } from '../types.js';
2
- export declare const getComponentApi: RegisterableResource;
2
+ export declare const getComponentApi: RegisterableResource<true>;
@@ -0,0 +1 @@
1
+ export declare const resources: ([name: string, uriOrTemplate: import('@modelcontextprotocol/sdk/server/mcp').ResourceTemplate, config: import('@modelcontextprotocol/sdk/server/mcp').ResourceMetadata, readCallback: import('@modelcontextprotocol/sdk/server/mcp').ReadResourceTemplateCallback] | [name: string, uriOrTemplate: string, config: import('@modelcontextprotocol/sdk/server/mcp').ResourceMetadata, readCallback: import('@modelcontextprotocol/sdk/server/mcp').ReadResourceCallback])[];
@@ -1,2 +1,2 @@
1
1
  import { RegisterableResource } from '../types.js';
2
- export declare const listComponents: RegisterableResource;
2
+ export declare const listComponents: RegisterableResource<true>;
@@ -0,0 +1,2 @@
1
+ import { RegisterableResource } from '../types.js';
2
+ export declare const listCssDesignTokens: RegisterableResource<true>;
@@ -1,2 +1,2 @@
1
1
  import { RegisterableResource } from '../types.js';
2
- export declare const listIcons: RegisterableResource;
2
+ export declare const listIcons: RegisterableResource<true>;
@@ -0,0 +1,2 @@
1
+ export declare const allSkills: [name: string, uriOrTemplate: string, config: import('@modelcontextprotocol/sdk/server/mcp').ResourceMetadata, readCallback: import('@modelcontextprotocol/sdk/server/mcp').ReadResourceCallback][];
2
+ export declare const writeSkillFiles: (skillsDirectory: string) => Promise<void[]>;
@@ -2,6 +2,5 @@ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
2
  type CreateServerOptions = {
3
3
  resourcesAsTools: boolean;
4
4
  };
5
- export declare const resources: [name: string, uriOrTemplate: import('@modelcontextprotocol/sdk/server/mcp').ResourceTemplate, config: import('@modelcontextprotocol/sdk/server/mcp').ResourceMetadata, readCallback: import('@modelcontextprotocol/sdk/server/mcp').ReadResourceTemplateCallback][];
6
5
  export declare const createServer: ({ resourcesAsTools }: CreateServerOptions) => McpServer;
7
6
  export {};
package/dist/types.d.ts CHANGED
@@ -2,10 +2,11 @@ import { McpServer, ToolCallback } from '@modelcontextprotocol/sdk/server/mcp.js
2
2
  import { AnySchema, ZodRawShapeCompat } from '@modelcontextprotocol/sdk/server/zod-compat';
3
3
  import { ToolAnnotations } from '@modelcontextprotocol/sdk/types';
4
4
  import { ComponentMeta, MetaCheckerOptions } from 'vue-component-meta';
5
+ import { GetFunctionOverloads } from './util/types.js';
5
6
  /**
6
7
  * Necessary Parameters to register a resource via `mcpServer.registerResource`
7
8
  */
8
- export type RegisterableResource = Parameters<McpServer["registerResource"]>;
9
+ export type RegisterableResource<WithTemplate extends boolean = false> = GetFunctionOverloads<McpServer["registerResource"]>[WithTemplate extends true ? 1 : 0]["parameters"];
9
10
  /**
10
11
  * Necessary Parameters to register a resource via `mcpServer.registerTool`
11
12
  */
@@ -1,3 +1,3 @@
1
1
  import { AnySchema, ZodRawShapeCompat } from '@modelcontextprotocol/sdk/server/zod-compat';
2
2
  import { RegisterableResource, RegisterableTool } from '../types.js';
3
- export declare const resourceToTool: <OutputArgs extends ZodRawShapeCompat | AnySchema, InputArgs extends undefined | ZodRawShapeCompat | AnySchema = undefined>(resource: RegisterableResource) => RegisterableTool<OutputArgs, InputArgs>;
3
+ export declare const resourceToTool: <OutputArgs extends ZodRawShapeCompat | AnySchema, InputArgs extends undefined | ZodRawShapeCompat | AnySchema = undefined>(resource: RegisterableResource<boolean>) => RegisterableTool<OutputArgs, InputArgs>;
@@ -0,0 +1 @@
1
+ export declare const retrieveOnyxDesignTokens: (versionOrTag: string) => Promise<string[]>;
@@ -1,8 +1,12 @@
1
1
  import { Headers } from 'tar-stream';
2
+ type Result = {
3
+ headers: Headers;
4
+ data: Buffer;
5
+ };
2
6
  type PackageIdentifier = {
3
7
  name: string;
4
8
  versionOrTag?: string;
5
9
  registry?: string;
6
10
  };
7
- export declare function getSingleFileFromPackage(packageIdent: PackageIdentifier, matcher: (headers: Headers) => boolean, userAgent: string): Promise<Buffer<ArrayBufferLike>>;
11
+ export declare function getFilesFromPackage(packageIdent: PackageIdentifier, filenames: string[], userAgent: string): Promise<Result[]>;
8
12
  export {};
@@ -0,0 +1,20 @@
1
+ interface FunctionSignature {
2
+ parameters: AnyArray;
3
+ returnType: unknown;
4
+ }
5
+ type ToObject<T extends object> = {
6
+ [K in keyof T]: T[K];
7
+ };
8
+ interface AddSignature<T extends object, Params extends AnyArray, Return> extends T {
9
+ (...args: Params): Return;
10
+ }
11
+ export type GetFunctionOverloads<T extends AnyFunction, Shape extends object = ToObject<T>, Signatures extends FunctionSignature[] = []> = Shape extends T ? Signatures : T extends AddSignature<Shape, infer Params, infer Return> ? GetFunctionOverloads<T, AddSignature<Shape, Params, Return>, [
12
+ {
13
+ parameters: Params;
14
+ returnType: Return;
15
+ },
16
+ ...Signatures
17
+ ]> : Signatures;
18
+ type AnyFunction = (arg0: never, ...args: never[]) => unknown;
19
+ type AnyArray = readonly unknown[];
20
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sit-onyx/modelcontextprotocol",
3
- "version": "0.1.1-dev-20260630065749",
3
+ "version": "0.2.0-dev-20260701075643",
4
4
  "description": "MCP (Model Context Protocol) Server that provide onyx specific tools and resources.",
5
5
  "homepage": "https://onyx.schwarz",
6
6
  "bugs": {
@@ -26,14 +26,23 @@
26
26
  "@modelcontextprotocol/sdk": "^1.29.0"
27
27
  },
28
28
  "devDependencies": {
29
+ "@adobe/css-tools": "^4.5.0",
30
+ "@types/mdast": "^4.0.4",
29
31
  "@types/node": "24.13.2",
30
32
  "@types/tar-stream": "^3.1.4",
33
+ "@types/unist": "^3.0.3",
31
34
  "query-registry": "^4.3.0",
35
+ "remark": "^15.0.1",
36
+ "remark-frontmatter": "^5.0.0",
37
+ "remark-parse": "^11.0.0",
38
+ "remark-stringify": "^11.0.0",
32
39
  "tar-stream": "^3.2.0",
33
40
  "typescript": "6.0.3",
41
+ "unified": "^11.0.5",
34
42
  "unplugin-dts": "1.0.3",
35
43
  "vite": "8.1.0",
36
44
  "vue-component-meta": "3.3.5",
45
+ "yaml": "^2.9.0",
37
46
  "zod": "^4.4.3",
38
47
  "@sit-onyx/shared": "^0.1.0"
39
48
  },