diff --git a/.changeset/component-improvements-and-mcp-server.md b/.changeset/component-improvements-and-mcp-server.md new file mode 100644 index 00000000..6f82ee68 --- /dev/null +++ b/.changeset/component-improvements-and-mcp-server.md @@ -0,0 +1,5 @@ +--- +"@tiny-design/react": patch +--- + +Improve color-picker, slider, split, popup, and input-otp components; add @tiny-design/mcp server package with component, token, and icon tools diff --git a/packages/mcp/.gitignore b/packages/mcp/.gitignore new file mode 100644 index 00000000..439def86 --- /dev/null +++ b/packages/mcp/.gitignore @@ -0,0 +1,2 @@ +src/data/ +dist/ diff --git a/packages/mcp/README.md b/packages/mcp/README.md new file mode 100644 index 00000000..24914908 --- /dev/null +++ b/packages/mcp/README.md @@ -0,0 +1,93 @@ +# @tiny-design/mcp + +MCP (Model Context Protocol) server that gives AI assistants structured access to the [Tiny Design](https://wangdicoder.github.io/tiny-design/) component library, design tokens, and icon catalog. + +## Setup + +Add to your MCP client config: + +### Claude Code + +```json +// .claude/settings.json +{ + "mcpServers": { + "tiny-design": { + "command": "npx", + "args": ["@tiny-design/mcp"] + } + } +} +``` + +### VS Code (GitHub Copilot) + +```json +// .vscode/mcp.json +{ + "mcpServers": { + "tiny-design": { + "command": "npx", + "args": ["@tiny-design/mcp"] + } + } +} +``` + +### Cursor + +```json +// .cursor/mcp.json +{ + "mcpServers": { + "tiny-design": { + "command": "npx", + "args": ["@tiny-design/mcp"] + } + } +} +``` + +## Available Tools + +| Tool | Description | +|------|-------------| +| `list_components` | List all 80+ components. Filter by category: Foundation, Layout, Navigation, Data Display, Form, Feedback, Miscellany. | +| `get_component_props` | Get the full props interface for a component — types, required flags, descriptions. | +| `get_component_example` | Get usage examples (demo code) for a component. | +| `get_design_tokens` | Get design tokens (SCSS variables) — colors, typography, spacing, breakpoints, shadows. | +| `list_icons` | List all 240+ icon names. Filter by search term. | +| `get_icon` | Get details and usage example for a specific icon. | + +## Examples + +Ask your AI assistant: + +- "List all form components in Tiny Design" +- "What props does the Modal component accept?" +- "Show me an example of using the Select component" +- "What colors are available in Tiny Design's design tokens?" +- "Find icons related to arrows" + +## Development + +```bash +# Install dependencies (from monorepo root) +pnpm install + +# Run extraction + build +pnpm --filter @tiny-design/mcp build + +# Run tests +pnpm --filter @tiny-design/mcp test +``` + +### How It Works + +1. **Build time:** Extraction scripts parse component `types.ts` files (via `ts-morph`), SCSS token variables (via regex), and icon barrel exports to produce static JSON. +2. **Bundle time:** `tsup` bundles the server code with inlined JSON data into a single self-contained `dist/index.js`. +3. **Runtime:** The MCP server loads the inlined data and serves it via 6 tools over stdio transport using `@modelcontextprotocol/sdk`. + +## License + +MIT diff --git a/packages/mcp/__tests__/extract-components.test.ts b/packages/mcp/__tests__/extract-components.test.ts new file mode 100644 index 00000000..68401162 --- /dev/null +++ b/packages/mcp/__tests__/extract-components.test.ts @@ -0,0 +1,45 @@ +import { extractComponents } from '../scripts/extract-components'; + +describe('extractComponents', () => { + let components: ReturnType; + + beforeAll(() => { + components = extractComponents(); + }); + + it('extracts all components', () => { + expect(components.length).toBeGreaterThan(80); + }); + + it('extracts Button component correctly', () => { + const button = components.find((c) => c.name === 'Button'); + expect(button).toBeDefined(); + expect(button!.category).toBe('Foundation'); + expect(button!.description).toBe('To trigger an operation.'); + + const btnType = button!.props.find((p) => p.name === 'btnType'); + expect(btnType).toBeDefined(); + expect(btnType!.required).toBe(false); + expect(btnType!.type).toContain('primary'); + + const style = button!.props.find((p) => p.name === 'style'); + expect(style).toBeDefined(); + }); + + it('extracts demo files', () => { + const button = components.find((c) => c.name === 'Button'); + expect(button!.demos.length).toBeGreaterThan(0); + expect(button!.demos[0].name).toBeDefined(); + expect(button!.demos[0].code).toContain('import'); + }); + + it('assigns categories to all components', () => { + const validCategories = [ + 'Foundation', 'Layout', 'Navigation', 'Data Display', + 'Form', 'Feedback', 'Miscellany', + ]; + components.forEach((c) => { + expect(validCategories).toContain(c.category); + }); + }); +}); diff --git a/packages/mcp/__tests__/extract-icons.test.ts b/packages/mcp/__tests__/extract-icons.test.ts new file mode 100644 index 00000000..ac5a95e5 --- /dev/null +++ b/packages/mcp/__tests__/extract-icons.test.ts @@ -0,0 +1,26 @@ +import { extractIcons } from '../scripts/extract-icons'; + +describe('extractIcons', () => { + it('returns icon names and shared props', () => { + const result = extractIcons(); + + // Check structure + expect(result.props).toEqual({ + size: { type: 'string | number', default: '"1em"' }, + color: { type: 'string', default: '"currentColor"' }, + }); + + // Check icons array is populated + expect(result.icons.length).toBeGreaterThan(200); + + // Check specific known icons exist + expect(result.icons).toContain('IconPlus'); + expect(result.icons).toContain('IconClose'); + expect(result.icons).toContain('IconHeart'); + + // All entries should start with "Icon" + result.icons.forEach((name) => { + expect(name).toMatch(/^Icon[A-Z]/); + }); + }); +}); diff --git a/packages/mcp/__tests__/extract-tokens.test.ts b/packages/mcp/__tests__/extract-tokens.test.ts new file mode 100644 index 00000000..23fb83c6 --- /dev/null +++ b/packages/mcp/__tests__/extract-tokens.test.ts @@ -0,0 +1,51 @@ +import { extractTokens } from '../scripts/extract-tokens'; + +describe('extractTokens', () => { + it('extracts tokens grouped by category', () => { + const result = extractTokens(); + + // Should have known categories + expect(Object.keys(result)).toEqual( + expect.arrayContaining(['colors', 'typography', 'spacing', 'breakpoints', 'shadows']) + ); + }); + + it('extracts color tokens', () => { + const result = extractTokens(); + + expect(result.colors['primary-color']).toEqual({ + variable: '$primary-color', + value: '#6e41bf', + }); + + expect(result.colors['info-color']).toEqual({ + variable: '$info-color', + value: '#1890ff', + }); + }); + + it('extracts typography tokens', () => { + const result = extractTokens(); + + expect(result.typography['font-size-base']).toEqual({ + variable: '$font-size-base', + value: '1rem', + }); + }); + + it('extracts breakpoint tokens', () => { + const result = extractTokens(); + + expect(result.breakpoints['size-xs']).toEqual({ + variable: '$size-xs', + value: '480px', + }); + }); + + it('extracts shadow tokens', () => { + const result = extractTokens(); + + expect(result.shadows).toBeDefined(); + expect(result.shadows['box-shadow-sm']).toBeDefined(); + }); +}); diff --git a/packages/mcp/__tests__/tool-components.test.ts b/packages/mcp/__tests__/tool-components.test.ts new file mode 100644 index 00000000..7b60fe7e --- /dev/null +++ b/packages/mcp/__tests__/tool-components.test.ts @@ -0,0 +1,63 @@ +import { listComponents, getComponentProps, getComponentExample } from '../src/tools/components'; + +describe('listComponents', () => { + it('returns all components', () => { + const result = listComponents(); + expect(result.length).toBeGreaterThan(80); + expect(result[0]).toHaveProperty('name'); + expect(result[0]).toHaveProperty('category'); + expect(result[0]).toHaveProperty('description'); + expect(result[0]).not.toHaveProperty('props'); + expect(result[0]).not.toHaveProperty('demos'); + }); + + it('filters by category', () => { + const result = listComponents('Foundation'); + expect(result.length).toBeGreaterThan(0); + result.forEach((c) => expect(c.category).toBe('Foundation')); + }); + + it('returns empty array for unknown category', () => { + expect(listComponents('Unknown')).toEqual([]); + }); +}); + +describe('getComponentProps', () => { + it('returns props for a known component', () => { + const result = getComponentProps('Button'); + expect(result).not.toBeNull(); + expect(result!.name).toBe('Button'); + expect(result!.props.length).toBeGreaterThan(0); + expect(result!.props.find((p) => p.name === 'btnType')).toBeDefined(); + }); + + it('is case-insensitive', () => { + const result = getComponentProps('button'); + expect(result).not.toBeNull(); + expect(result!.name).toBe('Button'); + }); + + it('returns null for unknown component', () => { + expect(getComponentProps('FooBar')).toBeNull(); + }); +}); + +describe('getComponentExample', () => { + it('returns all demos for a component', () => { + const result = getComponentExample('Button'); + expect(result).not.toBeNull(); + expect(result!.length).toBeGreaterThan(0); + expect(result![0].code).toContain('import'); + }); + + it('returns specific demo by name', () => { + const result = getComponentExample('Button', 'Type'); + expect(result).not.toBeNull(); + expect(result!.length).toBe(1); + expect(result![0].name).toBe('Type'); + }); + + it('returns null for unknown component', () => { + expect(getComponentExample('FooBar')).toBeNull(); + }); +}); diff --git a/packages/mcp/__tests__/tool-icons.test.ts b/packages/mcp/__tests__/tool-icons.test.ts new file mode 100644 index 00000000..3335cc55 --- /dev/null +++ b/packages/mcp/__tests__/tool-icons.test.ts @@ -0,0 +1,39 @@ +import { listIcons, getIcon } from '../src/tools/icons'; + +describe('listIcons', () => { + it('returns all icons', () => { + const result = listIcons(); + expect(result.length).toBeGreaterThan(200); + }); + + it('filters by search term', () => { + const result = listIcons('arrow'); + expect(result.length).toBeGreaterThan(0); + result.forEach((name) => { + expect(name.toLowerCase()).toContain('arrow'); + }); + }); + + it('returns empty for no matches', () => { + expect(listIcons('zzzznotanicon')).toEqual([]); + }); +}); + +describe('getIcon', () => { + it('returns icon details', () => { + const result = getIcon('IconPlus'); + expect(result).not.toBeNull(); + expect(result!.name).toBe('IconPlus'); + expect(result!.props).toBeDefined(); + expect(result!.usage).toContain('IconPlus'); + }); + + it('is case-insensitive', () => { + const result = getIcon('iconplus'); + expect(result).not.toBeNull(); + }); + + it('returns null for unknown icon', () => { + expect(getIcon('IconFooBar')).toBeNull(); + }); +}); diff --git a/packages/mcp/__tests__/tool-tokens.test.ts b/packages/mcp/__tests__/tool-tokens.test.ts new file mode 100644 index 00000000..0c621fdf --- /dev/null +++ b/packages/mcp/__tests__/tool-tokens.test.ts @@ -0,0 +1,21 @@ +import { getDesignTokens } from '../src/tools/tokens'; + +describe('getDesignTokens', () => { + it('returns all token categories', () => { + const result = getDesignTokens(); + expect(Object.keys(result)).toEqual( + expect.arrayContaining(['colors', 'typography', 'spacing', 'breakpoints', 'shadows']) + ); + }); + + it('filters by category', () => { + const result = getDesignTokens('colors'); + expect(Object.keys(result)).toEqual(['colors']); + expect(Object.keys(result.colors).length).toBeGreaterThan(0); + }); + + it('returns empty object for unknown category', () => { + const result = getDesignTokens('unknown'); + expect(result).toEqual({}); + }); +}); diff --git a/packages/mcp/jest.config.cjs b/packages/mcp/jest.config.cjs new file mode 100644 index 00000000..6a4d8bd7 --- /dev/null +++ b/packages/mcp/jest.config.cjs @@ -0,0 +1,22 @@ +/** @type {import('jest').Config} */ +module.exports = { + testEnvironment: 'node', + roots: ['/__tests__'], + extensionsToTreatAsEsm: ['.ts'], + transform: { + '^.+\\.tsx?$': ['ts-jest', { + useESM: true, + tsconfig: { + module: 'ESNext', + moduleResolution: 'bundler', + target: 'ES2022', + esModuleInterop: true, + resolveJsonModule: true, + strict: true, + }, + }], + }, + moduleNameMapper: { + '^(\\.{1,2}/.*)\\.js$': '$1', + }, +}; diff --git a/packages/mcp/package.json b/packages/mcp/package.json new file mode 100644 index 00000000..aba07c44 --- /dev/null +++ b/packages/mcp/package.json @@ -0,0 +1,39 @@ +{ + "name": "@tiny-design/mcp", + "version": "1.6.0", + "description": "MCP server for AI assistants to access the Tiny Design component library", + "license": "MIT", + "keywords": ["tiny-design", "mcp", "model-context-protocol", "ai"], + "repository": { + "type": "git", + "url": "https://github.com/wangdicoder/tiny-design.git", + "directory": "packages/mcp" + }, + "author": "Di Wang", + "publishConfig": { + "access": "public" + }, + "bin": { + "tiny-design-mcp": "./dist/index.js" + }, + "files": ["dist"], + "type": "module", + "scripts": { + "extract": "node --import tsx scripts/extract.ts", + "build": "pnpm extract && tsup", + "test": "NODE_OPTIONS='--experimental-vm-modules' jest" + }, + "dependencies": { + "@modelcontextprotocol/sdk": "^1.12.1" + }, + "devDependencies": { + "@types/jest": "^29.0.0", + "@types/node": "^22.0.0", + "jest": "^29.0.0", + "ts-jest": "^29.0.0", + "ts-morph": "^25.0.0", + "tsup": "^8.0.0", + "tsx": "^4.0.0", + "typescript": "^5.4.0" + } +} diff --git a/packages/mcp/scripts/extract-components.ts b/packages/mcp/scripts/extract-components.ts new file mode 100644 index 00000000..584dffea --- /dev/null +++ b/packages/mcp/scripts/extract-components.ts @@ -0,0 +1,185 @@ +import * as fs from 'node:fs'; +import * as path from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { Project, type InterfaceDeclaration } from 'ts-morph'; +import type { ComponentData, ComponentProp } from '../src/types'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +const REACT_SRC = path.resolve(__dirname, '../../react/src'); + +// Category mapping from routers.tsx +const CATEGORY_MAP: Record = { + button: 'Foundation', icon: 'Foundation', image: 'Foundation', + link: 'Foundation', typography: 'Foundation', + + 'aspect-ratio': 'Layout', divider: 'Layout', flex: 'Layout', + grid: 'Layout', layout: 'Layout', space: 'Layout', split: 'Layout', + waterfall: 'Layout', + + anchor: 'Navigation', breadcrumb: 'Navigation', dropdown: 'Navigation', + menu: 'Navigation', pagination: 'Navigation', 'speed-dial': 'Navigation', + steps: 'Navigation', + + avatar: 'Data Display', badge: 'Data Display', calendar: 'Data Display', + card: 'Data Display', carousel: 'Data Display', collapse: 'Data Display', + countdown: 'Data Display', empty: 'Data Display', descriptions: 'Data Display', + flip: 'Data Display', list: 'Data Display', marquee: 'Data Display', + popover: 'Data Display', progress: 'Data Display', 'scroll-number': 'Data Display', + statistic: 'Data Display', table: 'Data Display', tag: 'Data Display', + 'text-loop': 'Data Display', timeline: 'Data Display', tooltip: 'Data Display', + tree: 'Data Display', + + form: 'Form', 'auto-complete': 'Form', cascader: 'Form', checkbox: 'Form', + 'color-picker': 'Form', 'date-picker': 'Form', input: 'Form', + 'input-number': 'Form', 'input-password': 'Form', 'input-otp': 'Form', + 'native-select': 'Form', radio: 'Form', rate: 'Form', segmented: 'Form', + select: 'Form', slider: 'Form', 'split-button': 'Form', switch: 'Form', + tabs: 'Form', textarea: 'Form', 'time-picker': 'Form', transfer: 'Form', + upload: 'Form', + + alert: 'Feedback', drawer: 'Feedback', loader: 'Feedback', + overlay: 'Feedback', 'loading-bar': 'Feedback', message: 'Feedback', + modal: 'Feedback', notification: 'Feedback', 'pop-confirm': 'Feedback', + result: 'Feedback', 'scroll-indicator': 'Feedback', skeleton: 'Feedback', + 'strength-indicator': 'Feedback', + + 'back-top': 'Miscellany', 'config-provider': 'Miscellany', + 'copy-to-clipboard': 'Miscellany', keyboard: 'Miscellany', + sticky: 'Miscellany', +}; + +function getDescription(componentDir: string): string { + const mdPath = path.join(componentDir, 'index.md'); + if (!fs.existsSync(mdPath)) return ''; + + const content = fs.readFileSync(mdPath, 'utf-8'); + const lines = content.split('\n'); + + let foundHeading = false; + for (const line of lines) { + if (line.startsWith('# ')) { + foundHeading = true; + continue; + } + if (foundHeading && line.trim() !== '' && !line.startsWith('import ')) { + return line.trim(); + } + } + return ''; +} + +function getDemos(componentDir: string): { name: string; code: string }[] { + const demoDir = path.join(componentDir, 'demo'); + if (!fs.existsSync(demoDir)) return []; + + return fs + .readdirSync(demoDir) + .filter((f) => f.endsWith('.tsx')) + .map((f) => ({ + name: path.basename(f, '.tsx'), + code: fs.readFileSync(path.join(demoDir, f), 'utf-8'), + })); +} + +function resolveTypeText(typeText: string, iface: InterfaceDeclaration): string { + // If the type is a simple identifier (a type alias reference), try to resolve it + // from the same source file so we get the actual union/type text + if (/^[A-Z][A-Za-z0-9]*$/.test(typeText)) { + const sourceFile = iface.getSourceFile(); + const typeAlias = sourceFile.getTypeAlias(typeText); + if (typeAlias) { + const aliasTypeNode = typeAlias.getTypeNode(); + if (aliasTypeNode) { + return aliasTypeNode.getText(); + } + } + } + return typeText; +} + +function extractPropsFromInterface(iface: InterfaceDeclaration): ComponentProp[] { + const props: ComponentProp[] = []; + + for (const prop of iface.getProperties()) { + const name = prop.getName(); + const typeNode = prop.getTypeNode(); + const rawTypeText = typeNode ? typeNode.getText() : prop.getType().getText(prop); + const typeText = resolveTypeText(rawTypeText, iface); + const isOptional = prop.hasQuestionToken(); + + const jsDocs = prop.getJsDocs(); + const description = jsDocs.length > 0 ? jsDocs[0].getDescription().trim() : ''; + + props.push({ + name, + type: typeText, + required: !isOptional, + description, + }); + } + + return props; +} + +function dirNameToComponentName(dirName: string): string { + return dirName + .split('-') + .map((part) => part.charAt(0).toUpperCase() + part.slice(1)) + .join(''); +} + +export function extractComponents(): ComponentData[] { + const project = new Project({ + skipAddingFilesFromTsConfig: true, + skipFileDependencyResolution: true, + }); + + const components: ComponentData[] = []; + const dirs = fs.readdirSync(REACT_SRC, { withFileTypes: true }); + + for (const dir of dirs) { + if (!dir.isDirectory()) continue; + if (dir.name.startsWith('_')) continue; + + const dirName = dir.name; + const typesPath = path.join(REACT_SRC, dirName, 'types.ts'); + if (!fs.existsSync(typesPath)) continue; + + const category = CATEGORY_MAP[dirName]; + if (!category) continue; + + const sourceFile = project.addSourceFileAtPath(typesPath); + const interfaces = sourceFile.getInterfaces(); + + const componentName = dirNameToComponentName(dirName); + // Try exact match first, then fall back to the first exported interface in the file + const mainInterface = + interfaces.find((i) => i.getName() === `${componentName}Props`) ?? + interfaces.find((i) => i.isExported() && i.getName().endsWith('Props')); + + if (!mainInterface) continue; + + const props = extractPropsFromInterface(mainInterface); + + const baseProps: ComponentProp[] = [ + { name: 'style', type: 'CSSProperties', required: false, description: 'Inline styles' }, + { name: 'className', type: 'string', required: false, description: 'CSS class name' }, + { name: 'prefixCls', type: 'string', required: false, description: 'CSS class prefix (default: "ty")' }, + ]; + + const propNames = new Set(props.map((p) => p.name)); + const allProps = [...props, ...baseProps.filter((p) => !propNames.has(p.name))]; + + components.push({ + name: componentName, + category, + description: getDescription(path.join(REACT_SRC, dirName)), + props: allProps, + demos: getDemos(path.join(REACT_SRC, dirName)), + }); + } + + return components.sort((a, b) => a.name.localeCompare(b.name)); +} diff --git a/packages/mcp/scripts/extract-icons.ts b/packages/mcp/scripts/extract-icons.ts new file mode 100644 index 00000000..0ebb24fb --- /dev/null +++ b/packages/mcp/scripts/extract-icons.ts @@ -0,0 +1,33 @@ +import * as fs from 'node:fs'; +import * as path from 'node:path'; +import { fileURLToPath } from 'node:url'; +import type { IconData } from '../src/types'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +const ICONS_INDEX = path.resolve(__dirname, '../../icons/src/index.ts'); + +export function extractIcons(): IconData { + const content = fs.readFileSync(ICONS_INDEX, 'utf-8'); + + const icons: string[] = []; + const exportRegex = /export\s*\{\s*(\w+)\s*\}/g; + let match: RegExpExecArray | null; + + while ((match = exportRegex.exec(content)) !== null) { + const name = match[1]; + // Skip the IconProps type export + if (name !== 'IconProps') { + icons.push(name); + } + } + + return { + props: { + size: { type: 'string | number', default: '"1em"' }, + color: { type: 'string', default: '"currentColor"' }, + }, + icons, + }; +} diff --git a/packages/mcp/scripts/extract-tokens.ts b/packages/mcp/scripts/extract-tokens.ts new file mode 100644 index 00000000..88cd28a2 --- /dev/null +++ b/packages/mcp/scripts/extract-tokens.ts @@ -0,0 +1,62 @@ +import * as fs from 'node:fs'; +import * as path from 'node:path'; +import { fileURLToPath } from 'node:url'; +import type { TokenData } from '../src/types'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +const VARIABLES_PATH = path.resolve(__dirname, '../../tokens/scss/_variables.scss'); + +// Map variable name prefixes to categories +const CATEGORY_RULES: Array<{ test: (name: string) => boolean; category: string }> = [ + { test: (n) => /^(box-)?shadow/.test(n), category: 'shadows' }, + { test: (n) => /^size-(xs|sm|md|lg|xl|xxl)$/.test(n), category: 'breakpoints' }, + { test: (n) => /^(font|line-height|heading|h\d-)/.test(n), category: 'typography' }, + { test: (n) => /^(spacer|height-)/.test(n), category: 'spacing' }, + { + test: (n) => + /color$/.test(n) || + /^(white|black|gray|red|orange|yellow|green|teal|cyan|blue|indigo|purple|magenta)-/.test(n) || + /^(info|success|warning|danger|primary)-/.test(n) || + /^(body-bg|body-color)/.test(n), + category: 'colors', + }, +]; + +function categorize(name: string): string | null { + for (const rule of CATEGORY_RULES) { + if (rule.test(name)) return rule.category; + } + return null; +} + +export function extractTokens(): TokenData { + const content = fs.readFileSync(VARIABLES_PATH, 'utf-8'); + const result: TokenData = { + colors: {}, + typography: {}, + spacing: {}, + breakpoints: {}, + shadows: {}, + }; + + // Match SCSS variable declarations: $name: value !default; + const varRegex = /^\$([a-z0-9-]+):\s*(.+?)\s*!default\s*;/gm; + let match: RegExpExecArray | null; + + while ((match = varRegex.exec(content)) !== null) { + const name = match[1]; + const value = match[2]; + const category = categorize(name); + + if (category) { + result[category][name] = { + variable: `$${name}`, + value, + }; + } + } + + return result; +} diff --git a/packages/mcp/scripts/extract.ts b/packages/mcp/scripts/extract.ts new file mode 100644 index 00000000..df0e0b80 --- /dev/null +++ b/packages/mcp/scripts/extract.ts @@ -0,0 +1,37 @@ +import * as fs from 'node:fs'; +import * as path from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { extractComponents } from './extract-components'; +import { extractTokens } from './extract-tokens'; +import { extractIcons } from './extract-icons'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +const DATA_DIR = path.resolve(__dirname, '../src/data'); + +function ensureDir(dir: string) { + if (!fs.existsSync(dir)) { + fs.mkdirSync(dir, { recursive: true }); + } +} + +function writeJson(filename: string, data: unknown) { + const filePath = path.join(DATA_DIR, filename); + fs.writeFileSync(filePath, JSON.stringify(data, null, 2)); + console.log(` wrote ${filePath}`); +} + +console.log('Extracting Tiny Design data...'); +ensureDir(DATA_DIR); + +console.log(' extracting components...'); +writeJson('components.json', extractComponents()); + +console.log(' extracting tokens...'); +writeJson('tokens.json', extractTokens()); + +console.log(' extracting icons...'); +writeJson('icons.json', extractIcons()); + +console.log('Done.'); diff --git a/packages/mcp/src/index.ts b/packages/mcp/src/index.ts new file mode 100644 index 00000000..fde468d4 --- /dev/null +++ b/packages/mcp/src/index.ts @@ -0,0 +1,97 @@ +// Note: shebang is added by tsup via banner config — do NOT add #!/usr/bin/env node here +import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; +import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; +import { z } from 'zod'; +import { listComponents, getComponentProps, getComponentExample } from './tools/components.js'; +import { getDesignTokens } from './tools/tokens.js'; +import { listIcons, getIcon } from './tools/icons.js'; +import pkg from '../package.json'; + +const server = new McpServer({ + name: '@tiny-design/mcp', + version: pkg.version, +}); + +// --- Component tools --- + +server.tool( + 'list_components', + 'List all Tiny Design components. Optionally filter by category: Foundation, Layout, Navigation, Data Display, Form, Feedback, Miscellany.', + { category: z.string().optional().describe('Filter by component category') }, + async ({ category }) => ({ + content: [{ type: 'text' as const, text: JSON.stringify(listComponents(category), null, 2) }], + }) +); + +server.tool( + 'get_component_props', + 'Get the full props interface for a Tiny Design component, including types, required flags, and descriptions.', + { name: z.string().describe('Component name (e.g., "Button", "Modal", "Select")') }, + async ({ name }) => { + const result = getComponentProps(name); + if (!result) { + return { content: [{ type: 'text' as const, text: `Component "${name}" not found.` }] }; + } + return { content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }] }; + } +); + +server.tool( + 'get_component_example', + 'Get usage examples (demo code) for a Tiny Design component.', + { + name: z.string().describe('Component name (e.g., "Button")'), + demo: z.string().optional().describe('Specific demo name (e.g., "Type", "Size"). Returns all demos if omitted.'), + }, + async ({ name, demo }) => { + const result = getComponentExample(name, demo); + if (!result) { + return { content: [{ type: 'text' as const, text: `Component "${name}" not found.` }] }; + } + return { content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }] }; + } +); + +// --- Token tools --- + +server.tool( + 'get_design_tokens', + 'Get Tiny Design design tokens (SCSS variables). Categories: colors, typography, spacing, breakpoints, shadows.', + { category: z.string().optional().describe('Token category to filter by') }, + async ({ category }) => ({ + content: [{ type: 'text' as const, text: JSON.stringify(getDesignTokens(category), null, 2) }], + }) +); + +// --- Icon tools --- + +server.tool( + 'list_icons', + 'List all Tiny Design icon names. Optionally filter by search term.', + { search: z.string().optional().describe('Search term to filter icons (e.g., "arrow", "close")') }, + async ({ search }) => ({ + content: [{ type: 'text' as const, text: JSON.stringify(listIcons(search), null, 2) }], + }) +); + +server.tool( + 'get_icon', + 'Get details for a specific Tiny Design icon, including props and usage example.', + { name: z.string().describe('Icon name (e.g., "IconPlus", "IconClose")') }, + async ({ name }) => { + const result = getIcon(name); + if (!result) { + return { content: [{ type: 'text' as const, text: `Icon "${name}" not found.` }] }; + } + return { content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }] }; + } +); + +// --- Start server --- + +async function main() { + const transport = new StdioServerTransport(); + await server.connect(transport); +} + +main().catch(console.error); diff --git a/packages/mcp/src/tools/components.ts b/packages/mcp/src/tools/components.ts new file mode 100644 index 00000000..ec78cd79 --- /dev/null +++ b/packages/mcp/src/tools/components.ts @@ -0,0 +1,46 @@ +import type { ComponentData } from '../types.js'; +import componentsData from '../data/components.json'; + +const components = componentsData as ComponentData[]; + +export function listComponents(category?: string) { + const filtered = category + ? components.filter((c) => c.category === category) + : components; + + return filtered.map(({ name, category, description }) => ({ + name, + category, + description, + })); +} + +export function getComponentProps(name: string) { + const component = components.find( + (c) => c.name.toLowerCase() === name.toLowerCase() + ); + if (!component) return null; + + return { + name: component.name, + category: component.category, + description: component.description, + props: component.props, + }; +} + +export function getComponentExample(name: string, demo?: string) { + const component = components.find( + (c) => c.name.toLowerCase() === name.toLowerCase() + ); + if (!component) return null; + + if (demo) { + const found = component.demos.filter( + (d) => d.name.toLowerCase() === demo.toLowerCase() + ); + return found.length > 0 ? found : null; + } + + return component.demos; +} diff --git a/packages/mcp/src/tools/icons.ts b/packages/mcp/src/tools/icons.ts new file mode 100644 index 00000000..f8f76379 --- /dev/null +++ b/packages/mcp/src/tools/icons.ts @@ -0,0 +1,24 @@ +import type { IconData } from '../types.js'; +import iconsData from '../data/icons.json'; + +const data = iconsData as IconData; + +export function listIcons(search?: string): string[] { + if (search) { + const term = search.toLowerCase(); + return data.icons.filter((name) => name.toLowerCase().includes(term)); + } + return data.icons; +} + +export function getIcon(name: string) { + const icon = data.icons.find( + (i) => i.toLowerCase() === name.toLowerCase() + ); + if (!icon) return null; + return { + name: icon, + props: data.props, + usage: `import { ${icon} } from '@tiny-design/icons';\n\n<${icon} size={24} color="#6e41bf" />`, + }; +} diff --git a/packages/mcp/src/tools/tokens.ts b/packages/mcp/src/tools/tokens.ts new file mode 100644 index 00000000..5c797653 --- /dev/null +++ b/packages/mcp/src/tools/tokens.ts @@ -0,0 +1,12 @@ +import type { TokenData } from '../types.js'; +import tokensData from '../data/tokens.json'; + +const tokens = tokensData as TokenData; + +export function getDesignTokens(category?: string): TokenData { + if (category) { + if (!(category in tokens)) return {} as TokenData; + return { [category]: tokens[category] } as TokenData; + } + return tokens; +} diff --git a/packages/mcp/src/types.ts b/packages/mcp/src/types.ts new file mode 100644 index 00000000..6edeb96b --- /dev/null +++ b/packages/mcp/src/types.ts @@ -0,0 +1,38 @@ +export interface ComponentProp { + name: string; + type: string; + required: boolean; + description: string; +} + +export interface ComponentDemo { + name: string; + code: string; +} + +export interface ComponentData { + name: string; + category: string; + description: string; + props: ComponentProp[]; + demos: ComponentDemo[]; +} + +export interface TokenEntry { + variable: string; + value: string; +} + +export interface TokenData { + [category: string]: { + [name: string]: TokenEntry; + }; +} + +export interface IconData { + props: { + size: { type: string; default: string }; + color: { type: string; default: string }; + }; + icons: string[]; +} diff --git a/packages/mcp/tsconfig.json b/packages/mcp/tsconfig.json new file mode 100644 index 00000000..39206639 --- /dev/null +++ b/packages/mcp/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "ESNext", + "moduleResolution": "bundler", + "declaration": false, + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "outDir": "dist", + "rootDir": ".", + "resolveJsonModule": true + }, + "include": ["src/**/*", "scripts/**/*"], + "exclude": ["node_modules", "dist", "__tests__"] +} diff --git a/packages/mcp/tsup.config.ts b/packages/mcp/tsup.config.ts new file mode 100644 index 00000000..2738179c --- /dev/null +++ b/packages/mcp/tsup.config.ts @@ -0,0 +1,10 @@ +import { defineConfig } from 'tsup'; + +export default defineConfig({ + entry: ['src/index.ts'], + format: ['esm'], + outDir: 'dist', + clean: true, + banner: { js: '#!/usr/bin/env node' }, + loader: { '.json': 'json' }, +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fc88a7c0..ab8f59a8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -101,7 +101,7 @@ importers: version: 3.1.1(rollup@4.59.0) '@vitejs/plugin-react': specifier: ^5.1.4 - version: 5.1.4(vite@7.3.1(@types/node@25.4.0)(jiti@2.6.1)(sass@1.98.0)(yaml@2.8.2)) + version: 5.1.4(vite@7.3.1(@types/node@25.4.0)(jiti@2.6.1)(sass@1.98.0)(tsx@4.21.0)(yaml@2.8.2)) autoprefixer: specifier: ^10.4.4 version: 10.4.27(postcss@8.5.8) @@ -119,7 +119,7 @@ importers: version: 1.98.0 vite: specifier: ^7.3.1 - version: 7.3.1(@types/node@25.4.0)(jiti@2.6.1)(sass@1.98.0)(yaml@2.8.2) + version: 7.3.1(@types/node@25.4.0)(jiti@2.6.1)(sass@1.98.0)(tsx@4.21.0)(yaml@2.8.2) packages/icons: devDependencies: @@ -137,7 +137,7 @@ importers: version: 18.3.28 jest: specifier: ^29.0.0 - version: 29.7.0(@types/node@25.4.0) + version: 29.7.0(@types/node@22.19.15) jest-environment-jsdom: specifier: ^29.0.0 version: 29.7.0 @@ -152,7 +152,7 @@ importers: version: 3.0.2 ts-jest: specifier: ^29.0.0 - version: 29.4.6(@babel/core@7.29.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.29.0))(jest-util@29.7.0)(jest@29.7.0(@types/node@25.4.0))(typescript@5.9.3) + version: 29.4.6(@babel/core@7.29.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.29.0))(esbuild@0.27.3)(jest-util@29.7.0)(jest@29.7.0(@types/node@22.19.15))(typescript@5.9.3) tsdown: specifier: ^0.21.1 version: 0.21.2(typescript@5.9.3) @@ -160,6 +160,37 @@ importers: specifier: ^5.4.0 version: 5.9.3 + packages/mcp: + dependencies: + '@modelcontextprotocol/sdk': + specifier: ^1.12.1 + version: 1.27.1(zod@4.3.6) + devDependencies: + '@types/jest': + specifier: ^29.0.0 + version: 29.5.14 + '@types/node': + specifier: ^22.0.0 + version: 22.19.15 + jest: + specifier: ^29.0.0 + version: 29.7.0(@types/node@22.19.15) + ts-jest: + specifier: ^29.0.0 + version: 29.4.6(@babel/core@7.29.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.29.0))(esbuild@0.27.3)(jest-util@29.7.0)(jest@29.7.0(@types/node@22.19.15))(typescript@5.9.3) + ts-morph: + specifier: ^25.0.0 + version: 25.0.1 + tsup: + specifier: ^8.0.0 + version: 8.5.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2) + tsx: + specifier: ^4.0.0 + version: 4.21.0 + typescript: + specifier: ^5.4.0 + version: 5.9.3 + packages/react: dependencies: '@popperjs/core': @@ -748,6 +779,12 @@ packages: resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@hono/node-server@1.19.11': + resolution: {integrity: sha512-dr8/3zEaB+p0D2n/IUrlPF1HZm586qgJNXK1a9fhg/PzdtkK7Ksd5l312tJX2yBuALqDYBlG20QEbayqPyxn+g==} + engines: {node: '>=18.14.1'} + peerDependencies: + hono: ^4 + '@humanfs/core@0.19.1': resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} engines: {node: '>=18.18.0'} @@ -892,6 +929,16 @@ packages: peerDependencies: rollup: '>=2' + '@modelcontextprotocol/sdk@1.27.1': + resolution: {integrity: sha512-sr6GbP+4edBwFndLbM60gf07z0FQ79gaExpnsjMGePXqFcSSb7t6iscpjk9DhFhwd+mTEQrzNafGP8/iGGFYaA==} + engines: {node: '>=18'} + peerDependencies: + '@cfworker/json-schema': ^4.1.1 + zod: ^3.25 || ^4.0 + peerDependenciesMeta: + '@cfworker/json-schema': + optional: true + '@napi-rs/wasm-runtime@1.1.1': resolution: {integrity: sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==} @@ -1287,6 +1334,9 @@ packages: resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} engines: {node: '>= 10'} + '@ts-morph/common@0.26.1': + resolution: {integrity: sha512-Sn28TGl/4cFpcM+jwsH1wLncYq3FtN/BIpem+HOygfBWPT5pAeS5dB4VFVzV8FbnOKHpDLZmvAl4AjPEev5idA==} + '@tybys/wasm-util@0.10.1': resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} @@ -1356,6 +1406,9 @@ packages: '@types/node@12.20.55': resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} + '@types/node@22.19.15': + resolution: {integrity: sha512-F0R/h2+dsy5wJAUe3tAU6oqa2qbWY5TpNfL/RGmo1y38hiyO1w3x2jPtt76wmuaJI4DQnOBu21cNXQ2STIUUWg==} + '@types/node@25.4.0': resolution: {integrity: sha512-9wLpoeWuBlcbBpOY3XmzSTG3oscB6xjBEEtn+pYXTfhyXhIxC5FsBer2KTopBlvKEiW9l13po9fq+SJY/5lkhw==} @@ -1466,6 +1519,10 @@ packages: resolution: {integrity: sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==} deprecated: Use your platform's native atob() and btoa() methods instead + accepts@2.0.0: + resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} + engines: {node: '>= 0.6'} + acorn-globals@7.0.1: resolution: {integrity: sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==} @@ -1495,6 +1552,14 @@ packages: resolution: {integrity: sha512-yqXL+k5rr8+ZRpOAntkaaRgWgE5o8ESAj5DyRmVTCSoZxXmqemb9Dd7T4i5UzwuERdLAJUy6XzR9zFVuf0kzkw==} engines: {node: '>= 4.0.0'} + ajv-formats@3.0.1: + resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + ajv@6.14.0: resolution: {integrity: sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==} @@ -1705,6 +1770,10 @@ packages: bluebird@3.7.2: resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} + body-parser@2.2.2: + resolution: {integrity: sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==} + engines: {node: '>=18'} + boxen@1.3.0: resolution: {integrity: sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==} engines: {node: '>=4'} @@ -1712,6 +1781,9 @@ packages: brace-expansion@1.1.12: resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} + brace-expansion@2.0.2: + resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} + brace-expansion@5.0.4: resolution: {integrity: sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==} engines: {node: 18 || 20 || >=22} @@ -1747,6 +1819,20 @@ packages: builtins@1.0.3: resolution: {integrity: sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ==} + bundle-require@5.1.0: + resolution: {integrity: sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + peerDependencies: + esbuild: '>=0.18' + + bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + cac@7.0.0: resolution: {integrity: sha512-tixWYgm5ZoOD+3g6UTea91eow5z6AAHaho3g0V9CNSNb45gM8SmflpAc+GRd1InC4AqN/07Unrgp56Y94N9hJQ==} engines: {node: '>=20.19.0'} @@ -1887,6 +1973,9 @@ packages: resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} + code-block-writer@13.0.3: + resolution: {integrity: sha512-Oofo0pq3IKnsFtuHqSF7TqBfr71aeyZDVJ0HpmqB7FBM2qEigL0iPONSCZSO9pE9dZTAxANe5XHG9Uy0YMv8cg==} + codesandbox-import-util-types@2.2.3: resolution: {integrity: sha512-Qj00p60oNExthP2oR3vvXmUGjukij+rxJGuiaKM6tyUmSyimdZsqHI/TUvFFClAffk9s7hxGnQgWQ8KCce27qQ==} @@ -1947,13 +2036,36 @@ packages: resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==} engines: {'0': node >= 0.8} + confbox@0.1.8: + resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} + configstore@3.1.5: resolution: {integrity: sha512-nlOhI4+fdzoK5xmJ+NY+1gZK56bwEaWZr8fYuXohZ9Vkc1o3a4T/R3M+yE/w7x/ZVJ1zF8c+oaOvF0dztdUgmA==} engines: {node: '>=4'} + consola@3.4.2: + resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} + engines: {node: ^14.18.0 || >=16.10.0} + + content-disposition@1.0.1: + resolution: {integrity: sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==} + engines: {node: '>=18'} + + content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + cookie-signature@1.2.2: + resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} + engines: {node: '>=6.6.0'} + + cookie@0.7.2: + resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} + engines: {node: '>= 0.6'} + copy-concurrently@1.0.5: resolution: {integrity: sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==} deprecated: This package is no longer supported. @@ -1961,6 +2073,10 @@ packages: core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + cors@2.8.6: + resolution: {integrity: sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==} + engines: {node: '>= 0.10'} + cosmiconfig@9.0.1: resolution: {integrity: sha512-hr4ihw+DBqcvrsEDioRO31Z17x71pUYoNe/4h6Z0wB72p7MU7/9gH8Q3s12NFhHPfYBBOV3qyfUxmr/Yn3shnQ==} engines: {node: '>=14'} @@ -2118,6 +2234,10 @@ packages: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + dequal@2.0.3: resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} engines: {node: '>=6'} @@ -2191,6 +2311,9 @@ packages: resolution: {integrity: sha512-ptGvkwTvGdGfC0hfhKg0MT+TRLRKGtUiWGBInxOm5pz7ssADezahjCUaYuZ8Dr+C05FW0AECIIPt4WBxVINEhA==} engines: {node: '>=0.8'} + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + electron-to-chromium@1.5.307: resolution: {integrity: sha512-5z3uFKBWjiNR44nFcYdkcXjKMbg5KXNdciu7mhTPo9tB7NbqSNP2sSnGR+fqknZSCwKkBN+oxiiajWs4dT6ORg==} @@ -2208,6 +2331,10 @@ packages: resolution: {integrity: sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==} engines: {node: '>=14'} + encodeurl@2.0.0: + resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} + engines: {node: '>= 0.8'} + encoding@0.1.13: resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==} @@ -2296,6 +2423,9 @@ packages: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + escape-string-regexp@1.0.5: resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} engines: {node: '>=0.8.0'} @@ -2430,9 +2560,21 @@ packages: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + eventemitter3@5.0.4: resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==} + eventsource-parser@3.0.6: + resolution: {integrity: sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==} + engines: {node: '>=18.0.0'} + + eventsource@3.0.7: + resolution: {integrity: sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==} + engines: {node: '>=18.0.0'} + execa@0.7.0: resolution: {integrity: sha512-RztN09XglpYI7aBBrJCPW95jEH7YF1UEPOoX9yDhUTPdp7mK+CQvnLTuD10BNXZ3byLTu2uehZ8EcKT/4CGiFw==} engines: {node: '>=4'} @@ -2457,6 +2599,16 @@ packages: resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + express-rate-limit@8.3.1: + resolution: {integrity: sha512-D1dKN+cmyPWuvB+G2SREQDzPY1agpBIcTa9sJxOPMCNeH3gwzhqJRDWCXW3gg0y//+LQ/8j52JbMROWyrKdMdw==} + engines: {node: '>= 16'} + peerDependencies: + express: '>= 4.11' + + express@5.2.1: + resolution: {integrity: sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==} + engines: {node: '>= 18'} + extend-shallow@2.0.1: resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} engines: {node: '>=0.10.0'} @@ -2529,6 +2681,10 @@ packages: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} + finalhandler@2.1.1: + resolution: {integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==} + engines: {node: '>= 18.0.0'} + find-file-up@0.1.3: resolution: {integrity: sha512-mBxmNbVyjg1LQIIpgO8hN+ybWBgDQK8qjht+EbrTCGmmPV/sc7RF1i9stPTD6bpvXZywBdrwRYxhSdJv867L6A==} engines: {node: '>=0.10.0'} @@ -2545,6 +2701,9 @@ packages: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} + fix-dts-default-cjs-exports@1.0.1: + resolution: {integrity: sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg==} + flat-cache@4.0.1: resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} engines: {node: '>=16'} @@ -2570,9 +2729,17 @@ packages: resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} engines: {node: '>= 6'} + forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + fraction.js@5.3.4: resolution: {integrity: sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==} + fresh@2.0.0: + resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} + engines: {node: '>= 0.8'} + from2@2.3.0: resolution: {integrity: sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==} @@ -2796,6 +2963,10 @@ packages: resolution: {integrity: sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==} engines: {node: '>=0.10.0'} + hono@4.12.9: + resolution: {integrity: sha512-wy3T8Zm2bsEvxKZM5w21VdHDDcwVS1yUFFY6i8UobSsKfFceT7TOwhbhfKsDyx7tYQlmRM5FLpIuYvNFyjctiA==} + engines: {node: '>=16.9.0'} + hookable@6.0.1: resolution: {integrity: sha512-uKGyY8BuzN/a5gvzvA+3FVWo0+wUjgtfSdnmjtrOVwQCZPHpHDH2WRO3VZSOeluYrHoDCiXFffZXs8Dj1ULWtw==} @@ -2819,6 +2990,10 @@ packages: http-cache-semantics@3.8.1: resolution: {integrity: sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==} + http-errors@2.0.1: + resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} + engines: {node: '>= 0.8'} + http-proxy-agent@2.1.0: resolution: {integrity: sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==} engines: {node: '>= 4.5.0'} @@ -2935,9 +3110,17 @@ packages: resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} engines: {node: '>= 0.4'} + ip-address@10.1.0: + resolution: {integrity: sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==} + engines: {node: '>= 12'} + ip@1.1.9: resolution: {integrity: sha512-cyRxvOEpNHNtchU3Ln9KC/auJgup87llfQpQ+t5ghoC/UhL16SWzbueiCsdTnWmqAWl7LadfuwhlqmtOaqMHdQ==} + ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + is-alphabetical@2.0.1: resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} @@ -3080,6 +3263,9 @@ packages: is-potential-custom-element-name@1.0.1: resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} + is-promise@4.0.0: + resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} + is-redirect@1.0.0: resolution: {integrity: sha512-cr/SlUEe5zOGmzvj9bUyC4LVvkNVAXu4GytXLNMr1pny+a65MpQ9IJzFHD5vi7FyJgb4qt27+eS3TuQnqB+RQw==} engines: {node: '>=0.10.0'} @@ -3335,6 +3521,13 @@ packages: resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} hasBin: true + jose@6.2.2: + resolution: {integrity: sha512-d7kPDd34KO/YnzaDOlikGpOurfF0ByC2sEV4cANCtdqLlTfBlw2p14O/5d/zv40gJPbIQxfES3nSx1/oYNyuZQ==} + + joycon@3.1.1: + resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} + engines: {node: '>=10'} + js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -3375,6 +3568,9 @@ packages: json-schema-traverse@1.0.0: resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + json-schema-typed@8.0.2: + resolution: {integrity: sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==} + json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} @@ -3442,6 +3638,10 @@ packages: resolution: {integrity: sha512-LWzX2KsqcB1wqQ4AHgYb4RsDXauQiqhjLk+6hjbaeHG4zpjjVAB6wC/gz6X0l+Du1cN3pUB5ZlrvTbhGSNnUQQ==} engines: {node: '>=18.0.0'} + load-tsconfig@0.2.5: + resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + locate-path@5.0.0: resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} engines: {node: '>=8'} @@ -3494,6 +3694,9 @@ packages: resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} hasBin: true + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + make-dir@1.3.0: resolution: {integrity: sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==} engines: {node: '>=4'} @@ -3576,10 +3779,18 @@ packages: mdn-data@2.27.1: resolution: {integrity: sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==} + media-typer@1.1.0: + resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==} + engines: {node: '>= 0.8'} + meow@13.2.0: resolution: {integrity: sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==} engines: {node: '>=18'} + merge-descriptors@2.0.0: + resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==} + engines: {node: '>=18'} + merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} @@ -3700,10 +3911,18 @@ packages: resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} engines: {node: '>= 0.6'} + mime-db@1.54.0: + resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} + engines: {node: '>= 0.6'} + mime-types@2.1.35: resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} engines: {node: '>= 0.6'} + mime-types@3.0.2: + resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} + engines: {node: '>=18'} + mimer@1.1.0: resolution: {integrity: sha512-y9dVfy2uiycQvDNiAYW6zp49ZhFlXDMr5wfdOiMbdzGM/0N5LNR6HTUn3un+WUQcM0koaw8FMTG1bt5EnHJdvQ==} engines: {node: '>= 6.0'} @@ -3736,6 +3955,10 @@ packages: minimatch@3.1.5: resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} + minimatch@9.0.9: + resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==} + engines: {node: '>=16 || 14 >=14.17'} + minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} @@ -3750,6 +3973,9 @@ packages: resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} hasBin: true + mlly@1.8.2: + resolution: {integrity: sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==} + move-concurrently@1.0.1: resolution: {integrity: sha512-hdrFxZOycD/g6A6SoI2bB5NA/5NEqD0569+S47WZhPvm46sD50ZHdYaFmnua5lndde9rCHGjmfK7Z8BuCt/PcQ==} deprecated: This package is no longer supported. @@ -3778,6 +4004,10 @@ packages: natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + negotiator@1.0.0: + resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} + engines: {node: '>= 0.6'} + neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} @@ -3871,6 +4101,10 @@ packages: obug@2.1.1: resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} @@ -3992,6 +4226,13 @@ packages: parse5@7.3.0: resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} + parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + + path-browserify@1.0.1: + resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} + path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} @@ -4018,6 +4259,9 @@ packages: path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + path-to-regexp@8.3.0: + resolution: {integrity: sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==} + path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} @@ -4053,14 +4297,39 @@ packages: resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} engines: {node: '>= 6'} + pkce-challenge@5.0.1: + resolution: {integrity: sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==} + engines: {node: '>=16.20.0'} + pkg-dir@4.2.0: resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} engines: {node: '>=8'} + pkg-types@1.3.1: + resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} + possible-typed-array-names@1.1.0: resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} engines: {node: '>= 0.4'} + postcss-load-config@6.0.1: + resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} + engines: {node: '>= 18'} + peerDependencies: + jiti: '>=1.21.0' + postcss: '>=8.0.9' + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + jiti: + optional: true + postcss: + optional: true + tsx: + optional: true + yaml: + optional: true + postcss-media-query-parser@0.2.3: resolution: {integrity: sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==} @@ -4149,6 +4418,10 @@ packages: protoduck@4.0.0: resolution: {integrity: sha512-9sxuz0YTU/68O98xuDn8NBxTVH9EuMhrBTxZdiBL0/qxRmWhB/5a8MagAebDa+98vluAZTs8kMZibCdezbRCeQ==} + proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} + pseudomap@1.0.2: resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==} @@ -4175,6 +4448,10 @@ packages: resolution: {integrity: sha512-tsSGN1x3h569ZSU1u6diwhltLyfUWDp3YbFHedapTmpBl0B3P6U3+Qptg7xu+v+1io1EwhdPyyRHYbEw0KN2FA==} engines: {node: '>=20'} + qs@6.15.0: + resolution: {integrity: sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==} + engines: {node: '>=0.6'} + quansync@0.2.11: resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} @@ -4190,6 +4467,14 @@ packages: queue@6.0.1: resolution: {integrity: sha512-AJBQabRCCNr9ANq8v77RJEv73DPbn55cdTb+Giq4X0AVnNVZvMHlYp7XlQiN+1npCZj1DuSmaA2hYVUUDgxFDg==} + range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + + raw-body@3.0.2: + resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==} + engines: {node: '>= 0.10'} + rc@1.2.8: resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} hasBin: true @@ -4413,6 +4698,10 @@ packages: engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true + router@2.2.0: + resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} + engines: {node: '>= 18'} + run-async@2.4.1: resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} engines: {node: '>=0.12.0'} @@ -4477,6 +4766,14 @@ packages: engines: {node: '>=10'} hasBin: true + send@1.2.1: + resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==} + engines: {node: '>= 18'} + + serve-static@2.2.1: + resolution: {integrity: sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==} + engines: {node: '>= 18'} + set-function-length@1.2.2: resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} engines: {node: '>= 0.4'} @@ -4489,6 +4786,9 @@ packages: resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} engines: {node: '>= 0.4'} + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + shebang-command@1.2.0: resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} engines: {node: '>=0.10.0'} @@ -4608,6 +4908,10 @@ packages: resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} engines: {node: '>=10'} + statuses@2.0.2: + resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} + engines: {node: '>= 0.8'} + stop-iteration-iterator@1.1.0: resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} engines: {node: '>= 0.4'} @@ -4835,6 +5139,9 @@ packages: resolution: {integrity: sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==} engines: {node: '>=0.10.0'} + tinyexec@0.3.2: + resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + tinyexec@1.0.2: resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==} engines: {node: '>=18'} @@ -4858,6 +5165,10 @@ packages: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + tough-cookie@4.1.4: resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==} engines: {node: '>=6'} @@ -4915,6 +5226,9 @@ packages: jest-util: optional: true + ts-morph@25.0.1: + resolution: {integrity: sha512-QJEiTdnz1YjrB3JFhd626gX4rKHDLSjSVMvGGG4v7ONc3RBwa0Eei98G9AT9uNFDMtV54JyuXsFeC+OH0n6bXQ==} + tsdown@0.21.2: resolution: {integrity: sha512-pP8eAcd1XAWjl5gjosuJs0BAuVoheUe3V8VDHx31QK7YOgXjcCMsBSyFWO3CMh/CSUkjRUzR96JtGH3WJFTExQ==} engines: {node: '>=20.19.0'} @@ -4949,6 +5263,30 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + tsup@8.5.1: + resolution: {integrity: sha512-xtgkqwdhpKWr3tKPmCkvYmS9xnQK3m3XgxZHwSUjvfTjp7YfXe5tT3GgWi0F2N+ZSMsOeWeZFh7ZZFg5iPhing==} + engines: {node: '>=18'} + hasBin: true + peerDependencies: + '@microsoft/api-extractor': ^7.36.0 + '@swc/core': ^1 + postcss: ^8.4.12 + typescript: '>=4.5.0' + peerDependenciesMeta: + '@microsoft/api-extractor': + optional: true + '@swc/core': + optional: true + postcss: + optional: true + typescript: + optional: true + + tsx@4.21.0: + resolution: {integrity: sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==} + engines: {node: '>=18.0.0'} + hasBin: true + turbo-darwin-64@2.8.16: resolution: {integrity: sha512-KWa4hUMWrpADC6Q/wIHRkBLw6X6MV9nx6X7hSXbTrrMz0KdaKhmfudUZ3sS76bJFmgArBU25cSc0AUyyrswYxg==} cpu: [x64] @@ -4999,6 +5337,10 @@ packages: resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} engines: {node: '>=16'} + type-is@2.0.1: + resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==} + engines: {node: '>= 0.6'} + typed-array-buffer@1.0.3: resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} engines: {node: '>= 0.4'} @@ -5030,6 +5372,9 @@ packages: engines: {node: '>=14.17'} hasBin: true + ufo@1.6.3: + resolution: {integrity: sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==} + uglify-js@3.19.3: resolution: {integrity: sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==} engines: {node: '>=0.8.0'} @@ -5042,6 +5387,9 @@ packages: unconfig-core@7.5.0: resolution: {integrity: sha512-Su3FauozOGP44ZmKdHy2oE6LPjk51M/TRRjHv2HNCWiDvfvCoxC2lno6jevMA91MYAdCdwP05QnWdWpSbncX/w==} + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + undici-types@7.18.2: resolution: {integrity: sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==} @@ -5084,6 +5432,10 @@ packages: resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} engines: {node: '>= 4.0.0'} + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + unrun@0.2.32: resolution: {integrity: sha512-opd3z6791rf281JdByf0RdRQrpcc7WyzqittqIXodM/5meNWdTwrVxeyzbaCp4/Rgls/um14oUaif1gomO8YGg==} engines: {node: '>=20.19.0'} @@ -5131,6 +5483,10 @@ packages: validate-npm-package-name@3.0.0: resolution: {integrity: sha512-M6w37eVCMMouJ9V/sdPGnC5H4uDr73/+xdq0FBLO3TFFX1+7wiUY6Es328NN+y43tmY+doUdN9g9J21vqB7iLw==} + vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + vfile-message@4.0.3: resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} @@ -5325,6 +5681,14 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} + zod-to-json-schema@3.25.1: + resolution: {integrity: sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA==} + peerDependencies: + zod: ^3.25 || ^4 + + zod@4.3.6: + resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==} + zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} @@ -5884,6 +6248,10 @@ snapshots: '@eslint/core': 0.17.0 levn: 0.4.1 + '@hono/node-server@1.19.11(hono@4.12.9)': + dependencies: + hono: 4.12.9 + '@humanfs/core@0.19.1': {} '@humanfs/node@0.16.7': @@ -5915,7 +6283,7 @@ snapshots: '@jest/console@29.7.0': dependencies: '@jest/types': 29.6.3 - '@types/node': 25.4.0 + '@types/node': 22.19.15 chalk: 4.1.2 jest-message-util: 29.7.0 jest-util: 29.7.0 @@ -5928,14 +6296,14 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 25.4.0 + '@types/node': 22.19.15 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 3.9.0 exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@25.4.0) + jest-config: 29.7.0(@types/node@22.19.15) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -5960,7 +6328,7 @@ snapshots: dependencies: '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 25.4.0 + '@types/node': 22.19.15 jest-mock: 29.7.0 '@jest/expect-utils@29.7.0': @@ -5978,7 +6346,7 @@ snapshots: dependencies: '@jest/types': 29.6.3 '@sinonjs/fake-timers': 10.3.0 - '@types/node': 25.4.0 + '@types/node': 22.19.15 jest-message-util: 29.7.0 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -6000,7 +6368,7 @@ snapshots: '@jest/transform': 29.7.0 '@jest/types': 29.6.3 '@jridgewell/trace-mapping': 0.3.31 - '@types/node': 25.4.0 + '@types/node': 22.19.15 chalk: 4.1.2 collect-v8-coverage: 1.0.3 exit: 0.1.2 @@ -6070,7 +6438,7 @@ snapshots: '@jest/schemas': 29.6.3 '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 - '@types/node': 25.4.0 + '@types/node': 22.19.15 '@types/yargs': 17.0.35 chalk: 4.1.2 @@ -6163,6 +6531,28 @@ snapshots: transitivePeerDependencies: - supports-color + '@modelcontextprotocol/sdk@1.27.1(zod@4.3.6)': + dependencies: + '@hono/node-server': 1.19.11(hono@4.12.9) + ajv: 8.18.0 + ajv-formats: 3.0.1(ajv@8.18.0) + content-type: 1.0.5 + cors: 2.8.6 + cross-spawn: 7.0.6 + eventsource: 3.0.7 + eventsource-parser: 3.0.6 + express: 5.2.1 + express-rate-limit: 8.3.1(express@5.2.1) + hono: 4.12.9 + jose: 6.2.2 + json-schema-typed: 8.0.2 + pkce-challenge: 5.0.1 + raw-body: 3.0.2 + zod: 4.3.6 + zod-to-json-schema: 3.25.1(zod@4.3.6) + transitivePeerDependencies: + - supports-color + '@napi-rs/wasm-runtime@1.1.1': dependencies: '@emnapi/core': 1.8.1 @@ -6431,6 +6821,12 @@ snapshots: '@tootallnate/once@2.0.0': {} + '@ts-morph/common@0.26.1': + dependencies: + fast-glob: 3.3.3 + minimatch: 9.0.9 + path-browserify: 1.0.1 + '@tybys/wasm-util@0.10.1': dependencies: tslib: 2.8.1 @@ -6471,7 +6867,7 @@ snapshots: '@types/graceful-fs@4.1.9': dependencies: - '@types/node': 25.4.0 + '@types/node': 22.19.15 '@types/hast@3.0.4': dependencies: @@ -6494,7 +6890,7 @@ snapshots: '@types/jsdom@20.0.1': dependencies: - '@types/node': 25.4.0 + '@types/node': 22.19.15 '@types/tough-cookie': 4.0.5 parse5: 7.3.0 @@ -6504,7 +6900,7 @@ snapshots: '@types/keyv@3.1.4': dependencies: - '@types/node': 25.4.0 + '@types/node': 22.19.15 '@types/mdast@4.0.4': dependencies: @@ -6516,6 +6912,10 @@ snapshots: '@types/node@12.20.55': {} + '@types/node@22.19.15': + dependencies: + undici-types: 6.21.0 + '@types/node@25.4.0': dependencies: undici-types: 7.18.2 @@ -6535,7 +6935,7 @@ snapshots: '@types/responselike@1.0.3': dependencies: - '@types/node': 25.4.0 + '@types/node': 22.19.15 '@types/stack-utils@2.0.3': {} @@ -6644,7 +7044,7 @@ snapshots: '@ungap/structured-clone@1.3.0': {} - '@vitejs/plugin-react@5.1.4(vite@7.3.1(@types/node@25.4.0)(jiti@2.6.1)(sass@1.98.0)(yaml@2.8.2))': + '@vitejs/plugin-react@5.1.4(vite@7.3.1(@types/node@25.4.0)(jiti@2.6.1)(sass@1.98.0)(tsx@4.21.0)(yaml@2.8.2))': dependencies: '@babel/core': 7.29.0 '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.29.0) @@ -6652,12 +7052,17 @@ snapshots: '@rolldown/pluginutils': 1.0.0-rc.3 '@types/babel__core': 7.20.5 react-refresh: 0.18.0 - vite: 7.3.1(@types/node@25.4.0)(jiti@2.6.1)(sass@1.98.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@25.4.0)(jiti@2.6.1)(sass@1.98.0)(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - supports-color abab@2.0.6: {} + accepts@2.0.0: + dependencies: + mime-types: 3.0.2 + negotiator: 1.0.0 + acorn-globals@7.0.1: dependencies: acorn: 8.16.0 @@ -6687,6 +7092,10 @@ snapshots: dependencies: humanize-ms: 1.2.1 + ajv-formats@3.0.1(ajv@8.18.0): + optionalDependencies: + ajv: 8.18.0 + ajv@6.14.0: dependencies: fast-deep-equal: 3.1.3 @@ -6933,6 +7342,20 @@ snapshots: bluebird@3.7.2: {} + body-parser@2.2.2: + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 4.4.3 + http-errors: 2.0.1 + iconv-lite: 0.7.2 + on-finished: 2.4.1 + qs: 6.15.0 + raw-body: 3.0.2 + type-is: 2.0.1 + transitivePeerDependencies: + - supports-color + boxen@1.3.0: dependencies: ansi-align: 2.0.0 @@ -6948,6 +7371,10 @@ snapshots: balanced-match: 1.0.2 concat-map: 0.0.1 + brace-expansion@2.0.2: + dependencies: + balanced-match: 1.0.2 + brace-expansion@5.0.4: dependencies: balanced-match: 4.0.4 @@ -6985,6 +7412,15 @@ snapshots: builtins@1.0.3: {} + bundle-require@5.1.0(esbuild@0.27.3): + dependencies: + esbuild: 0.27.3 + load-tsconfig: 0.2.5 + + bytes@3.1.2: {} + + cac@6.7.14: {} + cac@7.0.0: {} cacache@10.0.4: @@ -7128,6 +7564,8 @@ snapshots: co@4.6.0: {} + code-block-writer@13.0.3: {} + codesandbox-import-util-types@2.2.3: {} codesandbox-import-utils@2.2.3: @@ -7203,6 +7641,8 @@ snapshots: readable-stream: 2.3.8 typedarray: 0.0.6 + confbox@0.1.8: {} + configstore@3.1.5: dependencies: dot-prop: 4.2.1 @@ -7212,8 +7652,18 @@ snapshots: write-file-atomic: 2.4.3 xdg-basedir: 3.0.0 + consola@3.4.2: {} + + content-disposition@1.0.1: {} + + content-type@1.0.5: {} + convert-source-map@2.0.0: {} + cookie-signature@1.2.2: {} + + cookie@0.7.2: {} + copy-concurrently@1.0.5: dependencies: aproba: 1.2.0 @@ -7225,6 +7675,11 @@ snapshots: core-util-is@1.0.3: {} + cors@2.8.6: + dependencies: + object-assign: 4.1.1 + vary: 1.1.2 + cosmiconfig@9.0.1(typescript@5.9.3): dependencies: env-paths: 2.2.1 @@ -7238,6 +7693,21 @@ snapshots: dependencies: capture-stack-trace: 1.0.2 + create-jest@29.7.0(@types/node@22.19.15): + dependencies: + '@jest/types': 29.6.3 + chalk: 4.1.2 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-config: 29.7.0(@types/node@22.19.15) + jest-util: 29.7.0 + prompts: 2.4.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + create-jest@29.7.0(@types/node@25.4.0): dependencies: '@jest/types': 29.6.3 @@ -7388,6 +7858,8 @@ snapshots: delayed-stream@1.0.0: {} + depd@2.0.0: {} + dequal@2.0.3: {} detect-indent@6.1.0: {} @@ -7447,6 +7919,8 @@ snapshots: errlop: 2.2.0 semver: 6.3.1 + ee-first@1.1.1: {} + electron-to-chromium@1.5.307: {} emittery@0.13.1: {} @@ -7457,6 +7931,8 @@ snapshots: empathic@2.0.0: {} + encodeurl@2.0.0: {} + encoding@0.1.13: dependencies: iconv-lite: 0.6.3 @@ -7649,6 +8125,8 @@ snapshots: escalade@3.2.0: {} + escape-html@1.0.3: {} + escape-string-regexp@1.0.5: {} escape-string-regexp@2.0.0: {} @@ -7821,8 +8299,16 @@ snapshots: esutils@2.0.3: {} + etag@1.8.1: {} + eventemitter3@5.0.4: {} + eventsource-parser@3.0.6: {} + + eventsource@3.0.7: + dependencies: + eventsource-parser: 3.0.6 + execa@0.7.0: dependencies: cross-spawn: 5.1.0 @@ -7871,6 +8357,44 @@ snapshots: jest-message-util: 29.7.0 jest-util: 29.7.0 + express-rate-limit@8.3.1(express@5.2.1): + dependencies: + express: 5.2.1 + ip-address: 10.1.0 + + express@5.2.1: + dependencies: + accepts: 2.0.0 + body-parser: 2.2.2 + content-disposition: 1.0.1 + content-type: 1.0.5 + cookie: 0.7.2 + cookie-signature: 1.2.2 + debug: 4.4.3 + depd: 2.0.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 2.1.1 + fresh: 2.0.0 + http-errors: 2.0.1 + merge-descriptors: 2.0.0 + mime-types: 3.0.2 + on-finished: 2.4.1 + once: 1.4.0 + parseurl: 1.3.3 + proxy-addr: 2.0.7 + qs: 6.15.0 + range-parser: 1.2.1 + router: 2.2.0 + send: 1.2.1 + serve-static: 2.2.1 + statuses: 2.0.2 + type-is: 2.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + extend-shallow@2.0.1: dependencies: is-extendable: 0.1.1 @@ -7935,6 +8459,17 @@ snapshots: dependencies: to-regex-range: 5.0.1 + finalhandler@2.1.1: + dependencies: + debug: 4.4.3 + encodeurl: 2.0.0 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + find-file-up@0.1.3: dependencies: fs-exists-sync: 0.1.0 @@ -7954,6 +8489,12 @@ snapshots: locate-path: 6.0.0 path-exists: 4.0.0 + fix-dts-default-cjs-exports@1.0.1: + dependencies: + magic-string: 0.30.21 + mlly: 1.8.2 + rollup: 4.59.0 + flat-cache@4.0.1: dependencies: flatted: 3.4.1 @@ -7990,8 +8531,12 @@ snapshots: hasown: 2.0.2 mime-types: 2.1.35 + forwarded@0.2.0: {} + fraction.js@5.3.4: {} + fresh@2.0.0: {} + from2@2.3.0: dependencies: inherits: 2.0.4 @@ -8287,6 +8832,8 @@ snapshots: dependencies: parse-passwd: 1.0.0 + hono@4.12.9: {} + hookable@6.0.1: {} hookified@1.15.1: {} @@ -8303,6 +8850,14 @@ snapshots: http-cache-semantics@3.8.1: {} + http-errors@2.0.1: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.2 + toidentifier: 1.0.1 + http-proxy-agent@2.1.0: dependencies: agent-base: 4.3.0 @@ -8421,8 +8976,12 @@ snapshots: hasown: 2.0.2 side-channel: 1.1.0 + ip-address@10.1.0: {} + ip@1.1.9: {} + ipaddr.js@1.9.1: {} + is-alphabetical@2.0.1: {} is-alphanumerical@2.0.1: @@ -8549,6 +9108,8 @@ snapshots: is-potential-custom-element-name@1.0.1: {} + is-promise@4.0.0: {} + is-redirect@1.0.0: {} is-regex@1.2.1: @@ -8682,7 +9243,7 @@ snapshots: '@jest/expect': 29.7.0 '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 25.4.0 + '@types/node': 22.19.15 chalk: 4.1.2 co: 4.6.0 dedent: 1.7.2 @@ -8702,6 +9263,25 @@ snapshots: - babel-plugin-macros - supports-color + jest-cli@29.7.0(@types/node@22.19.15): + dependencies: + '@jest/core': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + chalk: 4.1.2 + create-jest: 29.7.0(@types/node@22.19.15) + exit: 0.1.2 + import-local: 3.2.0 + jest-config: 29.7.0(@types/node@22.19.15) + jest-util: 29.7.0 + jest-validate: 29.7.0 + yargs: 17.7.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + jest-cli@29.7.0(@types/node@25.4.0): dependencies: '@jest/core': 29.7.0 @@ -8721,6 +9301,36 @@ snapshots: - supports-color - ts-node + jest-config@29.7.0(@types/node@22.19.15): + dependencies: + '@babel/core': 7.29.0 + '@jest/test-sequencer': 29.7.0 + '@jest/types': 29.6.3 + babel-jest: 29.7.0(@babel/core@7.29.0) + chalk: 4.1.2 + ci-info: 3.9.0 + deepmerge: 4.3.1 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-circus: 29.7.0 + jest-environment-node: 29.7.0 + jest-get-type: 29.6.3 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-runner: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + micromatch: 4.0.8 + parse-json: 5.2.0 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-json-comments: 3.1.1 + optionalDependencies: + '@types/node': 22.19.15 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + jest-config@29.7.0(@types/node@25.4.0): dependencies: '@babel/core': 7.29.0 @@ -8790,7 +9400,7 @@ snapshots: '@jest/environment': 29.7.0 '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 25.4.0 + '@types/node': 22.19.15 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -8800,7 +9410,7 @@ snapshots: dependencies: '@jest/types': 29.6.3 '@types/graceful-fs': 4.1.9 - '@types/node': 25.4.0 + '@types/node': 22.19.15 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.11 @@ -8839,7 +9449,7 @@ snapshots: jest-mock@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 25.4.0 + '@types/node': 22.19.15 jest-util: 29.7.0 jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): @@ -8874,7 +9484,7 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 25.4.0 + '@types/node': 22.19.15 chalk: 4.1.2 emittery: 0.13.1 graceful-fs: 4.2.11 @@ -8902,7 +9512,7 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 25.4.0 + '@types/node': 22.19.15 chalk: 4.1.2 cjs-module-lexer: 1.4.3 collect-v8-coverage: 1.0.3 @@ -8948,7 +9558,7 @@ snapshots: jest-util@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 25.4.0 + '@types/node': 22.19.15 chalk: 4.1.2 ci-info: 3.9.0 graceful-fs: 4.2.11 @@ -8967,7 +9577,7 @@ snapshots: dependencies: '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 25.4.0 + '@types/node': 22.19.15 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.13.1 @@ -8976,11 +9586,23 @@ snapshots: jest-worker@29.7.0: dependencies: - '@types/node': 25.4.0 + '@types/node': 22.19.15 jest-util: 29.7.0 merge-stream: 2.0.0 supports-color: 8.1.1 + jest@29.7.0(@types/node@22.19.15): + dependencies: + '@jest/core': 29.7.0 + '@jest/types': 29.6.3 + import-local: 3.2.0 + jest-cli: 29.7.0(@types/node@22.19.15) + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + jest@29.7.0(@types/node@25.4.0): dependencies: '@jest/core': 29.7.0 @@ -8996,6 +9618,10 @@ snapshots: jiti@2.6.1: optional: true + jose@6.2.2: {} + + joycon@3.1.1: {} + js-tokens@4.0.0: {} js-yaml@3.14.2: @@ -9052,6 +9678,8 @@ snapshots: json-schema-traverse@1.0.0: {} + json-schema-typed@8.0.2: {} + json-stable-stringify-without-jsonify@1.0.1: {} json5@2.2.3: {} @@ -9126,6 +9754,8 @@ snapshots: rfdc: 1.4.1 wrap-ansi: 9.0.2 + load-tsconfig@0.2.5: {} + locate-path@5.0.0: dependencies: p-locate: 4.1.0 @@ -9175,6 +9805,10 @@ snapshots: lz-string@1.5.0: {} + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + make-dir@1.3.0: dependencies: pify: 3.0.0 @@ -9378,8 +10012,12 @@ snapshots: mdn-data@2.27.1: {} + media-typer@1.1.0: {} + meow@13.2.0: {} + merge-descriptors@2.0.0: {} + merge-stream@2.0.0: {} merge2@1.4.1: {} @@ -9655,10 +10293,16 @@ snapshots: mime-db@1.52.0: {} + mime-db@1.54.0: {} + mime-types@2.1.35: dependencies: mime-db: 1.52.0 + mime-types@3.0.2: + dependencies: + mime-db: 1.54.0 + mimer@1.1.0: {} mimic-fn@1.2.0: {} @@ -9679,6 +10323,10 @@ snapshots: dependencies: brace-expansion: 1.1.12 + minimatch@9.0.9: + dependencies: + brace-expansion: 2.0.2 + minimist@1.2.8: {} mississippi@1.3.1: @@ -9711,6 +10359,13 @@ snapshots: dependencies: minimist: 1.2.8 + mlly@1.8.2: + dependencies: + acorn: 8.16.0 + pathe: 2.0.3 + pkg-types: 1.3.1 + ufo: 1.6.3 + move-concurrently@1.0.1: dependencies: aproba: 1.2.0 @@ -9738,6 +10393,8 @@ snapshots: natural-compare@1.4.0: {} + negotiator@1.0.0: {} + neo-async@2.6.2: {} node-addon-api@7.1.1: @@ -9844,6 +10501,10 @@ snapshots: obug@2.1.1: {} + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 + once@1.4.0: dependencies: wrappy: 1.0.2 @@ -10008,6 +10669,10 @@ snapshots: dependencies: entities: 6.0.1 + parseurl@1.3.3: {} + + path-browserify@1.0.1: {} + path-exists@4.0.0: {} path-is-absolute@1.0.1: {} @@ -10022,6 +10687,8 @@ snapshots: path-parse@1.0.7: {} + path-to-regexp@8.3.0: {} + path-type@4.0.0: {} pathe@2.0.3: {} @@ -10040,12 +10707,29 @@ snapshots: pirates@4.0.7: {} + pkce-challenge@5.0.1: {} + pkg-dir@4.2.0: dependencies: find-up: 4.1.0 + pkg-types@1.3.1: + dependencies: + confbox: 0.1.8 + mlly: 1.8.2 + pathe: 2.0.3 + possible-typed-array-names@1.1.0: {} + postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(yaml@2.8.2): + dependencies: + lilconfig: 3.1.3 + optionalDependencies: + jiti: 2.6.1 + postcss: 8.5.8 + tsx: 4.21.0 + yaml: 2.8.2 + postcss-media-query-parser@0.2.3: {} postcss-resolve-nested-selector@0.1.6: {} @@ -10125,6 +10809,11 @@ snapshots: dependencies: genfun: 4.0.1 + proxy-addr@2.0.7: + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + pseudomap@1.0.2: {} psl@1.15.0: @@ -10155,6 +10844,10 @@ snapshots: dependencies: hookified: 1.15.1 + qs@6.15.0: + dependencies: + side-channel: 1.1.0 + quansync@0.2.11: {} quansync@1.0.0: {} @@ -10167,6 +10860,15 @@ snapshots: dependencies: inherits: 2.0.4 + range-parser@1.2.1: {} + + raw-body@3.0.2: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.1 + iconv-lite: 0.7.2 + unpipe: 1.0.0 + rc@1.2.8: dependencies: deep-extend: 0.6.0 @@ -10494,6 +11196,16 @@ snapshots: '@rollup/rollup-win32-x64-msvc': 4.59.0 fsevents: 2.3.3 + router@2.2.0: + dependencies: + debug: 4.4.3 + depd: 2.0.0 + is-promise: 4.0.0 + parseurl: 1.3.3 + path-to-regexp: 8.3.0 + transitivePeerDependencies: + - supports-color + run-async@2.4.1: {} run-parallel@1.2.0: @@ -10559,6 +11271,31 @@ snapshots: semver@7.7.4: {} + send@1.2.1: + dependencies: + debug: 4.4.3 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 2.0.0 + http-errors: 2.0.1 + mime-types: 3.0.2 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + + serve-static@2.2.1: + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 1.2.1 + transitivePeerDependencies: + - supports-color + set-function-length@1.2.2: dependencies: define-data-property: 1.1.4 @@ -10581,6 +11318,8 @@ snapshots: es-errors: 1.3.0 es-object-atoms: 1.1.1 + setprototypeof@1.2.0: {} + shebang-command@1.2.0: dependencies: shebang-regex: 1.0.0 @@ -10707,6 +11446,8 @@ snapshots: dependencies: escape-string-regexp: 2.0.0 + statuses@2.0.2: {} + stop-iteration-iterator@1.1.0: dependencies: es-errors: 1.3.0 @@ -11010,6 +11751,8 @@ snapshots: timed-out@4.0.1: {} + tinyexec@0.3.2: {} + tinyexec@1.0.2: {} tinyglobby@0.2.15: @@ -11033,6 +11776,8 @@ snapshots: dependencies: is-number: 7.0.0 + toidentifier@1.0.1: {} + tough-cookie@4.1.4: dependencies: psl: 1.15.0 @@ -11058,6 +11803,27 @@ snapshots: ts-interface-checker@0.1.13: {} + ts-jest@29.4.6(@babel/core@7.29.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.29.0))(esbuild@0.27.3)(jest-util@29.7.0)(jest@29.7.0(@types/node@22.19.15))(typescript@5.9.3): + dependencies: + bs-logger: 0.2.6 + fast-json-stable-stringify: 2.1.0 + handlebars: 4.7.8 + jest: 29.7.0(@types/node@22.19.15) + json5: 2.2.3 + lodash.memoize: 4.1.2 + make-error: 1.3.6 + semver: 7.7.4 + type-fest: 4.41.0 + typescript: 5.9.3 + yargs-parser: 21.1.1 + optionalDependencies: + '@babel/core': 7.29.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + babel-jest: 29.7.0(@babel/core@7.29.0) + esbuild: 0.27.3 + jest-util: 29.7.0 + ts-jest@29.4.6(@babel/core@7.29.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.29.0))(jest-util@29.7.0)(jest@29.7.0(@types/node@25.4.0))(typescript@5.9.3): dependencies: bs-logger: 0.2.6 @@ -11078,6 +11844,11 @@ snapshots: babel-jest: 29.7.0(@babel/core@7.29.0) jest-util: 29.7.0 + ts-morph@25.0.1: + dependencies: + '@ts-morph/common': 0.26.1 + code-block-writer: 13.0.3 + tsdown@0.21.2(typescript@5.9.3): dependencies: ansis: 4.2.0 @@ -11109,6 +11880,41 @@ snapshots: tslib@2.8.1: {} + tsup@8.5.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2): + dependencies: + bundle-require: 5.1.0(esbuild@0.27.3) + cac: 6.7.14 + chokidar: 4.0.3 + consola: 3.4.2 + debug: 4.4.3 + esbuild: 0.27.3 + fix-dts-default-cjs-exports: 1.0.1 + joycon: 3.1.1 + picocolors: 1.1.1 + postcss-load-config: 6.0.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(yaml@2.8.2) + resolve-from: 5.0.0 + rollup: 4.59.0 + source-map: 0.7.6 + sucrase: 3.35.1 + tinyexec: 0.3.2 + tinyglobby: 0.2.15 + tree-kill: 1.2.2 + optionalDependencies: + postcss: 8.5.8 + typescript: 5.9.3 + transitivePeerDependencies: + - jiti + - supports-color + - tsx + - yaml + + tsx@4.21.0: + dependencies: + esbuild: 0.27.3 + get-tsconfig: 4.13.6 + optionalDependencies: + fsevents: 2.3.3 + turbo-darwin-64@2.8.16: optional: true @@ -11146,6 +11952,12 @@ snapshots: type-fest@4.41.0: {} + type-is@2.0.1: + dependencies: + content-type: 1.0.5 + media-typer: 1.1.0 + mime-types: 3.0.2 + typed-array-buffer@1.0.3: dependencies: call-bound: 1.0.4 @@ -11194,6 +12006,8 @@ snapshots: typescript@5.9.3: {} + ufo@1.6.3: {} + uglify-js@3.19.3: optional: true @@ -11209,6 +12023,8 @@ snapshots: '@quansync/fs': 1.0.0 quansync: 1.0.0 + undici-types@6.21.0: {} + undici-types@7.18.2: {} unified@11.0.5: @@ -11264,6 +12080,8 @@ snapshots: universalify@0.2.0: {} + unpipe@1.0.0: {} + unrun@0.2.32: dependencies: rolldown: 1.0.0-rc.9 @@ -11319,6 +12137,8 @@ snapshots: dependencies: builtins: 1.0.3 + vary@1.1.2: {} + vfile-message@4.0.3: dependencies: '@types/unist': 3.0.3 @@ -11329,7 +12149,7 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.3 - vite@7.3.1(@types/node@25.4.0)(jiti@2.6.1)(sass@1.98.0)(yaml@2.8.2): + vite@7.3.1(@types/node@25.4.0)(jiti@2.6.1)(sass@1.98.0)(tsx@4.21.0)(yaml@2.8.2): dependencies: esbuild: 0.27.3 fdir: 6.5.0(picomatch@4.0.3) @@ -11342,6 +12162,7 @@ snapshots: fsevents: 2.3.3 jiti: 2.6.1 sass: 1.98.0 + tsx: 4.21.0 yaml: 2.8.2 w3c-xmlserializer@4.0.0: @@ -11495,4 +12316,10 @@ snapshots: yocto-queue@0.1.0: {} + zod-to-json-schema@3.25.1(zod@4.3.6): + dependencies: + zod: 4.3.6 + + zod@4.3.6: {} + zwitch@2.0.4: {}